Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:14:48

0001 // (C) Copyright Jeremy Siek 2002.
0002 // Distributed under the Boost Software License, Version 1.0. (See
0003 // accompanying file LICENSE_1_0.txt or copy at
0004 // http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_ITERATOR_CATEGORIES_HPP
0007 # define BOOST_ITERATOR_CATEGORIES_HPP
0008 
0009 # include <boost/config.hpp>
0010 # include <boost/iterator/detail/config_def.hpp>
0011 
0012 # include <boost/detail/workaround.hpp>
0013 
0014 # include <boost/mpl/eval_if.hpp>
0015 # include <boost/mpl/identity.hpp>
0016 # include <boost/mpl/placeholders.hpp>
0017 # include <boost/mpl/aux_/lambda_support.hpp>
0018 
0019 # include <boost/type_traits/is_convertible.hpp>
0020 
0021 # include <boost/static_assert.hpp>
0022 
0023 #include <iterator>
0024 
0025 namespace boost {
0026 namespace iterators {
0027 
0028 //
0029 // Traversal Categories
0030 //
0031 
0032 struct no_traversal_tag {};
0033 
0034 struct incrementable_traversal_tag
0035   : no_traversal_tag
0036 {
0037 //     incrementable_traversal_tag() {}
0038 //     incrementable_traversal_tag(std::output_iterator_tag const&) {};
0039 };
0040 
0041 struct single_pass_traversal_tag
0042   : incrementable_traversal_tag
0043 {
0044 //     single_pass_traversal_tag() {}
0045 //     single_pass_traversal_tag(std::input_iterator_tag const&) {};
0046 };
0047 
0048 struct forward_traversal_tag
0049   : single_pass_traversal_tag
0050 {
0051 //     forward_traversal_tag() {}
0052 //     forward_traversal_tag(std::forward_iterator_tag const&) {};
0053 };
0054 
0055 struct bidirectional_traversal_tag
0056   : forward_traversal_tag
0057 {
0058 //     bidirectional_traversal_tag() {};
0059 //     bidirectional_traversal_tag(std::bidirectional_iterator_tag const&) {};
0060 };
0061 
0062 struct random_access_traversal_tag
0063   : bidirectional_traversal_tag
0064 {
0065 //     random_access_traversal_tag() {};
0066 //     random_access_traversal_tag(std::random_access_iterator_tag const&) {};
0067 };
0068 
0069 namespace detail
0070 {
0071   //
0072   // Convert a "strictly old-style" iterator category to a traversal
0073   // tag.  This is broken out into a separate metafunction to reduce
0074   // the cost of instantiating iterator_category_to_traversal, below,
0075   // for new-style types.
0076   //
0077   template <class Cat>
0078   struct old_category_to_traversal
0079     : mpl::eval_if<
0080           is_convertible<Cat,std::random_access_iterator_tag>
0081         , mpl::identity<random_access_traversal_tag>
0082         , mpl::eval_if<
0083               is_convertible<Cat,std::bidirectional_iterator_tag>
0084             , mpl::identity<bidirectional_traversal_tag>
0085             , mpl::eval_if<
0086                   is_convertible<Cat,std::forward_iterator_tag>
0087                 , mpl::identity<forward_traversal_tag>
0088                 , mpl::eval_if<
0089                       is_convertible<Cat,std::input_iterator_tag>
0090                     , mpl::identity<single_pass_traversal_tag>
0091                     , mpl::eval_if<
0092                           is_convertible<Cat,std::output_iterator_tag>
0093                         , mpl::identity<incrementable_traversal_tag>
0094                         , void
0095                       >
0096                   >
0097               >
0098           >
0099       >
0100   {};
0101 
0102 } // namespace detail
0103 
0104 //
0105 // Convert an iterator category into a traversal tag
0106 //
0107 template <class Cat>
0108 struct iterator_category_to_traversal
0109   : mpl::eval_if< // if already convertible to a traversal tag, we're done.
0110         is_convertible<Cat,incrementable_traversal_tag>
0111       , mpl::identity<Cat>
0112       , boost::iterators::detail::old_category_to_traversal<Cat>
0113     >
0114 {};
0115 
0116 // Trait to get an iterator's traversal category
0117 template <class Iterator = mpl::_1>
0118 struct iterator_traversal
0119   : iterator_category_to_traversal<
0120         typename std::iterator_traits<Iterator>::iterator_category
0121     >
0122 {};
0123 
0124 # ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
0125 // Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
0126 // out well.  Instantiating the nested apply template also
0127 // requires instantiating iterator_traits on the
0128 // placeholder. Instead we just specialize it as a metafunction
0129 // class.
0130 template <>
0131 struct iterator_traversal<mpl::_1>
0132 {
0133     template <class T>
0134     struct apply : iterator_traversal<T>
0135     {};
0136 };
0137 template <>
0138 struct iterator_traversal<mpl::_>
0139   : iterator_traversal<mpl::_1>
0140 {};
0141 # endif
0142 
0143 //
0144 // Convert an iterator traversal to one of the traversal tags.
0145 //
0146 template <class Traversal>
0147 struct pure_traversal_tag
0148   : mpl::eval_if<
0149         is_convertible<Traversal,random_access_traversal_tag>
0150       , mpl::identity<random_access_traversal_tag>
0151       , mpl::eval_if<
0152             is_convertible<Traversal,bidirectional_traversal_tag>
0153           , mpl::identity<bidirectional_traversal_tag>
0154           , mpl::eval_if<
0155                 is_convertible<Traversal,forward_traversal_tag>
0156               , mpl::identity<forward_traversal_tag>
0157               , mpl::eval_if<
0158                     is_convertible<Traversal,single_pass_traversal_tag>
0159                   , mpl::identity<single_pass_traversal_tag>
0160                   , mpl::eval_if<
0161                         is_convertible<Traversal,incrementable_traversal_tag>
0162                       , mpl::identity<incrementable_traversal_tag>
0163                       , void
0164                     >
0165                 >
0166             >
0167         >
0168     >
0169 {
0170 };
0171 
0172 //
0173 // Trait to retrieve one of the iterator traversal tags from the iterator category or traversal.
0174 //
0175 template <class Iterator = mpl::_1>
0176 struct pure_iterator_traversal
0177   : pure_traversal_tag<typename iterator_traversal<Iterator>::type>
0178 {};
0179 
0180 # ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
0181 template <>
0182 struct pure_iterator_traversal<mpl::_1>
0183 {
0184     template <class T>
0185     struct apply : pure_iterator_traversal<T>
0186     {};
0187 };
0188 template <>
0189 struct pure_iterator_traversal<mpl::_>
0190   : pure_iterator_traversal<mpl::_1>
0191 {};
0192 # endif
0193 
0194 } // namespace iterators
0195 
0196 using iterators::no_traversal_tag;
0197 using iterators::incrementable_traversal_tag;
0198 using iterators::single_pass_traversal_tag;
0199 using iterators::forward_traversal_tag;
0200 using iterators::bidirectional_traversal_tag;
0201 using iterators::random_access_traversal_tag;
0202 using iterators::iterator_category_to_traversal;
0203 using iterators::iterator_traversal;
0204 
0205 // This import is needed for backward compatibility with Boost.Range:
0206 // boost/range/detail/demote_iterator_traversal_tag.hpp
0207 // It should be removed when that header is fixed.
0208 namespace detail {
0209 using iterators::pure_traversal_tag;
0210 } // namespace detail
0211 
0212 } // namespace boost
0213 
0214 #include <boost/iterator/detail/config_undef.hpp>
0215 
0216 #endif // BOOST_ITERATOR_CATEGORIES_HPP