source: XIOS/dev/dev_olga/src/extern/boost/include/boost/range/concepts.hpp @ 1022

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
File size: 11.2 KB
Line 
1// Boost.Range library concept checks
2//
3//  Copyright Neil Groves 2009. Use, modification and distribution
4//  are subject to the Boost Software License, Version 1.0. (See
5//  accompanying file LICENSE_1_0.txt or copy at
6//  http://www.boost.org/LICENSE_1_0.txt)
7//
8//  Copyright Daniel Walker 2006. Use, modification and distribution
9//  are subject to the Boost Software License, Version 1.0. (See
10//  accompanying file LICENSE_1_0.txt or copy at
11//  http://www.boost.org/LICENSE_1_0.txt)
12//
13// For more information, see http://www.boost.org/libs/range/
14//
15
16#ifndef BOOST_RANGE_CONCEPTS_HPP
17#define BOOST_RANGE_CONCEPTS_HPP
18
19#include <boost/concept_check.hpp>
20#include <boost/iterator/iterator_concepts.hpp>
21#include <boost/range/begin.hpp>
22#include <boost/range/end.hpp>
23#include <boost/range/iterator.hpp>
24#include <boost/range/value_type.hpp>
25#include <boost/range/detail/misc_concept.hpp>
26
27/*!
28 * \file
29 * \brief Concept checks for the Boost Range library.
30 *
31 * The structures in this file may be used in conjunction with the
32 * Boost Concept Check library to insure that the type of a function
33 * parameter is compatible with a range concept. If not, a meaningful
34 * compile time error is generated. Checks are provided for the range
35 * concepts related to iterator traversal categories. For example, the
36 * following line checks that the type T models the ForwardRange
37 * concept.
38 *
39 * \code
40 * BOOST_CONCEPT_ASSERT((ForwardRangeConcept<T>));
41 * \endcode
42 *
43 * A different concept check is required to ensure writeable value
44 * access. For example to check for a ForwardRange that can be written
45 * to, the following code is required.
46 *
47 * \code
48 * BOOST_CONCEPT_ASSERT((WriteableForwardRangeConcept<T>));
49 * \endcode
50 *
51 * \see http://www.boost.org/libs/range/doc/range.html for details
52 * about range concepts.
53 * \see http://www.boost.org/libs/iterator/doc/iterator_concepts.html
54 * for details about iterator concepts.
55 * \see http://www.boost.org/libs/concept_check/concept_check.htm for
56 * details about concept checks.
57 */
58
59namespace boost {
60
61    namespace range_detail {
62
63#ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
64
65// List broken compiler versions here:
66    #ifdef __GNUC__
67        // GNUC 4.2 has strange issues correctly detecting compliance with the Concepts
68        // hence the least disruptive approach is to turn-off the concept checking for
69        // this version of the compiler.
70        #if __GNUC__ == 4 && __GNUC_MINOR__ == 2
71            #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
72        #endif
73    #endif
74
75    #ifdef __BORLANDC__
76        #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
77    #endif
78
79    #ifdef __PATHCC__
80        #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
81    #endif
82
83// Default to using the concept asserts unless we have defined it off
84// during the search for black listed compilers.
85    #ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
86        #define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 1
87    #endif
88
89#endif
90
91#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
92    #define BOOST_RANGE_CONCEPT_ASSERT( x ) BOOST_CONCEPT_ASSERT( x )
93#else
94    #define BOOST_RANGE_CONCEPT_ASSERT( x )
95#endif
96
97        // Rationale for the inclusion of redefined iterator concept
98        // classes:
99        //
100        // The Range algorithms often do not require that the iterators are
101        // Assignable, but the correct standard conformant iterators
102        // do require the iterators to be a model of the Assignable concept.
103        // Iterators that contains a functor that is not assignable therefore
104        // are not correct models of the standard iterator concepts,
105        // despite being adequate for most algorithms. An example of this
106        // use case is the combination of the boost::adaptors::filtered
107        // class with a boost::lambda::bind generated functor.
108        // Ultimately modeling the range concepts using composition
109        // with the Boost.Iterator concepts would render the library
110        // incompatible with many common Boost.Lambda expressions.
111        template<class Iterator>
112        struct IncrementableIteratorConcept : CopyConstructible<Iterator>
113        {
114#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
115            typedef BOOST_DEDUCED_TYPENAME iterator_traversal<Iterator>::type traversal_category;
116
117            BOOST_RANGE_CONCEPT_ASSERT((
118                Convertible<
119                    traversal_category,
120                    incrementable_traversal_tag
121                >));
122
123            BOOST_CONCEPT_USAGE(IncrementableIteratorConcept)
124            {
125                ++i;
126                (void)i++;
127            }
128        private:
129            Iterator i;
130#endif
131        };
132
133        template<class Iterator>
134        struct SinglePassIteratorConcept
135            : IncrementableIteratorConcept<Iterator>
136            , EqualityComparable<Iterator>
137        {
138#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
139            BOOST_RANGE_CONCEPT_ASSERT((
140                Convertible<
141                    BOOST_DEDUCED_TYPENAME SinglePassIteratorConcept::traversal_category,
142                    single_pass_traversal_tag
143                >));
144#endif
145        };
146
147        template<class Iterator>
148        struct ForwardIteratorConcept
149            : SinglePassIteratorConcept<Iterator>
150            , DefaultConstructible<Iterator>
151        {
152#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
153            typedef BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits<Iterator>::difference_type difference_type;
154
155            BOOST_MPL_ASSERT((is_integral<difference_type>));
156            BOOST_MPL_ASSERT_RELATION(std::numeric_limits<difference_type>::is_signed, ==, true);
157
158            BOOST_RANGE_CONCEPT_ASSERT((
159                Convertible<
160                    BOOST_DEDUCED_TYPENAME ForwardIteratorConcept::traversal_category,
161                    forward_traversal_tag
162                >));
163#endif
164         };
165
166         template<class Iterator>
167         struct BidirectionalIteratorConcept
168             : ForwardIteratorConcept<Iterator>
169         {
170 #if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
171             BOOST_RANGE_CONCEPT_ASSERT((
172                 Convertible<
173                     BOOST_DEDUCED_TYPENAME BidirectionalIteratorConcept::traversal_category,
174                     bidirectional_traversal_tag
175                 >));
176
177             BOOST_CONCEPT_USAGE(BidirectionalIteratorConcept)
178             {
179                 --i;
180                 (void)i--;
181             }
182         private:
183             Iterator i;
184 #endif
185         };
186
187         template<class Iterator>
188         struct RandomAccessIteratorConcept
189             : BidirectionalIteratorConcept<Iterator>
190         {
191 #if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
192             BOOST_RANGE_CONCEPT_ASSERT((
193                 Convertible<
194                     BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::traversal_category,
195                     random_access_traversal_tag
196                 >));
197
198             BOOST_CONCEPT_USAGE(RandomAccessIteratorConcept)
199             {
200                 i += n;
201                 i = i + n;
202                 i = n + i;
203                 i -= n;
204                 i = i - n;
205                 n = i - j;
206             }
207         private:
208             BOOST_DEDUCED_TYPENAME RandomAccessIteratorConcept::difference_type n;
209             Iterator i;
210             Iterator j;
211 #endif
212         };
213
214    } // namespace range_detail
215
216    //! Check if a type T models the SinglePassRange range concept.
217    template<class T>
218    struct SinglePassRangeConcept
219    {
220#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
221         typedef BOOST_DEDUCED_TYPENAME range_iterator<T const>::type  const_iterator;
222         typedef BOOST_DEDUCED_TYPENAME range_iterator<T>::type        iterator;
223
224         BOOST_RANGE_CONCEPT_ASSERT((range_detail::SinglePassIteratorConcept<iterator>));
225         BOOST_RANGE_CONCEPT_ASSERT((range_detail::SinglePassIteratorConcept<const_iterator>));
226
227         BOOST_CONCEPT_USAGE(SinglePassRangeConcept)
228         {
229            // This has been modified from assigning to this->i
230            // (where i was a member variable) to improve
231            // compatibility with Boost.Lambda
232            iterator i1 = boost::begin(*m_range);
233            iterator i2 = boost::end(*m_range);
234
235            ignore_unused_variable_warning(i1);
236            ignore_unused_variable_warning(i2);
237
238            const_constraints(*m_range);
239        }
240
241    private:
242        void const_constraints(const T& const_range)
243        {
244            const_iterator ci1 = boost::begin(const_range);
245            const_iterator ci2 = boost::end(const_range);
246
247            ignore_unused_variable_warning(ci1);
248            ignore_unused_variable_warning(ci2);
249        }
250
251       // Rationale:
252       // The type of m_range is T* rather than T because it allows
253       // T to be an abstract class. The other obvious alternative of
254       // T& produces a warning on some compilers.
255       T* m_range;
256#endif
257    };
258
259    //! Check if a type T models the ForwardRange range concept.
260    template<class T>
261    struct ForwardRangeConcept : SinglePassRangeConcept<T>
262    {
263#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
264        BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept<BOOST_DEDUCED_TYPENAME ForwardRangeConcept::iterator>));
265        BOOST_RANGE_CONCEPT_ASSERT((range_detail::ForwardIteratorConcept<BOOST_DEDUCED_TYPENAME ForwardRangeConcept::const_iterator>));
266#endif
267    };
268
269    template<class Range>
270    struct WriteableRangeConcept
271    {
272#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
273        typedef BOOST_DEDUCED_TYPENAME range_iterator<Range>::type iterator;
274
275        BOOST_CONCEPT_USAGE(WriteableRangeConcept)
276        {
277            *i = v;
278        }
279    private:
280        iterator i;
281        BOOST_DEDUCED_TYPENAME range_value<Range>::type v;
282#endif
283    };
284
285    //! Check if a type T models the WriteableForwardRange range concept.
286    template<class T>
287    struct WriteableForwardRangeConcept
288        : ForwardRangeConcept<T>
289        , WriteableRangeConcept<T>
290    {
291    };
292
293    //! Check if a type T models the BidirectionalRange range concept.
294    template<class T>
295    struct BidirectionalRangeConcept : ForwardRangeConcept<T>
296    {
297#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
298        BOOST_RANGE_CONCEPT_ASSERT((BidirectionalIteratorConcept<BOOST_DEDUCED_TYPENAME BidirectionalRangeConcept::iterator>));
299        BOOST_RANGE_CONCEPT_ASSERT((BidirectionalIteratorConcept<BOOST_DEDUCED_TYPENAME BidirectionalRangeConcept::const_iterator>));
300#endif
301    };
302
303    //! Check if a type T models the WriteableBidirectionalRange range concept.
304    template<class T>
305    struct WriteableBidirectionalRangeConcept
306        : BidirectionalRangeConcept<T>
307        , WriteableRangeConcept<T>
308    {
309    };
310
311    //! Check if a type T models the RandomAccessRange range concept.
312    template<class T>
313    struct RandomAccessRangeConcept : BidirectionalRangeConcept<T>
314    {
315#if BOOST_RANGE_ENABLE_CONCEPT_ASSERT
316        BOOST_RANGE_CONCEPT_ASSERT((RandomAccessIteratorConcept<BOOST_DEDUCED_TYPENAME RandomAccessRangeConcept::iterator>));
317        BOOST_RANGE_CONCEPT_ASSERT((RandomAccessIteratorConcept<BOOST_DEDUCED_TYPENAME RandomAccessRangeConcept::const_iterator>));
318#endif
319    };
320
321    //! Check if a type T models the WriteableRandomAccessRange range concept.
322    template<class T>
323    struct WriteableRandomAccessRangeConcept
324        : RandomAccessRangeConcept<T>
325        , WriteableRangeConcept<T>
326    {
327    };
328
329} // namespace boost
330
331#endif // BOOST_RANGE_CONCEPTS_HPP
Note: See TracBrowser for help on using the repository browser.