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