You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 satır
3.2KB

  1. /// \file
  2. // Range v3 library
  3. //
  4. // Copyright Casey Carter 2017
  5. // Copyright Gonzalo Brito Gadeschi 2017
  6. //
  7. // Use, modification and distribution is subject to the
  8. // Boost Software License, Version 1.0. (See accompanying
  9. // file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. //
  12. // Project home: https://github.com/ericniebler/range-v3
  13. //
  14. #ifndef RANGES_V3_VIEW_LINEAR_DISTRIBUTE_HPP
  15. #define RANGES_V3_VIEW_LINEAR_DISTRIBUTE_HPP
  16. #include <type_traits>
  17. #include <range/v3/range_fwd.hpp>
  18. #include <range/v3/iterator/default_sentinel.hpp>
  19. #include <range/v3/utility/static_const.hpp>
  20. #include <range/v3/view/facade.hpp>
  21. namespace ranges
  22. {
  23. namespace views
  24. {
  25. /// \addtogroup group-views
  26. /// @{
  27. template<typename T>
  28. struct linear_distribute_view : view_facade<linear_distribute_view<T>, finite>
  29. {
  30. CPP_assert(std::is_arithmetic<T>());
  31. private:
  32. friend range_access;
  33. T from_, to_;
  34. std::ptrdiff_t n_;
  35. constexpr T read() const noexcept
  36. {
  37. return from_;
  38. }
  39. constexpr bool equal(default_sentinel_t) const noexcept
  40. {
  41. return n_ == 0;
  42. }
  43. constexpr bool equal(linear_distribute_view const & other) const noexcept
  44. {
  45. bool const eq = n_ == other.n_;
  46. RANGES_DIAGNOSTIC_PUSH
  47. RANGES_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
  48. RANGES_EXPECT(to_ == other.to_);
  49. RANGES_EXPECT(!eq || from_ == other.from_);
  50. RANGES_DIAGNOSTIC_POP
  51. return eq;
  52. }
  53. constexpr void next() noexcept
  54. {
  55. RANGES_EXPECT(n_ > 0);
  56. --n_;
  57. if(n_ == 0)
  58. {
  59. from_ = to_;
  60. }
  61. else
  62. {
  63. from_ += (to_ - from_) / T(n_);
  64. }
  65. }
  66. public:
  67. constexpr linear_distribute_view() = default;
  68. constexpr linear_distribute_view(T from, T to__, std::ptrdiff_t n) noexcept
  69. : from_(from)
  70. , to_(to__)
  71. , n_(n)
  72. {
  73. RANGES_EXPECT(n_ > 0);
  74. RANGES_EXPECT(to_ >= from_);
  75. }
  76. constexpr std::size_t size() const noexcept
  77. {
  78. return static_cast<std::size_t>(n_);
  79. }
  80. };
  81. /// Distributes `n` values linearly in the closed interval [`from`, `to`].
  82. ///
  83. /// \pre `from <= to && n > 0`
  84. ///
  85. /// If `from == to`, returns n-times `to`.
  86. /// If `n == 1` returns `to`.
  87. struct linear_distribute_fn
  88. {
  89. template<typename T>
  90. constexpr auto CPP_fun(operator())(T from, T to, std::ptrdiff_t n)(
  91. const requires std::is_arithmetic<T>::value)
  92. {
  93. return linear_distribute_view<T>{from, to, n};
  94. }
  95. };
  96. /// \relates linear_distribute_fn
  97. /// \ingroup group-views
  98. RANGES_INLINE_VARIABLE(linear_distribute_fn, linear_distribute)
  99. } // namespace views
  100. } // namespace ranges
  101. #endif