/// \file // Range v3 library // // Copyright Eric Niebler 2013-present // // Use, modification and distribution is subject to the // Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Project home: https://github.com/ericniebler/range-v3 // #ifndef RANGES_V3_VIEW_DROP_HPP #define RANGES_V3_VIEW_DROP_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ranges { /// \addtogroup group-views /// @{ template struct RANGES_EMPTY_BASES drop_view : view_interface, is_finite::value ? finite : range_cardinality::value> , private detail::non_propagating_cache, drop_view, !random_access_range> { private: using difference_type_ = range_difference_t; Rng rng_; difference_type_ n_; template(bool Const = true)( requires Const AND range>) iterator_t> // get_begin_(std::true_type, std::true_type) const { CPP_assert(random_access_range>); return next(ranges::begin(rng_), n_, ranges::end(rng_)); } iterator_t get_begin_(std::true_type, std::false_type) { CPP_assert(random_access_range); return next(ranges::begin(rng_), n_, ranges::end(rng_)); } iterator_t get_begin_(std::false_type, detail::ignore_t) { CPP_assert(!random_access_range); using cache_t = detail::non_propagating_cache, drop_view>; auto & begin_ = static_cast(*this); if(!begin_) begin_ = next(ranges::begin(rng_), n_, ranges::end(rng_)); return *begin_; } public: drop_view() = default; drop_view(Rng rng, difference_type_ n) : rng_(std::move(rng)) , n_(n) { RANGES_EXPECT(n >= 0); } iterator_t begin() { return this->get_begin_(meta::bool_>{}, std::false_type{}); } sentinel_t end() { return ranges::end(rng_); } template(bool Const = true)( requires Const AND random_access_range>) iterator_t> begin() const { return this->get_begin_(std::true_type{}, std::true_type{}); } template(bool Const = true)( requires Const AND random_access_range>) sentinel_t> end() const { return ranges::end(rng_); } CPP_auto_member auto CPP_fun(size)()(const // requires sized_range) { auto const s = ranges::size(rng_); auto const n = static_cast>(n_); return s < n ? 0 : s - n; } CPP_auto_member auto CPP_fun(size)()( requires sized_range) { auto const s = ranges::size(rng_); auto const n = static_cast>(n_); return s < n ? 0 : s - n; } Rng base() const { return rng_; } }; template RANGES_INLINE_VAR constexpr bool enable_borrowed_range> = // enable_borrowed_range; #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17 template drop_view(Rng &&, range_difference_t) -> drop_view>; #endif namespace views { struct drop_base_fn { private: template static auto impl_(Rng && rng, range_difference_t n, input_range_tag) -> drop_view> { return {all(static_cast(rng)), n}; } template(typename Rng)( requires borrowed_range AND sized_range) static subrange, sentinel_t> // impl_(Rng && rng, range_difference_t n, random_access_range_tag) { return {begin(rng) + ranges::min(n, distance(rng)), end(rng)}; } public: template(typename Rng)( requires viewable_range AND input_range) auto operator()(Rng && rng, range_difference_t n) const { return drop_base_fn::impl_( static_cast(rng), n, range_tag_of{}); } }; struct drop_fn : drop_base_fn { using drop_base_fn::operator(); template(typename Int)( requires detail::integer_like_) constexpr auto operator()(Int n) const { return make_view_closure(bind_back(drop_base_fn{}, n)); } }; /// \relates drop_fn /// \ingroup group-views RANGES_INLINE_VARIABLE(drop_fn, drop) } // namespace views namespace cpp20 { namespace views { using ranges::views::drop; } template(typename Rng)( requires view_) using drop_view = ranges::drop_view; } // namespace cpp20 /// @} } // namespace ranges #include #include RANGES_SATISFY_BOOST_RANGE(::ranges::drop_view) #endif