Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:09:57

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Casey Carter 2017
0005 //  Copyright Gonzalo Brito Gadeschi 2017
0006 //
0007 //  Use, modification and distribution is subject to the
0008 //  Boost Software License, Version 1.0. (See accompanying
0009 //  file LICENSE_1_0.txt or copy at
0010 //  http://www.boost.org/LICENSE_1_0.txt)
0011 //
0012 // Project home: https://github.com/ericniebler/range-v3
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         /// \addtogroup group-views
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         /// Distributes `n` values linearly in the closed interval [`from`, `to`].
0100         ///
0101         /// \pre `from <= to && n > 0`
0102         ///
0103         /// If `from == to`, returns n-times `to`.
0104         /// If `n == 1` returns `to`.
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         /// \relates linear_distribute_fn
0116         /// \ingroup group-views
0117         RANGES_INLINE_VARIABLE(linear_distribute_fn, linear_distribute)
0118     } // namespace views
0119 } // namespace ranges
0120 
0121 #include <range/v3/detail/epilogue.hpp>
0122 
0123 #endif