Horizon
linear_distribute.hpp
Go to the documentation of this file.
1 // 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 
15 #ifndef RANGES_V3_VIEW_LINEAR_DISTRIBUTE_HPP
16 #define RANGES_V3_VIEW_LINEAR_DISTRIBUTE_HPP
17 
18 #include <type_traits>
19 
20 #include <meta/meta.hpp>
21 
22 #include <range/v3/range_fwd.hpp>
23 
25 #include <range/v3/utility/static_const.hpp>
26 #include <range/v3/view/facade.hpp>
27 
28 #include <range/v3/detail/prologue.hpp>
29 
30 namespace ranges
31 {
32  namespace views
33  {
36 
37  template<typename T>
38  struct linear_distribute_view : view_facade<linear_distribute_view<T>, finite>
39  {
40  CPP_assert(std::is_arithmetic<T>());
41 
42  private:
43  friend range_access;
45 
46  T from_, to_;
47  Calc delta_;
48  std::ptrdiff_t n_;
49 
50  constexpr T read() const noexcept
51  {
52  return from_;
53  }
54  constexpr bool equal(default_sentinel_t) const noexcept
55  {
56  return n_ == 0;
57  }
58  constexpr bool equal(linear_distribute_view const & other) const noexcept
59  {
60  bool const eq = n_ == other.n_;
61  RANGES_DIAGNOSTIC_PUSH
62  RANGES_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
63  RANGES_EXPECT(to_ == other.to_);
64  RANGES_EXPECT(!eq || from_ == other.from_);
65  RANGES_DIAGNOSTIC_POP
66  return eq;
67  }
68  constexpr void next() noexcept
69  {
70  RANGES_EXPECT(n_ > 0);
71  --n_;
72  if(n_ == 0)
73  {
74  from_ = to_;
75  }
76  else
77  {
78  from_ = T(to_ - (delta_ * Calc(n_ - 1)));
79  }
80  }
81 
82  public:
83  constexpr linear_distribute_view() = default;
84  constexpr linear_distribute_view(T from, T to, std::ptrdiff_t n) noexcept
85  : from_(from)
86  , to_(to)
87  , delta_(n > 1 ? (to - from) / Calc(n - 1) : 0)
88  , n_(n)
89  {
90  RANGES_EXPECT(n_ > 0);
91  RANGES_EXPECT(to_ >= from_);
92  }
93  constexpr std::size_t size() const noexcept
94  {
95  return static_cast<std::size_t>(n_);
96  }
97  };
98 
106  {
107  template(typename T)(
108  requires std::is_arithmetic<T>::value)
109  constexpr auto operator()(T from, T to, std::ptrdiff_t n) const
110  {
111  return linear_distribute_view<T>{from, to, n};
112  }
113  };
114 
117  RANGES_INLINE_VARIABLE(linear_distribute_fn, linear_distribute)
118  } // namespace views
119 } // namespace ranges
120 
121 #include <range/v3/detail/epilogue.hpp>
122 
123 #endif
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
std::integral_constant< std::size_t, N > size_t
An integral constant wrapper for std::size_t.
Definition: meta.hpp:163
typename detail::_cond< If >::template invoke< Then, Else > conditional_t
Select one type or another depending on a compile-time Boolean.
Definition: meta.hpp:1148
Tiny meta-programming library.
Definition: default_sentinel.hpp:26
A utility for constructing a view from a (derived) type that implements begin and end cursors.
Definition: facade.hpp:66
Distributes n values linearly in the closed interval [from, to].
Definition: linear_distribute.hpp:106
Definition: linear_distribute.hpp:39