collection_traits_detail.hpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  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 <utility>
  12. #include <iterator>
  13. #include <boost/type_traits/is_array.hpp>
  14. #include <boost/type_traits/is_pointer.hpp>
  15. #include <boost/type_traits/is_const.hpp>
  16. #include <boost/type_traits/is_convertible.hpp>
  17. #include <boost/type_traits/remove_pointer.hpp>
  18. #include <boost/type_traits/remove_cv.hpp>
  19. #include <boost/mpl/eval_if.hpp>
  20. #include <boost/mpl/identity.hpp>
  21. #include <boost/mpl/vector.hpp>
  22. #include <boost/mpl/fold.hpp>
  23. // Container traits implementation ---------------------------------------------------------
  24. namespace boost {
  25. namespace algorithm {
  26. namespace detail {
  27. // Default collection traits -----------------------------------------------------------------
  28. // Default collection helper
  29. /*
  30. Wraps std::container compliant containers
  31. */
  32. template< typename ContainerT >
  33. struct default_container_traits
  34. {
  35. typedef typename ContainerT::value_type value_type;
  36. typedef typename ContainerT::iterator iterator;
  37. typedef typename ContainerT::const_iterator const_iterator;
  38. typedef typename
  39. ::boost::mpl::if_< ::boost::is_const<ContainerT>,
  40. const_iterator,
  41. iterator
  42. >::type result_iterator;
  43. typedef typename ContainerT::difference_type difference_type;
  44. typedef typename ContainerT::size_type size_type;
  45. // static operations
  46. template< typename C >
  47. static size_type size( const C& c )
  48. {
  49. return c.size();
  50. }
  51. template< typename C >
  52. static bool empty( const C& c )
  53. {
  54. return c.empty();
  55. }
  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. };
  77. template<typename T>
  78. struct default_container_traits_selector
  79. {
  80. typedef default_container_traits<T> type;
  81. };
  82. // Pair container traits ---------------------------------------------------------------------
  83. typedef double yes_type;
  84. typedef char no_type;
  85. // pair selector
  86. template< typename T, typename U >
  87. yes_type is_pair_impl( const std::pair<T,U>* );
  88. no_type is_pair_impl( ... );
  89. template<typename T> struct is_pair
  90. {
  91. private:
  92. static T* t;
  93. public:
  94. BOOST_STATIC_CONSTANT( bool, value=
  95. sizeof(is_pair_impl(t))==sizeof(yes_type) );
  96. };
  97. // pair helper
  98. template< typename PairT >
  99. struct pair_container_traits
  100. {
  101. typedef typename PairT::first_type element_type;
  102. typedef typename
  103. std::iterator_traits<element_type>::value_type value_type;
  104. typedef std::size_t size_type;
  105. typedef typename
  106. std::iterator_traits<element_type>::difference_type difference_type;
  107. typedef element_type iterator;
  108. typedef element_type const_iterator;
  109. typedef element_type result_iterator;
  110. // static operations
  111. template< typename P >
  112. static size_type size( const P& p )
  113. {
  114. difference_type diff = std::distance( p.first, p.second );
  115. if ( diff < 0 )
  116. return 0;
  117. else
  118. return diff;
  119. }
  120. template< typename P >
  121. static bool empty( const P& p )
  122. {
  123. return p.first==p.second;
  124. }
  125. template< typename P >
  126. static const_iterator begin( const P& p )
  127. {
  128. return p.first;
  129. }
  130. template< typename P >
  131. static const_iterator end( const P& p )
  132. {
  133. return p.second;
  134. }
  135. }; // 'pair_container_helper'
  136. template<typename T>
  137. struct pair_container_traits_selector
  138. {
  139. typedef pair_container_traits<T> type;
  140. };
  141. // Array container traits ---------------------------------------------------------------
  142. // array traits ( partial specialization )
  143. template< typename T >
  144. struct array_traits;
  145. template< typename T, std::size_t sz >
  146. struct array_traits<T[sz]>
  147. {
  148. // typedef
  149. typedef T* iterator;
  150. typedef const T* const_iterator;
  151. typedef T value_type;
  152. typedef std::size_t size_type;
  153. typedef std::ptrdiff_t difference_type;
  154. // size of the array ( static );
  155. BOOST_STATIC_CONSTANT( size_type, array_size = sz );
  156. };
  157. // array length resolving
  158. /*
  159. Lenght of string contained in a static array could
  160. be different from the size of the array.
  161. For string processing we need the length without
  162. terminating 0.
  163. Therefore, the length is calculated for char and wchar_t
  164. using char_traits, rather then simply returning
  165. the array size.
  166. */
  167. template< typename T >
  168. struct array_length_selector
  169. {
  170. template< typename TraitsT >
  171. struct array_length
  172. {
  173. typedef typename
  174. TraitsT::size_type size_type;
  175. BOOST_STATIC_CONSTANT(
  176. size_type,
  177. array_size=TraitsT::array_size );
  178. template< typename A >
  179. static size_type length( const A& )
  180. {
  181. return array_size;
  182. }
  183. template< typename A >
  184. static bool empty( const A& )
  185. {
  186. return array_size==0;
  187. }
  188. };
  189. };
  190. // specialization for char
  191. template<>
  192. struct array_length_selector<char>
  193. {
  194. template< typename TraitsT >
  195. struct array_length
  196. {
  197. typedef typename
  198. TraitsT::size_type size_type;
  199. template< typename A >
  200. static size_type length( const A& a )
  201. {
  202. if ( a==0 )
  203. return 0;
  204. else
  205. return std::char_traits<char>::length(a);
  206. }
  207. template< typename A >
  208. static bool empty( const A& a )
  209. {
  210. return a==0 || a[0]==0;
  211. }
  212. };
  213. };
  214. // specialization for wchar_t
  215. template<>
  216. struct array_length_selector<wchar_t>
  217. {
  218. template< typename TraitsT >
  219. struct array_length
  220. {
  221. typedef typename
  222. TraitsT::size_type size_type;
  223. template< typename A >
  224. static size_type length( const A& a )
  225. {
  226. if ( a==0 )
  227. return 0;
  228. else
  229. return std::char_traits<wchar_t>::length(a);
  230. }
  231. template< typename A >
  232. static bool empty( const A& a )
  233. {
  234. return a==0 || a[0]==0;
  235. }
  236. };
  237. };
  238. template< typename T >
  239. struct array_container_traits
  240. {
  241. private:
  242. // resolve array traits
  243. typedef array_traits<T> traits_type;
  244. public:
  245. typedef typename
  246. traits_type::value_type value_type;
  247. typedef typename
  248. traits_type::iterator iterator;
  249. typedef typename
  250. traits_type::const_iterator const_iterator;
  251. typedef typename
  252. traits_type::size_type size_type;
  253. typedef typename
  254. traits_type::difference_type difference_type;
  255. typedef typename
  256. ::boost::mpl::if_< ::boost::is_const<T>,
  257. const_iterator,
  258. iterator
  259. >::type result_iterator;
  260. private:
  261. // resolve array size
  262. typedef typename
  263. ::boost::remove_cv<value_type>::type char_type;
  264. typedef typename
  265. array_length_selector<char_type>::
  266. BOOST_NESTED_TEMPLATE array_length<traits_type> array_length_type;
  267. public:
  268. BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
  269. // static operations
  270. template< typename A >
  271. static size_type size( const A& a )
  272. {
  273. return array_length_type::length(a);
  274. }
  275. template< typename A >
  276. static bool empty( const A& a )
  277. {
  278. return array_length_type::empty(a);
  279. }
  280. template< typename A >
  281. static iterator begin( A& a )
  282. {
  283. return a;
  284. }
  285. template< typename A >
  286. static const_iterator begin( const A& a )
  287. {
  288. return a;
  289. }
  290. template< typename A >
  291. static iterator end( A& a )
  292. {
  293. return a+array_length_type::length(a);
  294. }
  295. template< typename A >
  296. static const_iterator end( const A& a )
  297. {
  298. return a+array_length_type::length(a);
  299. }
  300. };
  301. template<typename T>
  302. struct array_container_traits_selector
  303. {
  304. typedef array_container_traits<T> type;
  305. };
  306. // Pointer container traits ---------------------------------------------------------------
  307. template<typename T>
  308. struct pointer_container_traits
  309. {
  310. typedef typename
  311. ::boost::remove_pointer<T>::type value_type;
  312. typedef typename
  313. ::boost::remove_cv<value_type>::type char_type;
  314. typedef ::std::char_traits<char_type> char_traits;
  315. typedef value_type* iterator;
  316. typedef const value_type* const_iterator;
  317. typedef std::ptrdiff_t difference_type;
  318. typedef std::size_t size_type;
  319. typedef typename
  320. ::boost::mpl::if_< ::boost::is_const<T>,
  321. const_iterator,
  322. iterator
  323. >::type result_iterator;
  324. // static operations
  325. template< typename P >
  326. static size_type size( const P& p )
  327. {
  328. if ( p==0 )
  329. return 0;
  330. else
  331. return char_traits::length(p);
  332. }
  333. template< typename P >
  334. static bool empty( const P& p )
  335. {
  336. return p==0 || p[0]==0;
  337. }
  338. template< typename P >
  339. static iterator begin( P& p )
  340. {
  341. return p;
  342. }
  343. template< typename P >
  344. static const_iterator begin( const P& p )
  345. {
  346. return p;
  347. }
  348. template< typename P >
  349. static iterator end( P& p )
  350. {
  351. if ( p==0 )
  352. return p;
  353. else
  354. return p+char_traits::length(p);
  355. }
  356. template< typename P >
  357. static const_iterator end( const P& p )
  358. {
  359. if ( p==0 )
  360. return p;
  361. else
  362. return p+char_traits::length(p);
  363. }
  364. };
  365. template<typename T>
  366. struct pointer_container_traits_selector
  367. {
  368. typedef pointer_container_traits<T> type;
  369. };
  370. } // namespace detail
  371. } // namespace algorithm
  372. } // namespace boost
  373. #endif // BOOST_STRING_DETAIL_COLLECTION_HPP