]> git.donarmstrong.com Git - rsem.git/blob - boost/fusion/iterator/detail/segmented_iterator.hpp
a5cfb450cd073fca64b0450e7e87c548bbb42ee5
[rsem.git] / boost / fusion / iterator / detail / segmented_iterator.hpp
1 /*=============================================================================
2     Copyright (c) 2011 Eric Niebler
3
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 #if !defined(BOOST_FUSION_SEGMENTED_ITERATOR_SEGMENTED_ITERATOR_HPP_INCLUDED)
8 #define BOOST_FUSION_SEGMENTED_ITERATOR_SEGMENTED_ITERATOR_HPP_INCLUDED
9
10 #include <boost/mpl/bool.hpp>
11 #include <boost/fusion/sequence/intrinsic_fwd.hpp>
12 #include <boost/fusion/iterator/iterator_facade.hpp>
13 #include <boost/fusion/iterator/deref.hpp>
14 #include <boost/fusion/iterator/deref_data.hpp>
15 #include <boost/fusion/iterator/key_of.hpp>
16 #include <boost/fusion/iterator/value_of.hpp>
17 #include <boost/fusion/iterator/value_of_data.hpp>
18 #include <boost/fusion/iterator/detail/segmented_equal_to.hpp>
19
20 namespace boost { namespace fusion
21 {
22     struct nil_;
23
24     namespace detail
25     {
26         template <typename Stack>
27         struct segmented_next_impl;
28     }
29
30     // A segmented iterator wraps a "context", which is a cons list
31     // of ranges, the frontmost is range over values and the rest
32     // are ranges over internal segments.
33     template <typename Context>
34     struct segmented_iterator
35       : iterator_facade<segmented_iterator<Context>, forward_traversal_tag>
36     {
37         explicit segmented_iterator(Context const& ctx)
38           : context(ctx)
39         {}
40
41         //auto deref(it)
42         //{
43         //  return deref(begin(car(it.context)))
44         //}
45         template <typename It>
46         struct deref
47         {
48             typedef
49                 typename result_of::deref<
50                     typename It::context_type::car_type::begin_type
51                 >::type
52             type;
53
54             static type call(It const& it)
55             {
56                 return *it.context.car.first;
57             }
58         };
59
60         //auto deref_data(it)
61         //{
62         //  return deref_data(begin(car(it.context)))
63         //}
64         template <typename It>
65         struct deref_data
66         {
67             typedef
68                 typename result_of::deref_data<
69                     typename It::context_type::car_type::begin_type
70                 >::type
71             type;
72
73             static type call(It const& it)
74             {
75                 return fusion::deref_data(it.context.car.first);
76             }
77         };
78
79         //auto key_of(it)
80         //{
81         //  return key_of(begin(car(it.context)))
82         //}
83         template <typename It>
84         struct key_of
85           : result_of::key_of<typename It::context_type::car_type::begin_type>
86         {};
87
88         //auto value_of(it)
89         //{
90         //  return value_of(begin(car(it.context)))
91         //}
92         template <typename It>
93         struct value_of
94           : result_of::value_of<typename It::context_type::car_type::begin_type>
95         {};
96
97         //auto value_of_data(it)
98         //{
99         //  return value_of_data(begin(car(it.context)))
100         //}
101         template <typename It>
102         struct value_of_data
103           : result_of::value_of_data<typename It::context_type::car_type::begin_type>
104         {};
105
106         // Compare all the segment iterators in each stack, starting with
107         // the bottom-most.
108         template <
109             typename It1
110           , typename It2
111           , int Size1 = It1::context_type::size::value
112           , int Size2 = It2::context_type::size::value
113         >
114         struct equal_to
115           : mpl::false_
116         {};
117
118         template <typename It1, typename It2, int Size>
119         struct equal_to<It1, It2, Size, Size>
120           : detail::segmented_equal_to<
121                 typename It1::context_type
122               , typename It2::context_type
123             >
124         {};
125
126         template <typename It>
127         struct next
128         {
129             typedef detail::segmented_next_impl<typename It::context_type> impl;
130             typedef segmented_iterator<typename impl::type> type;
131
132             static type call(It const& it)
133             {
134                 return type(impl::call(it.context));
135             }
136         };
137
138         typedef Context context_type;
139         context_type context;
140     };
141
142 }}
143
144 #endif