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