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.

1900 lines
63 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/string/string_view.hpp
  3. *
  4. * Purpose: basic_string_view class.
  5. *
  6. * Created: 16th October 2004
  7. * Updated: 5th March 2011
  8. *
  9. * Thanks to: Bjorn Karlsson and Scott Patterson for discussions on various
  10. * naming and design issues. Thanks also to Pablo Aguilar for
  11. * his eagle eyed reviews of beta code. :-)
  12. *
  13. * Home: http://stlsoft.org/
  14. *
  15. * Copyright (c) 2004-2011, Matthew Wilson and Synesis Software
  16. * All rights reserved.
  17. *
  18. * Redistribution and use in source and binary forms, with or without
  19. * modification, are permitted provided that the following conditions are met:
  20. *
  21. * - Redistributions of source code must retain the above copyright notice, this
  22. * list of conditions and the following disclaimer.
  23. * - Redistributions in binary form must reproduce the above copyright notice,
  24. * this list of conditions and the following disclaimer in the documentation
  25. * and/or other materials provided with the distribution.
  26. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  27. * any contributors may be used to endorse or promote products derived from
  28. * this software without specific prior written permission.
  29. *
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  31. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  34. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  35. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  36. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  37. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  38. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  39. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  40. * POSSIBILITY OF SUCH DAMAGE.
  41. *
  42. * ////////////////////////////////////////////////////////////////////// */
  43. /** \file stlsoft/string/string_view.hpp
  44. *
  45. * \brief [C++ only] Definition of the stlsoft::basic_string_view class
  46. * template
  47. * (\ref group__library__string "String" Library).
  48. */
  49. #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_STRING_VIEW
  50. #define STLSOFT_INCL_STLSOFT_STRING_HPP_STRING_VIEW
  51. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  52. # define STLSOFT_VER_STLSOFT_STRING_HPP_STRING_VIEW_MAJOR 3
  53. # define STLSOFT_VER_STLSOFT_STRING_HPP_STRING_VIEW_MINOR 3
  54. # define STLSOFT_VER_STLSOFT_STRING_HPP_STRING_VIEW_REVISION 4
  55. # define STLSOFT_VER_STLSOFT_STRING_HPP_STRING_VIEW_EDIT 95
  56. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  57. /* /////////////////////////////////////////////////////////////////////////
  58. * Compatibility
  59. */
  60. /*
  61. [Incompatibilies-start]
  62. STLSOFT_COMPILER_IS_MWERKS: __MWERKS__<0x3000
  63. STLSOFT_COMPILER_IS_WATCOM:
  64. [Incompatibilies-end]
  65. */
  66. /* /////////////////////////////////////////////////////////////////////////
  67. * Includes
  68. */
  69. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  70. # include <stlsoft/stlsoft.h>
  71. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  72. #if defined(STLSOFT_COMPILER_IS_MWERKS) && \
  73. ((__MWERKS__ & 0xff00) < 0x3000)
  74. # error stlsoft/string/string_view.hpp not compatible with Metrowerks 7.x (v2.4)
  75. #endif /* compiler */
  76. #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_CHAR_TRAITS
  77. # include <stlsoft/string/char_traits.hpp>
  78. #endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_CHAR_TRAITS */
  79. #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_STRING_TRAITS_FWD
  80. # include <stlsoft/string/string_traits_fwd.hpp>
  81. #endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_STRING_TRAITS_FWD */
  82. #ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER
  83. # include <stlsoft/util/std/iterator_helper.hpp>
  84. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_HPP_ITERATOR_HELPER */
  85. #ifndef STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS
  86. # include <stlsoft/collections/util/collections.hpp>
  87. #endif /* !STLSOFT_INCL_STLSOFT_COLLECTIONS_UTIL_HPP_COLLECTIONS */
  88. #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR
  89. # include <stlsoft/memory/allocator_selector.hpp>
  90. #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR */
  91. #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
  92. # include <stlsoft/util/std_swap.hpp>
  93. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP */
  94. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  95. # include <stdexcept> // for std::out_of_range
  96. #endif /* !STLSOFT_CF_EXCEPTION_SUPPORT */
  97. /* /////////////////////////////////////////////////////////////////////////
  98. * Namespace
  99. */
  100. #ifndef _STLSOFT_NO_NAMESPACE
  101. namespace stlsoft
  102. {
  103. #endif /* _STLSOFT_NO_NAMESPACE */
  104. /* /////////////////////////////////////////////////////////////////////////
  105. * Classes
  106. */
  107. // class basic_string_view
  108. /** \brief A string class that holds no internal storage, and merely represents a window into other string storage
  109. *
  110. * \ingroup group__library__string
  111. *
  112. * \param C The character type
  113. * \param T The traits type. On translators that support default template arguments this is defaulted
  114. * to char_traits<C>
  115. * \param A The allocator type. On translators that support default template arguments this is defaulted
  116. * to allocator_selector<C>::allocator_type. This is only used by the proxy generated by c_str()
  117. * \ingroup concepts_view
  118. */
  119. template< ss_typename_param_k C
  120. #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
  121. , ss_typename_param_k T = char_traits<C>
  122. , ss_typename_param_k A = ss_typename_type_def_k allocator_selector<C>::allocator_type
  123. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  124. , ss_typename_param_k T /* = char_traits<C> */
  125. , ss_typename_param_k A /* = allocator_selector<C>::allocator_type */
  126. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  127. >
  128. class basic_string_view
  129. #if defined(STLSOFT_COMPILER_IS_DMC)
  130. : protected A
  131. #else /* ? compiler */
  132. : private A
  133. #endif /* compiler */
  134. , public stl_collection_tag
  135. {
  136. public:
  137. /// The value type
  138. typedef C value_type;
  139. /// The traits type
  140. typedef T traits_type;
  141. /// The allocator type
  142. typedef A allocator_type;
  143. /// The current parameterisation of the type
  144. typedef basic_string_view<C, T, A> class_type;
  145. /// The character type
  146. typedef value_type char_type;
  147. #if 0
  148. /// The pointer type
  149. ///
  150. /// \note This type is not used by any functions, but is here to facilitate
  151. /// type detection
  152. typedef value_type const* pointer;
  153. #endif /* 0 */
  154. /// The non-mutable (const) pointer type
  155. typedef value_type const* const_pointer;
  156. #if 0
  157. /// The reference type
  158. typedef value_type& reference;
  159. #endif /* 0 */
  160. /// The non-mutable (const) reference type
  161. typedef value_type const& const_reference;
  162. /// The size type
  163. typedef ss_size_t size_type;
  164. /// The difference type
  165. typedef ss_ptrdiff_t difference_type;
  166. #if 0
  167. /// The iterator type
  168. typedef
  169. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  170. ss_typename_type_k
  171. #endif /* compiler */
  172. pointer_iterator < value_type
  173. , pointer
  174. , reference
  175. >::type iterator;
  176. #endif /* 0 */
  177. /// The non-mutating (const) iterator type
  178. typedef
  179. #if !defined(STLSOFT_COMPILER_IS_BORLAND)
  180. ss_typename_type_k
  181. #endif /* compiler */
  182. pointer_iterator < value_type const
  183. , const_pointer
  184. , const_reference
  185. >::type const_iterator;
  186. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  187. #if 0
  188. /// The reverse iterator type
  189. typedef reverse_iterator_base < iterator
  190. , value_type
  191. , reference
  192. , pointer
  193. , difference_type
  194. > reverse_iterator;
  195. #endif /* 0 */
  196. /// The non-mutating (const) reverse iterator type
  197. typedef const_reverse_iterator_base < const_iterator
  198. , value_type const
  199. , const_reference
  200. , const_pointer
  201. , difference_type
  202. > const_reverse_iterator;
  203. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  204. /// \name Construction
  205. /// @{
  206. public:
  207. /// Default constructor
  208. basic_string_view();
  209. /// Copy constructor
  210. basic_string_view(class_type const& rhs);
  211. /// Construct from the given string at the specified position
  212. basic_string_view(class_type const& s, size_type pos);
  213. /// Construct with \c cch characters from the given string at the specified position
  214. basic_string_view(class_type const& s, size_type pos, size_type cch);
  215. /// Construct from a null-terminated character string
  216. basic_string_view(char_type const* s); // No, not explicit! Sigh
  217. /// Construct with \c cch characters from the given character string
  218. basic_string_view(char_type const* s, size_type cch);
  219. /// Construct from the range [first:last)
  220. basic_string_view(char_type const* first, char_type const* last);
  221. /// Destructor
  222. ~basic_string_view() stlsoft_throw_0();
  223. /// Copy assignment operator
  224. class_type& operator =(class_type const& rhs);
  225. /// @}
  226. /// \name Operations
  227. /// @{
  228. public:
  229. /// Swaps the contents between \c this and \c other
  230. void swap(class_type& other) stlsoft_throw_0();
  231. /// Empties the string
  232. void clear() stlsoft_throw_0();
  233. /// \brief Clear c_str() representation
  234. ///
  235. /// Causes the c_str() representation, if currently allocated (see c_str() for details),
  236. /// to be destroyed, in order that the next call to c_str() will result in a fresh
  237. /// nul-terminated copy of the 'current' contents of the view.
  238. void refresh() stlsoft_throw_0();
  239. /// @}
  240. /// \name Attributes
  241. /// @{
  242. public:
  243. /// The number of elements in the string
  244. size_type size() const stlsoft_throw_0();
  245. /// The maximum number of elements that can be stored in the string
  246. static size_type max_size() stlsoft_throw_0();
  247. /// The number of elements in the string
  248. size_type length() const stlsoft_throw_0();
  249. /// The storage currently allocated by the string
  250. size_type capacity() const stlsoft_throw_0();
  251. /// Indicates whether the string is empty
  252. ss_bool_t empty() const stlsoft_throw_0();
  253. /// Returns an instance of the allocator type
  254. allocator_type get_allocator() const;
  255. /// @}
  256. /// \name Comparison
  257. /// @{
  258. public:
  259. /// Evaluates whether two strings are equal
  260. ss_bool_t equal(class_type const& rhs) const stlsoft_throw_0();
  261. /// Evaluates whether two strings are equal
  262. ss_bool_t equal(value_type const* rhs, size_type cchRhs) const stlsoft_throw_0();
  263. /// Compares \c this with the given string
  264. ss_sint_t compare(size_type pos, size_type cch, value_type const* s, size_type cchRhs) const stlsoft_throw_0();
  265. /// Compares \c this with the given string
  266. ss_sint_t compare(size_type pos, size_type cch, value_type const* s) const stlsoft_throw_0();
  267. /// Compares \c this with the given string
  268. ss_sint_t compare(value_type const* s) const stlsoft_throw_0();
  269. /// Compares \c this with the given string
  270. ss_sint_t compare(size_type pos, size_type cch, class_type const& rhs, size_type posRhs, size_type cchRhs) const stlsoft_throw_0();
  271. /// Compares \c this with the given string
  272. ss_sint_t compare(size_type pos, size_type cch, class_type const& rhs) const stlsoft_throw_0();
  273. /// Compares \c this with the given string
  274. ss_sint_t compare(class_type const& rhs) const stlsoft_throw_0();
  275. /// @}
  276. /// \name Accessors
  277. /// @{
  278. public:
  279. #if 0
  280. /// Returns mutable reference at the given index
  281. reference operator [](size_type index);
  282. #endif /* 0 */
  283. /// Returns non-mutable (const) reference at the given index
  284. ///
  285. /// \note Follows the convention of std::basic_string in returning a reference to
  286. /// char_type() if index == size(). This reference will <b>not</b> be part of the
  287. /// block constituting the string's viewed area.
  288. const_reference operator [](size_type index) const;
  289. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  290. /// Returns non-mutable (const) reference at the given index
  291. ///
  292. /// \note Throws std::out_of_range if index >= size()
  293. const_reference at(size_type index) const;
  294. #endif /* !STLSOFT_CF_EXCEPTION_SUPPORT */
  295. /// Returns null-terminated non-mutable (const) pointer to string data
  296. ///
  297. /// \note This returns a nul-terminated copy of the string. If the view's underlying
  298. /// string changes after this point, this will not be reflected in the value returned
  299. /// by c_str(), until such time as refresh() is called.
  300. ///
  301. /// \note If the view's parameterisation is with a no-throw allocator, behaviour
  302. /// is undefined in con
  303. value_type const* c_str() const;
  304. #if 0
  305. /// Facility for calling refresh() followed by c_str()
  306. ///
  307. /// \param bRefresh call refresh() before c_str()
  308. ///
  309. /// \note If bRefresh is \c false has identical semantics to c_str()
  310. value_type const* c_str(ss_bool_t bRefresh) const;
  311. #endif /* 0 */
  312. /// Returns non-mutable (const) pointer to string data
  313. value_type const* data() const stlsoft_throw_0();
  314. /// Returns value of base pointer
  315. value_type const* base() const stlsoft_throw_0();
  316. #if 0
  317. /// Returns the first character in the string
  318. ///
  319. /// \note It is up to the user to ensure that the string is not empty
  320. reference front();
  321. /// Returns the last character in the string
  322. ///
  323. /// \note It is up to the user to ensure that the string is not empty
  324. reference back();
  325. #endif /* 0 */
  326. /// Returns the first character in the string
  327. ///
  328. /// \note It is up to the user to ensure that the string is not empty
  329. const_reference front() const;
  330. /// Returns the last character in the string
  331. ///
  332. /// \note It is up to the user to ensure that the string is not empty
  333. const_reference back() const;
  334. /// Copies elements into the given destination
  335. size_type copy(value_type *dest, size_type cch, size_type pos = 0) const;
  336. /// @}
  337. /// \name Iteration
  338. /// @{
  339. public:
  340. /// Begins the iteration
  341. ///
  342. /// \return A non-mutable (const) iterator representing the start of the sequence
  343. const_iterator begin() const;
  344. /// Ends the iteration
  345. ///
  346. /// \return A non-mutable (const) iterator representing the end of the sequence
  347. const_iterator end() const;
  348. #if 0
  349. /// Begins the iteration
  350. ///
  351. /// \return An iterator representing the start of the sequence
  352. iterator begin();
  353. /// Ends the iteration
  354. ///
  355. /// \return An iterator representing the end of the sequence
  356. iterator end();
  357. #endif /* 0 */
  358. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  359. /// Begins the reverse iteration
  360. ///
  361. /// \return A non-mutable (const) iterator representing the start of the reverse sequence
  362. const_reverse_iterator rbegin() const;
  363. /// Ends the reverse iteration
  364. ///
  365. /// \return A non-mutable (const) iterator representing the end of the reverse sequence
  366. const_reverse_iterator rend() const;
  367. #if 0
  368. /// Begins the reverse iteration
  369. ///
  370. /// \return An iterator representing the start of the reverse sequence
  371. reverse_iterator rbegin();
  372. /// Ends the reverse iteration
  373. ///
  374. /// \return An iterator representing the end of the reverse sequence
  375. reverse_iterator rend();
  376. #endif /* 0 */
  377. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  378. /// @}
  379. /// \name Invariant
  380. /// @{
  381. #ifdef STLSOFT_UNITTEST
  382. public:
  383. #else
  384. private:
  385. #endif /* STLSOFT_UNITTEST */
  386. ss_bool_t is_valid() const;
  387. /// \name Implementation
  388. /// @{
  389. private:
  390. // Empty string
  391. static char_type const* empty_string_();
  392. // Comparison
  393. static ss_sint_t compare_(char_type const* lhs, size_type lhs_len, char_type const* rhs, size_type rhs_len);
  394. // Closes the m_cstr member
  395. void close_() stlsoft_throw_0();
  396. // Closes the m_cstr member and sets to NULL
  397. void close_set_null_() stlsoft_throw_0();
  398. /// @}
  399. /// \name Members
  400. /// @{
  401. private:
  402. size_type m_length; // The number of elements in the view
  403. char_type const* m_base; // Pointer to the first element in the view, or NULL for a null view
  404. char_type *m_cstr; // Pointer to a nul-terminated copy of the view, at the time of the c_str() call. Will be NULL before c_str() is called
  405. /// @}
  406. };
  407. /* /////////////////////////////////////////////////////////////////////////
  408. * Typedefs
  409. */
  410. #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
  411. typedef basic_string_view<ss_char_a_t> string_view;
  412. typedef basic_string_view<ss_char_w_t> wstring_view;
  413. #else /* ? STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  414. typedef basic_string_view<ss_char_a_t
  415. , stlsoft_char_traits<ss_char_a_t>
  416. , allocator_selector<ss_char_a_t>::allocator_type
  417. > string_view;
  418. typedef basic_string_view<ss_char_w_t
  419. , stlsoft_char_traits<ss_char_w_t>
  420. , allocator_selector<ss_char_w_t>::allocator_type
  421. > wstring_view;
  422. #endif /* STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
  423. /* /////////////////////////////////////////////////////////////////////////
  424. * Traits
  425. */
  426. /** Specialisation for stlsoft::basic_string_view<>
  427. */
  428. # ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
  429. template< ss_typename_param_k C
  430. , ss_typename_param_k T
  431. , ss_typename_param_k A
  432. >
  433. struct string_traits<basic_string_view<C, T, A> >
  434. {
  435. // NOTE: Originally, what is string_type_ was defined as value_type, but
  436. // Borland objects to value_type::value_type.
  437. typedef basic_string_view<C, T, A> string_type_;
  438. typedef ss_typename_type_k string_type_::value_type char_type;
  439. typedef ss_typename_type_k string_type_::size_type size_type;
  440. typedef char_type const const_char_type;
  441. typedef string_type_ string_type;
  442. typedef string_type_ value_type;
  443. // typedef ss_typename_type_k string_type::pointer pointer;
  444. typedef ss_typename_type_k string_type::const_pointer const_pointer;
  445. // typedef ss_typename_type_k string_type::iterator iterator;
  446. typedef ss_typename_type_k string_type::const_iterator const_iterator;
  447. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  448. // typedef ss_typename_type_k string_type::reverse_iterator reverse_iterator;
  449. typedef ss_typename_type_k string_type::const_reverse_iterator const_reverse_iterator;
  450. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  451. enum
  452. {
  453. is_pointer = false
  454. , is_pointer_to_const = false
  455. , char_type_size = sizeof(char_type)
  456. };
  457. static string_type empty_string()
  458. {
  459. return string_type();
  460. }
  461. static string_type construct(string_type const& src, size_type pos, size_type len)
  462. {
  463. return string_type(src, pos, len);
  464. }
  465. # ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  466. template <ss_typename_param_k I>
  467. static string_type &assign_inplace(string_type &str, I first, I last)
  468. # else /* ? STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  469. static string_type &assign_inplace(string_type &str, const_iterator first, const_iterator last)
  470. # endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  471. {
  472. // string view cannot assign in-place
  473. return (str = string_type(first, last), str);
  474. }
  475. };
  476. # else /* ? STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
  477. STLSOFT_TEMPLATE_SPECIALISATION
  478. struct string_traits<string_view>
  479. {
  480. typedef string_view value_type;
  481. typedef value_type::value_type char_type;
  482. typedef value_type::size_type size_type;
  483. typedef char_type const const_char_type;
  484. typedef value_type string_type;
  485. // typedef string_type::pointer pointer;
  486. typedef string_type::const_pointer const_pointer;
  487. // typedef string_type::iterator iterator;
  488. typedef string_type::const_iterator const_iterator;
  489. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  490. // typedef string_type::reverse_iterator reverse_iterator;
  491. typedef string_type::const_reverse_iterator const_reverse_iterator;
  492. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  493. enum
  494. {
  495. is_pointer = false
  496. , is_pointer_to_const = false
  497. , char_type_size = sizeof(char_type)
  498. };
  499. static string_type empty_string()
  500. {
  501. return string_type();
  502. }
  503. static string_type construct(string_type const& src, size_type pos, size_type len)
  504. {
  505. return string_type(src, pos, len);
  506. }
  507. # ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  508. template <ss_typename_param_k I>
  509. static string_type &assign_inplace(string_type &str, I first, I last)
  510. # else /* ? STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  511. static string_type &assign_inplace(string_type &str, const_iterator first, const_iterator last)
  512. # endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  513. {
  514. // string view cannot assign in-place
  515. return (str = string_type(first, last), str);
  516. }
  517. };
  518. STLSOFT_TEMPLATE_SPECIALISATION
  519. struct string_traits<wstring_view>
  520. {
  521. typedef wstring_view value_type;
  522. typedef value_type::value_type char_type;
  523. typedef value_type::size_type size_type;
  524. typedef char_type const const_char_type;
  525. typedef value_type string_type;
  526. // typedef string_type::pointer pointer;
  527. typedef string_type::const_pointer const_pointer;
  528. // typedef string_type::iterator iterator;
  529. typedef string_type::const_iterator const_iterator;
  530. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  531. // typedef string_type::reverse_iterator reverse_iterator;
  532. typedef string_type::const_reverse_iterator const_reverse_iterator;
  533. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  534. enum
  535. {
  536. is_pointer = false
  537. , is_pointer_to_const = false
  538. , char_type_size = sizeof(char_type)
  539. };
  540. static string_type empty_string()
  541. {
  542. return string_type();
  543. }
  544. static string_type construct(string_type const& src, size_type pos, size_type len)
  545. {
  546. return string_type(src, pos, len);
  547. }
  548. # ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
  549. template <ss_typename_param_k I>
  550. static string_type &assign_inplace(string_type &str, I first, I last)
  551. # else /* ? STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  552. static string_type &assign_inplace(string_type &str, const_iterator first, const_iterator last)
  553. # endif /* STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT */
  554. {
  555. // string view cannot assign in-place
  556. return (str = string_type(first, last), str);
  557. }
  558. };
  559. # endif /* STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
  560. /* /////////////////////////////////////////////////////////////////////////
  561. * Operators
  562. */
  563. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  564. // operator ==
  565. template< ss_typename_param_k C
  566. , ss_typename_param_k T
  567. , ss_typename_param_k A
  568. >
  569. inline ss_bool_t operator ==(basic_string_view<C, T, A> const& lhs, basic_string_view<C, T, A> const& rhs)
  570. {
  571. return lhs.equal(rhs);
  572. }
  573. template< ss_typename_param_k C
  574. , ss_typename_param_k T
  575. , ss_typename_param_k A
  576. >
  577. #ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
  578. inline ss_bool_t operator ==(basic_string_view<C, T, A> const& lhs, ss_typename_type_k basic_string_view<C, T, A>::char_type const* rhs)
  579. #else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  580. inline ss_bool_t operator ==(basic_string_view<C, T, A> const& lhs, C const* rhs)
  581. #endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  582. {
  583. typedef ss_typename_type_k basic_string_view<C, T, A>::size_type size_type;
  584. typedef ss_typename_type_k basic_string_view<C, T, A>::traits_type traits_type;
  585. size_type rhs_len = (NULL == rhs) ? 0 : traits_type::length(rhs);
  586. return lhs.equal(rhs, rhs_len);
  587. }
  588. template< ss_typename_param_k C
  589. , ss_typename_param_k T
  590. , ss_typename_param_k A
  591. >
  592. #ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
  593. inline ss_bool_t operator ==(ss_typename_type_k basic_string_view<C, T, A>::char_type const* lhs, basic_string_view<C, T, A> const& rhs)
  594. #else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  595. inline ss_bool_t operator ==(C *lhs, basic_string_view<C, T, A> const& rhs)
  596. #endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  597. {
  598. typedef ss_typename_type_k basic_string_view<C, T, A>::size_type size_type;
  599. typedef ss_typename_type_k basic_string_view<C, T, A>::traits_type traits_type;
  600. size_type lhs_len = (NULL == lhs) ? 0 : traits_type::length(lhs);
  601. return rhs.equal(lhs, lhs_len);
  602. }
  603. // operator !=
  604. template< ss_typename_param_k C
  605. , ss_typename_param_k T
  606. , ss_typename_param_k A
  607. >
  608. inline ss_bool_t operator !=(basic_string_view<C, T, A> const& lhs, basic_string_view<C, T, A> const& rhs)
  609. {
  610. return !lhs.equal(rhs);
  611. }
  612. template< ss_typename_param_k C
  613. , ss_typename_param_k T
  614. , ss_typename_param_k A
  615. >
  616. #ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
  617. inline ss_bool_t operator !=(basic_string_view<C, T, A> const& lhs, ss_typename_type_k basic_string_view<C, T, A>::char_type const* rhs)
  618. #else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  619. inline ss_bool_t operator !=(basic_string_view<C, T, A> const& lhs, C const* rhs)
  620. #endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  621. {
  622. typedef ss_typename_type_k basic_string_view<C, T, A>::size_type size_type;
  623. typedef ss_typename_type_k basic_string_view<C, T, A>::traits_type traits_type;
  624. size_type rhs_len = (NULL == rhs) ? 0 : traits_type::length(rhs);
  625. return !lhs.equal(rhs, rhs_len);
  626. }
  627. template< ss_typename_param_k C
  628. , ss_typename_param_k T
  629. , ss_typename_param_k A
  630. >
  631. #ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
  632. inline ss_bool_t operator !=(ss_typename_type_k basic_string_view<C, T, A>::char_type const* lhs, basic_string_view<C, T, A> const& rhs)
  633. #else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  634. inline ss_bool_t operator !=(C const* lhs, basic_string_view<C, T, A> const& rhs)
  635. #endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  636. {
  637. typedef ss_typename_type_k basic_string_view<C, T, A>::size_type size_type;
  638. typedef ss_typename_type_k basic_string_view<C, T, A>::traits_type traits_type;
  639. size_type lhs_len = (NULL == lhs) ? 0 : traits_type::length(lhs);
  640. return !rhs.equal(lhs, lhs_len);
  641. }
  642. // operator <
  643. template< ss_typename_param_k C
  644. , ss_typename_param_k T
  645. , ss_typename_param_k A
  646. >
  647. inline ss_bool_t operator <(basic_string_view<C, T, A> const& lhs, basic_string_view<C, T, A> const& rhs)
  648. {
  649. return lhs.compare(rhs) < 0;
  650. }
  651. template< ss_typename_param_k C
  652. , ss_typename_param_k T
  653. , ss_typename_param_k A
  654. >
  655. #ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
  656. inline ss_bool_t operator <(basic_string_view<C, T, A> const& lhs, ss_typename_type_k basic_string_view<C, T, A>::char_type const* rhs)
  657. #else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  658. inline ss_bool_t operator <(basic_string_view<C, T, A> const& lhs, C const* rhs)
  659. #endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  660. {
  661. return lhs.compare(rhs) < 0;
  662. }
  663. template< ss_typename_param_k C
  664. , ss_typename_param_k T
  665. , ss_typename_param_k A
  666. >
  667. #ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
  668. inline ss_bool_t operator <(ss_typename_type_k basic_string_view<C, T, A>::char_type const* lhs, basic_string_view<C, T, A> const& rhs)
  669. #else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  670. inline ss_bool_t operator <(C const* lhs, basic_string_view<C, T, A> const& rhs)
  671. #endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  672. {
  673. return rhs.compare(lhs) > 0;
  674. }
  675. // operator <=
  676. template< ss_typename_param_k C
  677. , ss_typename_param_k T
  678. , ss_typename_param_k A
  679. >
  680. inline ss_bool_t operator <=(basic_string_view<C, T, A> const& lhs, basic_string_view<C, T, A> const& rhs)
  681. {
  682. return lhs.compare(rhs) <= 0;
  683. }
  684. template< ss_typename_param_k C
  685. , ss_typename_param_k T
  686. , ss_typename_param_k A
  687. >
  688. #ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
  689. inline ss_bool_t operator <=(basic_string_view<C, T, A> const& lhs, ss_typename_type_k basic_string_view<C, T, A>::char_type const* rhs)
  690. #else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  691. inline ss_bool_t operator <=(basic_string_view<C, T, A> const& lhs, C const* rhs)
  692. #endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  693. {
  694. return lhs.compare(rhs) <= 0;
  695. }
  696. template< ss_typename_param_k C
  697. , ss_typename_param_k T
  698. , ss_typename_param_k A
  699. >
  700. #ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
  701. inline ss_bool_t operator <=(ss_typename_type_k basic_string_view<C, T, A>::char_type const* lhs, basic_string_view<C, T, A> const& rhs)
  702. #else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  703. inline ss_bool_t operator <=(C const* lhs, basic_string_view<C, T, A> const& rhs)
  704. #endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  705. {
  706. return rhs.compare(lhs) >= 0;
  707. }
  708. // operator >
  709. template< ss_typename_param_k C
  710. , ss_typename_param_k T
  711. , ss_typename_param_k A
  712. >
  713. inline ss_bool_t operator >(basic_string_view<C, T, A> const& lhs, basic_string_view<C, T, A> const& rhs)
  714. {
  715. return lhs.compare(rhs) > 0;
  716. }
  717. template< ss_typename_param_k C
  718. , ss_typename_param_k T
  719. , ss_typename_param_k A
  720. >
  721. #ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
  722. inline ss_bool_t operator >(basic_string_view<C, T, A> const& lhs, ss_typename_type_k basic_string_view<C, T, A>::char_type const* rhs)
  723. #else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  724. inline ss_bool_t operator >(basic_string_view<C, T, A> const& lhs, C const* rhs)
  725. #endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  726. {
  727. return lhs.compare(rhs) > 0;
  728. }
  729. template< ss_typename_param_k C
  730. , ss_typename_param_k T
  731. , ss_typename_param_k A
  732. >
  733. #ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
  734. inline ss_bool_t operator >(ss_typename_type_k basic_string_view<C, T, A>::char_type const* lhs, basic_string_view<C, T, A> const& rhs)
  735. #else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  736. inline ss_bool_t operator >(C const* lhs, basic_string_view<C, T, A> const& rhs)
  737. #endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  738. {
  739. return rhs.compare(lhs) < 0;
  740. }
  741. // operator >=
  742. template< ss_typename_param_k C
  743. , ss_typename_param_k T
  744. , ss_typename_param_k A
  745. >
  746. inline ss_bool_t operator >=(basic_string_view<C, T, A> const& lhs, basic_string_view<C, T, A> const& rhs)
  747. {
  748. return lhs.compare(rhs) >= 0;
  749. }
  750. template< ss_typename_param_k C
  751. , ss_typename_param_k T
  752. , ss_typename_param_k A
  753. >
  754. #ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
  755. inline ss_bool_t operator >=(basic_string_view<C, T, A> const& lhs, ss_typename_type_k basic_string_view<C, T, A>::char_type const* rhs)
  756. #else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  757. inline ss_bool_t operator >=(basic_string_view<C, T, A> const& lhs, C const* rhs)
  758. #endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  759. {
  760. return lhs.compare(rhs) >= 0;
  761. }
  762. template< ss_typename_param_k C
  763. , ss_typename_param_k T
  764. , ss_typename_param_k A
  765. >
  766. #ifdef STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT
  767. inline ss_bool_t operator >=(ss_typename_type_k basic_string_view<C, T, A>::char_type const* lhs, basic_string_view<C, T, A> const& rhs)
  768. #else /* ? STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  769. inline ss_bool_t operator >=(C const* lhs, basic_string_view<C, T, A> const& rhs)
  770. #endif /* STLSOFT_CF_TEMPLATE_OUTOFCLASSFN_QUALIFIED_TYPE_SUPPORT */
  771. {
  772. return rhs.compare(lhs) <= 0;
  773. }
  774. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  775. /* /////////////////////////////////////////////////////////////////////////
  776. * IOStream compatibility
  777. */
  778. template< ss_typename_param_k S
  779. , ss_typename_param_k C
  780. , ss_typename_param_k T
  781. , ss_typename_param_k A
  782. >
  783. inline S& operator <<(S& s, basic_string_view<C, T, A> const& str)
  784. {
  785. s.write(str.data(), static_cast<ss_streamoff_t>(str.length()));
  786. return s;
  787. }
  788. /* /////////////////////////////////////////////////////////////////////////
  789. * Unit-testing
  790. */
  791. #ifdef STLSOFT_UNITTEST
  792. # include "./unittest/string_view_unittest_.h"
  793. #endif /* STLSOFT_UNITTEST */
  794. /* /////////////////////////////////////////////////////////////////////////
  795. * Implementation
  796. */
  797. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  798. // Implementation
  799. template< ss_typename_param_k C
  800. , ss_typename_param_k T
  801. , ss_typename_param_k A
  802. >
  803. inline /* static */ ss_typename_type_ret_k basic_string_view<C, T, A>::char_type const* basic_string_view<C, T, A>::empty_string_()
  804. {
  805. // This character array is initialised to 0, which conveniently happens to
  806. // be the empty string, by the module/application load, so it is
  807. // guaranteed to be valid, and there are no threading/race conditions
  808. static char_type s_empty[1];
  809. STLSOFT_ASSERT(s_empty[0] == '\0'); // Paranoid check
  810. return s_empty;
  811. }
  812. template< ss_typename_param_k C
  813. , ss_typename_param_k T
  814. , ss_typename_param_k A
  815. >
  816. inline /* static */ ss_sint_t basic_string_view<C, T, A>::compare_( ss_typename_type_k basic_string_view<C, T, A>::value_type const* lhs
  817. , ss_typename_type_k basic_string_view<C, T, A>::size_type lhs_len
  818. , ss_typename_type_k basic_string_view<C, T, A>::value_type const* rhs
  819. , ss_typename_type_k basic_string_view<C, T, A>::size_type rhs_len)
  820. {
  821. size_type cmp_len = (lhs_len < rhs_len) ? lhs_len : rhs_len;
  822. ss_int_t result = traits_type::compare(lhs, rhs, cmp_len);
  823. if(0 == result)
  824. {
  825. result = static_cast<ss_int_t>(lhs_len) - static_cast<ss_int_t>(rhs_len);
  826. }
  827. return result;
  828. }
  829. template< ss_typename_param_k C
  830. , ss_typename_param_k T
  831. , ss_typename_param_k A
  832. >
  833. inline /* static */ void basic_string_view<C, T, A>::close_() stlsoft_throw_0()
  834. {
  835. STLSOFT_ASSERT(NULL != m_cstr);
  836. allocator_type &ator = *this;
  837. ator.deallocate(m_cstr, 1 + m_length);
  838. #if defined(STLSOFT_COMPILER_IS_BORLAND)
  839. STLSOFT_SUPPRESS_UNUSED(ator);
  840. #endif /* compiler */
  841. }
  842. template< ss_typename_param_k C
  843. , ss_typename_param_k T
  844. , ss_typename_param_k A
  845. >
  846. inline /* static */ void basic_string_view<C, T, A>::close_set_null_() stlsoft_throw_0()
  847. {
  848. if(NULL != m_cstr)
  849. {
  850. close_();
  851. m_cstr = NULL;
  852. }
  853. }
  854. /** \brief Invariant
  855. *
  856. * \ingroup group__library__string
  857. */
  858. template< ss_typename_param_k C
  859. , ss_typename_param_k T
  860. , ss_typename_param_k A
  861. >
  862. inline ss_bool_t basic_string_view<C, T, A>::is_valid() const
  863. {
  864. // NOTE: Must not call any methods or ctors in this function!!
  865. if( 0 == m_length &&
  866. NULL != m_cstr)
  867. {
  868. return false; // If the slice is empty, there should be no m_cstr
  869. }
  870. if( 0 != m_length &&
  871. NULL == m_base)
  872. {
  873. return false; // If the slice is non-empty, m_base should not be NULL
  874. }
  875. return true;
  876. }
  877. // Construction
  878. template< ss_typename_param_k C
  879. , ss_typename_param_k T
  880. , ss_typename_param_k A
  881. >
  882. inline basic_string_view<C, T, A>::basic_string_view()
  883. : m_length(0)
  884. , m_base(NULL)
  885. , m_cstr(NULL)
  886. {
  887. STLSOFT_ASSERT(is_valid());
  888. }
  889. template< ss_typename_param_k C
  890. , ss_typename_param_k T
  891. , ss_typename_param_k A
  892. >
  893. inline basic_string_view<C, T, A>::basic_string_view(basic_string_view<C, T, A> const& rhs)
  894. : m_length(rhs.m_length)
  895. , m_base(rhs.m_base)
  896. , m_cstr(NULL)
  897. {
  898. STLSOFT_ASSERT(is_valid());
  899. }
  900. template< ss_typename_param_k C
  901. , ss_typename_param_k T
  902. , ss_typename_param_k A
  903. >
  904. inline basic_string_view<C, T, A>::basic_string_view(basic_string_view<C, T, A> const& rhs, ss_typename_type_k basic_string_view<C, T, A>::size_type pos)
  905. : m_length(rhs.m_length - pos)
  906. , m_base(&rhs[pos]) // Use this so we get the debug-time invariant checking on the validity of pos
  907. , m_cstr(NULL)
  908. {
  909. STLSOFT_ASSERT(pos <= rhs.m_length);
  910. STLSOFT_ASSERT(is_valid());
  911. }
  912. template< ss_typename_param_k C
  913. , ss_typename_param_k T
  914. , ss_typename_param_k A
  915. >
  916. inline basic_string_view<C, T, A>::basic_string_view( basic_string_view<C, T, A> const& rhs
  917. , ss_typename_type_k basic_string_view<C, T, A>::size_type pos
  918. , ss_typename_type_k basic_string_view<C, T, A>::size_type cch)
  919. : m_length(cch)
  920. , m_base(&rhs[pos]) // Use this so we get the debug-time invariant checking on the validity of pos
  921. , m_cstr(NULL)
  922. {
  923. STLSOFT_ASSERT(is_valid());
  924. }
  925. template< ss_typename_param_k C
  926. , ss_typename_param_k T
  927. , ss_typename_param_k A
  928. >
  929. inline basic_string_view<C, T, A>::basic_string_view(ss_typename_type_k basic_string_view<C, T, A>::char_type const* s)
  930. : m_length(T::length(s))
  931. , m_base(s)
  932. , m_cstr(NULL)
  933. {
  934. STLSOFT_ASSERT(is_valid());
  935. }
  936. template< ss_typename_param_k C
  937. , ss_typename_param_k T
  938. , ss_typename_param_k A
  939. >
  940. inline basic_string_view<C, T, A>::basic_string_view( ss_typename_type_k basic_string_view<C, T, A>::char_type const* s
  941. , ss_typename_type_k basic_string_view<C, T, A>::size_type cch)
  942. : m_length(cch)
  943. , m_base(s)
  944. , m_cstr(NULL)
  945. {
  946. STLSOFT_ASSERT(is_valid());
  947. }
  948. template< ss_typename_param_k C
  949. , ss_typename_param_k T
  950. , ss_typename_param_k A
  951. >
  952. inline basic_string_view<C, T, A>::basic_string_view( ss_typename_type_k basic_string_view<C, T, A>::char_type const* first
  953. , ss_typename_type_k basic_string_view<C, T, A>::char_type const* last)
  954. : m_length(static_cast<size_type>(last - first))
  955. , m_base(first)
  956. , m_cstr(NULL)
  957. {
  958. STLSOFT_ASSERT(first <= last);
  959. STLSOFT_ASSERT(is_valid());
  960. }
  961. template< ss_typename_param_k C
  962. , ss_typename_param_k T
  963. , ss_typename_param_k A
  964. >
  965. inline basic_string_view<C, T, A>::~basic_string_view() stlsoft_throw_0()
  966. {
  967. STLSOFT_ASSERT(is_valid());
  968. if(NULL != m_cstr)
  969. {
  970. close_();
  971. }
  972. }
  973. template< ss_typename_param_k C
  974. , ss_typename_param_k T
  975. , ss_typename_param_k A
  976. >
  977. inline basic_string_view<C, T, A> &basic_string_view<C, T, A>::operator =(basic_string_view<C, T, A> const& rhs)
  978. {
  979. close_set_null_();
  980. m_length = rhs.m_length;
  981. m_base = rhs.m_base;
  982. return *this;
  983. }
  984. // Operations
  985. template< ss_typename_param_k C
  986. , ss_typename_param_k T
  987. , ss_typename_param_k A
  988. >
  989. inline void basic_string_view<C, T, A>::swap(ss_typename_type_k basic_string_view<C, T, A>::class_type& rhs) stlsoft_throw_0()
  990. {
  991. STLSOFT_ASSERT(is_valid());
  992. std_swap(m_length, rhs.m_length);
  993. std_swap(m_base, rhs.m_base);
  994. std_swap(m_cstr, rhs.m_cstr);
  995. STLSOFT_ASSERT(is_valid());
  996. }
  997. template< ss_typename_param_k C
  998. , ss_typename_param_k T
  999. , ss_typename_param_k A
  1000. >
  1001. inline void basic_string_view<C, T, A>::clear() stlsoft_throw_0()
  1002. {
  1003. STLSOFT_ASSERT(is_valid());
  1004. close_set_null_();
  1005. m_length = 0;
  1006. m_base = NULL;
  1007. STLSOFT_ASSERT(is_valid());
  1008. }
  1009. template< ss_typename_param_k C
  1010. , ss_typename_param_k T
  1011. , ss_typename_param_k A
  1012. >
  1013. inline void basic_string_view<C, T, A>::refresh() stlsoft_throw_0()
  1014. {
  1015. STLSOFT_ASSERT(is_valid());
  1016. close_set_null_();
  1017. STLSOFT_ASSERT(is_valid());
  1018. }
  1019. // Attributes
  1020. template< ss_typename_param_k C
  1021. , ss_typename_param_k T
  1022. , ss_typename_param_k A
  1023. >
  1024. inline ss_typename_type_ret_k basic_string_view<C, T, A>::size_type basic_string_view<C, T, A>::size() const stlsoft_throw_0()
  1025. {
  1026. STLSOFT_ASSERT(is_valid());
  1027. return m_length;
  1028. }
  1029. template< ss_typename_param_k C
  1030. , ss_typename_param_k T
  1031. , ss_typename_param_k A
  1032. >
  1033. inline /* static */ ss_typename_type_ret_k basic_string_view<C, T, A>::size_type basic_string_view<C, T, A>::max_size() stlsoft_throw_0()
  1034. {
  1035. return static_cast<size_type>(-1) / sizeof(char_type);
  1036. }
  1037. // size_type max_size() const;
  1038. template< ss_typename_param_k C
  1039. , ss_typename_param_k T
  1040. , ss_typename_param_k A
  1041. >
  1042. inline ss_typename_type_ret_k basic_string_view<C, T, A>::size_type basic_string_view<C, T, A>::length() const stlsoft_throw_0()
  1043. {
  1044. STLSOFT_ASSERT(is_valid());
  1045. return m_length;
  1046. }
  1047. template< ss_typename_param_k C
  1048. , ss_typename_param_k T
  1049. , ss_typename_param_k A
  1050. >
  1051. inline ss_typename_type_ret_k basic_string_view<C, T, A>::size_type basic_string_view<C, T, A>::capacity() const stlsoft_throw_0()
  1052. {
  1053. STLSOFT_ASSERT(is_valid());
  1054. return m_length;
  1055. }
  1056. template< ss_typename_param_k C
  1057. , ss_typename_param_k T
  1058. , ss_typename_param_k A
  1059. >
  1060. inline ss_bool_t basic_string_view<C, T, A>::empty() const stlsoft_throw_0()
  1061. {
  1062. STLSOFT_ASSERT(is_valid());
  1063. return 0 == size();
  1064. }
  1065. template< ss_typename_param_k C
  1066. , ss_typename_param_k T
  1067. , ss_typename_param_k A
  1068. >
  1069. inline ss_typename_type_ret_k basic_string_view<C, T, A>::allocator_type basic_string_view<C, T, A>::get_allocator() const
  1070. {
  1071. return *this;
  1072. }
  1073. // Comparison
  1074. template< ss_typename_param_k C
  1075. , ss_typename_param_k T
  1076. , ss_typename_param_k A
  1077. >
  1078. inline ss_bool_t basic_string_view<C, T, A>::equal(ss_typename_type_k basic_string_view<C, T, A>::class_type const& rhs) const stlsoft_throw_0()
  1079. {
  1080. STLSOFT_ASSERT(is_valid());
  1081. return (m_length == rhs.m_length) && ((m_base == rhs.m_base) || 0 == traits_type::compare(m_base, rhs.m_base, m_length));
  1082. }
  1083. template< ss_typename_param_k C
  1084. , ss_typename_param_k T
  1085. , ss_typename_param_k A
  1086. >
  1087. inline ss_bool_t basic_string_view<C, T, A>::equal(ss_typename_type_k basic_string_view<C, T, A>::value_type const* rhs, ss_typename_type_k basic_string_view<C, T, A>::size_type cchRhs) const stlsoft_throw_0()
  1088. {
  1089. STLSOFT_ASSERT(is_valid());
  1090. return (m_length == cchRhs) && ((m_base == rhs) || 0 == compare_(m_base, m_length, rhs, cchRhs));
  1091. }
  1092. template< ss_typename_param_k C
  1093. , ss_typename_param_k T
  1094. , ss_typename_param_k A
  1095. >
  1096. inline ss_sint_t basic_string_view<C, T, A>::compare( ss_typename_type_k basic_string_view<C, T, A>::size_type pos
  1097. , ss_typename_type_k basic_string_view<C, T, A>::size_type cch
  1098. , ss_typename_type_k basic_string_view<C, T, A>::value_type const *rhs
  1099. , ss_typename_type_k basic_string_view<C, T, A>::size_type cchRhs) const stlsoft_throw_0()
  1100. {
  1101. STLSOFT_ASSERT(is_valid());
  1102. size_type lhs_len = length();
  1103. if(!(pos < lhs_len))
  1104. {
  1105. pos = lhs_len;
  1106. }
  1107. else
  1108. {
  1109. lhs_len -= pos;
  1110. }
  1111. if(cch < lhs_len)
  1112. {
  1113. lhs_len = cch;
  1114. }
  1115. size_type rhs_len = (NULL == rhs) ? 0 : traits_type::length(rhs);
  1116. if(cchRhs < rhs_len)
  1117. {
  1118. rhs_len = cchRhs;
  1119. }
  1120. STLSOFT_ASSERT(is_valid());
  1121. return compare_(m_base + pos, lhs_len, rhs, rhs_len);
  1122. }
  1123. template< ss_typename_param_k C
  1124. , ss_typename_param_k T
  1125. , ss_typename_param_k A
  1126. >
  1127. inline ss_sint_t basic_string_view<C, T, A>::compare( ss_typename_type_k basic_string_view<C, T, A>::size_type pos
  1128. , ss_typename_type_k basic_string_view<C, T, A>::size_type cch
  1129. , ss_typename_type_k basic_string_view<C, T, A>::value_type const* rhs) const stlsoft_throw_0()
  1130. {
  1131. STLSOFT_ASSERT(is_valid());
  1132. size_type lhs_len = length();
  1133. if(!(pos < lhs_len))
  1134. {
  1135. pos = lhs_len;
  1136. }
  1137. else
  1138. {
  1139. lhs_len -= pos;
  1140. }
  1141. if(cch < lhs_len)
  1142. {
  1143. lhs_len = cch;
  1144. }
  1145. size_type rhs_len = (NULL == rhs) ? 0 : traits_type::length(rhs);
  1146. STLSOFT_ASSERT(is_valid());
  1147. return compare_(m_base + pos, lhs_len, rhs, rhs_len);
  1148. }
  1149. template< ss_typename_param_k C
  1150. , ss_typename_param_k T
  1151. , ss_typename_param_k A
  1152. >
  1153. inline ss_sint_t basic_string_view<C, T, A>::compare(ss_typename_type_k basic_string_view<C, T, A>::value_type const* rhs) const stlsoft_throw_0()
  1154. {
  1155. STLSOFT_ASSERT(is_valid());
  1156. size_type lhs_len = length();
  1157. size_type rhs_len = (NULL == rhs) ? 0 : traits_type::length(rhs);
  1158. return compare_(m_base, lhs_len, rhs, rhs_len);
  1159. }
  1160. template< ss_typename_param_k C
  1161. , ss_typename_param_k T
  1162. , ss_typename_param_k A
  1163. >
  1164. inline ss_sint_t basic_string_view<C, T, A>::compare( ss_typename_type_k basic_string_view<C, T, A>::size_type pos
  1165. , ss_typename_type_k basic_string_view<C, T, A>::size_type cch
  1166. , ss_typename_type_k basic_string_view<C, T, A>::class_type const& rhs
  1167. , ss_typename_type_k basic_string_view<C, T, A>::size_type posRhs
  1168. , ss_typename_type_k basic_string_view<C, T, A>::size_type cchRhs) const stlsoft_throw_0()
  1169. {
  1170. STLSOFT_ASSERT(is_valid());
  1171. STLSOFT_ASSERT(pos <= length());
  1172. STLSOFT_ASSERT(posRhs <= rhs.length());
  1173. size_type lhs_len = length();
  1174. if(pos == lhs_len)
  1175. {
  1176. lhs_len = 0u;
  1177. }
  1178. else if(pos + cch > lhs_len)
  1179. {
  1180. lhs_len -= pos;
  1181. }
  1182. if(cch < lhs_len)
  1183. {
  1184. lhs_len = cch;
  1185. }
  1186. size_type rhs_len = rhs.length();
  1187. if(posRhs == rhs_len)
  1188. {
  1189. rhs_len = 0u;
  1190. }
  1191. else if(posRhs + cchRhs > rhs_len)
  1192. {
  1193. rhs_len -= posRhs;
  1194. }
  1195. if(cchRhs < rhs_len)
  1196. {
  1197. rhs_len = cchRhs;
  1198. }
  1199. STLSOFT_ASSERT(is_valid());
  1200. return compare_(m_base + pos, lhs_len, rhs.m_base + posRhs, rhs_len);
  1201. }
  1202. template< ss_typename_param_k C
  1203. , ss_typename_param_k T
  1204. , ss_typename_param_k A
  1205. >
  1206. inline ss_sint_t basic_string_view<C, T, A>::compare( ss_typename_type_k basic_string_view<C, T, A>::size_type pos
  1207. , ss_typename_type_k basic_string_view<C, T, A>::size_type cch
  1208. , ss_typename_type_k basic_string_view<C, T, A>::class_type const& rhs) const stlsoft_throw_0()
  1209. {
  1210. STLSOFT_ASSERT(is_valid());
  1211. size_type lhs_len = length();
  1212. if(!(pos < lhs_len))
  1213. {
  1214. pos = lhs_len;
  1215. }
  1216. else
  1217. {
  1218. lhs_len -= pos;
  1219. }
  1220. if(cch < lhs_len)
  1221. {
  1222. lhs_len = cch;
  1223. }
  1224. size_type rhs_len = rhs.length();
  1225. STLSOFT_ASSERT(is_valid());
  1226. return compare_(m_base + pos, lhs_len, rhs.m_base, rhs_len);
  1227. }
  1228. template< ss_typename_param_k C
  1229. , ss_typename_param_k T
  1230. , ss_typename_param_k A
  1231. >
  1232. inline ss_sint_t basic_string_view<C, T, A>::compare(ss_typename_type_k basic_string_view<C, T, A>::class_type const& rhs) const stlsoft_throw_0()
  1233. {
  1234. STLSOFT_ASSERT(is_valid());
  1235. size_type lhs_len = length();
  1236. size_type rhs_len = rhs.length();
  1237. STLSOFT_ASSERT(is_valid());
  1238. return compare_(m_base, lhs_len, rhs.m_base, rhs_len);
  1239. }
  1240. // Accessors
  1241. #if 0
  1242. template< ss_typename_param_k C
  1243. , ss_typename_param_k T
  1244. , ss_typename_param_k A
  1245. >
  1246. inline ss_typename_type_ret_k basic_string_view<C, T, A>::reference basic_string_view<C, T, A>::operator [](ss_typename_type_k basic_string_view<C, T, A>::size_type index)
  1247. {
  1248. STLSOFT_ASSERT(is_valid());
  1249. return m_base[index];
  1250. }
  1251. #endif /* 0 */
  1252. template< ss_typename_param_k C
  1253. , ss_typename_param_k T
  1254. , ss_typename_param_k A
  1255. >
  1256. inline ss_typename_type_ret_k basic_string_view<C, T, A>::const_reference basic_string_view<C, T, A>::operator [](ss_typename_type_k basic_string_view<C, T, A>::size_type index) const
  1257. {
  1258. STLSOFT_MESSAGE_ASSERT("string_view index out of bounds", index <= size());
  1259. STLSOFT_ASSERT(is_valid());
  1260. return (index == size()) ? *empty_string_() : m_base[index];
  1261. }
  1262. #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
  1263. template< ss_typename_param_k C
  1264. , ss_typename_param_k T
  1265. , ss_typename_param_k A
  1266. >
  1267. inline ss_typename_type_ret_k basic_string_view<C, T, A>::const_reference basic_string_view<C, T, A>::at(ss_typename_type_k basic_string_view<C, T, A>::size_type index) const
  1268. {
  1269. STLSOFT_ASSERT(is_valid());
  1270. if(!(index < size()))
  1271. {
  1272. STLSOFT_THROW_X(stlsoft_ns_qual_std(out_of_range)("index out of range"));
  1273. }
  1274. STLSOFT_ASSERT(is_valid());
  1275. return m_base[index];
  1276. }
  1277. #endif /* !STLSOFT_CF_EXCEPTION_SUPPORT */
  1278. template< ss_typename_param_k C
  1279. , ss_typename_param_k T
  1280. , ss_typename_param_k A
  1281. >
  1282. inline ss_typename_type_ret_k basic_string_view<C, T, A>::value_type const* basic_string_view<C, T, A>::c_str() const
  1283. {
  1284. STLSOFT_ASSERT(is_valid());
  1285. if(NULL != m_cstr)
  1286. {
  1287. // Already allocated, so return; if underlying
  1288. return m_cstr;
  1289. }
  1290. else
  1291. {
  1292. if(0 == m_length)
  1293. {
  1294. return empty_string_();
  1295. }
  1296. else
  1297. {
  1298. // Must allocate the m_cstr member
  1299. allocator_type& ator = const_cast<class_type&>(*this);
  1300. char_type* s = ator.allocate(1 + length(), NULL);
  1301. STLSOFT_SUPPRESS_UNUSED(ator); // Need this for silly old Borland
  1302. // Because the class might be parameterised with a no-throw allocator,
  1303. // we'll check the result. This is really hokey, of course, since we're
  1304. // returning a NULL string in the circumstances where memory has
  1305. // failed to allocate. In such cases we can only hope that the memory
  1306. // exhaustion is non-local and that the callee is going to suffer and die
  1307. // anyway, irrespective of the fact that we've returned an invalid value
  1308. // to it.
  1309. if(NULL != s)
  1310. {
  1311. traits_type::copy(s, m_base, m_length);
  1312. s[m_length] = '\0';
  1313. remove_const(m_cstr) = s;
  1314. STLSOFT_ASSERT(is_valid());
  1315. }
  1316. return m_cstr;
  1317. }
  1318. }
  1319. }
  1320. #if 0
  1321. template< ss_typename_param_k C
  1322. , ss_typename_param_k T
  1323. , ss_typename_param_k A
  1324. >
  1325. inline ss_typename_type_ret_k basic_string_view<C, T, A>::value_type const* basic_string_view<C, T, A>::c_str(ss_bool_t bRefresh) const
  1326. {
  1327. if(bRefresh)
  1328. {
  1329. const_cast<class_type*>(this)->refresh();
  1330. }
  1331. return c_str();
  1332. }
  1333. #endif /* 0 */
  1334. template< ss_typename_param_k C
  1335. , ss_typename_param_k T
  1336. , ss_typename_param_k A
  1337. >
  1338. inline ss_typename_type_ret_k basic_string_view<C, T, A>::value_type const* basic_string_view<C, T, A>::data() const stlsoft_throw_0()
  1339. {
  1340. STLSOFT_ASSERT(is_valid());
  1341. return (0 == m_length) ? empty_string_() : m_base;
  1342. }
  1343. template< ss_typename_param_k C
  1344. , ss_typename_param_k T
  1345. , ss_typename_param_k A
  1346. >
  1347. inline ss_typename_type_ret_k basic_string_view<C, T, A>::value_type const* basic_string_view<C, T, A>::base() const stlsoft_throw_0()
  1348. {
  1349. STLSOFT_ASSERT(is_valid());
  1350. return m_base;
  1351. }
  1352. #if 0
  1353. template< ss_typename_param_k C
  1354. , ss_typename_param_k T
  1355. , ss_typename_param_k A
  1356. >
  1357. inline ss_typename_type_ret_k basic_string_view<C, T, A>::reference basic_string_view<C, T, A>::front()
  1358. {
  1359. STLSOFT_ASSERT(is_valid());
  1360. return (*this)[0];
  1361. }
  1362. template< ss_typename_param_k C
  1363. , ss_typename_param_k T
  1364. , ss_typename_param_k A
  1365. >
  1366. inline ss_typename_type_ret_k basic_string_view<C, T, A>::reference basic_string_view<C, T, A>::back()
  1367. {
  1368. STLSOFT_ASSERT(is_valid());
  1369. return (*this)[length() - 1];
  1370. }
  1371. #endif /* 0 */
  1372. template< ss_typename_param_k C
  1373. , ss_typename_param_k T
  1374. , ss_typename_param_k A
  1375. >
  1376. inline ss_typename_type_ret_k basic_string_view<C, T, A>::const_reference basic_string_view<C, T, A>::front() const
  1377. {
  1378. STLSOFT_ASSERT(is_valid());
  1379. return (*this)[0];
  1380. }
  1381. template< ss_typename_param_k C
  1382. , ss_typename_param_k T
  1383. , ss_typename_param_k A
  1384. >
  1385. inline ss_typename_type_ret_k basic_string_view<C, T, A>::const_reference basic_string_view<C, T, A>::back() const
  1386. {
  1387. STLSOFT_ASSERT(is_valid());
  1388. return (*this)[length() - 1];
  1389. }
  1390. template< ss_typename_param_k C
  1391. , ss_typename_param_k T
  1392. , ss_typename_param_k A
  1393. >
  1394. inline ss_typename_type_ret_k basic_string_view<C, T, A>::size_type basic_string_view<C, T, A>::copy( ss_typename_type_k basic_string_view<C, T, A>::value_type *dest
  1395. , ss_typename_type_k basic_string_view<C, T, A>::size_type cch
  1396. , ss_typename_type_k basic_string_view<C, T, A>::size_type pos /* = 0 */) const
  1397. {
  1398. STLSOFT_ASSERT(is_valid());
  1399. size_type len = length();
  1400. if(pos < len)
  1401. {
  1402. if(len < pos + cch)
  1403. {
  1404. cch = len - pos;
  1405. }
  1406. traits_type::copy(dest, data() + pos, cch);
  1407. }
  1408. else
  1409. {
  1410. cch = 0;
  1411. }
  1412. STLSOFT_ASSERT(is_valid());
  1413. return cch;
  1414. }
  1415. // Iteration
  1416. template< ss_typename_param_k C
  1417. , ss_typename_param_k T
  1418. , ss_typename_param_k A
  1419. >
  1420. inline ss_typename_type_ret_k basic_string_view<C, T, A>::const_iterator basic_string_view<C, T, A>::begin() const
  1421. {
  1422. STLSOFT_ASSERT(is_valid());
  1423. return m_base;
  1424. }
  1425. template< ss_typename_param_k C
  1426. , ss_typename_param_k T
  1427. , ss_typename_param_k A
  1428. >
  1429. inline ss_typename_type_ret_k basic_string_view<C, T, A>::const_iterator basic_string_view<C, T, A>::end() const
  1430. {
  1431. STLSOFT_ASSERT(is_valid());
  1432. return begin() + m_length;
  1433. }
  1434. #if 0
  1435. template< ss_typename_param_k C
  1436. , ss_typename_param_k T
  1437. , ss_typename_param_k A
  1438. >
  1439. inline ss_typename_type_ret_k basic_string_view<C, T, A>::iterator basic_string_view<C, T, A>::begin()
  1440. {
  1441. STLSOFT_ASSERT(is_valid());
  1442. return m_base;
  1443. }
  1444. template< ss_typename_param_k C
  1445. , ss_typename_param_k T
  1446. , ss_typename_param_k A
  1447. >
  1448. inline ss_typename_type_ret_k basic_string_view<C, T, A>::iterator basic_string_view<C, T, A>::end()
  1449. {
  1450. STLSOFT_ASSERT(is_valid());
  1451. return begin() + m_length;
  1452. }
  1453. #endif /* 0 */
  1454. #if defined(STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT)
  1455. template< ss_typename_param_k C
  1456. , ss_typename_param_k T
  1457. , ss_typename_param_k A
  1458. >
  1459. inline ss_typename_type_ret_k basic_string_view<C, T, A>::const_reverse_iterator basic_string_view<C, T, A>::rbegin() const
  1460. {
  1461. STLSOFT_ASSERT(is_valid());
  1462. return const_reverse_iterator(end());
  1463. }
  1464. template< ss_typename_param_k C
  1465. , ss_typename_param_k T
  1466. , ss_typename_param_k A
  1467. >
  1468. inline ss_typename_type_ret_k basic_string_view<C, T, A>::const_reverse_iterator basic_string_view<C, T, A>::rend() const
  1469. {
  1470. STLSOFT_ASSERT(is_valid());
  1471. return const_reverse_iterator(begin());
  1472. }
  1473. #if 0
  1474. template< ss_typename_param_k C
  1475. , ss_typename_param_k T
  1476. , ss_typename_param_k A
  1477. >
  1478. inline ss_typename_type_ret_k basic_string_view<C, T, A>::reverse_iterator basic_string_view<C, T, A>::rbegin()
  1479. {
  1480. STLSOFT_ASSERT(is_valid());
  1481. return reverse_iterator(end());
  1482. }
  1483. template< ss_typename_param_k C
  1484. , ss_typename_param_k T
  1485. , ss_typename_param_k A
  1486. >
  1487. inline ss_typename_type_ret_k basic_string_view<C, T, A>::reverse_iterator basic_string_view<C, T, A>::rend()
  1488. {
  1489. STLSOFT_ASSERT(is_valid());
  1490. return reverse_iterator(begin());
  1491. }
  1492. #endif /* 0 */
  1493. #endif /* STLSOFT_LF_BIDIRECTIONAL_ITERATOR_SUPPORT */
  1494. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  1495. /* /////////////////////////////////////////////////////////////////////////
  1496. * swapping
  1497. */
  1498. template< ss_typename_param_k C
  1499. , ss_typename_param_k T
  1500. , ss_typename_param_k A
  1501. >
  1502. inline void swap(basic_string_view<C, T, A>& lhs, basic_string_view<C, T, A>& rhs)
  1503. {
  1504. lhs.swap(rhs);
  1505. }
  1506. /* /////////////////////////////////////////////////////////////////////////
  1507. * String access shims
  1508. */
  1509. // c_str_data
  1510. /** \brief \ref group__concept__shim__string_access__c_str_data for stlsoft::basic_string_view
  1511. *
  1512. * \ingroup group__concept__shim__string_access
  1513. */
  1514. template< ss_typename_param_k C
  1515. , ss_typename_param_k T
  1516. , ss_typename_param_k A
  1517. >
  1518. inline C const* c_str_data(stlsoft_ns_qual(basic_string_view)<C, T, A> const& s)
  1519. {
  1520. return s.data();
  1521. }
  1522. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  1523. template <ss_typename_param_k T, ss_typename_param_k A>
  1524. inline ss_char_a_t const* c_str_data_a(stlsoft_ns_qual(basic_string_view)<ss_char_a_t, T, A> const& s)
  1525. {
  1526. return s.data();
  1527. }
  1528. template <ss_typename_param_k T, ss_typename_param_k A>
  1529. inline ss_char_w_t const* c_str_data_w(stlsoft_ns_qual(basic_string_view)<ss_char_w_t, T, A> const& s)
  1530. {
  1531. return s.data();
  1532. }
  1533. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  1534. // c_str_len
  1535. /** \brief \ref group__concept__shim__string_access__c_str_len for stlsoft::basic_string_view
  1536. *
  1537. * \ingroup group__concept__shim__string_access
  1538. */
  1539. template< ss_typename_param_k C
  1540. , ss_typename_param_k T
  1541. , ss_typename_param_k A
  1542. >
  1543. inline ss_size_t c_str_len(stlsoft_ns_qual(basic_string_view)<C, T, A> const& s)
  1544. {
  1545. return s.length();
  1546. }
  1547. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  1548. template <ss_typename_param_k T, ss_typename_param_k A>
  1549. inline ss_size_t c_str_len_a(stlsoft_ns_qual(basic_string_view)<ss_char_a_t, T, A> const& s)
  1550. {
  1551. return s.length();
  1552. }
  1553. template <ss_typename_param_k T, ss_typename_param_k A>
  1554. inline ss_size_t c_str_len_w(stlsoft_ns_qual(basic_string_view)<ss_char_w_t, T, A> const& s)
  1555. {
  1556. return s.length();
  1557. }
  1558. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  1559. // c_str_ptr
  1560. /** \brief \ref group__concept__shim__string_access__c_str_ptr for stlsoft::basic_string_view
  1561. *
  1562. * \ingroup group__concept__shim__string_access
  1563. */
  1564. template< ss_typename_param_k C
  1565. , ss_typename_param_k T
  1566. , ss_typename_param_k A
  1567. >
  1568. inline C const* c_str_ptr(stlsoft_ns_qual(basic_string_view)<C, T, A> const& s)
  1569. {
  1570. return s.c_str();
  1571. }
  1572. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  1573. template <ss_typename_param_k T, ss_typename_param_k A>
  1574. inline ss_char_a_t const* c_str_ptr_a(stlsoft_ns_qual(basic_string_view)<ss_char_a_t, T, A> const& s)
  1575. {
  1576. return s.c_str();
  1577. }
  1578. template <ss_typename_param_k T, ss_typename_param_k A>
  1579. inline ss_char_w_t const* c_str_ptr_w(stlsoft_ns_qual(basic_string_view)<ss_char_w_t, T, A> const& s)
  1580. {
  1581. return s.c_str();
  1582. }
  1583. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  1584. // c_str_ptr_null
  1585. /** \brief \ref group__concept__shim__string_access__c_str_ptr_null for stlsoft::basic_string_view
  1586. *
  1587. * \ingroup group__concept__shim__string_access
  1588. */
  1589. template< ss_typename_param_k C
  1590. , ss_typename_param_k T
  1591. , ss_typename_param_k A
  1592. >
  1593. inline C const* c_str_ptr_null(stlsoft_ns_qual(basic_string_view)<C, T, A> const& s)
  1594. {
  1595. return (0 != s.length()) ? s.c_str() : NULL;
  1596. }
  1597. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  1598. template <ss_typename_param_k T, ss_typename_param_k A>
  1599. inline ss_char_a_t const* c_str_ptr_null_a(stlsoft_ns_qual(basic_string_view)<ss_char_a_t, T, A> const& s)
  1600. {
  1601. return (0 != s.length()) ? s.c_str() : NULL;
  1602. }
  1603. template <ss_typename_param_k T, ss_typename_param_k A>
  1604. inline ss_char_w_t const* c_str_ptr_null_w(stlsoft_ns_qual(basic_string_view)<ss_char_w_t, T, A> const& s)
  1605. {
  1606. return (0 != s.length()) ? s.c_str() : NULL;
  1607. }
  1608. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  1609. /* ////////////////////////////////////////////////////////////////////// */
  1610. #ifndef _STLSOFT_NO_NAMESPACE
  1611. } // namespace stlsoft
  1612. #endif /* _STLSOFT_NO_NAMESPACE */
  1613. /* In the special case of Intel behaving as VC++ 7.0 or earlier on Win32, we
  1614. * illegally insert into the std namespace.
  1615. */
  1616. #if defined(STLSOFT_CF_std_NAMESPACE)
  1617. # if ( ( defined(STLSOFT_COMPILER_IS_INTEL) && \
  1618. defined(_MSC_VER))) && \
  1619. _MSC_VER < 1310
  1620. namespace std
  1621. {
  1622. template< ss_typename_param_k C
  1623. , ss_typename_param_k T
  1624. , ss_typename_param_k A
  1625. >
  1626. inline void swap(stlsoft_ns_qual(basic_string_view)<C, T, A>& lhs, stlsoft_ns_qual(basic_string_view)<C, T, A>& rhs)
  1627. {
  1628. lhs.swap(rhs);
  1629. }
  1630. } // namespace std
  1631. # endif /* INTEL && _MSC_VER < 1310 */
  1632. #endif /* STLSOFT_CF_std_NAMESPACE */
  1633. /* ////////////////////////////////////////////////////////////////////// */
  1634. #endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_STRING_VIEW */
  1635. /* ///////////////////////////// end of file //////////////////////////// */