]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/range/include/boost/range/detail/collection_traits_detail.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / range / include / boost / range / detail / collection_traits_detail.hpp
1 // Boost string_algo library collection_traits.hpp header file -----------------------//
2
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)
7
8 // See http://www.boost.org for updates, documentation, and revision history.
9
10 #ifndef BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
11 #define BOOST_RANGE_STRING_DETAIL_COLLECTION_TRAITS_HPP
12
13 #include <cstddef>
14 #include <string>
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>
26
27 // Container traits implementation ---------------------------------------------------------
28
29 namespace boost {
30 namespace algorithm {
31 namespace detail {
32
33 // Default collection traits -----------------------------------------------------------------
34
35 // Default collection helper
36 /*
37 Wraps std::container compliant containers
38 */
39 template< typename ContainerT >
40 struct default_container_traits
41 {
42 typedef typename ContainerT::value_type value_type;
43 typedef typename ContainerT::iterator iterator;
44 typedef typename ContainerT::const_iterator const_iterator;
45 typedef typename
46 ::boost::mpl::if_< ::boost::is_const<ContainerT>,
47 const_iterator,
48 iterator
49 >::type result_iterator;
50 typedef typename ContainerT::difference_type difference_type;
51 typedef typename ContainerT::size_type size_type;
52
53 // static operations
54 template< typename C >
55 static size_type size( const C& c )
56 {
57 return c.size();
58 }
59
60 template< typename C >
61 static bool empty( const C& c )
62 {
63 return c.empty();
64 }
65
66 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
67
68 template< typename C >
69 static iterator begin( C& c )
70 {
71 return c.begin();
72 }
73
74 template< typename C >
75 static const_iterator begin( const C& c )
76 {
77 return c.begin();
78 }
79
80 template< typename C >
81 static iterator end( C& c )
82 {
83 return c.end();
84 }
85
86 template< typename C >
87 static const_iterator end( const C& c )
88 {
89 return c.end();
90 }
91
92 #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
93
94 template< typename C >
95 static result_iterator begin( C& c )
96 {
97 return c.begin();
98 }
99
100 template< typename C >
101 static result_iterator end( C& c )
102 {
103 return c.end();
104 }
105
106 #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
107
108 };
109
110 template<typename T>
111 struct default_container_traits_selector
112 {
113 typedef default_container_traits<T> type;
114 };
115
116 // Pair container traits ---------------------------------------------------------------------
117
118 typedef double yes_type;
119 typedef char no_type;
120
121 // pair selector
122 template< typename T, typename U >
123 yes_type is_pair_impl( const std::pair<T,U>* );
124 no_type is_pair_impl( ... );
125
126 template<typename T> struct is_pair
127 {
128 private:
129 static T* t;
130 public:
131 BOOST_STATIC_CONSTANT( bool, value=
132 sizeof(is_pair_impl(t))==sizeof(yes_type) );
133 };
134
135 // pair helper
136 template< typename PairT >
137 struct pair_container_traits
138 {
139 typedef typename PairT::first_type element_type;
140
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;
146
147 typedef element_type iterator;
148 typedef element_type const_iterator;
149 typedef element_type result_iterator;
150
151 // static operations
152 template< typename P >
153 static size_type size( const P& p )
154 {
155 difference_type diff = std::distance( p.first, p.second );
156 if ( diff < 0 )
157 return 0;
158 else
159 return diff;
160 }
161
162 template< typename P >
163 static bool empty( const P& p )
164 {
165 return p.first==p.second;
166 }
167
168 template< typename P >
169 static const_iterator begin( const P& p )
170 {
171 return p.first;
172 }
173
174 template< typename P >
175 static const_iterator end( const P& p )
176 {
177 return p.second;
178 }
179 }; // 'pair_container_helper'
180
181 template<typename T>
182 struct pair_container_traits_selector
183 {
184 typedef pair_container_traits<T> type;
185 };
186
187 // Array container traits ---------------------------------------------------------------
188
189 // array traits ( partial specialization )
190 template< typename T >
191 struct array_traits;
192
193 template< typename T, std::size_t sz >
194 struct array_traits<T[sz]>
195 {
196 // typedef
197 typedef T* iterator;
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;
202
203 // size of the array ( static );
204 BOOST_STATIC_CONSTANT( size_type, array_size = sz );
205 };
206
207
208 // array length resolving
209 /*
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
213 terminating 0.
214
215 Therefore, the length is calculated for char and wchar_t
216 using char_traits, rather then simply returning
217 the array size.
218 */
219 template< typename T >
220 struct array_length_selector
221 {
222 template< typename TraitsT >
223 struct array_length
224 {
225 typedef typename
226 TraitsT::size_type size_type;
227
228 BOOST_STATIC_CONSTANT(
229 size_type,
230 array_size=TraitsT::array_size );
231
232 template< typename A >
233 static size_type length( const A& )
234 {
235 return array_size;
236 }
237
238 template< typename A >
239 static bool empty( const A& )
240 {
241 return array_size==0;
242 }
243 };
244 };
245
246 // specialization for char
247 template<>
248 struct array_length_selector<char>
249 {
250 template< typename TraitsT >
251 struct array_length
252 {
253 typedef typename
254 TraitsT::size_type size_type;
255
256 template< typename A >
257 static size_type length( const A& a )
258 {
259 if ( a==0 )
260 return 0;
261 else
262 return std::char_traits<char>::length(a);
263 }
264
265 template< typename A >
266 static bool empty( const A& a )
267 {
268 return a==0 || a[0]==0;
269 }
270 };
271 };
272
273 // specialization for wchar_t
274 template<>
275 struct array_length_selector<wchar_t>
276 {
277 template< typename TraitsT >
278 struct array_length
279 {
280 typedef typename
281 TraitsT::size_type size_type;
282
283 template< typename A >
284 static size_type length( const A& a )
285 {
286 if ( a==0 )
287 return 0;
288 else
289 return std::char_traits<wchar_t>::length(a);
290 }
291
292 template< typename A >
293 static bool empty( const A& a )
294 {
295 return a==0 || a[0]==0;
296 }
297 };
298 };
299
300 template< typename T >
301 struct array_container_traits
302 {
303 private:
304 // resolve array traits
305 typedef array_traits<T> traits_type;
306
307 public:
308 typedef typename
309 traits_type::value_type value_type;
310 typedef typename
311 traits_type::iterator iterator;
312 typedef typename
313 traits_type::const_iterator const_iterator;
314 typedef typename
315 traits_type::size_type size_type;
316 typedef typename
317 traits_type::difference_type difference_type;
318
319 typedef typename
320 ::boost::mpl::if_< ::boost::is_const<T>,
321 const_iterator,
322 iterator
323 >::type result_iterator;
324
325 private:
326 // resolve array size
327 typedef typename
328 ::boost::remove_cv<value_type>::type char_type;
329 typedef typename
330 array_length_selector<char_type>::
331 BOOST_NESTED_TEMPLATE array_length<traits_type> array_length_type;
332
333 public:
334 BOOST_STATIC_CONSTANT( size_type, array_size = traits_type::array_size );
335
336 // static operations
337 template< typename A >
338 static size_type size( const A& a )
339 {
340 return array_length_type::length(a);
341 }
342
343 template< typename A >
344 static bool empty( const A& a )
345 {
346 return array_length_type::empty(a);
347 }
348
349
350 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
351
352 template< typename A >
353 static iterator begin( A& a )
354 {
355 return a;
356 }
357
358 template< typename A >
359 static const_iterator begin( const A& a )
360 {
361 return a;
362 }
363
364 template< typename A >
365 static iterator end( A& a )
366 {
367 return a+array_length_type::length(a);
368 }
369
370 template< typename A >
371 static const_iterator end( const A& a )
372 {
373 return a+array_length_type::length(a);
374 }
375
376 #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
377
378 template< typename A >
379 static result_iterator begin( A& a )
380 {
381 return a;
382 }
383
384 template< typename A >
385 static result_iterator end( A& a )
386 {
387 return a+array_length_type::length(a);
388 }
389
390 #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
391
392 };
393
394 template<typename T>
395 struct array_container_traits_selector
396 {
397 typedef array_container_traits<T> type;
398 };
399
400 // Pointer container traits ---------------------------------------------------------------
401
402 template<typename T>
403 struct pointer_container_traits
404 {
405 typedef typename
406 ::boost::remove_pointer<T>::type value_type;
407
408 typedef typename
409 ::boost::remove_cv<value_type>::type char_type;
410 typedef ::std::char_traits<char_type> char_traits;
411
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;
416
417 typedef typename
418 ::boost::mpl::if_< ::boost::is_const<T>,
419 const_iterator,
420 iterator
421 >::type result_iterator;
422
423 // static operations
424 template< typename P >
425 static size_type size( const P& p )
426 {
427 if ( p==0 )
428 return 0;
429 else
430 return char_traits::length(p);
431 }
432
433 template< typename P >
434 static bool empty( const P& p )
435 {
436 return p==0 || p[0]==0;
437 }
438
439 #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
440
441 template< typename P >
442 static iterator begin( P& p )
443 {
444 return p;
445 }
446
447 template< typename P >
448 static const_iterator begin( const P& p )
449 {
450 return p;
451 }
452
453 template< typename P >
454 static iterator end( P& p )
455 {
456 if ( p==0 )
457 return p;
458 else
459 return p+char_traits::length(p);
460 }
461
462 template< typename P >
463 static const_iterator end( const P& p )
464 {
465 if ( p==0 )
466 return p;
467 else
468 return p+char_traits::length(p);
469 }
470
471 #else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
472
473 template< typename P >
474 static result_iterator begin( P& p )
475 {
476 return p;
477 }
478
479 template< typename P >
480 static result_iterator end( P& p )
481 {
482 if ( p==0 )
483 return p;
484 else
485 return p+char_traits::length(p);
486 }
487
488 #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
489 };
490
491 template<typename T>
492 struct pointer_container_traits_selector
493 {
494 typedef pointer_container_traits<T> type;
495 };
496
497 } // namespace detail
498 } // namespace algorithm
499 } // namespace boost
500
501
502 #endif // BOOST_STRING_DETAIL_COLLECTION_HPP