File indexing completed on 2025-01-18 10:09:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef RANGES_V3_VIEW_LINEAR_DISTRIBUTE_HPP
0016 #define RANGES_V3_VIEW_LINEAR_DISTRIBUTE_HPP
0017
0018 #include <type_traits>
0019
0020 #include <meta/meta.hpp>
0021
0022 #include <range/v3/range_fwd.hpp>
0023
0024 #include <range/v3/iterator/default_sentinel.hpp>
0025 #include <range/v3/utility/static_const.hpp>
0026 #include <range/v3/view/facade.hpp>
0027
0028 #include <range/v3/detail/prologue.hpp>
0029
0030 namespace ranges
0031 {
0032 namespace views
0033 {
0034
0035
0036
0037 template<typename T>
0038 struct linear_distribute_view : view_facade<linear_distribute_view<T>, finite>
0039 {
0040 CPP_assert(std::is_arithmetic<T>());
0041
0042 private:
0043 friend range_access;
0044 using Calc = meta::conditional_t<std::is_floating_point<T>::value, T, double>;
0045
0046 T from_, to_;
0047 Calc delta_;
0048 std::ptrdiff_t n_;
0049
0050 constexpr T read() const noexcept
0051 {
0052 return from_;
0053 }
0054 constexpr bool equal(default_sentinel_t) const noexcept
0055 {
0056 return n_ == 0;
0057 }
0058 constexpr bool equal(linear_distribute_view const & other) const noexcept
0059 {
0060 bool const eq = n_ == other.n_;
0061 RANGES_DIAGNOSTIC_PUSH
0062 RANGES_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
0063 RANGES_EXPECT(to_ == other.to_);
0064 RANGES_EXPECT(!eq || from_ == other.from_);
0065 RANGES_DIAGNOSTIC_POP
0066 return eq;
0067 }
0068 constexpr void next() noexcept
0069 {
0070 RANGES_EXPECT(n_ > 0);
0071 --n_;
0072 if(n_ == 0)
0073 {
0074 from_ = to_;
0075 }
0076 else
0077 {
0078 from_ = T(to_ - (delta_ * Calc(n_ - 1)));
0079 }
0080 }
0081
0082 public:
0083 constexpr linear_distribute_view() = default;
0084 constexpr linear_distribute_view(T from, T to, std::ptrdiff_t n) noexcept
0085 : from_(from)
0086 , to_(to)
0087 , delta_(n > 1 ? (to - from) / Calc(n - 1) : 0)
0088 , n_(n)
0089 {
0090 RANGES_EXPECT(n_ > 0);
0091 RANGES_EXPECT(to_ >= from_);
0092 }
0093 constexpr std::size_t size() const noexcept
0094 {
0095 return static_cast<std::size_t>(n_);
0096 }
0097 };
0098
0099
0100
0101
0102
0103
0104
0105 struct linear_distribute_fn
0106 {
0107 template(typename T)(
0108 requires std::is_arithmetic<T>::value)
0109 constexpr auto operator()(T from, T to, std::ptrdiff_t n) const
0110 {
0111 return linear_distribute_view<T>{from, to, n};
0112 }
0113 };
0114
0115
0116
0117 RANGES_INLINE_VARIABLE(linear_distribute_fn, linear_distribute)
0118 }
0119 }
0120
0121 #include <range/v3/detail/epilogue.hpp>
0122
0123 #endif