Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2014-present
0005 //
0006 //  Use, modification and distribution is subject to the
0007 //  Boost Software License, Version 1.0. (See accompanying
0008 //  file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // Project home: https://github.com/ericniebler/range-v3
0012 //
0013 
0014 #ifndef RANGES_V3_VIEW_TAIL_HPP
0015 #define RANGES_V3_VIEW_TAIL_HPP
0016 
0017 #include <type_traits>
0018 #include <utility>
0019 
0020 #include <range/v3/range_fwd.hpp>
0021 
0022 #include <range/v3/iterator/operations.hpp>
0023 #include <range/v3/range/access.hpp>
0024 #include <range/v3/range/concepts.hpp>
0025 #include <range/v3/range/primitives.hpp>
0026 #include <range/v3/range/traits.hpp>
0027 #include <range/v3/utility/static_const.hpp>
0028 #include <range/v3/view/all.hpp>
0029 #include <range/v3/view/interface.hpp>
0030 #include <range/v3/view/view.hpp>
0031 
0032 #include <range/v3/detail/prologue.hpp>
0033 
0034 namespace ranges
0035 {
0036     namespace detail
0037     {
0038         template<typename T>
0039         constexpr T prev_or_zero_(T n)
0040         {
0041             return n == 0 ? T(0) : T(n - 1);
0042         }
0043     } // namespace detail
0044 
0045     /// \addtogroup group-views
0046     /// @{
0047     template<typename Rng>
0048     struct tail_view
0049       : view_interface<tail_view<Rng>,
0050                        (range_cardinality<Rng>::value >= 0)
0051                            ? detail::prev_or_zero_(range_cardinality<Rng>::value)
0052                            : range_cardinality<Rng>::value>
0053     {
0054     private:
0055         Rng rng_;
0056 
0057     public:
0058         tail_view() = default;
0059         tail_view(Rng rng)
0060           : rng_(static_cast<Rng &&>(rng))
0061         {
0062             CPP_assert(input_range<Rng>);
0063         }
0064         iterator_t<Rng> begin()
0065         {
0066             return next(ranges::begin(rng_), 1, ranges::end(rng_));
0067         }
0068         template(bool Const = true)(
0069             requires Const AND range<meta::const_if_c<Const, Rng>>)
0070         iterator_t<meta::const_if_c<Const, Rng>> begin() const
0071         {
0072             return next(ranges::begin(rng_), 1, ranges::end(rng_));
0073         }
0074         sentinel_t<Rng> end()
0075         {
0076             return ranges::end(rng_);
0077         }
0078         template(bool Const = true)(
0079             requires Const AND range<meta::const_if_c<Const, Rng>>)
0080         sentinel_t<meta::const_if_c<Const, Rng>> end() const
0081         {
0082             return ranges::end(rng_);
0083         }
0084         // Strange cast to bool in the requires clause is to work around gcc bug.
0085         CPP_auto_member
0086         constexpr auto CPP_fun(size)()(
0087             requires(bool(sized_range<Rng>)))
0088         {
0089             using size_type = range_size_t<Rng>;
0090             return range_cardinality<Rng>::value >= 0
0091                        ? detail::prev_or_zero_((size_type)range_cardinality<Rng>::value)
0092                        : detail::prev_or_zero_(ranges::size(rng_));
0093         }
0094         CPP_auto_member
0095         constexpr auto CPP_fun(size)()(const //
0096             requires(bool(sized_range<Rng const>)))
0097         {
0098             using size_type = range_size_t<Rng>;
0099             return range_cardinality<Rng>::value >= 0
0100                        ? detail::prev_or_zero_((size_type)range_cardinality<Rng>::value)
0101                        : detail::prev_or_zero_(ranges::size(rng_));
0102         }
0103         Rng base() const
0104         {
0105             return rng_;
0106         }
0107     };
0108 
0109     template<typename Rng>
0110     RANGES_INLINE_VAR constexpr bool enable_borrowed_range<tail_view<Rng>> = //
0111         enable_borrowed_range<Rng>;
0112 
0113 #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
0114     template(typename Rng)(
0115         requires viewable_range<Rng>)
0116         tail_view(Rng &&)
0117             ->tail_view<views::all_t<Rng>>;
0118 #endif
0119 
0120     namespace views
0121     {
0122         struct tail_fn
0123         {
0124             template(typename Rng)(
0125                 requires viewable_range<Rng> AND input_range<Rng>)
0126             meta::if_c<range_cardinality<Rng>::value == 0,
0127                        all_t<Rng>,
0128                        tail_view<all_t<Rng>>> //
0129             operator()(Rng && rng) const
0130             {
0131                 return all(static_cast<Rng &&>(rng));
0132             }
0133         };
0134 
0135         /// \relates tail_fn
0136         /// \ingroup group-views
0137         RANGES_INLINE_VARIABLE(view_closure<tail_fn>, tail)
0138     } // namespace views
0139     /// @}
0140 } // namespace ranges
0141 
0142 #include <range/v3/detail/epilogue.hpp>
0143 #include <range/v3/detail/satisfy_boost_range.hpp>
0144 RANGES_SATISFY_BOOST_RANGE(::ranges::tail_view)
0145 
0146 #endif