collection_traits_detail.hpp 14 KB

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