File: shared.hpp

package info (click to toggle)
range-v3 0.12.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,652 kB
  • sloc: cpp: 76,839; xml: 226; sh: 89; python: 34; makefile: 19; perl: 15
file content (131 lines) | stat: -rw-r--r-- 4,043 bytes parent folder | download | duplicates (6)
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