range.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*!
  2. @file
  3. Forward declares `boost::hana::range`.
  4. Copyright Louis Dionne 2013-2022
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_HANA_FWD_RANGE_HPP
  9. #define BOOST_HANA_FWD_RANGE_HPP
  10. #include <boost/hana/config.hpp>
  11. #include <boost/hana/fwd/core/make.hpp>
  12. #include <boost/hana/fwd/integral_constant.hpp>
  13. namespace boost { namespace hana {
  14. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  15. //! @ingroup group-datatypes
  16. //! Compile-time half-open interval of `hana::integral_constant`s.
  17. //!
  18. //! A `range` represents a half-open interval of the form `[from, to)`
  19. //! containing `hana::integral_constant`s of a given type. The `[from, to)`
  20. //! notation represents the values starting at `from` (inclusively) up
  21. //! to but excluding `from`. In other words, it is a bit like the list
  22. //! `from, from+1, ..., to-1`.
  23. //!
  24. //! In particular, note that the bounds of the range can be any
  25. //! `hana::integral_constant`s (negative numbers are allowed) and the
  26. //! range does not have to start at zero. The only requirement is that
  27. //! `from <= to`.
  28. //!
  29. //! @note
  30. //! The representation of `hana::range` is implementation defined. In
  31. //! particular, one should not take for granted the number and types
  32. //! of template parameters. The proper way to create a `hana::range`
  33. //! is to use `hana::range_c` or `hana::make_range`. More details
  34. //! [in the tutorial](@ref tutorial-containers-types).
  35. //!
  36. //!
  37. //! Modeled concepts
  38. //! ----------------
  39. //! 1. `Comparable`\n
  40. //! Two ranges are equal if and only if they are both empty or they both
  41. //! span the same interval.
  42. //! @include example/range/comparable.cpp
  43. //!
  44. //! 2. `Foldable`\n
  45. //! Folding a `range` is equivalent to folding a list of the
  46. //! `integral_constant`s in the interval it spans.
  47. //! @include example/range/foldable.cpp
  48. //!
  49. //! 3. `Iterable`\n
  50. //! Iterating over a `range` is equivalent to iterating over a list of
  51. //! the values it spans. In other words, iterating over the range
  52. //! `[from, to)` is equivalent to iterating over a list containing
  53. //! `from, from+1, from+2, ..., to-1`. Also note that `operator[]` can
  54. //! be used in place of the `at` function.
  55. //! @include example/range/iterable.cpp
  56. //!
  57. //! 4. `Searchable`\n
  58. //! Searching a `range` is equivalent to searching a list of the values
  59. //! in the range `[from, to)`, but it is much more compile-time efficient.
  60. //! @include example/range/searchable.cpp
  61. template <typename T, T from, T to>
  62. struct range {
  63. //! Equivalent to `hana::equal`
  64. template <typename X, typename Y>
  65. friend constexpr auto operator==(X&& x, Y&& y);
  66. //! Equivalent to `hana::not_equal`
  67. template <typename X, typename Y>
  68. friend constexpr auto operator!=(X&& x, Y&& y);
  69. //! Equivalent to `hana::at`
  70. template <typename N>
  71. constexpr decltype(auto) operator[](N&& n);
  72. };
  73. #else
  74. template <typename T, T from, T to>
  75. struct range;
  76. #endif
  77. //! Tag representing a `hana::range`.
  78. //! @relates hana::range
  79. struct range_tag { };
  80. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  81. //! Create a `hana::range` representing a half-open interval of
  82. //! `integral_constant`s.
  83. //! @relates hana::range
  84. //!
  85. //! Given two `IntegralConstant`s `from` and `to`, `make<range_tag>`
  86. //! returns a `hana::range` representing the half-open interval of
  87. //! `integral_constant`s `[from, to)`. `from` and `to` must form a
  88. //! valid interval, which means that `from <= to` must be true. Otherwise,
  89. //! a compilation error is triggered. Also note that if `from` and `to`
  90. //! are `IntegralConstant`s with different underlying integral types,
  91. //! the created range contains `integral_constant`s whose underlying
  92. //! type is their common type.
  93. //!
  94. //!
  95. //! Example
  96. //! -------
  97. //! @include example/range/make.cpp
  98. template <>
  99. constexpr auto make<range_tag> = [](auto const& from, auto const& to) {
  100. return range<implementation_defined>{implementation_defined};
  101. };
  102. #endif
  103. //! Alias to `make<range_tag>`; provided for convenience.
  104. //! @relates hana::range
  105. BOOST_HANA_INLINE_VARIABLE constexpr auto make_range = make<range_tag>;
  106. //! Shorthand to create a `hana::range` with the given bounds.
  107. //! @relates hana::range
  108. //!
  109. //! This shorthand is provided for convenience only and it is equivalent
  110. //! to `make_range`. Specifically, `range_c<T, from, to>` is such that
  111. //! @code
  112. //! range_c<T, from, to> == make_range(integral_c<T, from>, integral_c<T, to>)
  113. //! @endcode
  114. //!
  115. //!
  116. //! @tparam T
  117. //! The underlying integral type of the `integral_constant`s in the
  118. //! created range.
  119. //!
  120. //! @tparam from
  121. //! The inclusive lower bound of the created range.
  122. //!
  123. //! @tparam to
  124. //! The exclusive upper bound of the created range.
  125. //!
  126. //!
  127. //! Example
  128. //! -------
  129. //! @include example/range/range_c.cpp
  130. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  131. template <typename T, T from, T to>
  132. constexpr auto range_c = make_range(integral_c<T, from>, integral_c<T, to>);
  133. #else
  134. template <typename T, T from, T to>
  135. BOOST_HANA_INLINE_VARIABLE constexpr range<T, from, to> range_c{};
  136. #endif
  137. }} // end namespace boost::hana
  138. #endif // !BOOST_HANA_FWD_RANGE_HPP