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