/// \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_TAKE_EXACTLY_HPP #define RANGES_V3_VIEW_TAKE_EXACTLY_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ranges { /// \cond namespace detail { template struct is_random_access_common_ : meta::bool_<(bool)random_access_range && (bool)common_range> {}; // BUGBUG Per the discussion in https://github.com/ericniebler/stl2/issues/63, // it's unclear if we can infer anything from random_access_range && // common_range template::value*/> struct take_exactly_view_ : view_interface, finite> { private: Rng rng_; range_difference_t n_; public: take_exactly_view_() = default; take_exactly_view_(Rng rng, range_difference_t n) : rng_(std::move(rng)) , n_(n) { RANGES_EXPECT(n >= 0); } counted_iterator> begin() { return {ranges::begin(rng_), n_}; } template(typename BaseRng = Rng)( requires range) counted_iterator> begin() const { return {ranges::begin(rng_), n_}; } default_sentinel_t end() const { return {}; } auto size() const { return static_cast>>(n_); } Rng base() const { return rng_; } }; template struct take_exactly_view_ : view_interface, finite> { private: Rng rng_; range_difference_t n_; public: take_exactly_view_() = default; take_exactly_view_(Rng rng, range_difference_t n) : rng_(std::move(rng)) , n_(n) { RANGES_EXPECT(n >= 0); RANGES_EXPECT(!(bool)sized_range || n <= ranges::distance(rng_)); } iterator_t begin() { return ranges::begin(rng_); } iterator_t end() { return ranges::begin(rng_) + n_; } CPP_auto_member auto CPP_fun(begin)()(const // requires range) { return ranges::begin(rng_); } CPP_auto_member auto CPP_fun(end)()(const // requires range) { return ranges::begin(rng_) + n_; } detail::iter_size_t> size() const { return static_cast>>(n_); } Rng base() const { return rng_; } }; } // namespace detail /// \endcond /// \addtogroup group-views /// @{ template using take_exactly_view = detail::take_exactly_view_; template RANGES_INLINE_VAR constexpr bool // enable_borrowed_range> = // enable_borrowed_range; namespace views { struct take_exactly_base_fn { private: template static constexpr take_exactly_view> impl_( Rng && rng, range_difference_t n, input_range_tag) { return {all(static_cast(rng)), n}; } template(typename Rng)( requires borrowed_range) static constexpr subrange> impl_(Rng && rng, range_difference_t n, random_access_range_tag) { return {begin(rng), next(begin(rng), n)}; } public: template(typename Rng)( requires viewable_range AND input_range) constexpr auto operator()(Rng && rng, range_difference_t n) const { return take_exactly_base_fn::impl_( static_cast(rng), n, range_tag_of{}); } }; struct take_exactly_fn : take_exactly_base_fn { using take_exactly_base_fn::operator(); template(typename Int)( requires detail::integer_like_) constexpr auto operator()(Int n) const { return make_view_closure(bind_back(take_exactly_base_fn{}, n)); } }; /// \relates take_exactly_fn /// \ingroup group-views RANGES_INLINE_VARIABLE(take_exactly_fn, take_exactly) } // namespace views /// @} } // namespace ranges #include #include RANGES_SATISFY_BOOST_RANGE(::ranges::detail::take_exactly_view_) #endif