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:
any_range()111             any_range()
112             {
113             }
114 
any_range(const any_range & other)115             any_range(const any_range& other)
116                 : base_type(other)
117             {
118             }
119 
120             template<class WrappedRange>
any_range(WrappedRange & wrapped_range)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>
any_range(const WrappedRange & wrapped_range)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             >
any_range(const any_range<OtherValue,OtherTraversal,OtherReference,OtherDifference,Buffer> & other)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>
any_range(Iterator first,Iterator last)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