]>
git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/nostd/internal/absl/base/internal/invoke.h
1 // Copyright 2017 The Abseil Authors.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // https://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 // absl::base_internal::Invoke(f, args...) is an implementation of
16 // INVOKE(f, args...) from section [func.require] of the C++ standard.
19 // Define INVOKE (f, t1, t2, ..., tN) as follows:
20 // 1. (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T
21 // and t1 is an object of type T or a reference to an object of type T or a
22 // reference to an object of a type derived from T;
23 // 2. ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a
24 // class T and t1 is not one of the types described in the previous item;
25 // 3. t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is
26 // an object of type T or a reference to an object of type T or a reference
27 // to an object of a type derived from T;
28 // 4. (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1
29 // is not one of the types described in the previous item;
30 // 5. f(t1, t2, ..., tN) in all other cases.
32 // The implementation is SFINAE-friendly: substitution failure within Invoke()
35 #ifndef OTABSL_BASE_INTERNAL_INVOKE_H_
36 #define OTABSL_BASE_INTERNAL_INVOKE_H_
39 #include <type_traits>
42 #include "../../meta/type_traits.h"
44 // The following code is internal implementation detail. See the comment at the
45 // top of this file for the API documentation.
48 OTABSL_NAMESPACE_BEGIN
49 namespace base_internal
{
51 // The five classes below each implement one of the clauses from the definition
52 // of INVOKE. The inner class template Accept<F, Args...> checks whether the
53 // clause is applicable; static function template Invoke(f, args...) does the
56 // By separating the clause selection logic from invocation we make sure that
57 // Invoke() does exactly what the standard says.
59 template <typename Derived
>
60 struct StrippedAccept
{
61 template <typename
... Args
>
62 struct Accept
: Derived::template AcceptImpl
<typename
std::remove_cv
<
63 typename
std::remove_reference
<Args
>::type
>::type
...> {};
66 // (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T
67 // and t1 is an object of type T or a reference to an object of type T or a
68 // reference to an object of a type derived from T.
69 struct MemFunAndRef
: StrippedAccept
<MemFunAndRef
> {
70 template <typename
... Args
>
71 struct AcceptImpl
: std::false_type
{};
73 template <typename MemFunType
, typename C
, typename Obj
, typename
... Args
>
74 struct AcceptImpl
<MemFunType
C::*, Obj
, Args
...>
75 : std::integral_constant
<bool, std::is_base_of
<C
, Obj
>::value
&&
76 absl::is_function
<MemFunType
>::value
> {
79 template <typename MemFun
, typename Obj
, typename
... Args
>
80 static decltype((std::declval
<Obj
>().*
81 std::declval
<MemFun
>())(std::declval
<Args
>()...))
82 Invoke(MemFun
&& mem_fun
, Obj
&& obj
, Args
&&... args
) {
83 return (std::forward
<Obj
>(obj
).*
84 std::forward
<MemFun
>(mem_fun
))(std::forward
<Args
>(args
)...);
88 // ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a
89 // class T and t1 is not one of the types described in the previous item.
90 struct MemFunAndPtr
: StrippedAccept
<MemFunAndPtr
> {
91 template <typename
... Args
>
92 struct AcceptImpl
: std::false_type
{};
94 template <typename MemFunType
, typename C
, typename Ptr
, typename
... Args
>
95 struct AcceptImpl
<MemFunType
C::*, Ptr
, Args
...>
96 : std::integral_constant
<bool, !std::is_base_of
<C
, Ptr
>::value
&&
97 absl::is_function
<MemFunType
>::value
> {
100 template <typename MemFun
, typename Ptr
, typename
... Args
>
101 static decltype(((*std::declval
<Ptr
>()).*
102 std::declval
<MemFun
>())(std::declval
<Args
>()...))
103 Invoke(MemFun
&& mem_fun
, Ptr
&& ptr
, Args
&&... args
) {
104 return ((*std::forward
<Ptr
>(ptr
)).*
105 std::forward
<MemFun
>(mem_fun
))(std::forward
<Args
>(args
)...);
109 // t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is
110 // an object of type T or a reference to an object of type T or a reference
111 // to an object of a type derived from T.
112 struct DataMemAndRef
: StrippedAccept
<DataMemAndRef
> {
113 template <typename
... Args
>
114 struct AcceptImpl
: std::false_type
{};
116 template <typename R
, typename C
, typename Obj
>
117 struct AcceptImpl
<R
C::*, Obj
>
118 : std::integral_constant
<bool, std::is_base_of
<C
, Obj
>::value
&&
119 !absl::is_function
<R
>::value
> {};
121 template <typename DataMem
, typename Ref
>
122 static decltype(std::declval
<Ref
>().*std::declval
<DataMem
>()) Invoke(
123 DataMem
&& data_mem
, Ref
&& ref
) {
124 return std::forward
<Ref
>(ref
).*std::forward
<DataMem
>(data_mem
);
128 // (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1
129 // is not one of the types described in the previous item.
130 struct DataMemAndPtr
: StrippedAccept
<DataMemAndPtr
> {
131 template <typename
... Args
>
132 struct AcceptImpl
: std::false_type
{};
134 template <typename R
, typename C
, typename Ptr
>
135 struct AcceptImpl
<R
C::*, Ptr
>
136 : std::integral_constant
<bool, !std::is_base_of
<C
, Ptr
>::value
&&
137 !absl::is_function
<R
>::value
> {};
139 template <typename DataMem
, typename Ptr
>
140 static decltype((*std::declval
<Ptr
>()).*std::declval
<DataMem
>()) Invoke(
141 DataMem
&& data_mem
, Ptr
&& ptr
) {
142 return (*std::forward
<Ptr
>(ptr
)).*std::forward
<DataMem
>(data_mem
);
146 // f(t1, t2, ..., tN) in all other cases.
148 // Callable doesn't have Accept because it's the last clause that gets picked
149 // when none of the previous clauses are applicable.
150 template <typename F
, typename
... Args
>
151 static decltype(std::declval
<F
>()(std::declval
<Args
>()...)) Invoke(
152 F
&& f
, Args
&&... args
) {
153 return std::forward
<F
>(f
)(std::forward
<Args
>(args
)...);
157 // Resolves to the first matching clause.
158 template <typename
... Args
>
160 typedef typename
std::conditional
<
161 MemFunAndRef::Accept
<Args
...>::value
, MemFunAndRef
,
162 typename
std::conditional
<
163 MemFunAndPtr::Accept
<Args
...>::value
, MemFunAndPtr
,
164 typename
std::conditional
<
165 DataMemAndRef::Accept
<Args
...>::value
, DataMemAndRef
,
166 typename
std::conditional
<DataMemAndPtr::Accept
<Args
...>::value
,
167 DataMemAndPtr
, Callable
>::type
>::type
>::
171 // The result type of Invoke<F, Args...>.
172 template <typename F
, typename
... Args
>
173 using InvokeT
= decltype(Invoker
<F
, Args
...>::type::Invoke(
174 std::declval
<F
>(), std::declval
<Args
>()...));
176 // Invoke(f, args...) is an implementation of INVOKE(f, args...) from section
177 // [func.require] of the C++ standard.
178 template <typename F
, typename
... Args
>
179 InvokeT
<F
, Args
...> Invoke(F
&& f
, Args
&&... args
) {
180 return Invoker
<F
, Args
...>::type::Invoke(std::forward
<F
>(f
),
181 std::forward
<Args
>(args
)...);
184 } // namespace base_internal
188 #endif // OTABSL_BASE_INTERNAL_INVOKE_H_