summaryrefslogtreecommitdiff
path: root/boost/hana/fwd/range.hpp
blob: 4ddb5a96b83b0ed943a46161b7e8dddb21dbf7e1 (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
/*!
@file
Forward declares `boost::hana::range`.

@copyright Louis Dionne 2013-2016
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
 */

#ifndef BOOST_HANA_FWD_RANGE_HPP
#define BOOST_HANA_FWD_RANGE_HPP

#include <boost/hana/config.hpp>
#include <boost/hana/fwd/core/make.hpp>
#include <boost/hana/fwd/integral_constant.hpp>


BOOST_HANA_NAMESPACE_BEGIN
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    //! @ingroup group-datatypes
    //! Compile-time half-open interval of `hana::integral_constant`s.
    //!
    //! A `range` represents a half-open interval of the form `[from, to)`
    //! containing `hana::integral_constant`s of a given type. The `[from, to)`
    //! notation represents the values starting at `from` (inclusively) up
    //! to but excluding `from`. In other words, it is a bit like the list
    //! `from, from+1, ..., to-1`.
    //!
    //! In particular, note that the bounds of the range can be any
    //! `hana::integral_constant`s (negative numbers are allowed) and the
    //! range does not have to start at zero. The only requirement is that
    //! `from <= to`.
    //!
    //! @note
    //! The representation of `hana::range` is implementation defined. In
    //! particular, one should not take for granted the number and types
    //! of template parameters. The proper way to create a `hana::range`
    //! is to use `hana::range_c` or `hana::make_range`.
    //!
    //!
    //! Modeled concepts
    //! ----------------
    //! 1. `Comparable`\n
    //! Two ranges are equal if and only if they are both empty or they both
    //! span the same interval.
    //! @include example/range/comparable.cpp
    //!
    //! 2. `Foldable`\n
    //! Folding a `range` is equivalent to folding a list of the
    //! `integral_constant`s in the interval it spans.
    //! @include example/range/foldable.cpp
    //!
    //! 3. `Iterable`\n
    //! Iterating over a `range` is equivalent to iterating over a list of
    //! the values it spans. In other words, iterating over the range
    //! `[from, to)` is equivalent to iterating over a list containing
    //! `from, from+1, from+2, ..., to-1`. Also note that `operator[]` can
    //! be used in place of the `at` function.
    //! @include example/range/iterable.cpp
    //!
    //! 4. `Searchable`\n
    //! Searching a `range` is equivalent to searching a list of the values
    //! in the range `[from, to)`, but it is much more compile-time efficient.
    //! @include example/range/searchable.cpp
    template <typename T, T from, T to>
    struct range {
        //! Equivalent to `hana::equal`
        template <typename X, typename Y>
        friend constexpr auto operator==(X&& x, Y&& y);

        //! Equivalent to `hana::not_equal`
        template <typename X, typename Y>
        friend constexpr auto operator!=(X&& x, Y&& y);

        //! Equivalent to `hana::at`
        template <typename N>
        constexpr decltype(auto) operator[](N&& n);
    };
#else
    template <typename T, T from, T to>
    struct range;
#endif

    //! Tag representing a `hana::range`.
    //! @relates hana::range
    struct range_tag { };

#ifdef BOOST_HANA_DOXYGEN_INVOKED
    //! Create a `hana::range` representing a half-open interval of
    //! `integral_constant`s.
    //! @relates hana::range
    //!
    //! Given two `IntegralConstant`s `from` and `to`, `make<range_tag>`
    //! returns a `hana::range` representing the half-open interval of
    //! `integral_constant`s `[from, to)`. `from` and `to` must form a
    //! valid interval, which means that `from <= to` must be true. Otherwise,
    //! a compilation error is triggered. Also note that if `from` and `to`
    //! are `IntegralConstant`s with different underlying integral types,
    //! the created range contains `integral_constant`s whose underlying
    //! type is their common type.
    //!
    //!
    //! Example
    //! -------
    //! @include example/range/make.cpp
    template <>
    constexpr auto make<range_tag> = [](auto const& from, auto const& to) {
        return range<implementation_defined>{implementation_defined};
    };
#endif

    //! Alias to `make<range_tag>`; provided for convenience.
    //! @relates hana::range
    constexpr auto make_range = make<range_tag>;

    //! Shorthand to create a `hana::range` with the given bounds.
    //! @relates hana::range
    //!
    //! This shorthand is provided for convenience only and it is equivalent
    //! to `make_range`. Specifically, `range_c<T, from, to>` is such that
    //! @code
    //!     range_c<T, from, to> == make_range(integral_c<T, from>, integral_c<T, to>)
    //! @endcode
    //!
    //!
    //! @tparam T
    //! The underlying integral type of the `integral_constant`s in the
    //! created range.
    //!
    //! @tparam from
    //! The inclusive lower bound of the created range.
    //!
    //! @tparam to
    //! The exclusive upper bound of the created range.
    //!
    //!
    //! Example
    //! -------
    //! @include example/range/range_c.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
    template <typename T, T from, T to>
    constexpr auto range_c = make_range(integral_c<T, from>, integral_c<T, to>);
#else
    template <typename T, T from, T to>
    constexpr range<T, from, to> range_c{};
#endif
BOOST_HANA_NAMESPACE_END

#endif // !BOOST_HANA_FWD_RANGE_HPP