collection_traits_detail.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  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 <cstddef>
  10. #include <string>
  11. #include <boost/type_traits/is_array.hpp>
  12. #include <boost/type_traits/is_pointer.hpp>
  13. #include <boost/type_traits/is_const.hpp>
  14. #include <boost/type_traits/is_convertible.hpp>
  15. #include <boost/type_traits/remove_pointer.hpp>
  16. #include <boost/type_traits/remove_cv.hpp>
  17. #include <boost/mpl/eval_if.hpp>
  18. #include <boost/mpl/identity.hpp>
  19. #include <boost/mpl/vector.hpp>
  20. #include <boost/mpl/fold.hpp>
  21. #include <boost/detail/iterator.hpp>
  22. // Container traits implementation ---------------------------------------------------------
  23. namespace boost {
  24. namespace algorithm {
  25. namespace detail {
  26. // Default collection traits -----------------------------------------------------------------
  27. // Default collection helper
  28. /*
  29. Wraps std::container compliant containers
  30. */
  31. template< typename ContainerT >
  32. struct default_container_traits
  33. {
  34. typedef typename ContainerT::value_type value_type;
  35. typedef typename ContainerT::iterator iterator;
  36. typedef typename ContainerT::const_iterator const_iterator;
  37. typedef typename
  38. ::boost::mpl::if_< ::boost::is_const<ContainerT>,
  39. const_iterator,
  40. iterator
  41. >::type result_iterator;
  42. typedef typename ContainerT::difference_type difference_type;
  43. typedef typename ContainerT::size_type size_type;
  44. // static operations
  45. template< typename C >
  46. static size_type size( const C& c )
  47. {
  48. return c.size();
  49. }
  50. template< typename C >
  51. static bool empty( const C& c )
  52. {
  53. return c.empty();
  54. }
  55. #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  56. template< typename C >
  57. static iterator begin( C& c )
  58. {
  59. return c.begin();
  60. }
  61. template< typename C >
  62. static const_iterator begin( const C& c )
  63. {
  64. return c.begin();
  65. }
  66. template< typename C >
  67. static iterator end( C& c )
  68. {
  69. return c.end();
  70. }
  71. template< typename C >
  72. static const_iterator end( const C& c )
  73. {
  74. return c.end();
  75. }
  76. #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  77. template< typename C >
  78. static result_iterator begin( C& c )
  79. {
  80. return c.begin();
  81. }
  82. template< typename C >
  83. static result_iterator end( C& c )
  84. {
  85. return c.end();
  86. }
  87. #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  88. };
  89. template<typename T>
  90. struct default_container_traits_selector
  91. {
  92. typedef default_container_traits<T> type;
  93. };
  94. // Pair container traits ---------------------------------------------------------------------
  95. typedef double yes_type;
  96. typedef char no_type;
  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 typename PairT::first_type element_type;
  114. typedef typename ::boost::detail::
  115. iterator_traits<element_type>::value_type value_type;
  116. typedef std::size_t size_type;
  117. typedef 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. // array traits ( partial specialization )
  155. template< typename T >
  156. struct array_traits;
  157. template< typename T, std::size_t sz >
  158. struct array_traits<T[sz]>
  159. {
  160. // typedef
  161. typedef T* iterator;
  162. typedef const T* const_iterator;
  163. typedef T value_type;
  164. typedef std::size_t size_type;
  165. typedef std::ptrdiff_t difference_type;
  166. // size of the array ( static );
  167. BOOST_STATIC_CONSTANT( size_type, array_size = sz );
  168. };
  169. // array length resolving
  170. /*
  171. Lenght of string contained in a static array could
  172. be different from the size of the array.
  173. For string processing we need the length without
  174. terminating 0.
  175. Therefore, the length is calculated for char and wchar_t
  176. using char_traits, rather then simply returning
  177. the array size.
  178. */
  179. template< typename T >
  180. struct array_length_selector
  181. {
  182. template< typename TraitsT >
  183. struct array_length
  184. {
  185. typedef typename
  186. TraitsT::size_type size_type;
  187. BOOST_STATIC_CONSTANT(
  188. size_type,
  189. array_size=TraitsT::array_size );
  190. template< typename A >
  191. static size_type length( const A& )
  192. {
  193. return array_size;
  194. }
  195. template< typename A >
  196. static bool empty( const A& )
  197. {
  198. return array_size==0;
  199. }
  200. };
  201. };
  202. // specialization for char
  203. template<>
  204. struct array_length_selector<char>
  205. {
  206. template< typename TraitsT >
  207. struct array_length
  208. {
  209. typedef typename
  210. TraitsT::size_type size_type;
  211. template< typename A >
  212. static size_type length( const A& a )
  213. {
  214. if ( a==0 )
  215. return 0;
  216. else
  217. return std::char_traits<char>::length(a);
  218. }
  219. template< typename A >
  220. static bool empty( const A& a )
  221. {
  222. return a==0 || a[0]==0;
  223. }
  224. };
  225. };
  226. // specialization for wchar_t
  227. template<>
  228. struct array_length_selector<wchar_t>
  229. {
  230. template< typename TraitsT >
  231. struct array_length
  232. {
  233. typedef typename
  234. TraitsT::size_type size_type;
  235. template< typename A >
  236. static size_type length( const A& a )
  237. {
  238. if ( a==0 )
  239. return 0;
  240. else
  241. return std::char_traits<wchar_t>::length(a);
  242. }
  243. template< typename A >
  244. static bool empty( const A& a )
  245. {
  246. return a==0 || a[0]==0;
  247. }
  248. };
  249. };
  250. template< typename T >
  251. struct array_container_traits
  252. {
  253. private:
  254. // resolve array traits
  255. typedef array_traits<T> traits_type;
  256. public:
  257. typedef typename
  258. traits_type::value_type value_type;
  259. typedef typename
  260. traits_type::iterator iterator;
  261. typedef typename
  262. traits_type::const_iterator const_iterator;
  263. typedef typename
  264. traits_type::size_type size_type;
  265. typedef typename
  266. traits_type::difference_type difference_type;
  267. typedef typename
  268. ::boost::mpl::if_< ::boost::is_const<T>,
  269. const_iterator,
  270. iterator
  271. >::type result_iterator;
  272. private:
  273. // resolve array size
  274. typedef typename
  275. ::boost::remove_cv<value_type>::type char_type;
  276. typedef typename
  277. array_length_selector<char_type>::
  278. BOOST_NESTED_TEMPLATE array_length<traits_type> array_length_type;
  279. public:
  280. BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
  281. // static operations
  282. template< typename A >
  283. static size_type size( const A& a )
  284. {
  285. return array_length_type::length(a);
  286. }
  287. template< typename A >
  288. static bool empty( const A& a )
  289. {
  290. return array_length_type::empty(a);
  291. }
  292. #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  293. template< typename A >
  294. static iterator begin( A& a )
  295. {
  296. return a;
  297. }
  298. template< typename A >
  299. static const_iterator begin( const A& a )
  300. {
  301. return a;
  302. }
  303. template< typename A >
  304. static iterator end( A& a )
  305. {
  306. return a+array_length_type::length(a);
  307. }
  308. template< typename A >
  309. static const_iterator end( const A& a )
  310. {
  311. return a+array_length_type::length(a);
  312. }
  313. #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  314. template< typename A >
  315. static result_iterator begin( A& a )
  316. {
  317. return a;
  318. }
  319. template< typename A >
  320. static result_iterator end( A& a )
  321. {
  322. return a+array_length_type::length(a);
  323. }
  324. #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  325. };
  326. template<typename T>
  327. struct array_container_traits_selector
  328. {
  329. typedef array_container_traits<T> type;
  330. };
  331. // Pointer container traits ---------------------------------------------------------------
  332. template<typename T>
  333. struct pointer_container_traits
  334. {
  335. typedef typename
  336. ::boost::remove_pointer<T>::type value_type;
  337. typedef typename
  338. ::boost::remove_cv<value_type>::type char_type;
  339. typedef ::std::char_traits<char_type> char_traits;
  340. typedef value_type* iterator;
  341. typedef const value_type* const_iterator;
  342. typedef std::ptrdiff_t difference_type;
  343. typedef std::size_t size_type;
  344. typedef typename
  345. ::boost::mpl::if_< ::boost::is_const<T>,
  346. const_iterator,
  347. iterator
  348. >::type result_iterator;
  349. // static operations
  350. template< typename P >
  351. static size_type size( const P& p )
  352. {
  353. if ( p==0 )
  354. return 0;
  355. else
  356. return char_traits::length(p);
  357. }
  358. template< typename P >
  359. static bool empty( const P& p )
  360. {
  361. return p==0 || p[0]==0;
  362. }
  363. #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  364. template< typename P >
  365. static iterator begin( P& p )
  366. {
  367. return p;
  368. }
  369. template< typename P >
  370. static const_iterator begin( const P& p )
  371. {
  372. return p;
  373. }
  374. template< typename P >
  375. static iterator end( P& p )
  376. {
  377. if ( p==0 )
  378. return p;
  379. else
  380. return p+char_traits::length(p);
  381. }
  382. template< typename P >
  383. static const_iterator end( const P& p )
  384. {
  385. if ( p==0 )
  386. return p;
  387. else
  388. return p+char_traits::length(p);
  389. }
  390. #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  391. template< typename P >
  392. static result_iterator begin( P& p )
  393. {
  394. return p;
  395. }
  396. template< typename P >
  397. static result_iterator end( P& p )
  398. {
  399. if ( p==0 )
  400. return p;
  401. else
  402. return p+char_traits::length(p);
  403. }
  404. #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
  405. };
  406. template<typename T>
  407. struct pointer_container_traits_selector
  408. {
  409. typedef pointer_container_traits<T> type;
  410. };
  411. } // namespace detail
  412. } // namespace algorithm
  413. } // namespace boost
  414. #endif // BOOST_STRING_DETAIL_COLLECTION_HPP