1 // Boost string_algo library collection_traits.hpp header file -----------------------//
3 // Copyright Pavol Droba 2002-2003. Use, modification and
4 // distribution is subject to the Boost Software License, Version
5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 // See http://www.boost.org for updates, documentation, and revision history.
10 #ifndef BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
11 #define BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
17 #include <boost/type_traits/is_array.hpp>
18 #include <boost/type_traits/is_pointer.hpp>
19 #include <boost/type_traits/is_const.hpp>
20 #include <boost/type_traits/is_convertible.hpp>
21 #include <boost/type_traits/remove_pointer.hpp>
22 #include <boost/type_traits/remove_cv.hpp>
23 #include <boost/mpl/eval_if.hpp>
24 #include <boost/mpl/identity.hpp>
25 #include <boost/mpl/vector.hpp>
26 #include <boost/mpl/fold.hpp>
28 // Container traits implementation ---------------------------------------------------------
34 // Default collection traits -----------------------------------------------------------------
36 // Default collection helper
38 Wraps std::container compliant containers
40 template< typename ContainerT >
41 struct default_container_traits
43 typedef typename ContainerT::value_type value_type;
44 typedef typename ContainerT::iterator iterator;
45 typedef typename ContainerT::const_iterator const_iterator;
47 ::boost::mpl::if_< ::boost::is_const<ContainerT>,
50 >::type result_iterator;
51 typedef typename ContainerT::difference_type difference_type;
52 typedef typename ContainerT::size_type size_type;
55 template< typename C >
56 static size_type size( const C& c )
61 template< typename C >
62 static bool empty( const C& c )
67 template< typename C >
68 static iterator begin( C& c )
73 template< typename C >
74 static const_iterator begin( const C& c )
79 template< typename C >
80 static iterator end( C& c )
85 template< typename C >
86 static const_iterator end( const C& c )
94 struct default_container_traits_selector
96 typedef default_container_traits<T> type;
99 // Pair container traits ---------------------------------------------------------------------
101 typedef double yes_type;
102 typedef char no_type;
105 template< typename T, typename U >
106 yes_type is_pair_impl( const std::pair<T,U>* );
107 no_type is_pair_impl( ... );
109 template<typename T> struct is_pair
114 BOOST_STATIC_CONSTANT( bool, value=
115 sizeof(is_pair_impl(t))==sizeof(yes_type) );
119 template< typename PairT >
120 struct pair_container_traits
122 typedef typename PairT::first_type element_type;
125 std::iterator_traits<element_type>::value_type value_type;
126 typedef std::size_t size_type;
128 std::iterator_traits<element_type>::difference_type difference_type;
130 typedef element_type iterator;
131 typedef element_type const_iterator;
132 typedef element_type result_iterator;
135 template< typename P >
136 static size_type size( const P& p )
138 difference_type diff = std::distance( p.first, p.second );
145 template< typename P >
146 static bool empty( const P& p )
148 return p.first==p.second;
151 template< typename P >
152 static const_iterator begin( const P& p )
157 template< typename P >
158 static const_iterator end( const P& p )
162 }; // 'pair_container_helper'
165 struct pair_container_traits_selector
167 typedef pair_container_traits<T> type;
170 // Array container traits ---------------------------------------------------------------
172 // array traits ( partial specialization )
173 template< typename T >
176 template< typename T, std::size_t sz >
177 struct array_traits<T[sz]>
181 typedef const T* const_iterator;
182 typedef T value_type;
183 typedef std::size_t size_type;
184 typedef std::ptrdiff_t difference_type;
186 // size of the array ( static );
187 BOOST_STATIC_CONSTANT( size_type, array_size = sz );
191 // array length resolving
193 Lenght of string contained in a static array could
194 be different from the size of the array.
195 For string processing we need the length without
198 Therefore, the length is calculated for char and wchar_t
199 using char_traits, rather then simply returning
202 template< typename T >
203 struct array_length_selector
205 template< typename TraitsT >
209 TraitsT::size_type size_type;
211 BOOST_STATIC_CONSTANT(
213 array_size=TraitsT::array_size );
215 template< typename A >
216 static size_type length( const A& )
221 template< typename A >
222 static bool empty( const A& )
224 return array_size==0;
229 // specialization for char
231 struct array_length_selector<char>
233 template< typename TraitsT >
237 TraitsT::size_type size_type;
239 template< typename A >
240 static size_type length( const A& a )
245 return std::char_traits<char>::length(a);
248 template< typename A >
249 static bool empty( const A& a )
251 return a==0 || a[0]==0;
256 // specialization for wchar_t
258 struct array_length_selector<wchar_t>
260 template< typename TraitsT >
264 TraitsT::size_type size_type;
266 template< typename A >
267 static size_type length( const A& a )
272 return std::char_traits<wchar_t>::length(a);
275 template< typename A >
276 static bool empty( const A& a )
278 return a==0 || a[0]==0;
283 template< typename T >
284 struct array_container_traits
287 // resolve array traits
288 typedef array_traits<T> traits_type;
292 traits_type::value_type value_type;
294 traits_type::iterator iterator;
296 traits_type::const_iterator const_iterator;
298 traits_type::size_type size_type;
300 traits_type::difference_type difference_type;
303 ::boost::mpl::if_< ::boost::is_const<T>,
306 >::type result_iterator;
309 // resolve array size
311 ::boost::remove_cv<value_type>::type char_type;
313 array_length_selector<char_type>::
314 BOOST_NESTED_TEMPLATE array_length<traits_type> array_length_type;
317 BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
320 template< typename A >
321 static size_type size( const A& a )
323 return array_length_type::length(a);
326 template< typename A >
327 static bool empty( const A& a )
329 return array_length_type::empty(a);
333 template< typename A >
334 static iterator begin( A& a )
339 template< typename A >
340 static const_iterator begin( const A& a )
345 template< typename A >
346 static iterator end( A& a )
348 return a+array_length_type::length(a);
351 template< typename A >
352 static const_iterator end( const A& a )
354 return a+array_length_type::length(a);
360 struct array_container_traits_selector
362 typedef array_container_traits<T> type;
365 // Pointer container traits ---------------------------------------------------------------
368 struct pointer_container_traits
371 ::boost::remove_pointer<T>::type value_type;
374 ::boost::remove_cv<value_type>::type char_type;
375 typedef ::std::char_traits<char_type> char_traits;
377 typedef value_type* iterator;
378 typedef const value_type* const_iterator;
379 typedef std::ptrdiff_t difference_type;
380 typedef std::size_t size_type;
383 ::boost::mpl::if_< ::boost::is_const<T>,
386 >::type result_iterator;
389 template< typename P >
390 static size_type size( const P& p )
395 return char_traits::length(p);
398 template< typename P >
399 static bool empty( const P& p )
401 return p==0 || p[0]==0;
404 template< typename P >
405 static iterator begin( P& p )
410 template< typename P >
411 static const_iterator begin( const P& p )
416 template< typename P >
417 static iterator end( P& p )
422 return p+char_traits::length(p);
425 template< typename P >
426 static const_iterator end( const P& p )
431 return p+char_traits::length(p);
437 struct pointer_container_traits_selector
439 typedef pointer_container_traits<T> type;
442 } // namespace detail
443 } // namespace algorithm
447 #endif // BOOST_STRING_DETAIL_COLLECTION_HPP