1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
/// \file
// Range v3 library
//
// Copyright Filip Matzner 2017
//
// 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_EXPERIMENTAL_VIEW_SHARED_HPP
#define RANGES_V3_EXPERIMENTAL_VIEW_SHARED_HPP
#include <memory>
#include <type_traits>
#include <meta/meta.hpp>
#include <range/v3/functional/compose.hpp>
#include <range/v3/range/access.hpp>
#include <range/v3/range/concepts.hpp>
#include <range/v3/range/primitives.hpp>
#include <range/v3/view/all.hpp>
#include <range/v3/detail/prologue.hpp>
namespace ranges
{
/// \addtogroup group-views
/// @{
namespace experimental
{
template<typename Rng>
struct shared_view
: view_interface<shared_view<Rng>, range_cardinality<Rng>::value>
{
private:
// shared storage
std::shared_ptr<Rng> rng_ptr_;
public:
shared_view() = default;
// construct from a range rvalue
explicit shared_view(Rng rng)
: rng_ptr_{std::make_shared<Rng>(std::move(rng))}
{}
// use the stored range's begin and end
iterator_t<Rng> begin() const
{
return ranges::begin(*rng_ptr_);
}
sentinel_t<Rng> end() const
{
return ranges::end(*rng_ptr_);
}
CPP_auto_member
auto CPP_fun(size)()(const
requires sized_range<Rng>)
{
return ranges::size(*rng_ptr_);
}
};
template<typename SharedFn>
struct shared_closure;
struct RANGES_STRUCT_WITH_ADL_BARRIER(shared_closure_base)
{
// Piping requires viewable_ranges.
template(typename Rng, typename SharedFn)(
requires range<Rng> AND (!viewable_range<Rng>) AND
constructible_from<detail::decay_t<Rng>, Rng>)
friend constexpr auto operator|(Rng && rng, shared_closure<SharedFn> vw)
{
return static_cast<SharedFn &&>(vw)(static_cast<Rng &&>(rng));
}
template<typename SharedFn, typename Pipeable>
friend constexpr auto operator|(shared_closure<SharedFn> sh, Pipeable pipe)
-> CPP_broken_friend_ret(shared_closure<composed<Pipeable, SharedFn>>)(
requires (is_pipeable_v<Pipeable>))
{
return shared_closure<composed<Pipeable, SharedFn>>{compose(
static_cast<Pipeable &&>(pipe), static_cast<SharedFn &&>(sh))};
}
};
template<typename SharedFn>
struct shared_closure
: shared_closure_base
, SharedFn
{
shared_closure() = default;
constexpr explicit shared_closure(SharedFn fn)
: SharedFn(static_cast<SharedFn &&>(fn))
{}
};
namespace views
{
struct shared_fn
{
template(typename Rng)(
requires range<Rng> AND (!viewable_range<Rng>)AND
constructible_from<detail::decay_t<Rng>, Rng>)
shared_view<detail::decay_t<Rng>> operator()(Rng && rng) const
{
return shared_view<detail::decay_t<Rng>>{static_cast<Rng &&>(rng)};
}
};
/// \relates shared_fn
/// \ingroup group-views
RANGES_INLINE_VARIABLE(shared_closure<shared_fn>, shared)
} // namespace views
} // namespace experimental
template<typename SharedFn>
RANGES_INLINE_VAR constexpr bool
is_pipeable_v<experimental::shared_closure<SharedFn>> = true;
/// @}
} // namespace ranges
#include <range/v3/detail/epilogue.hpp>
#endif
|