collection_traits_detail.hpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. // Boost string_algo library collection_traits.hpp header file -----------------------//
  2. // Copyright Pavol Droba 2002-2003. Use, modification and
  3. // distribution is subject to the Boost Software License, Version
  4. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // See http://www.boost.org for updates, documentation, and revision history.
  7. #ifndef BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
  8. #define BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
  9. #include <boost/algorithm/string/config.hpp>
  10. #include <cstddef>
  11. #include <string>
  12. #include <boost/type_traits/is_array.hpp>
  13. #include <boost/type_traits/is_pointer.hpp>
  14. #include <boost/type_traits/is_const.hpp>
  15. #include <boost/type_traits/is_convertible.hpp>
  16. #include <boost/type_traits/remove_pointer.hpp>
  17. #include <boost/type_traits/remove_cv.hpp>
  18. #include <boost/mpl/eval_if.hpp>
  19. #include <boost/mpl/identity.hpp>
  20. #include <boost/mpl/vector.hpp>
  21. #include <boost/mpl/fold.hpp>
  22. #include <boost/detail/iterator.hpp>
  23. #include <boost/algorithm/string/yes_no_type.hpp>
  24. // Container traits implementation ---------------------------------------------------------
  25. namespace boost {
  26. namespace algorithm {
  27. namespace detail {
  28. // Default collection traits -----------------------------------------------------------------
  29. // Default collection helper
  30. /*
  31. Wraps std::container compliant containers
  32. */
  33. template< typename ContainerT >
  34. struct default_container_traits
  35. {
  36. typedef BOOST_STRING_TYPENAME ContainerT::value_type value_type;
  37. typedef BOOST_STRING_TYPENAME ContainerT::iterator iterator;
  38. typedef BOOST_STRING_TYPENAME ContainerT::const_iterator const_iterator;
  39. typedef BOOST_STRING_TYPENAME
  40. ::boost::mpl::if_< ::boost::is_const<ContainerT>,
  41. const_iterator,
  42. iterator
  43. >::type result_iterator;
  44. typedef BOOST_STRING_TYPENAME ContainerT::difference_type difference_type;
  45. typedef BOOST_STRING_TYPENAME ContainerT::size_type size_type;
  46. // static operations
  47. template< typename C >
  48. static size_type size( const C& c )
  49. {
  50. return c.size();
  51. }
  52. template< typename C >
  53. static bool empty( const C& c )
  54. {
  55. return c.empty();
  56. }
  57. #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  58. template< typename C >
  59. static iterator begin( C& c )
  60. {
  61. return c.begin();
  62. }
  63. template< typename C >
  64. static const_iterator begin( const C& c )
  65. {
  66. return c.begin();
  67. }
  68. template< typename C >
  69. static iterator end( C& c )
  70. {
  71. return c.end();
  72. }
  73. template< typename C >
  74. static const_iterator end( const C& c )
  75. {
  76. return c.end();
  77. }
  78. #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  79. template< typename C >
  80. static result_iterator begin( C& c )
  81. {
  82. return c.begin();
  83. }
  84. template< typename C >
  85. static result_iterator end( C& c )
  86. {
  87. return c.end();
  88. }
  89. #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  90. };
  91. template<typename T>
  92. struct default_container_traits_selector
  93. {
  94. typedef default_container_traits<T> type;
  95. };
  96. // Pair container traits ---------------------------------------------------------------------
  97. // pair selector
  98. template< typename T, typename U >
  99. yes_type is_pair_impl( const std::pair<T,U>* );
  100. no_type is_pair_impl( ... );
  101. template<typename T> struct is_pair
  102. {
  103. private:
  104. static T* t;
  105. public:
  106. BOOST_STATIC_CONSTANT( bool, value=
  107. sizeof(is_pair_impl(t))==sizeof(yes_type) );
  108. };
  109. // pair helper
  110. template< typename PairT >
  111. struct pair_container_traits
  112. {
  113. typedef BOOST_STRING_TYPENAME PairT::first_type element_type;
  114. typedef BOOST_STRING_TYPENAME ::boost::detail::
  115. iterator_traits<element_type>::value_type value_type;
  116. typedef std::size_t size_type;
  117. typedef BOOST_STRING_TYPENAME ::boost::detail::
  118. iterator_traits<element_type>::difference_type difference_type;
  119. typedef element_type iterator;
  120. typedef element_type const_iterator;
  121. typedef element_type result_iterator;
  122. // static operations
  123. template< typename P >
  124. static size_type size( const P& p )
  125. {
  126. difference_type diff = std::distance( p.first, p.second );
  127. if ( diff < 0 )
  128. return 0;
  129. else
  130. return diff;
  131. }
  132. template< typename P >
  133. static bool empty( const P& p )
  134. {
  135. return p.first==p.second;
  136. }
  137. template< typename P >
  138. static const_iterator begin( const P& p )
  139. {
  140. return p.first;
  141. }
  142. template< typename P >
  143. static const_iterator end( const P& p )
  144. {
  145. return p.second;
  146. }
  147. }; // 'pair_container_helper'
  148. template<typename T>
  149. struct pair_container_traits_selector
  150. {
  151. typedef pair_container_traits<T> type;
  152. };
  153. // Array container traits ---------------------------------------------------------------
  154. #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  155. // array traits ( partial specialization )
  156. template< typename T >
  157. struct array_traits;
  158. template< typename T, std::size_t sz >
  159. struct array_traits<T[sz]>
  160. {
  161. // typedef
  162. typedef T* iterator;
  163. typedef const T* const_iterator;
  164. typedef T value_type;
  165. typedef std::size_t size_type;
  166. typedef std::ptrdiff_t difference_type;
  167. // size of the array ( static );
  168. BOOST_STATIC_CONSTANT( size_type, array_size = sz );
  169. };
  170. #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  171. // array traits ( no partial specialization )
  172. /*
  173. without parial specialization we are able to
  174. provide support only for a limited number of
  175. types. Currently the primitive numeric types
  176. are supported
  177. */
  178. template< typename T, typename BaseT >
  179. struct array_traits_impl
  180. {
  181. typedef BaseT value_type;
  182. typedef BaseT* iterator;
  183. typedef const BaseT* const_iterator;
  184. typedef std::size_t size_type;
  185. typedef std::ptrdiff_t difference_type;
  186. // size of the array
  187. BOOST_STATIC_CONSTANT( size_type, array_size = sizeof(T)/sizeof(BaseT) );
  188. };
  189. template< typename T, typename BaseT >
  190. struct array_traits_impl_selector
  191. {
  192. typedef array_traits_impl<T,BaseT> type;
  193. };
  194. struct array_traits_void
  195. {
  196. typedef void type;
  197. };
  198. template< typename T, typename BaseT >
  199. struct array_traits_cv_selector
  200. {
  201. typedef BOOST_STRING_TYPENAME
  202. ::boost::mpl::eval_if<
  203. ::boost::is_convertible<T,BaseT*>,
  204. array_traits_impl_selector<T,BaseT>,
  205. ::boost::mpl::eval_if<
  206. ::boost::is_convertible<T,const BaseT*>,
  207. array_traits_impl_selector<T, const BaseT>,
  208. ::boost::mpl::eval_if<
  209. ::boost::is_convertible<T, volatile BaseT*>,
  210. array_traits_impl_selector<T, volatile BaseT>,
  211. array_traits_impl_selector<T, const volatile BaseT>
  212. >
  213. >
  214. >::type type;
  215. };
  216. template< typename T >
  217. struct array_traits_select
  218. {
  219. template< typename T1, typename T2 >
  220. struct apply
  221. {
  222. typedef BOOST_STRING_TYPENAME
  223. ::boost::mpl::eval_if<
  224. ::boost::is_convertible<T,const volatile T2*>,
  225. array_traits_cv_selector<T,T2>,
  226. ::boost::mpl::identity<T1> >::type type;
  227. };
  228. };
  229. template< typename T >
  230. struct array_traits_selector
  231. {
  232. private:
  233. // supported array base types
  234. #ifndef BOOST_NO_INTRINSIC_WCHAR_T
  235. typedef BOOST_STRING_TYPENAME
  236. ::boost::mpl::vector10<
  237. wchar_t,
  238. #else // BOOST_NO_INTRINSIC_WCHAR_T
  239. typedef BOOST_STRING_TYPENAME
  240. ::boost::mpl::vector9<
  241. #endif // BOOST_NO_INTRINSIC_WCHAR_T
  242. char,
  243. signed char,
  244. unsigned char,
  245. signed short,
  246. unsigned short,
  247. signed int,
  248. unsigned int,
  249. signed long,
  250. unsigned long
  251. >::type array_base_types;
  252. public:
  253. typedef BOOST_STRING_TYPENAME
  254. ::boost::mpl::fold<
  255. array_base_types,
  256. ::boost::algorithm::detail::array_traits_void,
  257. ::boost::algorithm::detail::array_traits_select<T> >::type type;
  258. };
  259. template< typename T >
  260. struct array_traits
  261. {
  262. typedef BOOST_STRING_TYPENAME
  263. array_traits_selector<T>::type traits_type;
  264. typedef BOOST_STRING_TYPENAME
  265. traits_type::value_type value_type;
  266. typedef BOOST_STRING_TYPENAME
  267. traits_type::iterator iterator;
  268. typedef BOOST_STRING_TYPENAME
  269. traits_type::const_iterator const_iterator;
  270. typedef BOOST_STRING_TYPENAME
  271. traits_type::size_type size_type;
  272. typedef BOOST_STRING_TYPENAME
  273. traits_type::difference_type difference_type;
  274. BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
  275. };
  276. #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  277. // array lenght resolving
  278. /*
  279. Lenght of string contained in a static array could
  280. be different from the size of the array.
  281. For string processing we need the lenght without
  282. terminating 0.
  283. Therefore, the lenght is calulated for char and wchar_t
  284. using char_traits, rather then simply returning
  285. the array size.
  286. */
  287. template< typename T >
  288. struct array_length_selector
  289. {
  290. template< typename TraitsT >
  291. struct array_length
  292. {
  293. typedef BOOST_STRING_TYPENAME
  294. TraitsT::size_type size_type;
  295. BOOST_STATIC_CONSTANT(
  296. size_type,
  297. array_size=TraitsT::array_size );
  298. template< typename A >
  299. static size_type length( const A& )
  300. {
  301. return array_size;
  302. }
  303. template< typename A >
  304. static bool empty( const A& )
  305. {
  306. return array_size==0;
  307. }
  308. };
  309. };
  310. // specialization for char
  311. template<>
  312. struct array_length_selector<char>
  313. {
  314. template< typename TraitsT >
  315. struct array_length
  316. {
  317. typedef BOOST_STRING_TYPENAME
  318. TraitsT::size_type size_type;
  319. template< typename A >
  320. static size_type length( const A& a )
  321. {
  322. if ( a==0 )
  323. return 0;
  324. else
  325. return std::char_traits<char>::length(a);
  326. }
  327. template< typename A >
  328. static bool empty( const A& a )
  329. {
  330. return a==0 || a[0]==0;
  331. }
  332. };
  333. };
  334. // specialization for wchar_t
  335. template<>
  336. struct array_length_selector<wchar_t>
  337. {
  338. template< typename TraitsT >
  339. struct array_length
  340. {
  341. typedef BOOST_STRING_TYPENAME
  342. TraitsT::size_type size_type;
  343. template< typename A >
  344. static size_type length( const A& a )
  345. {
  346. if ( a==0 )
  347. return 0;
  348. else
  349. return std::char_traits<wchar_t>::length(a);
  350. }
  351. template< typename A >
  352. static bool empty( const A& a )
  353. {
  354. return a==0 || a[0]==0;
  355. }
  356. };
  357. };
  358. template< typename T >
  359. struct array_container_traits
  360. {
  361. private:
  362. // resolve array traits
  363. typedef array_traits<T> traits_type;
  364. public:
  365. typedef BOOST_STRING_TYPENAME
  366. traits_type::value_type value_type;
  367. typedef BOOST_STRING_TYPENAME
  368. traits_type::iterator iterator;
  369. typedef BOOST_STRING_TYPENAME
  370. traits_type::const_iterator const_iterator;
  371. typedef BOOST_STRING_TYPENAME
  372. traits_type::size_type size_type;
  373. typedef BOOST_STRING_TYPENAME
  374. traits_type::difference_type difference_type;
  375. typedef BOOST_STRING_TYPENAME
  376. ::boost::mpl::if_< ::boost::is_const<T>,
  377. const_iterator,
  378. iterator
  379. >::type result_iterator;
  380. private:
  381. // resolve array size
  382. typedef BOOST_STRING_TYPENAME
  383. ::boost::remove_cv<value_type>::type char_type;
  384. typedef BOOST_STRING_TYPENAME
  385. array_length_selector<char_type>::
  386. BOOST_NESTED_TEMPLATE array_length<traits_type> array_length_type;
  387. public:
  388. BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
  389. // static operations
  390. template< typename A >
  391. static size_type size( const A& a )
  392. {
  393. return array_length_type::length(a);
  394. }
  395. template< typename A >
  396. static bool empty( const A& a )
  397. {
  398. return array_length_type::empty(a);
  399. }
  400. #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  401. template< typename A >
  402. static iterator begin( A& a )
  403. {
  404. return a;
  405. }
  406. template< typename A >
  407. static const_iterator begin( const A& a )
  408. {
  409. return a;
  410. }
  411. template< typename A >
  412. static iterator end( A& a )
  413. {
  414. return a+array_length_type::length(a);
  415. }
  416. template< typename A >
  417. static const_iterator end( const A& a )
  418. {
  419. return a+array_length_type::length(a);
  420. }
  421. #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  422. template< typename A >
  423. static result_iterator begin( A& a )
  424. {
  425. return a;
  426. }
  427. template< typename A >
  428. static result_iterator end( A& a )
  429. {
  430. return a+array_length_type::length(a);
  431. }
  432. #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  433. };
  434. template<typename T>
  435. struct array_container_traits_selector
  436. {
  437. typedef array_container_traits<T> type;
  438. };
  439. // Pointer container traits ---------------------------------------------------------------
  440. template<typename T>
  441. struct pointer_container_traits
  442. {
  443. typedef BOOST_STRING_TYPENAME
  444. ::boost::remove_pointer<T>::type value_type;
  445. typedef BOOST_STRING_TYPENAME
  446. ::boost::remove_cv<value_type>::type char_type;
  447. typedef ::std::char_traits<char_type> char_traits;
  448. typedef value_type* iterator;
  449. typedef const value_type* const_iterator;
  450. typedef std::ptrdiff_t difference_type;
  451. typedef std::size_t size_type;
  452. typedef BOOST_STRING_TYPENAME
  453. ::boost::mpl::if_< ::boost::is_const<T>,
  454. const_iterator,
  455. iterator
  456. >::type result_iterator;
  457. // static operations
  458. template< typename P >
  459. static size_type size( const P& p )
  460. {
  461. if ( p==0 )
  462. return 0;
  463. else
  464. return char_traits::length(p);
  465. }
  466. template< typename P >
  467. static bool empty( const P& p )
  468. {
  469. return p==0 || p[0]==0;
  470. }
  471. #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  472. template< typename P >
  473. static iterator begin( P& p )
  474. {
  475. return p;
  476. }
  477. template< typename P >
  478. static const_iterator begin( const P& p )
  479. {
  480. return p;
  481. }
  482. template< typename P >
  483. static iterator end( P& p )
  484. {
  485. if ( p==0 )
  486. return p;
  487. else
  488. return p+char_traits::length(p);
  489. }
  490. template< typename P >
  491. static const_iterator end( const P& p )
  492. {
  493. if ( p==0 )
  494. return p;
  495. else
  496. return p+char_traits::length(p);
  497. }
  498. #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  499. template< typename P >
  500. static result_iterator begin( P& p )
  501. {
  502. return p;
  503. }
  504. template< typename P >
  505. static result_iterator end( P& p )
  506. {
  507. if ( p==0 )
  508. return p;
  509. else
  510. return p+char_traits::length(p);
  511. }
  512. #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  513. };
  514. template<typename T>
  515. struct pointer_container_traits_selector
  516. {
  517. typedef pointer_container_traits<T> type;
  518. };
  519. } // namespace detail
  520. } // namespace algorithm
  521. } // namespace boost
  522. #endif // BOOST_STRING_DETAIL_COLLECTION_HPP