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.

397 lines
12 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/string/view_slice_functions.hpp
  3. *
  4. * Purpose: String view slice functions.
  5. *
  6. * Created: 25th April 2005
  7. * Updated: 4th July 2012
  8. *
  9. * Thanks: To Pablo Aguilar for inspiration for these functions, and
  10. * collaboration on their implementation.
  11. *
  12. * Home: http://stlsoft.org/
  13. *
  14. * Copyright (c) 2005-2012, Matthew Wilson and Synesis Software
  15. * Copyright (c) 2005, Pablo Aguilar
  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/view_slice_functions.hpp
  44. *
  45. * \brief [C++ only] String view slice functions
  46. * (\ref group__library__string "String" Library).
  47. */
  48. #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_VIEW_SLICE_FUNCTIONS
  49. #define STLSOFT_INCL_STLSOFT_STRING_HPP_VIEW_SLICE_FUNCTIONS
  50. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  51. # define STLSOFT_VER_INCL_STLSOFT_STRING_HPP_VIEW_SLICE_FUNCTIONS_MAJOR 2
  52. # define STLSOFT_VER_INCL_STLSOFT_STRING_HPP_VIEW_SLICE_FUNCTIONS_MINOR 1
  53. # define STLSOFT_VER_INCL_STLSOFT_STRING_HPP_VIEW_SLICE_FUNCTIONS_REVISION 6
  54. # define STLSOFT_VER_INCL_STLSOFT_STRING_HPP_VIEW_SLICE_FUNCTIONS_EDIT 26
  55. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  56. /* /////////////////////////////////////////////////////////////////////////
  57. * Compatibility
  58. */
  59. /*
  60. [Incompatibilies-start]
  61. STLSOFT_COMPILER_IS_MWERKS: __MWERKS__<0x3000
  62. STLSOFT_COMPILER_IS_WATCOM:
  63. [Incompatibilies-end]
  64. */
  65. /* /////////////////////////////////////////////////////////////////////////
  66. * Includes
  67. */
  68. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  69. # include <stlsoft/stlsoft.h>
  70. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  71. #if defined(STLSOFT_COMPILER_IS_MWERKS) && \
  72. ((__MWERKS__ & 0xff00) < 0x3000)
  73. # error stlsoft/string/view_slice_functions.hpp not compatible with Metrowerks 7.x (v2.4)
  74. #endif /* compiler */
  75. #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
  76. # include <stlsoft/shims/access/string.hpp>
  77. #endif /* !STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING */
  78. #if defined(STLSOFT_COMPILER_IS_GCC)
  79. # ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_SIMPLE_STRING
  80. # include <stlsoft/string/simple_string.hpp>
  81. # endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_SIMPLE_STRING */
  82. #endif
  83. #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_STRING_VIEW
  84. # include <stlsoft/string/string_view.hpp>
  85. #endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_STRING_VIEW */
  86. #ifdef STLSOFT_UNITTEST
  87. # include <string>
  88. # ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_SIMPLE_STRING
  89. # include <stlsoft/string/simple_string.hpp>
  90. # endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_SIMPLE_STRING */
  91. #endif /* STLSOFT_UNITTEST */
  92. /* /////////////////////////////////////////////////////////////////////////
  93. * Namespace
  94. */
  95. #ifndef _STLSOFT_NO_NAMESPACE
  96. namespace stlsoft
  97. {
  98. #endif /* _STLSOFT_NO_NAMESPACE */
  99. /* /////////////////////////////////////////////////////////////////////////
  100. * Helper classes
  101. */
  102. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  103. template <ss_typename_param_k S>
  104. struct string_view_helper_traits
  105. {
  106. typedef S string_type;
  107. typedef ss_typename_type_k string_type::value_type char_type;
  108. typedef basic_string_view<char_type> view_type;
  109. };
  110. # if !defined(STLSOFT_COMPILER_IS_MSVC) || \
  111. _MSC_VER >= 1310
  112. STLSOFT_TEMPLATE_SPECIALISATION
  113. struct string_view_helper_traits<ss_char_a_t*>
  114. {
  115. typedef ss_char_a_t char_type;
  116. typedef basic_string_view<char_type> view_type;
  117. };
  118. # endif /* compiler */
  119. STLSOFT_TEMPLATE_SPECIALISATION
  120. struct string_view_helper_traits<ss_char_a_t const*>
  121. {
  122. typedef ss_char_a_t char_type;
  123. typedef basic_string_view<char_type> view_type;
  124. };
  125. # ifdef STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT
  126. template <size_t N>
  127. struct string_view_helper_traits<ss_char_a_t [N]>
  128. {
  129. typedef ss_char_a_t char_type;
  130. typedef basic_string_view<char_type> view_type;
  131. };
  132. template <size_t N>
  133. struct string_view_helper_traits<ss_char_a_t const [N]>
  134. {
  135. typedef ss_char_a_t char_type;
  136. typedef basic_string_view<char_type> view_type;
  137. };
  138. # endif /* STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT */
  139. # if !defined(STLSOFT_COMPILER_IS_MSVC) || \
  140. _MSC_VER >= 1310
  141. STLSOFT_TEMPLATE_SPECIALISATION
  142. struct string_view_helper_traits<ss_char_w_t*>
  143. {
  144. typedef ss_char_w_t char_type;
  145. typedef basic_string_view<char_type> view_type;
  146. };
  147. # endif /* compiler */
  148. STLSOFT_TEMPLATE_SPECIALISATION
  149. struct string_view_helper_traits<ss_char_w_t const*>
  150. {
  151. typedef ss_char_w_t char_type;
  152. typedef basic_string_view<char_type> view_type;
  153. };
  154. # ifdef STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT
  155. template <size_t N>
  156. struct string_view_helper_traits<ss_char_w_t [N]>
  157. {
  158. typedef ss_char_w_t char_type;
  159. typedef basic_string_view<char_type> view_type;
  160. };
  161. template <size_t N>
  162. struct string_view_helper_traits<ss_char_w_t const [N]>
  163. {
  164. typedef ss_char_w_t char_type;
  165. typedef basic_string_view<char_type> view_type;
  166. };
  167. # endif /* STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT */
  168. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  169. /* /////////////////////////////////////////////////////////////////////////
  170. * Slice functions
  171. */
  172. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  173. template <ss_typename_param_k C>
  174. inline basic_string_view<C> left_view_helper(C const* s, ss_size_t n)
  175. {
  176. const ss_size_t len = stlsoft_ns_qual(c_str_len)(s);
  177. if(n > len)
  178. {
  179. // Want more than is available, so get all
  180. n = len;
  181. }
  182. return basic_string_view<C>(s, n);
  183. }
  184. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  185. /** \brief
  186. *
  187. * \ingroup group__library__string
  188. */
  189. inline basic_string_view<ss_char_a_t> left_view(ss_char_a_t const* s, ss_size_t n)
  190. {
  191. return left_view_helper(s, n);
  192. }
  193. /** \brief
  194. *
  195. * \ingroup group__library__string
  196. */
  197. inline basic_string_view<ss_char_w_t> left_view(ss_char_w_t const* s, ss_size_t n)
  198. {
  199. return left_view_helper(s, n);
  200. }
  201. template <ss_typename_param_k S>
  202. inline ss_typename_type_ret_k string_view_helper_traits<S>::view_type left_view(S const& s, ss_size_t n)
  203. {
  204. typedef string_view_helper_traits<S> traits_t;
  205. typedef ss_typename_type_k traits_t::view_type view_t;
  206. const ss_size_t len = stlsoft_ns_qual(c_str_len)(s);
  207. if(n > len)
  208. {
  209. // Want more than is available, so get all
  210. n = len;
  211. }
  212. return view_t(s.data(), n);
  213. }
  214. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  215. template <ss_typename_param_k C>
  216. inline basic_string_view<C> right_view_helper(C const* s, ss_size_t n)
  217. {
  218. const ss_size_t len = stlsoft_ns_qual(c_str_len)(s);
  219. if(n > len)
  220. {
  221. // Want more than is available, so get all, from start
  222. n = len;
  223. }
  224. else
  225. {
  226. // Want less than is available, so get n from end
  227. s += (len - n);
  228. }
  229. return basic_string_view<C>(s, n);
  230. }
  231. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  232. /** \brief
  233. *
  234. * \ingroup group__library__string
  235. */
  236. inline basic_string_view<ss_char_a_t> right_view(ss_char_a_t const* s, ss_size_t n)
  237. {
  238. return right_view_helper(s, n);
  239. }
  240. /** \brief
  241. *
  242. * \ingroup group__library__string
  243. */
  244. inline basic_string_view<ss_char_w_t> right_view(ss_char_w_t const* s, ss_size_t n)
  245. {
  246. return right_view_helper(s, n);
  247. }
  248. template <ss_typename_param_k S>
  249. inline ss_typename_type_ret_k string_view_helper_traits<S>::view_type right_view(S const& s, ss_size_t n)
  250. {
  251. typedef string_view_helper_traits<S> traits_t;
  252. typedef ss_typename_type_k traits_t::view_type view_t;
  253. const ss_size_t len = stlsoft_ns_qual(c_str_len)(s);
  254. ss_size_t off = 0;
  255. if(n > len)
  256. {
  257. // Want more than is available, so get all, from start
  258. n = len;
  259. }
  260. else
  261. {
  262. off = len - n;
  263. }
  264. return view_t(s.data() + off, n);
  265. }
  266. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  267. template <ss_typename_param_k C>
  268. inline basic_string_view<C> mid_view_helper(C const* s, ss_size_t start, ss_size_t n)
  269. {
  270. const ss_size_t len = stlsoft_ns_qual(c_str_len)(s);
  271. ss_size_t off = 0;
  272. if(start > len)
  273. {
  274. // Want more than is available, so we start at the end
  275. off = len;
  276. }
  277. else
  278. {
  279. off = start;
  280. }
  281. if(off + n > len)
  282. {
  283. // Want more than is available starting at off, so we just get what is available
  284. n = len - off;
  285. }
  286. return basic_string_view<C>(s + off, n);
  287. }
  288. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  289. /** \brief
  290. *
  291. * \ingroup group__library__string
  292. */
  293. inline basic_string_view<ss_char_a_t> mid_view(ss_char_a_t const* s, ss_size_t start, ss_size_t n)
  294. {
  295. return mid_view_helper(s, start, n);
  296. }
  297. /** \brief
  298. *
  299. * \ingroup group__library__string
  300. */
  301. inline basic_string_view<ss_char_w_t> mid_view(ss_char_w_t const* s, ss_size_t start, ss_size_t n)
  302. {
  303. return mid_view_helper(s, start, n);
  304. }
  305. template <ss_typename_param_k S>
  306. inline ss_typename_type_ret_k string_view_helper_traits<S>::view_type mid_view(S const& s, ss_size_t start, ss_size_t n)
  307. {
  308. typedef string_view_helper_traits<S> traits_t;
  309. typedef ss_typename_type_k traits_t::view_type view_t;
  310. const ss_size_t len = stlsoft_ns_qual(c_str_len)(s);
  311. ss_size_t off = 0;
  312. if(start > len)
  313. {
  314. // Want more than is available, so we start at the end
  315. off = len;
  316. }
  317. else
  318. {
  319. off = start;
  320. }
  321. if(off + n > len)
  322. {
  323. // Want more than is available starting at off, so we just get what is available
  324. n = len - off;
  325. }
  326. return view_t(s.data() + off, n);
  327. }
  328. ////////////////////////////////////////////////////////////////////////////
  329. // Unit-testing
  330. #ifdef STLSOFT_UNITTEST
  331. # include "./unittest/view_slice_functions_unittest_.h"
  332. #endif /* STLSOFT_UNITTEST */
  333. /* ////////////////////////////////////////////////////////////////////// */
  334. #ifndef _STLSOFT_NO_NAMESPACE
  335. } // namespace stlsoft
  336. #endif /* _STLSOFT_NO_NAMESPACE */
  337. /* ////////////////////////////////////////////////////////////////////// */
  338. #endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_VIEW_SLICE_FUNCTIONS */
  339. /* ///////////////////////////// end of file //////////////////////////// */