/// \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 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 auto begin() const -> CPP_ret(counted_iterator>)( // requires range) { 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_member auto CPP_fun(begin)()(const requires range) { return ranges::begin(rng_); } CPP_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_; namespace views { struct take_exactly_fn { private: friend view_access; template static constexpr auto CPP_fun(bind)(take_exactly_fn take_exactly, Int n)( // requires integral) { return make_pipeable(bind_back(take_exactly, n)); } template static constexpr take_exactly_view> impl_( Rng && rng, range_difference_t n, input_range_tag) { return {all(static_cast(rng)), n}; } template static constexpr auto impl_(Rng && rng, range_difference_t n, random_access_range_tag) -> CPP_ret(subrange>)( // requires forwarding_range_) { return {begin(rng), next(begin(rng), n)}; } public: template constexpr auto CPP_fun(operator())(Rng && rng, range_difference_t n)( const requires viewable_range && input_range) { return take_exactly_fn::impl_( static_cast(rng), n, range_tag_of{}); } }; /// \relates take_exactly_fn /// \ingroup group-views RANGES_INLINE_VARIABLE(view, take_exactly) } // namespace views /// @} } // namespace ranges #include RANGES_SATISFY_BOOST_RANGE(::ranges::detail::take_exactly_view_) #endif