1 | // Copyright Neil Groves 2010. Use, modification and |
2 | // distribution is subject to the Boost Software License, Version |
3 | // 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
4 | // http://www.boost.org/LICENSE_1_0.txt) |
5 | // |
6 | // |
7 | // For more information, see http://www.boost.org/libs/range/ |
8 | // |
9 | #ifndef BOOST_RANGE_ANY_RANGE_HPP_INCLUDED |
10 | #define BOOST_RANGE_ANY_RANGE_HPP_INCLUDED |
11 | |
12 | #include <boost/config.hpp> |
13 | #include <boost/iterator/iterator_categories.hpp> |
14 | #include <boost/iterator/iterator_traits.hpp> |
15 | #include <boost/iterator/iterator_facade.hpp> |
16 | #include <boost/iterator/iterator_adaptor.hpp> |
17 | #include <boost/range/detail/any_iterator.hpp> |
18 | #include <boost/range/concepts.hpp> |
19 | #include <boost/range/reference.hpp> |
20 | #include <boost/range/value_type.hpp> |
21 | #include <boost/range/iterator_range_core.hpp> |
22 | |
23 | namespace boost |
24 | { |
25 | namespace range_detail |
26 | { |
27 | // If T is use_default, return the result of Default, otherwise |
28 | // return T. |
29 | // |
30 | // This is an implementation artifact used to pick intelligent default |
31 | // values when the user specified boost::use_default as a template |
32 | // parameter. |
33 | template< |
34 | class T, |
35 | class Default |
36 | > |
37 | struct any_range_default_help |
38 | : mpl::eval_if< |
39 | is_same<T, use_default> |
40 | , Default |
41 | , mpl::identity<T> |
42 | > |
43 | { |
44 | }; |
45 | |
46 | template< |
47 | class WrappedRange |
48 | , class Value |
49 | , class Reference |
50 | > |
51 | struct any_range_value_type |
52 | { |
53 | # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY |
54 | typedef typename any_range_default_help< |
55 | Value |
56 | , mpl::eval_if< |
57 | is_same<Reference, use_default> |
58 | , range_value< |
59 | typename remove_const<WrappedRange> |
60 | ::type> |
61 | , remove_reference<Reference> |
62 | > |
63 | >::type type; |
64 | # else |
65 | typedef typename any_range_default_help< |
66 | Value |
67 | , range_value< |
68 | typename remove_const<WrappedRange> |
69 | ::type> |
70 | >::type type; |
71 | # endif |
72 | }; |
73 | |
74 | template< |
75 | class Value |
76 | , class Traversal |
77 | , class Reference = Value& |
78 | , class Difference = std::ptrdiff_t |
79 | , class Buffer = use_default |
80 | > |
81 | class any_range |
82 | : public iterator_range< |
83 | any_iterator< |
84 | Value |
85 | , Traversal |
86 | , Reference |
87 | , Difference |
88 | , typename any_range_default_help< |
89 | Buffer |
90 | , mpl::identity<any_iterator_default_buffer> |
91 | >::type |
92 | > |
93 | > |
94 | { |
95 | typedef iterator_range< |
96 | any_iterator< |
97 | Value |
98 | , Traversal |
99 | , Reference |
100 | , Difference |
101 | , typename any_range_default_help< |
102 | Buffer |
103 | , mpl::identity<any_iterator_default_buffer> |
104 | >::type |
105 | > |
106 | > base_type; |
107 | |
108 | struct enabler {}; |
109 | struct disabler {}; |
110 | public: |
111 | any_range() |
112 | { |
113 | } |
114 | |
115 | any_range(const any_range& other) |
116 | : base_type(other) |
117 | { |
118 | } |
119 | |
120 | template<class WrappedRange> |
121 | any_range(WrappedRange& wrapped_range) |
122 | : base_type(boost::begin(wrapped_range), |
123 | boost::end(wrapped_range)) |
124 | { |
125 | } |
126 | |
127 | template<class WrappedRange> |
128 | any_range(const WrappedRange& wrapped_range) |
129 | : base_type(boost::begin(wrapped_range), |
130 | boost::end(wrapped_range)) |
131 | { |
132 | } |
133 | |
134 | template< |
135 | class OtherValue |
136 | , class OtherTraversal |
137 | , class OtherReference |
138 | , class OtherDifference |
139 | > |
140 | any_range(const any_range< |
141 | OtherValue |
142 | , OtherTraversal |
143 | , OtherReference |
144 | , OtherDifference |
145 | , Buffer |
146 | >& other) |
147 | : base_type(boost::begin(other), boost::end(other)) |
148 | { |
149 | } |
150 | |
151 | template<class Iterator> |
152 | any_range(Iterator first, Iterator last) |
153 | : base_type(first, last) |
154 | { |
155 | } |
156 | }; |
157 | |
158 | template< |
159 | class WrappedRange |
160 | , class Value = use_default |
161 | , class Traversal = use_default |
162 | , class Reference = use_default |
163 | , class Difference = use_default |
164 | , class Buffer = use_default |
165 | > |
166 | struct any_range_type_generator |
167 | { |
168 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<WrappedRange> )); |
169 | typedef any_range< |
170 | typename any_range_value_type< |
171 | WrappedRange |
172 | , Value |
173 | , typename any_range_default_help< |
174 | Reference |
175 | , range_reference<WrappedRange> |
176 | >::type |
177 | >::type |
178 | , typename any_range_default_help< |
179 | Traversal |
180 | , iterator_traversal< |
181 | typename range_iterator<WrappedRange>::type |
182 | > |
183 | >::type |
184 | , typename any_range_default_help< |
185 | Reference |
186 | , range_reference<WrappedRange> |
187 | >::type |
188 | , typename any_range_default_help< |
189 | Difference |
190 | , range_difference<WrappedRange> |
191 | >::type |
192 | , typename any_range_default_help< |
193 | Buffer |
194 | , mpl::identity<any_iterator_default_buffer> |
195 | >::type |
196 | > type; |
197 | }; |
198 | } // namespace range_detail |
199 | |
200 | using range_detail::any_range; |
201 | using range_detail::any_range_type_generator; |
202 | } // namespace boost |
203 | |
204 | #endif // include guard |
205 | |