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
15 #include <boost/type_traits/is_array.hpp>
16 #include <boost/type_traits/is_pointer.hpp>
17 #include <boost/type_traits/is_const.hpp>
18 #include <boost/type_traits/is_convertible.hpp>
19 #include <boost/type_traits/remove_pointer.hpp>
20 #include <boost/type_traits/remove_cv.hpp>
21 #include <boost/mpl/eval_if.hpp>
22 #include <boost/mpl/identity.hpp>
23 #include <boost/mpl/vector.hpp>
24 #include <boost/mpl/fold.hpp>
25 #include <boost/detail/iterator.hpp>
27 // Container traits implementation ---------------------------------------------------------
33 // Default collection traits -----------------------------------------------------------------
35 // Default collection helper
37 Wraps std::container compliant containers
39 template< typename ContainerT >
40 struct default_container_traits
42 typedef typename ContainerT::value_type value_type;
43 typedef typename ContainerT::iterator iterator;
44 typedef typename ContainerT::const_iterator const_iterator;
46 ::boost::mpl::if_< ::boost::is_const<ContainerT>,
49 >::type result_iterator;
50 typedef typename ContainerT::difference_type difference_type;
51 typedef typename ContainerT::size_type size_type;
54 template< typename C >
55 static size_type size( const C& c )
60 template< typename C >
61 static bool empty( const C& c )
66 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
68 template< typename C >
69 static iterator begin( C& c )
74 template< typename C >
75 static const_iterator begin( const C& c )
80 template< typename C >
81 static iterator end( C& c )
86 template< typename C >
87 static const_iterator end( const C& c )
92 #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
94 template< typename C >
95 static result_iterator begin( C& c )
100 template< typename C >
101 static result_iterator end( C& c )
106 #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
111 struct default_container_traits_selector
113 typedef default_container_traits<T> type;
116 // Pair container traits ---------------------------------------------------------------------
118 typedef double yes_type;
119 typedef char no_type;
122 template< typename T, typename U >
123 yes_type is_pair_impl( const std::pair<T,U>* );
124 no_type is_pair_impl( ... );
126 template<typename T> struct is_pair
131 BOOST_STATIC_CONSTANT( bool, value=
132 sizeof(is_pair_impl(t))==sizeof(yes_type) );
136 template< typename PairT >
137 struct pair_container_traits
139 typedef typename PairT::first_type element_type;
141 typedef typename ::boost::detail::
142 iterator_traits<element_type>::value_type value_type;
143 typedef std::size_t size_type;
144 typedef typename ::boost::detail::
145 iterator_traits<element_type>::difference_type difference_type;
147 typedef element_type iterator;
148 typedef element_type const_iterator;
149 typedef element_type result_iterator;
152 template< typename P >
153 static size_type size( const P& p )
155 difference_type diff = std::distance( p.first, p.second );
162 template< typename P >
163 static bool empty( const P& p )
165 return p.first==p.second;
168 template< typename P >
169 static const_iterator begin( const P& p )
174 template< typename P >
175 static const_iterator end( const P& p )
179 }; // 'pair_container_helper'
182 struct pair_container_traits_selector
184 typedef pair_container_traits<T> type;
187 // Array container traits ---------------------------------------------------------------
189 // array traits ( partial specialization )
190 template< typename T >
193 template< typename T, std::size_t sz >
194 struct array_traits<T[sz]>
198 typedef const T* const_iterator;
199 typedef T value_type;
200 typedef std::size_t size_type;
201 typedef std::ptrdiff_t difference_type;
203 // size of the array ( static );
204 BOOST_STATIC_CONSTANT( size_type, array_size = sz );
208 // array length resolving
210 Lenght of string contained in a static array could
211 be different from the size of the array.
212 For string processing we need the length without
215 Therefore, the length is calculated for char and wchar_t
216 using char_traits, rather then simply returning
219 template< typename T >
220 struct array_length_selector
222 template< typename TraitsT >
226 TraitsT::size_type size_type;
228 BOOST_STATIC_CONSTANT(
230 array_size=TraitsT::array_size );
232 template< typename A >
233 static size_type length( const A& )
238 template< typename A >
239 static bool empty( const A& )
241 return array_size==0;
246 // specialization for char
248 struct array_length_selector<char>
250 template< typename TraitsT >
254 TraitsT::size_type size_type;
256 template< typename A >
257 static size_type length( const A& a )
262 return std::char_traits<char>::length(a);
265 template< typename A >
266 static bool empty( const A& a )
268 return a==0 || a[0]==0;
273 // specialization for wchar_t
275 struct array_length_selector<wchar_t>
277 template< typename TraitsT >
281 TraitsT::size_type size_type;
283 template< typename A >
284 static size_type length( const A& a )
289 return std::char_traits<wchar_t>::length(a);
292 template< typename A >
293 static bool empty( const A& a )
295 return a==0 || a[0]==0;
300 template< typename T >
301 struct array_container_traits
304 // resolve array traits
305 typedef array_traits<T> traits_type;
309 traits_type::value_type value_type;
311 traits_type::iterator iterator;
313 traits_type::const_iterator const_iterator;
315 traits_type::size_type size_type;
317 traits_type::difference_type difference_type;
320 ::boost::mpl::if_< ::boost::is_const<T>,
323 >::type result_iterator;
326 // resolve array size
328 ::boost::remove_cv<value_type>::type char_type;
330 array_length_selector<char_type>::
331 BOOST_NESTED_TEMPLATE array_length<traits_type> array_length_type;
334 BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
337 template< typename A >
338 static size_type size( const A& a )
340 return array_length_type::length(a);
343 template< typename A >
344 static bool empty( const A& a )
346 return array_length_type::empty(a);
350 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
352 template< typename A >
353 static iterator begin( A& a )
358 template< typename A >
359 static const_iterator begin( const A& a )
364 template< typename A >
365 static iterator end( A& a )
367 return a+array_length_type::length(a);
370 template< typename A >
371 static const_iterator end( const A& a )
373 return a+array_length_type::length(a);
376 #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
378 template< typename A >
379 static result_iterator begin( A& a )
384 template< typename A >
385 static result_iterator end( A& a )
387 return a+array_length_type::length(a);
390 #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
395 struct array_container_traits_selector
397 typedef array_container_traits<T> type;
400 // Pointer container traits ---------------------------------------------------------------
403 struct pointer_container_traits
406 ::boost::remove_pointer<T>::type value_type;
409 ::boost::remove_cv<value_type>::type char_type;
410 typedef ::std::char_traits<char_type> char_traits;
412 typedef value_type* iterator;
413 typedef const value_type* const_iterator;
414 typedef std::ptrdiff_t difference_type;
415 typedef std::size_t size_type;
418 ::boost::mpl::if_< ::boost::is_const<T>,
421 >::type result_iterator;
424 template< typename P >
425 static size_type size( const P& p )
430 return char_traits::length(p);
433 template< typename P >
434 static bool empty( const P& p )
436 return p==0 || p[0]==0;
439 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
441 template< typename P >
442 static iterator begin( P& p )
447 template< typename P >
448 static const_iterator begin( const P& p )
453 template< typename P >
454 static iterator end( P& p )
459 return p+char_traits::length(p);
462 template< typename P >
463 static const_iterator end( const P& p )
468 return p+char_traits::length(p);
471 #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
473 template< typename P >
474 static result_iterator begin( P& p )
479 template< typename P >
480 static result_iterator end( P& p )
485 return p+char_traits::length(p);
488 #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
492 struct pointer_container_traits_selector
494 typedef pointer_container_traits<T> type;
497 } // namespace detail
498 } // namespace algorithm
502 #endif // BOOST_STRING_DETAIL_COLLECTION_HPP