File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/XS/librangeV3.x/i/range/v3/utility/invoke.hpp
Criterion Covered Total %
statement 14 14 100.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 14 14 100.0


line stmt bran cond sub pod time code
1             /// \file
2             // Range v3 library
3             //
4             // Copyright Eric Niebler 2013-present
5             // Copyright Casey Carter 2016
6             //
7             // Use, modification and distribution is subject to the
8             // Boost Software License, Version 1.0. (See accompanying
9             // file LICENSE_1_0.txt or copy at
10             // http://www.boost.org/LICENSE_1_0.txt)
11             //
12             // Project home: https://github.com/ericniebler/range-v3
13             //
14             #ifndef RANGES_V3_UTILITY_INVOKE_HPP
15             #define RANGES_V3_UTILITY_INVOKE_HPP
16              
17             #include
18             #include
19             #include
20             #include
21             #include
22             #include
23             #include
24             #include
25              
26             RANGES_DIAGNOSTIC_PUSH
27             RANGES_DIAGNOSTIC_IGNORE_CXX17_COMPAT
28              
29             namespace ranges
30             {
31             inline namespace v3
32             {
33             /// \addtogroup group-utility
34             /// @{
35             template
36             struct is_reference_wrapper
37             : meta::if_<
38             std::is_same, T>,
39             std::false_type,
40             is_reference_wrapper>>
41             {};
42              
43             template
44             struct is_reference_wrapper>
45             : std::true_type
46             {};
47              
48             template
49             struct is_reference_wrapper>
50             : std::true_type
51             {};
52              
53             template
54             using is_reference_wrapper_t = meta::_t>;
55              
56             struct invoke_fn
57             {
58             private:
59             template
60             static constexpr auto invoke_member_fn(
61             std::true_type, detail::any, MemberFunctionPtr fn, First && first, Rest &&... rest)
62             RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT
63             (
64             (static_cast(first).*fn)(static_cast(rest)...)
65             )
66             template
67             static constexpr auto invoke_member_fn(
68             std::false_type, std::true_type, MemberFunctionPtr fn, First && first, Rest &&... rest)
69             RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT
70             (
71             (static_cast(first).get().*fn)(static_cast(rest)...)
72             )
73             template
74             static constexpr auto invoke_member_fn(
75             std::false_type, std::false_type, MemberFunctionPtr fn, First && first, Rest &&... rest)
76             RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT
77             (
78             ((*static_cast(first)).*fn)(static_cast(rest)...)
79             )
80              
81             template
82             static constexpr auto invoke_member_data(
83             std::true_type, detail::any, MemberDataPtr ptr, First && first)
84             RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT
85             (
86             static_cast(first).*ptr
87             )
88             template
89             static constexpr auto invoke_member_data(
90             std::false_type, std::true_type, MemberDataPtr ptr, First && first)
91             RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT
92             (
93             static_cast(first).get().*ptr
94             )
95             template
96             static constexpr auto invoke_member_data(
97             std::false_type, std::false_type, MemberDataPtr ptr, First && first)
98             RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT
99             (
100             (*static_cast(first)).*ptr
101             )
102             public:
103             template
104             meta::if_c::value, int> = 0>
105             constexpr auto operator()(F Obj::*ptr, First && first, Rest &&... rest) const
106             RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT
107             (
108             invoke_member_fn(std::is_base_of>{},
109             is_reference_wrapper_t>{},
110             ptr, static_cast(first), static_cast(rest)...)
111             )
112             template
113             meta::if_c::value, int> = 0>
114             constexpr auto operator()(Data Obj::*ptr, First && first) const
115             RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT
116             (
117             invoke_member_data(std::is_base_of>{},
118             is_reference_wrapper_t>{},
119             ptr, static_cast(first))
120             )
121             template
122             meta::if_c>::value, int> = 0>
123 6726           constexpr auto operator()(F && fn, Args &&... args) const
124 6726           RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT
125             (
126             static_cast(fn)(static_cast(args)...)
127             )
128             };
129             RANGES_INLINE_VARIABLE(invoke_fn, invoke)
130              
131             /// \cond
132             namespace detail
133             {
134             template
135             struct reference_wrapper_
136             {
137             T *t_ = nullptr;
138             constexpr reference_wrapper_() = default;
139 638           constexpr reference_wrapper_(T &t) noexcept
140 638           : t_(std::addressof(t))
141 638           {}
142             constexpr reference_wrapper_(T &&) = delete;
143 154           constexpr T &get() const noexcept
144             {
145 154           return *t_;
146             }
147             };
148             template
149             struct reference_wrapper_ : reference_wrapper_
150             {
151             using reference_wrapper_::reference_wrapper_;
152             };
153             template
154             struct reference_wrapper_
155             {
156             T *t_ = nullptr;
157             constexpr reference_wrapper_() = default;
158             constexpr reference_wrapper_(T &&t) noexcept
159             : t_(std::addressof(t))
160             {}
161             constexpr T &&get() const noexcept
162             {
163             return static_cast(*t_);
164             }
165             };
166             }
167             /// \endcond
168              
169             // Can be used to store rvalue references in addition to lvalue references.
170             // Also, see: https://wg21.link/lwg2993
171             template
172             struct reference_wrapper : private detail::reference_wrapper_
173             {
174             private:
175             using base_ = detail::reference_wrapper_;
176             public:
177             using type = meta::_t>;
178             using reference = meta::if_, T, T &>;
179              
180             constexpr reference_wrapper() = default;
181             template
182             CONCEPT_REQUIRES_(Constructible() &&
183             !Same, reference_wrapper>())>
184 638           constexpr reference_wrapper(U &&u)
185             noexcept(std::is_nothrow_constructible::value)
186 638           : detail::reference_wrapper_{static_cast(u)}
187 638           {}
188 154           constexpr reference get() const noexcept
189             {
190 154           return this->base_::get();
191             }
192             constexpr operator reference() const noexcept
193             {
194             return get();
195             }
196             CONCEPT_REQUIRES(!std::is_rvalue_reference::value)
197             operator std::reference_wrapper () const noexcept
198             {
199             return {get()};
200             }
201             template
202 154           constexpr auto operator()(Args &&...args) const
203             RANGES_DECLTYPE_NOEXCEPT(
204             invoke(std::declval(), std::declval()...))
205             {
206 154           return invoke(get(), static_cast(args)...);
207             }
208             };
209              
210             #ifdef RANGES_WORKAROUND_MSVC_701385
211             /// \cond
212             namespace detail
213             {
214             template
215             struct _invoke_result_
216             {};
217              
218             template
219             struct _invoke_result_<
220             meta::void_(), std::declval()...))>,
221             Fun, Args...>
222             {
223             using type = decltype(invoke(std::declval(), std::declval()...));
224             };
225             }
226             /// \endcond
227              
228             template
229             using invoke_result = detail::_invoke_result_;
230              
231             template
232             using invoke_result_t = meta::_t>;
233             #else // RANGES_WORKAROUND_MSVC_701385
234             template
235             using invoke_result_t =
236             decltype(invoke(std::declval(), std::declval()...));
237              
238             template
239             struct invoke_result
240             : meta::defer
241             {};
242             #endif // RANGES_WORKAROUND_MSVC_701385
243              
244             template
245             struct result_of
246             {};
247              
248             template
249             struct result_of
250             : meta::defer
251             {};
252             } // namespace v3
253             } // namespace ranges
254              
255             RANGES_DIAGNOSTIC_POP
256              
257             #endif // RANGES_V3_UTILITY_INVOKE_HPP