File indexing completed on 2025-01-18 10:09:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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 }
0044
0045
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
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
0136
0137 RANGES_INLINE_VARIABLE(view_closure<tail_fn>, tail)
0138 }
0139
0140 }
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