]> AND Private Git Repository - canny.git/blob - stc/exp/ml_stc_linux_make_v1.0/include/boost/detail/iterator.hpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
48345e88bbafffd83cedcd0403f6d04d82a0059e
[canny.git] / stc / exp / ml_stc_linux_make_v1.0 / include / boost / detail / iterator.hpp
1 // (C) Copyright David Abrahams 2002.\r
2 // Distributed under the Boost Software License, Version 1.0. (See\r
3 // accompanying file LICENSE_1_0.txt or copy at\r
4 // http://www.boost.org/LICENSE_1_0.txt)\r
5 \r
6 // Boost versions of\r
7 //\r
8 //    std::iterator_traits<>::iterator_category\r
9 //    std::iterator_traits<>::difference_type\r
10 //    std::distance()\r
11 //\r
12 // ...for all compilers and iterators\r
13 //\r
14 // Additionally, if X is a pointer\r
15 //    std::iterator_traits<X>::pointer\r
16 \r
17 // Otherwise, if partial specialization is supported or X is not a pointer\r
18 //    std::iterator_traits<X>::value_type\r
19 //    std::iterator_traits<X>::pointer\r
20 //    std::iterator_traits<X>::reference\r
21 //\r
22 // See http://www.boost.org for most recent version including documentation.\r
23 \r
24 // Revision History\r
25 // 04 Mar 2001 - More attempted fixes for Intel C++ (David Abrahams)\r
26 // 03 Mar 2001 - Put all implementation into namespace\r
27 //               boost::detail::iterator_traits_. Some progress made on fixes\r
28 //               for Intel compiler. (David Abrahams)\r
29 // 02 Mar 2001 - Changed BOOST_MSVC to BOOST_MSVC_STD_ITERATOR in a few\r
30 //               places. (Jeremy Siek)\r
31 // 19 Feb 2001 - Improved workarounds for stock MSVC6; use yes_type and\r
32 //               no_type from type_traits.hpp; stopped trying to remove_cv\r
33 //               before detecting is_pointer, in honor of the new type_traits\r
34 //               semantics. (David Abrahams)\r
35 // 13 Feb 2001 - Make it work with nearly all standard-conforming iterators\r
36 //               under raw VC6. The one category remaining which will fail is\r
37 //               that of iterators derived from std::iterator but not\r
38 //               boost::iterator and which redefine difference_type.\r
39 // 11 Feb 2001 - Clean away code which can never be used (David Abrahams)\r
40 // 09 Feb 2001 - Always have a definition for each traits member, even if it\r
41 //               can't be properly deduced. These will be incomplete types in\r
42 //               some cases (undefined<void>), but it helps suppress MSVC errors\r
43 //               elsewhere (David Abrahams)\r
44 // 07 Feb 2001 - Support for more of the traits members where possible, making\r
45 //               this useful as a replacement for std::iterator_traits<T> when\r
46 //               used as a default template parameter.\r
47 // 06 Feb 2001 - Removed useless #includes of standard library headers\r
48 //               (David Abrahams)\r
49 \r
50 #ifndef ITERATOR_DWA122600_HPP_\r
51 # define ITERATOR_DWA122600_HPP_\r
52 \r
53 # include <boost/config.hpp>\r
54 # include <iterator>\r
55 \r
56 // STLPort 4.0 and betas have a bug when debugging is enabled and there is no\r
57 // partial specialization: instead of an iterator_category typedef, the standard\r
58 // container iterators have _Iterator_category.\r
59 //\r
60 // Also, whether debugging is enabled or not, there is a broken specialization\r
61 // of std::iterator<output_iterator_tag,void,void,void,void> which has no\r
62 // typedefs but iterator_category.\r
63 # if defined(__SGI_STL_PORT)\r
64 \r
65 #  if (__SGI_STL_PORT <= 0x410) && !defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && defined(__STL_DEBUG)\r
66 #   define BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF\r
67 #  endif\r
68 \r
69 #  define BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION\r
70 \r
71 # endif // STLPort <= 4.1b4 && no partial specialization\r
72 \r
73 # if !defined(BOOST_NO_STD_ITERATOR_TRAITS)             \\r
74   && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \\r
75   && !defined(BOOST_MSVC_STD_ITERATOR)\r
76     \r
77 namespace boost { namespace detail {\r
78 \r
79 // Define a new template so it can be specialized\r
80 template <class Iterator>\r
81 struct iterator_traits\r
82     : std::iterator_traits<Iterator>\r
83 {};\r
84 using std::distance;\r
85 \r
86 }} // namespace boost::detail\r
87 \r
88 # else\r
89 \r
90 #  if  !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)  \\r
91     && !defined(BOOST_MSVC_STD_ITERATOR)\r
92 \r
93 // This is the case where everything conforms except BOOST_NO_STD_ITERATOR_TRAITS\r
94 \r
95 namespace boost { namespace detail {\r
96 \r
97 // Rogue Wave Standard Library fools itself into thinking partial\r
98 // specialization is missing on some platforms (e.g. Sun), so fails to\r
99 // supply iterator_traits!\r
100 template <class Iterator>\r
101 struct iterator_traits\r
102 {\r
103     typedef typename Iterator::value_type value_type;\r
104     typedef typename Iterator::reference reference;\r
105     typedef typename Iterator::pointer pointer;\r
106     typedef typename Iterator::difference_type difference_type;\r
107     typedef typename Iterator::iterator_category iterator_category;\r
108 };\r
109 \r
110 template <class T>\r
111 struct iterator_traits<T*>\r
112 {\r
113     typedef T value_type;\r
114     typedef T& reference;\r
115     typedef T* pointer;\r
116     typedef std::ptrdiff_t difference_type;\r
117     typedef std::random_access_iterator_tag iterator_category;\r
118 };\r
119 \r
120 template <class T>\r
121 struct iterator_traits<T const*>\r
122 {\r
123     typedef T value_type;\r
124     typedef T const& reference;\r
125     typedef T const* pointer;\r
126     typedef std::ptrdiff_t difference_type;\r
127     typedef std::random_access_iterator_tag iterator_category;\r
128 };\r
129 \r
130 }} // namespace boost::detail\r
131 \r
132 #  else\r
133 \r
134 # include <boost/type_traits/remove_const.hpp>\r
135 # include <boost/type_traits/detail/yes_no_type.hpp>\r
136 # include <boost/type_traits/is_pointer.hpp>\r
137 \r
138 # ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION\r
139 #  include <boost/type_traits/is_same.hpp>\r
140 #  include <boost/type_traits/remove_pointer.hpp>\r
141 # endif\r
142 # ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION\r
143 #  include <boost/type_traits/is_base_and_derived.hpp>\r
144 # endif\r
145 \r
146 # include <boost/mpl/if.hpp>\r
147 # include <boost/mpl/has_xxx.hpp>\r
148 # include <cstddef>\r
149 \r
150 // should be the last #include\r
151 # include "boost/type_traits/detail/bool_trait_def.hpp"\r
152 \r
153 namespace boost { namespace detail {\r
154 \r
155 BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type)\r
156 BOOST_MPL_HAS_XXX_TRAIT_DEF(reference)\r
157 BOOST_MPL_HAS_XXX_TRAIT_DEF(pointer)\r
158 BOOST_MPL_HAS_XXX_TRAIT_DEF(difference_type)\r
159 BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator_category)\r
160 \r
161 // is_mutable_iterator --\r
162 //\r
163 //   A metafunction returning true iff T is a mutable iterator type\r
164 //   with a nested value_type. Will only work portably with iterators\r
165 //   whose operator* returns a reference, but that seems to be OK for\r
166 //   the iterators supplied by Dinkumware. Some input iterators may\r
167 //   compile-time if they arrive here, and if the compiler is strict\r
168 //   about not taking the address of an rvalue.\r
169 \r
170 // This one detects ordinary mutable iterators - the result of\r
171 // operator* is convertible to the value_type.\r
172 template <class T>\r
173 type_traits::yes_type is_mutable_iterator_helper(T const*, BOOST_DEDUCED_TYPENAME T::value_type*);\r
174 \r
175 // Since you can't take the address of an rvalue, the guts of\r
176 // is_mutable_iterator_impl will fail if we use &*t directly.  This\r
177 // makes sure we can still work with non-lvalue iterators.\r
178 template <class T> T* mutable_iterator_lvalue_helper(T& x);\r
179 int mutable_iterator_lvalue_helper(...);\r
180 \r
181 \r
182 // This one detects output iterators such as ostream_iterator which\r
183 // return references to themselves.\r
184 template <class T>\r
185 type_traits::yes_type is_mutable_iterator_helper(T const*, T const*);\r
186 \r
187 type_traits::no_type is_mutable_iterator_helper(...);\r
188 \r
189 template <class T>\r
190 struct is_mutable_iterator_impl\r
191 {\r
192     static T t;\r
193     \r
194     BOOST_STATIC_CONSTANT(\r
195         bool, value = sizeof(\r
196             detail::is_mutable_iterator_helper(\r
197                 (T*)0\r
198               , mutable_iterator_lvalue_helper(*t) // like &*t\r
199             ))\r
200         == sizeof(type_traits::yes_type)\r
201     );\r
202 };\r
203 \r
204 BOOST_TT_AUX_BOOL_TRAIT_DEF1(\r
205     is_mutable_iterator,T,::boost::detail::is_mutable_iterator_impl<T>::value)\r
206 \r
207 \r
208 // is_full_iterator_traits --\r
209 //\r
210 //   A metafunction returning true iff T has all the requisite nested\r
211 //   types to satisfy the requirements for a fully-conforming\r
212 //   iterator_traits implementation.\r
213 template <class T>\r
214 struct is_full_iterator_traits_impl\r
215 {\r
216     enum { value = \r
217            has_value_type<T>::value \r
218            & has_reference<T>::value \r
219            & has_pointer<T>::value \r
220            & has_difference_type<T>::value\r
221            & has_iterator_category<T>::value\r
222     };\r
223 };\r
224 \r
225 BOOST_TT_AUX_BOOL_TRAIT_DEF1(\r
226     is_full_iterator_traits,T,::boost::detail::is_full_iterator_traits_impl<T>::value)\r
227 \r
228 \r
229 #   ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF\r
230 BOOST_MPL_HAS_XXX_TRAIT_DEF(_Iterator_category)\r
231     \r
232 // is_stlport_40_debug_iterator --\r
233 //\r
234 //   A metafunction returning true iff T has all the requisite nested\r
235 //   types to satisfy the requirements of an STLPort 4.0 debug iterator\r
236 //   iterator_traits implementation.\r
237 template <class T>\r
238 struct is_stlport_40_debug_iterator_impl\r
239 {\r
240     enum { value = \r
241            has_value_type<T>::value \r
242            & has_reference<T>::value \r
243            & has_pointer<T>::value \r
244            & has_difference_type<T>::value\r
245            & has__Iterator_category<T>::value\r
246     };\r
247 };\r
248 \r
249 BOOST_TT_AUX_BOOL_TRAIT_DEF1(\r
250     is_stlport_40_debug_iterator,T,::boost::detail::is_stlport_40_debug_iterator_impl<T>::value)\r
251 \r
252 template <class T>\r
253 struct stlport_40_debug_iterator_traits\r
254 {\r
255     typedef typename T::value_type value_type;\r
256     typedef typename T::reference reference;\r
257     typedef typename T::pointer pointer;\r
258     typedef typename T::difference_type difference_type;\r
259     typedef typename T::_Iterator_category iterator_category;\r
260 };\r
261 #   endif // BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF \r
262 \r
263 template <class T> struct pointer_iterator_traits;\r
264 \r
265 #   ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION\r
266 template <class T>\r
267 struct pointer_iterator_traits<T*>\r
268 {\r
269     typedef typename remove_const<T>::type value_type;\r
270     typedef T* pointer;\r
271     typedef T& reference;\r
272     typedef std::random_access_iterator_tag iterator_category;\r
273     typedef std::ptrdiff_t difference_type;\r
274 };\r
275 #   else\r
276 \r
277 // In case of no template partial specialization, and if T is a\r
278 // pointer, iterator_traits<T>::value_type can still be computed.  For\r
279 // some basic types, remove_pointer is manually defined in\r
280 // type_traits/broken_compiler_spec.hpp. For others, do it yourself.\r
281 \r
282 template<class P> class please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee;\r
283 \r
284 template<class P>\r
285 struct pointer_value_type\r
286   : mpl::if_<\r
287         is_same<P, typename remove_pointer<P>::type>\r
288       , please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee<P>\r
289       , typename remove_const<\r
290             typename remove_pointer<P>::type\r
291         >::type\r
292     >\r
293 {\r
294 };\r
295 \r
296 \r
297 template<class P>\r
298 struct pointer_reference\r
299   : mpl::if_<\r
300         is_same<P, typename remove_pointer<P>::type>\r
301       , please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee<P>\r
302       , typename remove_pointer<P>::type&\r
303     >\r
304 {\r
305 };\r
306 \r
307 template <class T>\r
308 struct pointer_iterator_traits\r
309 {\r
310     typedef T pointer;\r
311     typedef std::random_access_iterator_tag iterator_category;\r
312     typedef std::ptrdiff_t difference_type;\r
313 \r
314     typedef typename pointer_value_type<T>::type value_type;\r
315     typedef typename pointer_reference<T>::type reference;\r
316 };\r
317 \r
318 #   endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION\r
319 \r
320 // We'll sort iterator types into one of these classifications, from which we\r
321 // can determine the difference_type, pointer, reference, and value_type\r
322 template <class Iterator>\r
323 struct standard_iterator_traits\r
324 {\r
325     typedef typename Iterator::difference_type difference_type;\r
326     typedef typename Iterator::value_type value_type;\r
327     typedef typename Iterator::pointer pointer;\r
328     typedef typename Iterator::reference reference;\r
329     typedef typename Iterator::iterator_category iterator_category;\r
330 };\r
331 \r
332 template <class Iterator>\r
333 struct msvc_stdlib_mutable_traits\r
334     : std::iterator_traits<Iterator>\r
335 {\r
336     typedef typename std::iterator_traits<Iterator>::distance_type difference_type;\r
337     typedef typename std::iterator_traits<Iterator>::value_type* pointer;\r
338     typedef typename std::iterator_traits<Iterator>::value_type& reference;\r
339 };\r
340 \r
341 template <class Iterator>\r
342 struct msvc_stdlib_const_traits\r
343     : std::iterator_traits<Iterator>\r
344 {\r
345     typedef typename std::iterator_traits<Iterator>::distance_type difference_type;\r
346     typedef const typename std::iterator_traits<Iterator>::value_type* pointer;\r
347     typedef const typename std::iterator_traits<Iterator>::value_type& reference;\r
348 };\r
349 \r
350 #   ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION\r
351 template <class Iterator>\r
352 struct is_bad_output_iterator\r
353     : is_base_and_derived<\r
354         std::iterator<std::output_iterator_tag,void,void,void,void>\r
355         , Iterator>\r
356 {\r
357 };\r
358 \r
359 struct bad_output_iterator_traits\r
360 {\r
361     typedef void value_type;\r
362     typedef void difference_type;\r
363     typedef std::output_iterator_tag iterator_category;\r
364     typedef void pointer;\r
365     typedef void reference;\r
366 };\r
367 #   endif\r
368 \r
369 // If we're looking at an MSVC6 (old Dinkumware) ``standard''\r
370 // iterator, this will generate an appropriate traits class. \r
371 template <class Iterator>\r
372 struct msvc_stdlib_iterator_traits\r
373     : mpl::if_<\r
374        is_mutable_iterator<Iterator>\r
375        , msvc_stdlib_mutable_traits<Iterator>\r
376        , msvc_stdlib_const_traits<Iterator>\r
377       >::type\r
378 {};\r
379 \r
380 template <class Iterator>\r
381 struct non_pointer_iterator_traits\r
382     : mpl::if_<\r
383         // if the iterator contains all the right nested types...\r
384         is_full_iterator_traits<Iterator>\r
385         // Use a standard iterator_traits implementation\r
386         , standard_iterator_traits<Iterator>\r
387 #   ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF\r
388         // Check for STLPort 4.0 broken _Iterator_category type\r
389         , mpl::if_<\r
390              is_stlport_40_debug_iterator<Iterator>\r
391              , stlport_40_debug_iterator_traits<Iterator>\r
392 #   endif\r
393         // Otherwise, assume it's a Dinkum iterator\r
394         , msvc_stdlib_iterator_traits<Iterator>\r
395 #   ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF\r
396         >::type\r
397 #   endif \r
398     >::type\r
399 {\r
400 };\r
401 \r
402 template <class Iterator>\r
403 struct iterator_traits_aux\r
404     : mpl::if_<\r
405         is_pointer<Iterator>\r
406         , pointer_iterator_traits<Iterator>\r
407         , non_pointer_iterator_traits<Iterator>\r
408     >::type\r
409 {\r
410 };\r
411 \r
412 template <class Iterator>\r
413 struct iterator_traits\r
414 {\r
415     // Explicit forwarding from base class needed to keep MSVC6 happy\r
416     // under some circumstances.\r
417  private:\r
418 #   ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION\r
419     typedef \r
420     typename mpl::if_<\r
421         is_bad_output_iterator<Iterator>\r
422         , bad_output_iterator_traits\r
423         , iterator_traits_aux<Iterator>\r
424     >::type base;\r
425 #   else\r
426     typedef iterator_traits_aux<Iterator> base;\r
427 #   endif\r
428  public:\r
429     typedef typename base::value_type value_type;\r
430     typedef typename base::pointer pointer;\r
431     typedef typename base::reference reference;\r
432     typedef typename base::difference_type difference_type;\r
433     typedef typename base::iterator_category iterator_category;\r
434 };\r
435 \r
436 // This specialization cuts off ETI (Early Template Instantiation) for MSVC.\r
437 template <> struct iterator_traits<int>\r
438 {\r
439     typedef int value_type;\r
440     typedef int pointer;\r
441     typedef int reference;\r
442     typedef int difference_type;\r
443     typedef int iterator_category;\r
444 };\r
445 \r
446 }} // namespace boost::detail\r
447 \r
448 #  endif // workarounds\r
449 \r
450 namespace boost { namespace detail {\r
451 \r
452 namespace iterator_traits_\r
453 {\r
454   template <class Iterator, class Difference>\r
455   struct distance_select\r
456   {\r
457       static Difference execute(Iterator i1, const Iterator i2, ...)\r
458       {\r
459           Difference result = 0;\r
460           while (i1 != i2)\r
461           {\r
462               ++i1;\r
463               ++result;\r
464           }\r
465           return result;\r
466       }\r
467 \r
468       static Difference execute(Iterator i1, const Iterator i2, std::random_access_iterator_tag*)\r
469       {\r
470           return i2 - i1;\r
471       }\r
472   };\r
473 } // namespace boost::detail::iterator_traits_\r
474 \r
475 template <class Iterator>\r
476 inline typename iterator_traits<Iterator>::difference_type\r
477 distance(Iterator first, Iterator last)\r
478 {\r
479     typedef typename iterator_traits<Iterator>::difference_type diff_t;\r
480     typedef typename ::boost::detail::iterator_traits<Iterator>::iterator_category iterator_category;\r
481     \r
482     return iterator_traits_::distance_select<Iterator,diff_t>::execute(\r
483         first, last, (iterator_category*)0);\r
484 }\r
485 \r
486 }}\r
487 \r
488 # endif\r
489 \r
490 \r
491 # undef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF\r
492 # undef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION\r
493 \r
494 #endif // ITERATOR_DWA122600_HPP_\r