1 /*============================================================================= 2 Copyright (c) 2005-2012 Joel de Guzman 3 Copyright (c) 2005-2006 Dan Marsden 4 5 Distributed under the Boost Software License, Version 1.0. (See accompanying 6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 ==============================================================================*/ 8 #if !defined(BOOST_FUSION_DEQUE_ITERATOR_26112006_2154) 9 #define BOOST_FUSION_DEQUE_ITERATOR_26112006_2154 10 11 #include <boost/fusion/support/config.hpp> 12 #include <boost/fusion/iterator/iterator_facade.hpp> 13 #include <boost/fusion/container/deque/detail/keyed_element.hpp> 14 #include <boost/mpl/int.hpp> 15 #include <boost/mpl/minus.hpp> 16 #include <boost/mpl/equal_to.hpp> 17 #include <boost/mpl/identity.hpp> 18 #include <boost/mpl/if.hpp> 19 #include <boost/type_traits/is_const.hpp> 20 #include <boost/type_traits/add_const.hpp> 21 #include <boost/type_traits/add_reference.hpp> 22 23 namespace boost { namespace fusion { 24 25 struct bidirectional_traversal_tag; 26 27 template <typename Seq, int Pos> 28 struct deque_iterator 29 : iterator_facade<deque_iterator<Seq, Pos>, bidirectional_traversal_tag> 30 { 31 typedef Seq sequence; 32 typedef mpl::int_<Pos> index; 33 34 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED deque_iteratorboost::fusion::deque_iterator35 deque_iterator(Seq& seq) 36 : seq_(seq) 37 {} 38 39 template<typename Iterator> 40 struct value_of 41 : detail::keyed_element_value_at< 42 typename Iterator::sequence, typename Iterator::index> 43 {}; 44 45 template<typename Iterator> 46 struct deref 47 { 48 typedef typename detail::keyed_element_value_at< 49 typename Iterator::sequence, typename Iterator::index>::type element_type; 50 51 typedef typename add_reference< 52 typename mpl::eval_if< 53 is_const<typename Iterator::sequence>, 54 add_const<element_type>, 55 mpl::identity<element_type> >::type>::type type; 56 57 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 58 static type callboost::fusion::deque_iterator::deref59 call(Iterator const& it) 60 { 61 return it.seq_.get(typename Iterator::index()); 62 } 63 }; 64 65 template <typename Iterator, typename N> 66 struct advance 67 { 68 typedef typename Iterator::index index; 69 typedef typename Iterator::sequence sequence; 70 typedef deque_iterator<sequence, index::value + N::value> type; 71 72 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 73 static type callboost::fusion::deque_iterator::advance74 call(Iterator const& i) 75 { 76 return type(i.seq_); 77 } 78 }; 79 80 template<typename Iterator> 81 struct next 82 : advance<Iterator, mpl::int_<1> > 83 {}; 84 85 template<typename Iterator> 86 struct prior 87 : advance<Iterator, mpl::int_<-1> > 88 {}; 89 90 template <typename I1, typename I2> 91 struct distance : mpl::minus<typename I2::index, typename I1::index> 92 { 93 typedef typename 94 mpl::minus< 95 typename I2::index, typename I1::index 96 >::type 97 type; 98 99 BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED 100 static type callboost::fusion::deque_iterator::distance101 call(I1 const&, I2 const&) 102 { 103 return type(); 104 } 105 }; 106 107 template<typename I1, typename I2> 108 struct equal_to 109 : mpl::equal_to<typename I1::index, typename I2::index> 110 {}; 111 112 Seq& seq_; 113 114 // silence MSVC warning C4512: assignment operator could not be generated 115 BOOST_DELETED_FUNCTION(deque_iterator& operator= (deque_iterator const&)) 116 }; 117 118 }} 119 120 #ifdef BOOST_FUSION_WORKAROUND_FOR_LWG_2408 121 namespace std 122 { 123 template <typename Seq, int Pos> 124 struct iterator_traits< ::boost::fusion::deque_iterator<Seq, Pos> > 125 { }; 126 } 127 #endif 128 129 #endif 130