You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

363 lines
10 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/string/shim_string.hpp
  3. *
  4. * Purpose: Contains the basic_shim_string template class.
  5. *
  6. * Created: 9th July 2004
  7. * Updated: 11th May 2010
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2004-2010, Matthew Wilson and Synesis Software
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright notice, this
  18. * list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  23. * any contributors may be used to endorse or promote products derived from
  24. * this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * ////////////////////////////////////////////////////////////////////// */
  39. /** \file stlsoft/string/shim_string.hpp
  40. *
  41. * \brief [C++ only] Definition of the stlsoft::basic_shim_string class
  42. * template
  43. * (\ref group__library__string "String" Library).
  44. */
  45. #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_SHIM_STRING
  46. #define STLSOFT_INCL_STLSOFT_STRING_HPP_SHIM_STRING
  47. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  48. # define STLSOFT_VER_STLSOFT_STRING_HPP_SHIM_STRING_MAJOR 3
  49. # define STLSOFT_VER_STLSOFT_STRING_HPP_SHIM_STRING_MINOR 3
  50. # define STLSOFT_VER_STLSOFT_STRING_HPP_SHIM_STRING_REVISION 1
  51. # define STLSOFT_VER_STLSOFT_STRING_HPP_SHIM_STRING_EDIT 44
  52. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  53. /* /////////////////////////////////////////////////////////////////////////
  54. * Includes
  55. */
  56. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  57. # include <stlsoft/stlsoft.h>
  58. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  59. #if defined(STLSOFT_COMPILER_IS_MSVC) && \
  60. _MSC_VER < 1200
  61. # include <stlsoft/string/shim_string_vc5_.hpp>
  62. #else /* ? compiler */
  63. #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_CHAR_TRAITS
  64. # include <stlsoft/string/char_traits.hpp>
  65. #endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_CHAR_TRAITS */
  66. #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR
  67. # include <stlsoft/memory/allocator_selector.hpp>
  68. #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR */
  69. #ifndef STLSOFT_INCL_STLSOFT_HPP_MEMORY_AUTO_BUFFER
  70. # include <stlsoft/memory/auto_buffer.hpp>
  71. #endif /* !STLSOFT_INCL_STLSOFT_HPP_MEMORY_AUTO_BUFFER */
  72. #ifndef STLSOFT_INCL_STLSOFT_META_HPP_YESNO
  73. # include <stlsoft/meta/yesno.hpp>
  74. #endif /* !STLSOFT_INCL_STLSOFT_META_HPP_YESNO */
  75. #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
  76. # include <stlsoft/util/std_swap.hpp>
  77. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP */
  78. #if defined(STLSOFT_COMPILER_IS_MSVC) && \
  79. _MSC_VER < 1310
  80. # include <iosfwd>
  81. #endif /* compiler */
  82. /* /////////////////////////////////////////////////////////////////////////
  83. * Namespace
  84. */
  85. #ifndef _STLSOFT_NO_NAMESPACE
  86. namespace stlsoft
  87. {
  88. #endif /* _STLSOFT_NO_NAMESPACE */
  89. /* /////////////////////////////////////////////////////////////////////////
  90. * Classes
  91. */
  92. /** \brief An implementation class, which provides efficient intermediate string
  93. * objects for conversion shims.
  94. *
  95. * \param C The character type
  96. * \param N The number of characters in the internal auto_buffer
  97. * \param U The nUll indicator. If true, the implicit conversion operator returns
  98. * NULL for an empty string, otherwise it returns the empty string
  99. * \param A The allocator
  100. * \param T The char traits type
  101. *
  102. * \ingroup group__library__string
  103. */
  104. template< ss_typename_param_k C
  105. , ss_size_t N = 64
  106. , ss_bool_t U = false
  107. , ss_typename_param_k A = ss_typename_type_def_k allocator_selector<C>::allocator_type
  108. , ss_typename_param_k T = stlsoft_char_traits<C>
  109. >
  110. class basic_shim_string
  111. {
  112. /// \name Types
  113. /// @{
  114. public:
  115. /// The value type
  116. typedef C char_type;
  117. /// The allocator type
  118. typedef A allocator_type;
  119. /// The traits type
  120. typedef T traits_type;
  121. /// The current parameterisation of the type
  122. typedef basic_shim_string<C, N, U, A, T> class_type;
  123. /// The size type
  124. typedef ss_size_t size_type;
  125. /// The buffer type
  126. typedef auto_buffer_old<char_type, allocator_type, N + 1> buffer_type;
  127. /// @}
  128. /// \name Construction
  129. /// @{
  130. public:
  131. /// \brief Constructor
  132. ss_explicit_k basic_shim_string(size_type n)
  133. : m_buffer(1 + n)
  134. {
  135. m_buffer[0] = '\0';
  136. m_buffer[m_buffer.size() - 1] = '\0';
  137. }
  138. /// \brief Constructor
  139. basic_shim_string(char_type const* s, size_type n)
  140. : m_buffer(1 + n)
  141. {
  142. traits_type::copy(&m_buffer[0], s, m_buffer.size() - 1);
  143. m_buffer[m_buffer.size() - 1] = '\0';
  144. }
  145. /// \brief Constructor
  146. basic_shim_string(char_type const* s)
  147. : m_buffer(1 + ((NULL == s) ? 0 : traits_type::length(s)))
  148. {
  149. traits_type::copy(&m_buffer[0], s, m_buffer.size() - 1);
  150. m_buffer[m_buffer.size() - 1] = '\0';
  151. }
  152. /// \brief Copy constructor
  153. basic_shim_string(class_type const& rhs)
  154. : m_buffer(rhs.m_buffer.size())
  155. {
  156. traits_type::copy(&m_buffer[0], &rhs.m_buffer[0], m_buffer.size());
  157. m_buffer[m_buffer.size() - 1] = '\0';
  158. }
  159. /// Swaps the contents of this instance with another
  160. void swap(class_type& rhs) stlsoft_throw_0()
  161. {
  162. m_buffer.swap(rhs.get_buffer());
  163. }
  164. /// @}
  165. /// \name Operations
  166. /// @{
  167. public:
  168. void write(char_type const* s)
  169. {
  170. traits_type::copy(&m_buffer[0], s, m_buffer.size());
  171. m_buffer[m_buffer.size() - 1] = '\0';
  172. }
  173. /// Truncates the string to the given length
  174. ///
  175. /// \note The length specified must be less than or equal to the current length
  176. void truncate(ss_size_t n)
  177. {
  178. STLSOFT_MESSAGE_ASSERT("shim_string truncation size must be <= current size", n <= size());
  179. m_buffer.resize(1 + n);
  180. m_buffer[m_buffer.size() - 1] = '\0';
  181. }
  182. buffer_type& get_buffer()
  183. {
  184. return m_buffer;
  185. }
  186. /// @}
  187. /// \name Accessors
  188. /// @{
  189. public:
  190. size_type size() const
  191. {
  192. STLSOFT_ASSERT(m_buffer.size() > 0);
  193. return m_buffer.size() - 1;
  194. }
  195. static size_type internal_size()
  196. {
  197. return buffer_type::internal_size();
  198. }
  199. char_type* data()
  200. {
  201. return m_buffer.data();
  202. }
  203. char_type const* data() const
  204. {
  205. return m_buffer.data();
  206. }
  207. /// @}
  208. /// \name Implicit Conversions
  209. /// @{
  210. operator char_type const* () const
  211. {
  212. typedef ss_typename_type_k value_to_yesno_type<U>::type yesno_t;
  213. return get_ptr_(m_buffer, yesno_t());
  214. }
  215. operator ss_size_t() const
  216. {
  217. return size();
  218. }
  219. /// @}
  220. /// \name Implementation
  221. /// @{
  222. private:
  223. static char_type const* get_ptr_(buffer_type const& buffer, yes_type)
  224. {
  225. return ('\0' != buffer[0]) ? buffer.data() : NULL;
  226. }
  227. static char_type const* get_ptr_(buffer_type const& buffer, no_type)
  228. {
  229. return buffer.data();
  230. }
  231. /// @}
  232. /// \name Members
  233. /// @{
  234. private:
  235. buffer_type m_buffer;
  236. /// @}
  237. // Not to be implemented
  238. private:
  239. basic_shim_string& operator =(class_type const&);
  240. };
  241. /* /////////////////////////////////////////////////////////////////////////
  242. * Shims
  243. */
  244. #if !defined(STLSOFT_COMPILER_IS_WATCOM)
  245. template< ss_typename_param_k C
  246. , ss_size_t N
  247. , ss_bool_t U
  248. , ss_typename_param_k A
  249. , ss_typename_param_k T
  250. >
  251. inline C const* c_str_ptr(basic_shim_string<C, N, U, A, T> const& ss)
  252. {
  253. return ss.data();
  254. }
  255. template< ss_typename_param_k C
  256. , ss_size_t N
  257. , ss_bool_t U
  258. , ss_typename_param_k A
  259. , ss_typename_param_k T
  260. >
  261. inline C const* c_str_data(basic_shim_string<C, N, U, A, T> const& ss)
  262. {
  263. return ss.data();
  264. }
  265. template< ss_typename_param_k C
  266. , ss_size_t N
  267. , ss_bool_t U
  268. , ss_typename_param_k A
  269. , ss_typename_param_k T
  270. >
  271. inline ss_size_t c_str_len(basic_shim_string<C, N, U, A, T> const& ss)
  272. {
  273. return ss.size();
  274. }
  275. template< ss_typename_param_k S
  276. , ss_typename_param_k C
  277. , ss_size_t N
  278. , ss_bool_t U
  279. , ss_typename_param_k A
  280. , ss_typename_param_k T
  281. >
  282. inline S& operator <<(S& s, basic_shim_string<C, N, U, A, T> const& ss)
  283. {
  284. s << ss.data();
  285. return s;
  286. }
  287. #endif /* compiler */
  288. /* ////////////////////////////////////////////////////////////////////// */
  289. #ifndef _STLSOFT_NO_NAMESPACE
  290. } // namespace stlsoft
  291. # if defined(STLSOFT_COMPILER_IS_MSVC) && \
  292. _MSC_VER < 1310
  293. template< ss_typename_param_k C
  294. , stlsoft::ss_size_t N
  295. , stlsoft::ss_bool_t U
  296. , ss_typename_param_k A
  297. , ss_typename_param_k T
  298. >
  299. inline std::basic_ostream<C>& operator <<(std::basic_ostream<C> &s, stlsoft::basic_shim_string<C, N, U, A, T> const& ss)
  300. {
  301. s << ss.data();
  302. return s;
  303. }
  304. # endif /* compiler */
  305. #endif /* _STLSOFT_NO_NAMESPACE */
  306. /* ////////////////////////////////////////////////////////////////////// */
  307. #endif /* ? compiler */
  308. /* ////////////////////////////////////////////////////////////////////// */
  309. #endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_SHIM_STRING */
  310. /* ///////////////////////////// end of file //////////////////////////// */