File indexing completed on 2025-09-12 08:49:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
0011 #define BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
0012
0013 #include <cstddef>
0014 #include <string>
0015 #include <utility>
0016 #include <iterator>
0017 #include <boost/type_traits/is_array.hpp>
0018 #include <boost/type_traits/is_pointer.hpp>
0019 #include <boost/type_traits/is_const.hpp>
0020 #include <boost/type_traits/is_convertible.hpp>
0021 #include <boost/type_traits/remove_pointer.hpp>
0022 #include <boost/type_traits/remove_cv.hpp>
0023 #include <boost/mpl/if.hpp>
0024
0025
0026
0027 namespace boost {
0028 namespace algorithm {
0029 namespace detail {
0030
0031
0032
0033
0034
0035
0036
0037 template< typename ContainerT >
0038 struct default_container_traits
0039 {
0040 typedef typename ContainerT::value_type value_type;
0041 typedef typename ContainerT::iterator iterator;
0042 typedef typename ContainerT::const_iterator const_iterator;
0043 typedef typename
0044 ::boost::mpl::if_< ::boost::is_const<ContainerT>,
0045 const_iterator,
0046 iterator
0047 >::type result_iterator;
0048 typedef typename ContainerT::difference_type difference_type;
0049 typedef typename ContainerT::size_type size_type;
0050
0051
0052 template< typename C >
0053 static size_type size( const C& c )
0054 {
0055 return c.size();
0056 }
0057
0058 template< typename C >
0059 static bool empty( const C& c )
0060 {
0061 return c.empty();
0062 }
0063
0064 template< typename C >
0065 static iterator begin( C& c )
0066 {
0067 return c.begin();
0068 }
0069
0070 template< typename C >
0071 static const_iterator begin( const C& c )
0072 {
0073 return c.begin();
0074 }
0075
0076 template< typename C >
0077 static iterator end( C& c )
0078 {
0079 return c.end();
0080 }
0081
0082 template< typename C >
0083 static const_iterator end( const C& c )
0084 {
0085 return c.end();
0086 }
0087
0088 };
0089
0090 template<typename T>
0091 struct default_container_traits_selector
0092 {
0093 typedef default_container_traits<T> type;
0094 };
0095
0096
0097
0098 typedef double yes_type;
0099 typedef char no_type;
0100
0101
0102 template< typename T, typename U >
0103 yes_type is_pair_impl( const std::pair<T,U>* );
0104 no_type is_pair_impl( ... );
0105
0106 template<typename T> struct is_pair
0107 {
0108 private:
0109 static T* t;
0110 public:
0111 BOOST_STATIC_CONSTANT( bool, value=
0112 sizeof(is_pair_impl(t))==sizeof(yes_type) );
0113 };
0114
0115
0116 template< typename PairT >
0117 struct pair_container_traits
0118 {
0119 typedef typename PairT::first_type element_type;
0120
0121 typedef typename
0122 std::iterator_traits<element_type>::value_type value_type;
0123 typedef std::size_t size_type;
0124 typedef typename
0125 std::iterator_traits<element_type>::difference_type difference_type;
0126
0127 typedef element_type iterator;
0128 typedef element_type const_iterator;
0129 typedef element_type result_iterator;
0130
0131
0132 template< typename P >
0133 static size_type size( const P& p )
0134 {
0135 difference_type diff = std::distance( p.first, p.second );
0136 if ( diff < 0 )
0137 return 0;
0138 else
0139 return diff;
0140 }
0141
0142 template< typename P >
0143 static bool empty( const P& p )
0144 {
0145 return p.first==p.second;
0146 }
0147
0148 template< typename P >
0149 static const_iterator begin( const P& p )
0150 {
0151 return p.first;
0152 }
0153
0154 template< typename P >
0155 static const_iterator end( const P& p )
0156 {
0157 return p.second;
0158 }
0159 };
0160
0161 template<typename T>
0162 struct pair_container_traits_selector
0163 {
0164 typedef pair_container_traits<T> type;
0165 };
0166
0167
0168
0169
0170 template< typename T >
0171 struct array_traits;
0172
0173 template< typename T, std::size_t sz >
0174 struct array_traits<T[sz]>
0175 {
0176
0177 typedef T* iterator;
0178 typedef const T* const_iterator;
0179 typedef T value_type;
0180 typedef std::size_t size_type;
0181 typedef std::ptrdiff_t difference_type;
0182
0183
0184 BOOST_STATIC_CONSTANT( size_type, array_size = sz );
0185 };
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199 template< typename T >
0200 struct array_length_selector
0201 {
0202 template< typename TraitsT >
0203 struct array_length
0204 {
0205 typedef typename
0206 TraitsT::size_type size_type;
0207
0208 BOOST_STATIC_CONSTANT(
0209 size_type,
0210 array_size=TraitsT::array_size );
0211
0212 template< typename A >
0213 static size_type length( const A& )
0214 {
0215 return array_size;
0216 }
0217
0218 template< typename A >
0219 static bool empty( const A& )
0220 {
0221 return array_size==0;
0222 }
0223 };
0224 };
0225
0226
0227 template<>
0228 struct array_length_selector<char>
0229 {
0230 template< typename TraitsT >
0231 struct array_length
0232 {
0233 typedef typename
0234 TraitsT::size_type size_type;
0235
0236 template< typename A >
0237 static size_type length( const A& a )
0238 {
0239 if ( a==0 )
0240 return 0;
0241 else
0242 return std::char_traits<char>::length(a);
0243 }
0244
0245 template< typename A >
0246 static bool empty( const A& a )
0247 {
0248 return a==0 || a[0]==0;
0249 }
0250 };
0251 };
0252
0253
0254 template<>
0255 struct array_length_selector<wchar_t>
0256 {
0257 template< typename TraitsT >
0258 struct array_length
0259 {
0260 typedef typename
0261 TraitsT::size_type size_type;
0262
0263 template< typename A >
0264 static size_type length( const A& a )
0265 {
0266 if ( a==0 )
0267 return 0;
0268 else
0269 return std::char_traits<wchar_t>::length(a);
0270 }
0271
0272 template< typename A >
0273 static bool empty( const A& a )
0274 {
0275 return a==0 || a[0]==0;
0276 }
0277 };
0278 };
0279
0280 template< typename T >
0281 struct array_container_traits
0282 {
0283 private:
0284
0285 typedef array_traits<T> traits_type;
0286
0287 public:
0288 typedef typename
0289 traits_type::value_type value_type;
0290 typedef typename
0291 traits_type::iterator iterator;
0292 typedef typename
0293 traits_type::const_iterator const_iterator;
0294 typedef typename
0295 traits_type::size_type size_type;
0296 typedef typename
0297 traits_type::difference_type difference_type;
0298
0299 typedef typename
0300 ::boost::mpl::if_< ::boost::is_const<T>,
0301 const_iterator,
0302 iterator
0303 >::type result_iterator;
0304
0305 private:
0306
0307 typedef typename
0308 ::boost::remove_cv<value_type>::type char_type;
0309 typedef typename
0310 array_length_selector<char_type>::
0311 BOOST_NESTED_TEMPLATE array_length<traits_type> array_length_type;
0312
0313 public:
0314 BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
0315
0316
0317 template< typename A >
0318 static size_type size( const A& a )
0319 {
0320 return array_length_type::length(a);
0321 }
0322
0323 template< typename A >
0324 static bool empty( const A& a )
0325 {
0326 return array_length_type::empty(a);
0327 }
0328
0329
0330 template< typename A >
0331 static iterator begin( A& a )
0332 {
0333 return a;
0334 }
0335
0336 template< typename A >
0337 static const_iterator begin( const A& a )
0338 {
0339 return a;
0340 }
0341
0342 template< typename A >
0343 static iterator end( A& a )
0344 {
0345 return a+array_length_type::length(a);
0346 }
0347
0348 template< typename A >
0349 static const_iterator end( const A& a )
0350 {
0351 return a+array_length_type::length(a);
0352 }
0353
0354 };
0355
0356 template<typename T>
0357 struct array_container_traits_selector
0358 {
0359 typedef array_container_traits<T> type;
0360 };
0361
0362
0363
0364 template<typename T>
0365 struct pointer_container_traits
0366 {
0367 typedef typename
0368 ::boost::remove_pointer<T>::type value_type;
0369
0370 typedef typename
0371 ::boost::remove_cv<value_type>::type char_type;
0372 typedef ::std::char_traits<char_type> char_traits;
0373
0374 typedef value_type* iterator;
0375 typedef const value_type* const_iterator;
0376 typedef std::ptrdiff_t difference_type;
0377 typedef std::size_t size_type;
0378
0379 typedef typename
0380 ::boost::mpl::if_< ::boost::is_const<T>,
0381 const_iterator,
0382 iterator
0383 >::type result_iterator;
0384
0385
0386 template< typename P >
0387 static size_type size( const P& p )
0388 {
0389 if ( p==0 )
0390 return 0;
0391 else
0392 return char_traits::length(p);
0393 }
0394
0395 template< typename P >
0396 static bool empty( const P& p )
0397 {
0398 return p==0 || p[0]==0;
0399 }
0400
0401 template< typename P >
0402 static iterator begin( P& p )
0403 {
0404 return p;
0405 }
0406
0407 template< typename P >
0408 static const_iterator begin( const P& p )
0409 {
0410 return p;
0411 }
0412
0413 template< typename P >
0414 static iterator end( P& p )
0415 {
0416 if ( p==0 )
0417 return p;
0418 else
0419 return p+char_traits::length(p);
0420 }
0421
0422 template< typename P >
0423 static const_iterator end( const P& p )
0424 {
0425 if ( p==0 )
0426 return p;
0427 else
0428 return p+char_traits::length(p);
0429 }
0430
0431 };
0432
0433 template<typename T>
0434 struct pointer_container_traits_selector
0435 {
0436 typedef pointer_container_traits<T> type;
0437 };
0438
0439 }
0440 }
0441 }
0442
0443
0444 #endif