/// \file // Range v3 library // // Copyright Eric Niebler 2014-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_REVERSE_HPP #define RANGES_V3_VIEW_REVERSE_HPP #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 reverse_view : view_interface, range_cardinality::value> , private detail::non_propagating_cache, reverse_view, !common_range> { private: CPP_assert(bidirectional_range); Rng rng_; constexpr reverse_iterator> begin_(std::true_type) { return make_reverse_iterator(ranges::end(rng_)); } constexpr reverse_iterator> begin_(std::false_type) { using cache_t = detail::non_propagating_cache, reverse_view>; auto & end_ = static_cast(*this); if(!end_) end_ = ranges::next(ranges::begin(rng_), ranges::end(rng_)); return make_reverse_iterator(*end_); } public: reverse_view() = default; explicit constexpr reverse_view(Rng rng) : rng_(detail::move(rng)) {} Rng base() const { return rng_; } constexpr reverse_iterator> begin() { return begin_(meta::bool_<(bool)common_range>{}); } template constexpr auto begin() const -> CPP_ret(reverse_iterator>>)( // requires Const && common_range>) { return make_reverse_iterator(ranges::end(rng_)); } constexpr reverse_iterator> end() { return make_reverse_iterator(ranges::begin(rng_)); } template constexpr auto end() const -> CPP_ret(reverse_iterator>>)( // requires Const && common_range>) { return make_reverse_iterator(ranges::begin(rng_)); } CPP_member constexpr auto CPP_fun(size)()(requires sized_range) { return ranges::size(rng_); } CPP_member constexpr auto CPP_fun(size)()(const requires sized_range) { return ranges::size(rng_); } }; template struct reverse_view> : Rng { CPP_assert(bidirectional_range); CPP_assert( same_as>().base())>, Rng>); reverse_view() = default; explicit constexpr reverse_view(reverse_view rng) : Rng(rng.base()) {} constexpr reverse_view base() const { return reverse_view{*this}; } }; #if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17 template reverse_view(Rng &&)->reverse_view>; template reverse_view(reverse_view)->reverse_view>; #endif namespace views { struct reverse_fn { template constexpr auto operator()(Rng && rng) const -> CPP_ret(reverse_view>)( // requires viewable_range && bidirectional_range) { return reverse_view>{all(static_cast(rng))}; } }; /// \relates reverse_fn /// \ingroup group-views RANGES_INLINE_VARIABLE(view, reverse) } // namespace views namespace cpp20 { namespace views { using ranges::views::reverse; } CPP_template(typename Rng)( // requires view_ && bidirectional_range) // using reverse_view = ranges::reverse_view; } // namespace cpp20 /// @} } // namespace ranges #include RANGES_SATISFY_BOOST_RANGE(::ranges::reverse_view) #endif