concepts.hpp 3.99 KB
Newer Older
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
// 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/begin.hpp>
#include <boost/range/end.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_iterator<T const>::type  range_const_iterator;
        typedef typename range_iterator<T>::type        range_iterator;

        void constraints()
        {
            function_requires<
                boost_concepts::SinglePassIteratorConcept<
                    range_iterator
                >
            >();
            i = boost::begin(a);
            i = boost::end(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;
    };

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

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

    //! 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