summaryrefslogtreecommitdiff
path: root/boost/boost/range/concepts.hpp
blob: 2441d43371de13b472dbfd806b469cb22b8e4138 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Boost.Range library concept checks
//
//  Copyright Daniel Walker 2006. Use, modification and distribution
//  are subject to the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//

#ifndef BOOST_RANGE_CONCEPTS_HPP
#define BOOST_RANGE_CONCEPTS_HPP

#include <boost/concept_check.hpp>
#include <boost/iterator/iterator_concepts.hpp>
#include <boost/range/functions.hpp>
#include <boost/range/metafunctions.hpp>

/*!
 * \file
 * \brief Concept checks for the Boost Range library.
 *
 * The structures in this file may be used in conjunction with the
 * Boost Concept Check library to insure that the type of a function
 * parameter is compatible with a range concept. If not, a meaningful
 * compile time error is generated. Checks are provided for the range
 * concepts related to iterator traversal categories. For example, the
 * following line checks that the type T models the ForwardRange
 * concept.
 *
 * \code
 * function_requires<ForwardRangeConcept<T> >();
 * \endcode
 *
 * An additional concept check is required for the value access
 * property of the range. For example to check for a
 * ForwardReadableRange, the following code is required.
 *
 * \code
 * function_requires<ForwardRangeConcept<T> >();
 * function_requires<
 *     ReadableIteratorConcept<
 *         typename range_iterator<T>::type
 *     >
 * >();
 * \endcode
 *
 * \see http://www.boost.org/libs/range/doc/range.html for details
 * about range concepts.
 * \see http://www.boost.org/libs/iterator/doc/iterator_concepts.html
 * for details about iterator concepts.
 * \see http://www.boost.org/libs/concept_check/concept_check.htm for
 * details about concept checks.
 */

namespace boost {

    //! Check if a type T models the SinglePassRange range concept.
    template<typename T>
    struct SinglePassRangeConcept {
        typedef typename range_value<T>::type range_value;
        typedef typename range_iterator<T>::type range_iterator;
        typedef typename range_const_iterator<T>::type range_const_iterator;
        void constraints()
        {
            function_requires<
                boost_concepts::SinglePassIteratorConcept<
                    range_iterator
                >
            >();
            i = boost::begin(a);
            i = boost::end(a);
            b = boost::empty(a);
            const_constraints(a);
        }
        void const_constraints(const T& a)
        {
            ci = boost::begin(a);
            ci = boost::end(a);
        }
        T a;
        range_iterator i;
        range_const_iterator ci;
        bool b;
    };

    //! Check if a type T models the ForwardRange range concept.
    template<typename T>
    struct ForwardRangeConcept {
        typedef typename range_difference<T>::type range_difference;
        typedef typename range_size<T>::type range_size;
        void constraints()
        {
            function_requires<
                SinglePassRangeConcept<T>
            >();        
            function_requires<
                boost_concepts::ForwardTraversalConcept<
                    typename range_iterator<T>::type
                >
            >();
            s = boost::size(a);
        }
        T a;
        range_size s;
    };

    //! Check if a type T models the BidirectionalRange range concept.
    template<typename T>
    struct BidirectionalRangeConcept {
        typedef typename range_reverse_iterator<T>::type range_reverse_iterator;
        typedef typename range_const_reverse_iterator<T>::type range_const_reverse_iterator;
        void constraints()
        {
            function_requires<
                    ForwardRangeConcept<T>
            >();        
            function_requires<
                boost_concepts::BidirectionalTraversalConcept<
                    typename range_iterator<T>::type
                >
            >();
            i = boost::rbegin(a);
            i = boost::rend(a);
            const_constraints(a);
            }
        void const_constraints(const T& a)
        {
            ci = boost::rbegin(a);
            ci = boost::rend(a);
        }
        T a;
        range_reverse_iterator i;
        range_const_reverse_iterator ci;
    };

    //! Check if a type T models the RandomAccessRange range concept.
    template<typename T>
    struct RandomAccessRangeConcept {
        void constraints()
        {
            function_requires<
                BidirectionalRangeConcept<T>
            >();        
            function_requires<
                boost_concepts::RandomAccessTraversalConcept<
                    typename range_iterator<T>::type
                >
            >();
            }
    };

} // namespace boost

#endif // BOOST_RANGE_CONCEPTS_HPP