xref: /aosp_15_r20/external/abseil-cpp/absl/functional/any_invocable_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1 // Copyright 2022 The Abseil Authors.
2 //
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
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
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.
14 
15 #include "absl/functional/any_invocable.h"
16 
17 #include <cstddef>
18 #include <initializer_list>
19 #include <memory>
20 #include <numeric>
21 #include <type_traits>
22 
23 #include "gtest/gtest.h"
24 #include "absl/base/config.h"
25 #include "absl/meta/type_traits.h"
26 #include "absl/utility/utility.h"
27 
28 static_assert(absl::internal_any_invocable::kStorageSize >= sizeof(void*),
29               "These tests assume that the small object storage is at least "
30               "the size of a pointer.");
31 
32 namespace {
33 
34 // Helper macro used to avoid spelling `noexcept` in language versions older
35 // than C++17, where it is not part of the type system, in order to avoid
36 // compilation failures and internal compiler errors.
37 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
38 #define ABSL_INTERNAL_NOEXCEPT_SPEC(noex) noexcept(noex)
39 #else
40 #define ABSL_INTERNAL_NOEXCEPT_SPEC(noex)
41 #endif
42 
43 // A dummy type we use when passing qualifiers to metafunctions
44 struct _ {};
45 
46 template <class T>
47 struct Wrapper {
48   template <class U,
49             class = absl::enable_if_t<std::is_convertible<U, T>::value>>
50   Wrapper(U&&);  // NOLINT
51 };
52 
53 // This will cause a recursive trait instantiation if the SFINAE checks are
54 // not ordered correctly for constructibility.
55 static_assert(std::is_constructible<Wrapper<absl::AnyInvocable<void()>>,
56                                     Wrapper<absl::AnyInvocable<void()>>>::value,
57               "");
58 
59 // A metafunction that takes the cv and l-value reference qualifiers that were
60 // associated with a function type (here passed via qualifiers of an object
61 // type), and .
62 template <class Qualifiers, class This>
63 struct QualifiersForThisImpl {
64   static_assert(std::is_object<This>::value, "");
65   using type =
66       absl::conditional_t<std::is_const<Qualifiers>::value, const This, This>&;
67 };
68 
69 template <class Qualifiers, class This>
70 struct QualifiersForThisImpl<Qualifiers&, This>
71     : QualifiersForThisImpl<Qualifiers, This> {};
72 
73 template <class Qualifiers, class This>
74 struct QualifiersForThisImpl<Qualifiers&&, This> {
75   static_assert(std::is_object<This>::value, "");
76   using type =
77       absl::conditional_t<std::is_const<Qualifiers>::value, const This, This>&&;
78 };
79 
80 template <class Qualifiers, class This>
81 using QualifiersForThis =
82     typename QualifiersForThisImpl<Qualifiers, This>::type;
83 
84 // A metafunction that takes the cv and l-value reference qualifier of T and
85 // applies them to U's function type qualifiers.
86 template <class T, class Fun>
87 struct GiveQualifiersToFunImpl;
88 
89 template <class T, class R, class... P>
90 struct GiveQualifiersToFunImpl<T, R(P...)> {
91   using type =
92       absl::conditional_t<std::is_const<T>::value, R(P...) const, R(P...)>;
93 };
94 
95 template <class T, class R, class... P>
96 struct GiveQualifiersToFunImpl<T&, R(P...)> {
97   using type =
98       absl::conditional_t<std::is_const<T>::value, R(P...) const&, R(P...)&>;
99 };
100 
101 template <class T, class R, class... P>
102 struct GiveQualifiersToFunImpl<T&&, R(P...)> {
103   using type =
104       absl::conditional_t<std::is_const<T>::value, R(P...) const&&, R(P...) &&>;
105 };
106 
107 // If noexcept is a part of the type system, then provide the noexcept forms.
108 #if defined(__cpp_noexcept_function_type)
109 
110 template <class T, class R, class... P>
111 struct GiveQualifiersToFunImpl<T, R(P...) noexcept> {
112   using type = absl::conditional_t<std::is_const<T>::value,
113                                    R(P...) const noexcept, R(P...) noexcept>;
114 };
115 
116 template <class T, class R, class... P>
117 struct GiveQualifiersToFunImpl<T&, R(P...) noexcept> {
118   using type =
119       absl::conditional_t<std::is_const<T>::value, R(P...) const & noexcept,
120                           R(P...) & noexcept>;
121 };
122 
123 template <class T, class R, class... P>
124 struct GiveQualifiersToFunImpl<T&&, R(P...) noexcept> {
125   using type =
126       absl::conditional_t<std::is_const<T>::value, R(P...) const && noexcept,
127                           R(P...) && noexcept>;
128 };
129 
130 #endif  // defined(__cpp_noexcept_function_type)
131 
132 template <class T, class Fun>
133 using GiveQualifiersToFun = typename GiveQualifiersToFunImpl<T, Fun>::type;
134 
135 // This is used in template parameters to decide whether or not to use a type
136 // that fits in the small object optimization storage.
137 enum class ObjSize { small, large };
138 
139 // A base type that is used with classes as a means to insert an
140 // appropriately-sized dummy datamember when Size is ObjSize::large so that the
141 // user's class type is guaranteed to not fit in small object storage.
142 template <ObjSize Size>
143 struct TypeErasedPadding;
144 
145 template <>
146 struct TypeErasedPadding<ObjSize::small> {};
147 
148 template <>
149 struct TypeErasedPadding<ObjSize::large> {
150   char dummy_data[absl::internal_any_invocable::kStorageSize + 1] = {};
151 };
152 
153 struct Int {
Int__anon5a17cb360111::Int154   Int(int v) noexcept : value(v) {}  // NOLINT
155 #ifndef _MSC_VER
Int__anon5a17cb360111::Int156   Int(Int&&) noexcept {
157     // NOTE: Prior to C++17, this not being called requires optimizations to
158     //       take place when performing the top-level invocation. In practice,
159     //       most supported compilers perform this optimization prior to C++17.
160     std::abort();
161   }
162 #else
163   Int(Int&& v) noexcept = default;
164 #endif
operator int__anon5a17cb360111::Int165   operator int() && noexcept { return value; }  // NOLINT
166 
MemberFunctionAdd__anon5a17cb360111::Int167   int MemberFunctionAdd(int const& b, int c) noexcept {  // NOLINT
168     return value + b + c;
169   }
170 
171   int value;
172 };
173 
174 enum class Movable { no, yes, nothrow, trivial };
175 
176 enum class NothrowCall { no, yes };
177 
178 enum class Destructible { nothrow, trivial };
179 
180 enum class ObjAlign : std::size_t {
181   normal = absl::internal_any_invocable::kAlignment,
182   large = absl::internal_any_invocable::kAlignment * 2,
183 };
184 
185 // A function-object template that has knobs for each property that can affect
186 // how the object is stored in AnyInvocable.
187 template <Movable Movability, Destructible Destructibility, class Qual,
188           NothrowCall CallExceptionSpec, ObjSize Size, ObjAlign Alignment>
189 struct add;
190 
191 #define ABSL_INTERNALS_ADD(qual)                                              \
192   template <NothrowCall CallExceptionSpec, ObjSize Size, ObjAlign Alignment>  \
193   struct alignas(static_cast<std::size_t>(Alignment))                         \
194       add<Movable::trivial, Destructible::trivial, _ qual, CallExceptionSpec, \
195           Size, Alignment> : TypeErasedPadding<Size> {                        \
196     explicit add(int state_init) : state(state_init) {}                       \
197     explicit add(std::initializer_list<int> state_init, int tail)             \
198         : state(std::accumulate(std::begin(state_init), std::end(state_init), \
199                                 0) +                                          \
200                 tail) {}                                                      \
201     add(add&& other) = default; /*NOLINT*/                                    \
202     Int operator()(int a, int b, int c) qual                                  \
203         ABSL_INTERNAL_NOEXCEPT_SPEC(CallExceptionSpec == NothrowCall::yes) {  \
204       return state + a + b + c;                                               \
205     }                                                                         \
206     int state;                                                                \
207   };                                                                          \
208                                                                               \
209   template <NothrowCall CallExceptionSpec, ObjSize Size, ObjAlign Alignment>  \
210   struct alignas(static_cast<std::size_t>(Alignment))                         \
211       add<Movable::trivial, Destructible::nothrow, _ qual, CallExceptionSpec, \
212           Size, Alignment> : TypeErasedPadding<Size> {                        \
213     explicit add(int state_init) : state(state_init) {}                       \
214     explicit add(std::initializer_list<int> state_init, int tail)             \
215         : state(std::accumulate(std::begin(state_init), std::end(state_init), \
216                                 0) +                                          \
217                 tail) {}                                                      \
218     ~add() noexcept {}                                                        \
219     add(add&& other) = default; /*NOLINT*/                                    \
220     Int operator()(int a, int b, int c) qual                                  \
221         ABSL_INTERNAL_NOEXCEPT_SPEC(CallExceptionSpec == NothrowCall::yes) {  \
222       return state + a + b + c;                                               \
223     }                                                                         \
224     int state;                                                                \
225   }
226 
227 // Explicitly specify an empty argument.
228 // MSVC (at least up to _MSC_VER 1931, if not beyond) warns that
229 // ABSL_INTERNALS_ADD() is an undefined zero-arg overload.
230 #define ABSL_INTERNALS_NOARG
231 ABSL_INTERNALS_ADD(ABSL_INTERNALS_NOARG);
232 #undef ABSL_INTERNALS_NOARG
233 
234 ABSL_INTERNALS_ADD(const);
235 ABSL_INTERNALS_ADD(&);
236 ABSL_INTERNALS_ADD(const&);
237 ABSL_INTERNALS_ADD(&&);       // NOLINT
238 ABSL_INTERNALS_ADD(const&&);  // NOLINT
239 
240 #undef ABSL_INTERNALS_ADD
241 
242 template <Destructible Destructibility, class Qual,
243           NothrowCall CallExceptionSpec, ObjSize Size, ObjAlign Alignment>
244 struct add<Movable::no, Destructibility, Qual, CallExceptionSpec, Size,
245            Alignment> : private add<Movable::trivial, Destructibility, Qual,
246                                     CallExceptionSpec, Size, Alignment> {
247   using Base = add<Movable::trivial, Destructibility, Qual, CallExceptionSpec,
248                    Size, Alignment>;
249 
add__anon5a17cb360111::add250   explicit add(int state_init) : Base(state_init) {}
251 
add__anon5a17cb360111::add252   explicit add(std::initializer_list<int> state_init, int tail)
253       : Base(state_init, tail) {}
254 
255   add(add&&) = delete;
256 
257   using Base::operator();
258   using Base::state;
259 };
260 
261 template <Destructible Destructibility, class Qual,
262           NothrowCall CallExceptionSpec, ObjSize Size, ObjAlign Alignment>
263 struct add<Movable::yes, Destructibility, Qual, CallExceptionSpec, Size,
264            Alignment> : private add<Movable::trivial, Destructibility, Qual,
265                                     CallExceptionSpec, Size, Alignment> {
266   using Base = add<Movable::trivial, Destructibility, Qual, CallExceptionSpec,
267                    Size, Alignment>;
268 
add__anon5a17cb360111::add269   explicit add(int state_init) : Base(state_init) {}
270 
add__anon5a17cb360111::add271   explicit add(std::initializer_list<int> state_init, int tail)
272       : Base(state_init, tail) {}
273 
add__anon5a17cb360111::add274   add(add&& other) noexcept(false) : Base(other.state) {}  // NOLINT
275 
276   using Base::operator();
277   using Base::state;
278 };
279 
280 template <Destructible Destructibility, class Qual,
281           NothrowCall CallExceptionSpec, ObjSize Size, ObjAlign Alignment>
282 struct add<Movable::nothrow, Destructibility, Qual, CallExceptionSpec, Size,
283            Alignment> : private add<Movable::trivial, Destructibility, Qual,
284                                     CallExceptionSpec, Size, Alignment> {
285   using Base = add<Movable::trivial, Destructibility, Qual, CallExceptionSpec,
286                    Size, Alignment>;
287 
add__anon5a17cb360111::add288   explicit add(int state_init) : Base(state_init) {}
289 
add__anon5a17cb360111::add290   explicit add(std::initializer_list<int> state_init, int tail)
291       : Base(state_init, tail) {}
292 
add__anon5a17cb360111::add293   add(add&& other) noexcept : Base(other.state) {}
294 
295   using Base::operator();
296   using Base::state;
297 };
298 
299 // Actual non-member functions rather than function objects
add_function(Int && a,int b,int c)300 Int add_function(Int&& a, int b, int c) noexcept { return a.value + b + c; }
301 
mult_function(Int && a,int b,int c)302 Int mult_function(Int&& a, int b, int c) noexcept { return a.value * b * c; }
303 
square_function(Int const && a)304 Int square_function(Int const&& a) noexcept { return a.value * a.value; }
305 
306 template <class Sig>
307 using AnyInvocable = absl::AnyInvocable<Sig>;
308 
309 // Instantiations of this template contains all of the compile-time parameters
310 // for a given instantiation of the AnyInvocable test suite.
311 template <Movable Movability, Destructible Destructibility, class Qual,
312           NothrowCall CallExceptionSpec, ObjSize Size, ObjAlign Alignment>
313 struct TestParams {
314   static constexpr Movable kMovability = Movability;
315   static constexpr Destructible kDestructibility = Destructibility;
316   using Qualifiers = Qual;
317   static constexpr NothrowCall kCallExceptionSpec = CallExceptionSpec;
318   static constexpr bool kIsNoexcept = kCallExceptionSpec == NothrowCall::yes;
319   static constexpr bool kIsRvalueQualified =
320       std::is_rvalue_reference<Qual>::value;
321   static constexpr ObjSize kSize = Size;
322   static constexpr ObjAlign kAlignment = Alignment;
323 
324   // These types are used when testing with member object pointer Invocables
325   using UnqualifiedUnaryFunType = int(Int const&&)
326       ABSL_INTERNAL_NOEXCEPT_SPEC(CallExceptionSpec == NothrowCall::yes);
327   using UnaryFunType = GiveQualifiersToFun<Qualifiers, UnqualifiedUnaryFunType>;
328   using MemObjPtrType = int(Int::*);
329   using UnaryAnyInvType = AnyInvocable<UnaryFunType>;
330   using UnaryThisParamType = QualifiersForThis<Qualifiers, UnaryAnyInvType>;
331 
332   template <class T>
ToUnaryThisParam__anon5a17cb360111::TestParams333   static UnaryThisParamType ToUnaryThisParam(T&& fun) {
334     return static_cast<UnaryThisParamType>(fun);
335   }
336 
337   // This function type intentionally uses 3 "kinds" of parameter types.
338   //     - A user-defined type
339   //     - A reference type
340   //     - A scalar type
341   //
342   // These were chosen because internal forwarding takes place on parameters
343   // differently depending based on type properties (scalars are forwarded by
344   // value).
345   using ResultType = Int;
346   using AnyInvocableFunTypeNotNoexcept = Int(Int, const int&, int);
347   using UnqualifiedFunType =
348       typename std::conditional<kIsNoexcept, Int(Int, const int&, int) noexcept,
349                                 Int(Int, const int&, int)>::type;
350   using FunType = GiveQualifiersToFun<Qualifiers, UnqualifiedFunType>;
351   using MemFunPtrType =
352       typename std::conditional<kIsNoexcept,
353                                 Int (Int::*)(const int&, int) noexcept,
354                                 Int (Int::*)(const int&, int)>::type;
355   using AnyInvType = AnyInvocable<FunType>;
356   using AddType = add<kMovability, kDestructibility, Qualifiers,
357                       kCallExceptionSpec, kSize, kAlignment>;
358   using ThisParamType = QualifiersForThis<Qualifiers, AnyInvType>;
359 
360   template <class T>
ToThisParam__anon5a17cb360111::TestParams361   static ThisParamType ToThisParam(T&& fun) {
362     return static_cast<ThisParamType>(fun);
363   }
364 
365   // These typedefs are used when testing void return type covariance.
366   using UnqualifiedVoidFunType =
367       typename std::conditional<kIsNoexcept,
368                                 void(Int, const int&, int) noexcept,
369                                 void(Int, const int&, int)>::type;
370   using VoidFunType = GiveQualifiersToFun<Qualifiers, UnqualifiedVoidFunType>;
371   using VoidAnyInvType = AnyInvocable<VoidFunType>;
372   using VoidThisParamType = QualifiersForThis<Qualifiers, VoidAnyInvType>;
373 
374   template <class T>
ToVoidThisParam__anon5a17cb360111::TestParams375   static VoidThisParamType ToVoidThisParam(T&& fun) {
376     return static_cast<VoidThisParamType>(fun);
377   }
378 
379   using CompatibleAnyInvocableFunType =
380       absl::conditional_t<std::is_rvalue_reference<Qual>::value,
381                           GiveQualifiersToFun<const _&&, UnqualifiedFunType>,
382                           GiveQualifiersToFun<const _&, UnqualifiedFunType>>;
383 
384   using CompatibleAnyInvType = AnyInvocable<CompatibleAnyInvocableFunType>;
385 
386   using IncompatibleInvocable =
387       absl::conditional_t<std::is_rvalue_reference<Qual>::value,
388                           GiveQualifiersToFun<_&, UnqualifiedFunType>(_::*),
389                           GiveQualifiersToFun<_&&, UnqualifiedFunType>(_::*)>;
390 };
391 
392 // Given a member-pointer type, this metafunction yields the target type of the
393 // pointer, not including the class-type. It is used to verify that the function
394 // call operator of AnyInvocable has the proper signature, corresponding to the
395 // function type that the user provided.
396 template <class MemberPtrType>
397 struct MemberTypeOfImpl;
398 
399 template <class Class, class T>
400 struct MemberTypeOfImpl<T(Class::*)> {
401   using type = T;
402 };
403 
404 template <class MemberPtrType>
405 using MemberTypeOf = typename MemberTypeOfImpl<MemberPtrType>::type;
406 
407 template <class T, class = void>
408 struct IsMemberSwappableImpl : std::false_type {
409   static constexpr bool kIsNothrow = false;
410 };
411 
412 template <class T>
413 struct IsMemberSwappableImpl<
414     T, absl::void_t<decltype(std::declval<T&>().swap(std::declval<T&>()))>>
415     : std::true_type {
416   static constexpr bool kIsNothrow =
417       noexcept(std::declval<T&>().swap(std::declval<T&>()));
418 };
419 
420 template <class T>
421 using IsMemberSwappable = IsMemberSwappableImpl<T>;
422 
423 template <class T>
424 using IsNothrowMemberSwappable =
425     std::integral_constant<bool, IsMemberSwappableImpl<T>::kIsNothrow>;
426 
427 template <class T>
428 class AnyInvTestBasic : public ::testing::Test {};
429 
430 TYPED_TEST_SUITE_P(AnyInvTestBasic);
431 
TYPED_TEST_P(AnyInvTestBasic,DefaultConstruction)432 TYPED_TEST_P(AnyInvTestBasic, DefaultConstruction) {
433   using AnyInvType = typename TypeParam::AnyInvType;
434 
435   AnyInvType fun;
436 
437   EXPECT_FALSE(static_cast<bool>(fun));
438 
439   EXPECT_TRUE(std::is_nothrow_default_constructible<AnyInvType>::value);
440 }
441 
TYPED_TEST_P(AnyInvTestBasic,ConstructionNullptr)442 TYPED_TEST_P(AnyInvTestBasic, ConstructionNullptr) {
443   using AnyInvType = typename TypeParam::AnyInvType;
444 
445   AnyInvType fun = nullptr;
446 
447   EXPECT_FALSE(static_cast<bool>(fun));
448 
449   EXPECT_TRUE(
450       (std::is_nothrow_constructible<AnyInvType, std::nullptr_t>::value));
451 }
452 
TYPED_TEST_P(AnyInvTestBasic,ConstructionNullFunctionPtr)453 TYPED_TEST_P(AnyInvTestBasic, ConstructionNullFunctionPtr) {
454   using AnyInvType = typename TypeParam::AnyInvType;
455   using UnqualifiedFunType = typename TypeParam::UnqualifiedFunType;
456 
457   UnqualifiedFunType* const null_fun_ptr = nullptr;
458   AnyInvType fun = null_fun_ptr;
459 
460   EXPECT_FALSE(static_cast<bool>(fun));
461 }
462 
TYPED_TEST_P(AnyInvTestBasic,ConstructionNullMemberFunctionPtr)463 TYPED_TEST_P(AnyInvTestBasic, ConstructionNullMemberFunctionPtr) {
464   using AnyInvType = typename TypeParam::AnyInvType;
465   using MemFunPtrType = typename TypeParam::MemFunPtrType;
466 
467   const MemFunPtrType null_mem_fun_ptr = nullptr;
468   AnyInvType fun = null_mem_fun_ptr;
469 
470   EXPECT_FALSE(static_cast<bool>(fun));
471 }
472 
TYPED_TEST_P(AnyInvTestBasic,ConstructionNullMemberObjectPtr)473 TYPED_TEST_P(AnyInvTestBasic, ConstructionNullMemberObjectPtr) {
474   using UnaryAnyInvType = typename TypeParam::UnaryAnyInvType;
475   using MemObjPtrType = typename TypeParam::MemObjPtrType;
476 
477   const MemObjPtrType null_mem_obj_ptr = nullptr;
478   UnaryAnyInvType fun = null_mem_obj_ptr;
479 
480   EXPECT_FALSE(static_cast<bool>(fun));
481 }
482 
TYPED_TEST_P(AnyInvTestBasic,ConstructionMemberFunctionPtr)483 TYPED_TEST_P(AnyInvTestBasic, ConstructionMemberFunctionPtr) {
484   using AnyInvType = typename TypeParam::AnyInvType;
485 
486   AnyInvType fun = &Int::MemberFunctionAdd;
487 
488   EXPECT_TRUE(static_cast<bool>(fun));
489   EXPECT_EQ(24, TypeParam::ToThisParam(fun)(7, 8, 9).value);
490 }
491 
TYPED_TEST_P(AnyInvTestBasic,ConstructionMemberObjectPtr)492 TYPED_TEST_P(AnyInvTestBasic, ConstructionMemberObjectPtr) {
493   using UnaryAnyInvType = typename TypeParam::UnaryAnyInvType;
494 
495   UnaryAnyInvType fun = &Int::value;
496 
497   EXPECT_TRUE(static_cast<bool>(fun));
498   EXPECT_EQ(13, TypeParam::ToUnaryThisParam(fun)(13));
499 }
500 
TYPED_TEST_P(AnyInvTestBasic,ConstructionFunctionReferenceDecay)501 TYPED_TEST_P(AnyInvTestBasic, ConstructionFunctionReferenceDecay) {
502   using AnyInvType = typename TypeParam::AnyInvType;
503 
504   AnyInvType fun = add_function;
505 
506   EXPECT_TRUE(static_cast<bool>(fun));
507   EXPECT_EQ(24, TypeParam::ToThisParam(fun)(7, 8, 9).value);
508 }
509 
TYPED_TEST_P(AnyInvTestBasic,ConstructionCompatibleAnyInvocableEmpty)510 TYPED_TEST_P(AnyInvTestBasic, ConstructionCompatibleAnyInvocableEmpty) {
511   using AnyInvType = typename TypeParam::AnyInvType;
512   using CompatibleAnyInvType = typename TypeParam::CompatibleAnyInvType;
513 
514   CompatibleAnyInvType other;
515   AnyInvType fun = std::move(other);
516 
517   EXPECT_FALSE(static_cast<bool>(other));  // NOLINT
518   EXPECT_EQ(other, nullptr);               // NOLINT
519   EXPECT_EQ(nullptr, other);               // NOLINT
520 
521   EXPECT_FALSE(static_cast<bool>(fun));
522 }
523 
TYPED_TEST_P(AnyInvTestBasic,ConstructionCompatibleAnyInvocableNonempty)524 TYPED_TEST_P(AnyInvTestBasic, ConstructionCompatibleAnyInvocableNonempty) {
525   using AnyInvType = typename TypeParam::AnyInvType;
526   using CompatibleAnyInvType = typename TypeParam::CompatibleAnyInvType;
527 
528   CompatibleAnyInvType other = &add_function;
529   AnyInvType fun = std::move(other);
530 
531   EXPECT_FALSE(static_cast<bool>(other));  // NOLINT
532   EXPECT_EQ(other, nullptr);               // NOLINT
533   EXPECT_EQ(nullptr, other);               // NOLINT
534 
535   EXPECT_TRUE(static_cast<bool>(fun));
536   EXPECT_EQ(24, TypeParam::ToThisParam(fun)(7, 8, 9).value);
537 }
538 
TYPED_TEST_P(AnyInvTestBasic,ConversionToBool)539 TYPED_TEST_P(AnyInvTestBasic, ConversionToBool) {
540   using AnyInvType = typename TypeParam::AnyInvType;
541 
542   {
543     AnyInvType fun;
544 
545     // This tests contextually-convertible-to-bool.
546     EXPECT_FALSE(fun ? true : false);  // NOLINT
547 
548     // Make sure that the conversion is not implicit.
549     EXPECT_TRUE(
550         (std::is_nothrow_constructible<bool, const AnyInvType&>::value));
551     EXPECT_FALSE((std::is_convertible<const AnyInvType&, bool>::value));
552   }
553 
554   {
555     AnyInvType fun = &add_function;
556 
557     // This tests contextually-convertible-to-bool.
558     EXPECT_TRUE(fun ? true : false);  // NOLINT
559   }
560 }
561 
TYPED_TEST_P(AnyInvTestBasic,Invocation)562 TYPED_TEST_P(AnyInvTestBasic, Invocation) {
563   using AnyInvType = typename TypeParam::AnyInvType;
564 
565   using FunType = typename TypeParam::FunType;
566   using AnyInvCallType = MemberTypeOf<decltype(&AnyInvType::operator())>;
567 
568   // Make sure the function call operator of AnyInvocable always has the
569   // type that was specified via the template argument.
570   EXPECT_TRUE((std::is_same<AnyInvCallType, FunType>::value));
571 
572   AnyInvType fun = &add_function;
573 
574   EXPECT_EQ(24, TypeParam::ToThisParam(fun)(7, 8, 9).value);
575 }
576 
TYPED_TEST_P(AnyInvTestBasic,InPlaceConstruction)577 TYPED_TEST_P(AnyInvTestBasic, InPlaceConstruction) {
578   using AnyInvType = typename TypeParam::AnyInvType;
579   using AddType = typename TypeParam::AddType;
580 
581   AnyInvType fun(absl::in_place_type<AddType>, 5);
582 
583   EXPECT_TRUE(static_cast<bool>(fun));
584   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
585 }
586 
TYPED_TEST_P(AnyInvTestBasic,InPlaceConstructionInitializerList)587 TYPED_TEST_P(AnyInvTestBasic, InPlaceConstructionInitializerList) {
588   using AnyInvType = typename TypeParam::AnyInvType;
589   using AddType = typename TypeParam::AddType;
590 
591   AnyInvType fun(absl::in_place_type<AddType>, {1, 2, 3, 4}, 5);
592 
593   EXPECT_TRUE(static_cast<bool>(fun));
594   EXPECT_EQ(39, TypeParam::ToThisParam(fun)(7, 8, 9).value);
595 }
596 
TYPED_TEST_P(AnyInvTestBasic,InPlaceNullFunPtrConstruction)597 TYPED_TEST_P(AnyInvTestBasic, InPlaceNullFunPtrConstruction) {
598   using AnyInvType = typename TypeParam::AnyInvType;
599   using UnqualifiedFunType = typename TypeParam::UnqualifiedFunType;
600 
601   AnyInvType fun(absl::in_place_type<UnqualifiedFunType*>, nullptr);
602 
603   // In-place construction does not lead to empty.
604   EXPECT_TRUE(static_cast<bool>(fun));
605 }
606 
TYPED_TEST_P(AnyInvTestBasic,InPlaceNullFunPtrConstructionValueInit)607 TYPED_TEST_P(AnyInvTestBasic, InPlaceNullFunPtrConstructionValueInit) {
608   using AnyInvType = typename TypeParam::AnyInvType;
609   using UnqualifiedFunType = typename TypeParam::UnqualifiedFunType;
610 
611   AnyInvType fun(absl::in_place_type<UnqualifiedFunType*>);
612 
613   // In-place construction does not lead to empty.
614   EXPECT_TRUE(static_cast<bool>(fun));
615 }
616 
TYPED_TEST_P(AnyInvTestBasic,InPlaceNullMemFunPtrConstruction)617 TYPED_TEST_P(AnyInvTestBasic, InPlaceNullMemFunPtrConstruction) {
618   using AnyInvType = typename TypeParam::AnyInvType;
619   using MemFunPtrType = typename TypeParam::MemFunPtrType;
620 
621   AnyInvType fun(absl::in_place_type<MemFunPtrType>, nullptr);
622 
623   // In-place construction does not lead to empty.
624   EXPECT_TRUE(static_cast<bool>(fun));
625 }
626 
TYPED_TEST_P(AnyInvTestBasic,InPlaceNullMemFunPtrConstructionValueInit)627 TYPED_TEST_P(AnyInvTestBasic, InPlaceNullMemFunPtrConstructionValueInit) {
628   using AnyInvType = typename TypeParam::AnyInvType;
629   using MemFunPtrType = typename TypeParam::MemFunPtrType;
630 
631   AnyInvType fun(absl::in_place_type<MemFunPtrType>);
632 
633   // In-place construction does not lead to empty.
634   EXPECT_TRUE(static_cast<bool>(fun));
635 }
636 
TYPED_TEST_P(AnyInvTestBasic,InPlaceNullMemObjPtrConstruction)637 TYPED_TEST_P(AnyInvTestBasic, InPlaceNullMemObjPtrConstruction) {
638   using UnaryAnyInvType = typename TypeParam::UnaryAnyInvType;
639   using MemObjPtrType = typename TypeParam::MemObjPtrType;
640 
641   UnaryAnyInvType fun(absl::in_place_type<MemObjPtrType>, nullptr);
642 
643   // In-place construction does not lead to empty.
644   EXPECT_TRUE(static_cast<bool>(fun));
645 }
646 
TYPED_TEST_P(AnyInvTestBasic,InPlaceNullMemObjPtrConstructionValueInit)647 TYPED_TEST_P(AnyInvTestBasic, InPlaceNullMemObjPtrConstructionValueInit) {
648   using UnaryAnyInvType = typename TypeParam::UnaryAnyInvType;
649   using MemObjPtrType = typename TypeParam::MemObjPtrType;
650 
651   UnaryAnyInvType fun(absl::in_place_type<MemObjPtrType>);
652 
653   // In-place construction does not lead to empty.
654   EXPECT_TRUE(static_cast<bool>(fun));
655 }
656 
TYPED_TEST_P(AnyInvTestBasic,InPlaceVoidCovarianceConstruction)657 TYPED_TEST_P(AnyInvTestBasic, InPlaceVoidCovarianceConstruction) {
658   using VoidAnyInvType = typename TypeParam::VoidAnyInvType;
659   using AddType = typename TypeParam::AddType;
660 
661   VoidAnyInvType fun(absl::in_place_type<AddType>, 5);
662 
663   EXPECT_TRUE(static_cast<bool>(fun));
664 }
665 
TYPED_TEST_P(AnyInvTestBasic,MoveConstructionFromEmpty)666 TYPED_TEST_P(AnyInvTestBasic, MoveConstructionFromEmpty) {
667   using AnyInvType = typename TypeParam::AnyInvType;
668 
669   AnyInvType source_fun;
670   AnyInvType fun(std::move(source_fun));
671 
672   EXPECT_FALSE(static_cast<bool>(fun));
673 
674   EXPECT_TRUE(std::is_nothrow_move_constructible<AnyInvType>::value);
675 }
676 
TYPED_TEST_P(AnyInvTestBasic,MoveConstructionFromNonEmpty)677 TYPED_TEST_P(AnyInvTestBasic, MoveConstructionFromNonEmpty) {
678   using AnyInvType = typename TypeParam::AnyInvType;
679   using AddType = typename TypeParam::AddType;
680 
681   AnyInvType source_fun(absl::in_place_type<AddType>, 5);
682   AnyInvType fun(std::move(source_fun));
683 
684   EXPECT_TRUE(static_cast<bool>(fun));
685   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
686 
687   EXPECT_TRUE(std::is_nothrow_move_constructible<AnyInvType>::value);
688 }
689 
TYPED_TEST_P(AnyInvTestBasic,ComparisonWithNullptrEmpty)690 TYPED_TEST_P(AnyInvTestBasic, ComparisonWithNullptrEmpty) {
691   using AnyInvType = typename TypeParam::AnyInvType;
692 
693   AnyInvType fun;
694 
695   EXPECT_TRUE(fun == nullptr);
696   EXPECT_TRUE(nullptr == fun);
697 
698   EXPECT_FALSE(fun != nullptr);
699   EXPECT_FALSE(nullptr != fun);
700 }
701 
TYPED_TEST_P(AnyInvTestBasic,ComparisonWithNullptrNonempty)702 TYPED_TEST_P(AnyInvTestBasic, ComparisonWithNullptrNonempty) {
703   using AnyInvType = typename TypeParam::AnyInvType;
704   using AddType = typename TypeParam::AddType;
705 
706   AnyInvType fun(absl::in_place_type<AddType>, 5);
707 
708   EXPECT_FALSE(fun == nullptr);
709   EXPECT_FALSE(nullptr == fun);
710 
711   EXPECT_TRUE(fun != nullptr);
712   EXPECT_TRUE(nullptr != fun);
713 }
714 
TYPED_TEST_P(AnyInvTestBasic,ResultType)715 TYPED_TEST_P(AnyInvTestBasic, ResultType) {
716   using AnyInvType = typename TypeParam::AnyInvType;
717   using ExpectedResultType = typename TypeParam::ResultType;
718 
719   EXPECT_TRUE((std::is_same<typename AnyInvType::result_type,
720                             ExpectedResultType>::value));
721 }
722 
723 template <class T>
724 class AnyInvTestCombinatoric : public ::testing::Test {};
725 
726 TYPED_TEST_SUITE_P(AnyInvTestCombinatoric);
727 
TYPED_TEST_P(AnyInvTestCombinatoric,MoveAssignEmptyEmptyLhsRhs)728 TYPED_TEST_P(AnyInvTestCombinatoric, MoveAssignEmptyEmptyLhsRhs) {
729   using AnyInvType = typename TypeParam::AnyInvType;
730 
731   AnyInvType source_fun;
732   AnyInvType fun;
733 
734   fun = std::move(source_fun);
735 
736   EXPECT_FALSE(static_cast<bool>(fun));
737 }
738 
TYPED_TEST_P(AnyInvTestCombinatoric,MoveAssignEmptyLhsNonemptyRhs)739 TYPED_TEST_P(AnyInvTestCombinatoric, MoveAssignEmptyLhsNonemptyRhs) {
740   using AnyInvType = typename TypeParam::AnyInvType;
741   using AddType = typename TypeParam::AddType;
742 
743   AnyInvType source_fun(absl::in_place_type<AddType>, 5);
744   AnyInvType fun;
745 
746   fun = std::move(source_fun);
747 
748   EXPECT_TRUE(static_cast<bool>(fun));
749   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
750 }
751 
TYPED_TEST_P(AnyInvTestCombinatoric,MoveAssignNonemptyEmptyLhsRhs)752 TYPED_TEST_P(AnyInvTestCombinatoric, MoveAssignNonemptyEmptyLhsRhs) {
753   using AnyInvType = typename TypeParam::AnyInvType;
754   using AddType = typename TypeParam::AddType;
755 
756   AnyInvType source_fun;
757   AnyInvType fun(absl::in_place_type<AddType>, 5);
758 
759   fun = std::move(source_fun);
760 
761   EXPECT_FALSE(static_cast<bool>(fun));
762 }
763 
TYPED_TEST_P(AnyInvTestCombinatoric,MoveAssignNonemptyLhsNonemptyRhs)764 TYPED_TEST_P(AnyInvTestCombinatoric, MoveAssignNonemptyLhsNonemptyRhs) {
765   using AnyInvType = typename TypeParam::AnyInvType;
766   using AddType = typename TypeParam::AddType;
767 
768   AnyInvType source_fun(absl::in_place_type<AddType>, 5);
769   AnyInvType fun(absl::in_place_type<AddType>, 20);
770 
771   fun = std::move(source_fun);
772 
773   EXPECT_TRUE(static_cast<bool>(fun));
774   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
775 }
776 
TYPED_TEST_P(AnyInvTestCombinatoric,SelfMoveAssignEmpty)777 TYPED_TEST_P(AnyInvTestCombinatoric, SelfMoveAssignEmpty) {
778   using AnyInvType = typename TypeParam::AnyInvType;
779 
780   AnyInvType source_fun;
781   source_fun = std::move(source_fun);
782 
783   // This space intentionally left blank.
784 }
785 
TYPED_TEST_P(AnyInvTestCombinatoric,SelfMoveAssignNonempty)786 TYPED_TEST_P(AnyInvTestCombinatoric, SelfMoveAssignNonempty) {
787   using AnyInvType = typename TypeParam::AnyInvType;
788   using AddType = typename TypeParam::AddType;
789 
790   AnyInvType source_fun(absl::in_place_type<AddType>, 5);
791   source_fun = std::move(source_fun);
792 
793   // This space intentionally left blank.
794 }
795 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignNullptrEmptyLhs)796 TYPED_TEST_P(AnyInvTestCombinatoric, AssignNullptrEmptyLhs) {
797   using AnyInvType = typename TypeParam::AnyInvType;
798 
799   AnyInvType fun;
800   fun = nullptr;
801 
802   EXPECT_FALSE(static_cast<bool>(fun));
803 }
804 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignNullFunctionPtrEmptyLhs)805 TYPED_TEST_P(AnyInvTestCombinatoric, AssignNullFunctionPtrEmptyLhs) {
806   using AnyInvType = typename TypeParam::AnyInvType;
807   using UnqualifiedFunType = typename TypeParam::UnqualifiedFunType;
808 
809   UnqualifiedFunType* const null_fun_ptr = nullptr;
810   AnyInvType fun;
811   fun = null_fun_ptr;
812 
813   EXPECT_FALSE(static_cast<bool>(fun));
814 }
815 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignNullMemberFunctionPtrEmptyLhs)816 TYPED_TEST_P(AnyInvTestCombinatoric, AssignNullMemberFunctionPtrEmptyLhs) {
817   using AnyInvType = typename TypeParam::AnyInvType;
818   using MemFunPtrType = typename TypeParam::MemFunPtrType;
819 
820   const MemFunPtrType null_mem_fun_ptr = nullptr;
821   AnyInvType fun;
822   fun = null_mem_fun_ptr;
823 
824   EXPECT_FALSE(static_cast<bool>(fun));
825 }
826 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignNullMemberObjectPtrEmptyLhs)827 TYPED_TEST_P(AnyInvTestCombinatoric, AssignNullMemberObjectPtrEmptyLhs) {
828   using UnaryAnyInvType = typename TypeParam::UnaryAnyInvType;
829   using MemObjPtrType = typename TypeParam::MemObjPtrType;
830 
831   const MemObjPtrType null_mem_obj_ptr = nullptr;
832   UnaryAnyInvType fun;
833   fun = null_mem_obj_ptr;
834 
835   EXPECT_FALSE(static_cast<bool>(fun));
836 }
837 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignMemberFunctionPtrEmptyLhs)838 TYPED_TEST_P(AnyInvTestCombinatoric, AssignMemberFunctionPtrEmptyLhs) {
839   using AnyInvType = typename TypeParam::AnyInvType;
840 
841   AnyInvType fun;
842   fun = &Int::MemberFunctionAdd;
843 
844   EXPECT_TRUE(static_cast<bool>(fun));
845   EXPECT_EQ(24, TypeParam::ToThisParam(fun)(7, 8, 9).value);
846 }
847 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignMemberObjectPtrEmptyLhs)848 TYPED_TEST_P(AnyInvTestCombinatoric, AssignMemberObjectPtrEmptyLhs) {
849   using UnaryAnyInvType = typename TypeParam::UnaryAnyInvType;
850 
851   UnaryAnyInvType fun;
852   fun = &Int::value;
853 
854   EXPECT_TRUE(static_cast<bool>(fun));
855   EXPECT_EQ(13, TypeParam::ToUnaryThisParam(fun)(13));
856 }
857 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignFunctionReferenceDecayEmptyLhs)858 TYPED_TEST_P(AnyInvTestCombinatoric, AssignFunctionReferenceDecayEmptyLhs) {
859   using AnyInvType = typename TypeParam::AnyInvType;
860 
861   AnyInvType fun;
862   fun = add_function;
863 
864   EXPECT_TRUE(static_cast<bool>(fun));
865   EXPECT_EQ(24, TypeParam::ToThisParam(fun)(7, 8, 9).value);
866 }
867 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignCompatibleAnyInvocableEmptyLhsEmptyRhs)868 TYPED_TEST_P(AnyInvTestCombinatoric,
869              AssignCompatibleAnyInvocableEmptyLhsEmptyRhs) {
870   using AnyInvType = typename TypeParam::AnyInvType;
871   using CompatibleAnyInvType = typename TypeParam::CompatibleAnyInvType;
872 
873   CompatibleAnyInvType other;
874   AnyInvType fun;
875   fun = std::move(other);
876 
877   EXPECT_FALSE(static_cast<bool>(other));  // NOLINT
878   EXPECT_EQ(other, nullptr);               // NOLINT
879   EXPECT_EQ(nullptr, other);               // NOLINT
880 
881   EXPECT_FALSE(static_cast<bool>(fun));
882 }
883 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignCompatibleAnyInvocableEmptyLhsNonemptyRhs)884 TYPED_TEST_P(AnyInvTestCombinatoric,
885              AssignCompatibleAnyInvocableEmptyLhsNonemptyRhs) {
886   using AnyInvType = typename TypeParam::AnyInvType;
887   using CompatibleAnyInvType = typename TypeParam::CompatibleAnyInvType;
888 
889   CompatibleAnyInvType other = &add_function;
890   AnyInvType fun;
891   fun = std::move(other);
892 
893   EXPECT_FALSE(static_cast<bool>(other));  // NOLINT
894 
895   EXPECT_TRUE(static_cast<bool>(fun));
896   EXPECT_EQ(24, TypeParam::ToThisParam(fun)(7, 8, 9).value);
897 }
898 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignNullptrNonemptyLhs)899 TYPED_TEST_P(AnyInvTestCombinatoric, AssignNullptrNonemptyLhs) {
900   using AnyInvType = typename TypeParam::AnyInvType;
901 
902   AnyInvType fun = &mult_function;
903   fun = nullptr;
904 
905   EXPECT_FALSE(static_cast<bool>(fun));
906 }
907 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignNullFunctionPtrNonemptyLhs)908 TYPED_TEST_P(AnyInvTestCombinatoric, AssignNullFunctionPtrNonemptyLhs) {
909   using AnyInvType = typename TypeParam::AnyInvType;
910   using UnqualifiedFunType = typename TypeParam::UnqualifiedFunType;
911 
912   UnqualifiedFunType* const null_fun_ptr = nullptr;
913   AnyInvType fun = &mult_function;
914   fun = null_fun_ptr;
915 
916   EXPECT_FALSE(static_cast<bool>(fun));
917 }
918 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignNullMemberFunctionPtrNonemptyLhs)919 TYPED_TEST_P(AnyInvTestCombinatoric, AssignNullMemberFunctionPtrNonemptyLhs) {
920   using AnyInvType = typename TypeParam::AnyInvType;
921   using MemFunPtrType = typename TypeParam::MemFunPtrType;
922 
923   const MemFunPtrType null_mem_fun_ptr = nullptr;
924   AnyInvType fun = &mult_function;
925   fun = null_mem_fun_ptr;
926 
927   EXPECT_FALSE(static_cast<bool>(fun));
928 }
929 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignNullMemberObjectPtrNonemptyLhs)930 TYPED_TEST_P(AnyInvTestCombinatoric, AssignNullMemberObjectPtrNonemptyLhs) {
931   using UnaryAnyInvType = typename TypeParam::UnaryAnyInvType;
932   using MemObjPtrType = typename TypeParam::MemObjPtrType;
933 
934   const MemObjPtrType null_mem_obj_ptr = nullptr;
935   UnaryAnyInvType fun = &square_function;
936   fun = null_mem_obj_ptr;
937 
938   EXPECT_FALSE(static_cast<bool>(fun));
939 }
940 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignMemberFunctionPtrNonemptyLhs)941 TYPED_TEST_P(AnyInvTestCombinatoric, AssignMemberFunctionPtrNonemptyLhs) {
942   using AnyInvType = typename TypeParam::AnyInvType;
943 
944   AnyInvType fun = &mult_function;
945   fun = &Int::MemberFunctionAdd;
946 
947   EXPECT_TRUE(static_cast<bool>(fun));
948   EXPECT_EQ(24, TypeParam::ToThisParam(fun)(7, 8, 9).value);
949 }
950 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignMemberObjectPtrNonemptyLhs)951 TYPED_TEST_P(AnyInvTestCombinatoric, AssignMemberObjectPtrNonemptyLhs) {
952   using UnaryAnyInvType = typename TypeParam::UnaryAnyInvType;
953 
954   UnaryAnyInvType fun = &square_function;
955   fun = &Int::value;
956 
957   EXPECT_TRUE(static_cast<bool>(fun));
958   EXPECT_EQ(13, TypeParam::ToUnaryThisParam(fun)(13));
959 }
960 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignFunctionReferenceDecayNonemptyLhs)961 TYPED_TEST_P(AnyInvTestCombinatoric, AssignFunctionReferenceDecayNonemptyLhs) {
962   using AnyInvType = typename TypeParam::AnyInvType;
963 
964   AnyInvType fun = &mult_function;
965   fun = add_function;
966 
967   EXPECT_TRUE(static_cast<bool>(fun));
968   EXPECT_EQ(24, TypeParam::ToThisParam(fun)(7, 8, 9).value);
969 }
970 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignCompatibleAnyInvocableNonemptyLhsEmptyRhs)971 TYPED_TEST_P(AnyInvTestCombinatoric,
972              AssignCompatibleAnyInvocableNonemptyLhsEmptyRhs) {
973   using AnyInvType = typename TypeParam::AnyInvType;
974   using CompatibleAnyInvType = typename TypeParam::CompatibleAnyInvType;
975 
976   CompatibleAnyInvType other;
977   AnyInvType fun = &mult_function;
978   fun = std::move(other);
979 
980   EXPECT_FALSE(static_cast<bool>(other));  // NOLINT
981   EXPECT_EQ(other, nullptr);               // NOLINT
982   EXPECT_EQ(nullptr, other);               // NOLINT
983 
984   EXPECT_FALSE(static_cast<bool>(fun));
985 }
986 
TYPED_TEST_P(AnyInvTestCombinatoric,AssignCompatibleAnyInvocableNonemptyLhsNonemptyRhs)987 TYPED_TEST_P(AnyInvTestCombinatoric,
988              AssignCompatibleAnyInvocableNonemptyLhsNonemptyRhs) {
989   using AnyInvType = typename TypeParam::AnyInvType;
990   using CompatibleAnyInvType = typename TypeParam::CompatibleAnyInvType;
991 
992   CompatibleAnyInvType other = &add_function;
993   AnyInvType fun = &mult_function;
994   fun = std::move(other);
995 
996   EXPECT_FALSE(static_cast<bool>(other));  // NOLINT
997 
998   EXPECT_TRUE(static_cast<bool>(fun));
999   EXPECT_EQ(24, TypeParam::ToThisParam(fun)(7, 8, 9).value);
1000 }
1001 
TYPED_TEST_P(AnyInvTestCombinatoric,SwapEmptyLhsEmptyRhs)1002 TYPED_TEST_P(AnyInvTestCombinatoric, SwapEmptyLhsEmptyRhs) {
1003   using AnyInvType = typename TypeParam::AnyInvType;
1004 
1005   // Swap idiom
1006   {
1007     AnyInvType fun;
1008     AnyInvType other;
1009 
1010     using std::swap;
1011     swap(fun, other);
1012 
1013     EXPECT_FALSE(static_cast<bool>(fun));
1014     EXPECT_FALSE(static_cast<bool>(other));
1015 
1016     EXPECT_TRUE(
1017         absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value);
1018   }
1019 
1020   // Member swap
1021   {
1022     AnyInvType fun;
1023     AnyInvType other;
1024 
1025     fun.swap(other);
1026 
1027     EXPECT_FALSE(static_cast<bool>(fun));
1028     EXPECT_FALSE(static_cast<bool>(other));
1029 
1030     EXPECT_TRUE(IsNothrowMemberSwappable<AnyInvType>::value);
1031   }
1032 }
1033 
TYPED_TEST_P(AnyInvTestCombinatoric,SwapEmptyLhsNonemptyRhs)1034 TYPED_TEST_P(AnyInvTestCombinatoric, SwapEmptyLhsNonemptyRhs) {
1035   using AnyInvType = typename TypeParam::AnyInvType;
1036   using AddType = typename TypeParam::AddType;
1037 
1038   // Swap idiom
1039   {
1040     AnyInvType fun;
1041     AnyInvType other(absl::in_place_type<AddType>, 5);
1042 
1043     using std::swap;
1044     swap(fun, other);
1045 
1046     EXPECT_TRUE(static_cast<bool>(fun));
1047     EXPECT_FALSE(static_cast<bool>(other));
1048 
1049     EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
1050 
1051     EXPECT_TRUE(
1052         absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value);
1053   }
1054 
1055   // Member swap
1056   {
1057     AnyInvType fun;
1058     AnyInvType other(absl::in_place_type<AddType>, 5);
1059 
1060     fun.swap(other);
1061 
1062     EXPECT_TRUE(static_cast<bool>(fun));
1063     EXPECT_FALSE(static_cast<bool>(other));
1064 
1065     EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
1066 
1067     EXPECT_TRUE(IsNothrowMemberSwappable<AnyInvType>::value);
1068   }
1069 }
1070 
TYPED_TEST_P(AnyInvTestCombinatoric,SwapNonemptyLhsEmptyRhs)1071 TYPED_TEST_P(AnyInvTestCombinatoric, SwapNonemptyLhsEmptyRhs) {
1072   using AnyInvType = typename TypeParam::AnyInvType;
1073   using AddType = typename TypeParam::AddType;
1074 
1075   // Swap idiom
1076   {
1077     AnyInvType fun(absl::in_place_type<AddType>, 5);
1078     AnyInvType other;
1079 
1080     using std::swap;
1081     swap(fun, other);
1082 
1083     EXPECT_FALSE(static_cast<bool>(fun));
1084     EXPECT_TRUE(static_cast<bool>(other));
1085 
1086     EXPECT_EQ(29, TypeParam::ToThisParam(other)(7, 8, 9).value);
1087 
1088     EXPECT_TRUE(
1089         absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value);
1090   }
1091 
1092   // Member swap
1093   {
1094     AnyInvType fun(absl::in_place_type<AddType>, 5);
1095     AnyInvType other;
1096 
1097     fun.swap(other);
1098 
1099     EXPECT_FALSE(static_cast<bool>(fun));
1100     EXPECT_TRUE(static_cast<bool>(other));
1101 
1102     EXPECT_EQ(29, TypeParam::ToThisParam(other)(7, 8, 9).value);
1103 
1104     EXPECT_TRUE(IsNothrowMemberSwappable<AnyInvType>::value);
1105   }
1106 }
1107 
TYPED_TEST_P(AnyInvTestCombinatoric,SwapNonemptyLhsNonemptyRhs)1108 TYPED_TEST_P(AnyInvTestCombinatoric, SwapNonemptyLhsNonemptyRhs) {
1109   using AnyInvType = typename TypeParam::AnyInvType;
1110   using AddType = typename TypeParam::AddType;
1111 
1112   // Swap idiom
1113   {
1114     AnyInvType fun(absl::in_place_type<AddType>, 5);
1115     AnyInvType other(absl::in_place_type<AddType>, 6);
1116 
1117     using std::swap;
1118     swap(fun, other);
1119 
1120     EXPECT_TRUE(static_cast<bool>(fun));
1121     EXPECT_TRUE(static_cast<bool>(other));
1122 
1123     EXPECT_EQ(30, TypeParam::ToThisParam(fun)(7, 8, 9).value);
1124     EXPECT_EQ(29, TypeParam::ToThisParam(other)(7, 8, 9).value);
1125 
1126     EXPECT_TRUE(
1127         absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value);
1128   }
1129 
1130   // Member swap
1131   {
1132     AnyInvType fun(absl::in_place_type<AddType>, 5);
1133     AnyInvType other(absl::in_place_type<AddType>, 6);
1134 
1135     fun.swap(other);
1136 
1137     EXPECT_TRUE(static_cast<bool>(fun));
1138     EXPECT_TRUE(static_cast<bool>(other));
1139 
1140     EXPECT_EQ(30, TypeParam::ToThisParam(fun)(7, 8, 9).value);
1141     EXPECT_EQ(29, TypeParam::ToThisParam(other)(7, 8, 9).value);
1142 
1143     EXPECT_TRUE(IsNothrowMemberSwappable<AnyInvType>::value);
1144   }
1145 }
1146 
1147 template <class T>
1148 class AnyInvTestMovable : public ::testing::Test {};
1149 
1150 TYPED_TEST_SUITE_P(AnyInvTestMovable);
1151 
TYPED_TEST_P(AnyInvTestMovable,ConversionConstructionUserDefinedType)1152 TYPED_TEST_P(AnyInvTestMovable, ConversionConstructionUserDefinedType) {
1153   using AnyInvType = typename TypeParam::AnyInvType;
1154   using AddType = typename TypeParam::AddType;
1155 
1156   AnyInvType fun(AddType(5));
1157 
1158   EXPECT_TRUE(static_cast<bool>(fun));
1159   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
1160 }
1161 
TYPED_TEST_P(AnyInvTestMovable,ConversionConstructionVoidCovariance)1162 TYPED_TEST_P(AnyInvTestMovable, ConversionConstructionVoidCovariance) {
1163   using VoidAnyInvType = typename TypeParam::VoidAnyInvType;
1164   using AddType = typename TypeParam::AddType;
1165 
1166   VoidAnyInvType fun(AddType(5));
1167 
1168   EXPECT_TRUE(static_cast<bool>(fun));
1169 }
1170 
TYPED_TEST_P(AnyInvTestMovable,ConversionAssignUserDefinedTypeEmptyLhs)1171 TYPED_TEST_P(AnyInvTestMovable, ConversionAssignUserDefinedTypeEmptyLhs) {
1172   using AnyInvType = typename TypeParam::AnyInvType;
1173   using AddType = typename TypeParam::AddType;
1174 
1175   AnyInvType fun;
1176   fun = AddType(5);
1177 
1178   EXPECT_TRUE(static_cast<bool>(fun));
1179   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
1180 }
1181 
TYPED_TEST_P(AnyInvTestMovable,ConversionAssignUserDefinedTypeNonemptyLhs)1182 TYPED_TEST_P(AnyInvTestMovable, ConversionAssignUserDefinedTypeNonemptyLhs) {
1183   using AnyInvType = typename TypeParam::AnyInvType;
1184   using AddType = typename TypeParam::AddType;
1185 
1186   AnyInvType fun = &add_function;
1187   fun = AddType(5);
1188 
1189   EXPECT_TRUE(static_cast<bool>(fun));
1190   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
1191 }
1192 
TYPED_TEST_P(AnyInvTestMovable,ConversionAssignVoidCovariance)1193 TYPED_TEST_P(AnyInvTestMovable, ConversionAssignVoidCovariance) {
1194   using VoidAnyInvType = typename TypeParam::VoidAnyInvType;
1195   using AddType = typename TypeParam::AddType;
1196 
1197   VoidAnyInvType fun;
1198   fun = AddType(5);
1199 
1200   EXPECT_TRUE(static_cast<bool>(fun));
1201 }
1202 
1203 template <class T>
1204 class AnyInvTestNoexceptFalse : public ::testing::Test {};
1205 
1206 TYPED_TEST_SUITE_P(AnyInvTestNoexceptFalse);
1207 
TYPED_TEST_P(AnyInvTestNoexceptFalse,ConversionConstructionConstraints)1208 TYPED_TEST_P(AnyInvTestNoexceptFalse, ConversionConstructionConstraints) {
1209   using AnyInvType = typename TypeParam::AnyInvType;
1210 
1211   EXPECT_TRUE((std::is_constructible<
1212                AnyInvType,
1213                typename TypeParam::AnyInvocableFunTypeNotNoexcept*>::value));
1214   EXPECT_FALSE((
1215       std::is_constructible<AnyInvType,
1216                             typename TypeParam::IncompatibleInvocable>::value));
1217 }
1218 
TYPED_TEST_P(AnyInvTestNoexceptFalse,ConversionAssignConstraints)1219 TYPED_TEST_P(AnyInvTestNoexceptFalse, ConversionAssignConstraints) {
1220   using AnyInvType = typename TypeParam::AnyInvType;
1221 
1222   EXPECT_TRUE((std::is_assignable<
1223                AnyInvType&,
1224                typename TypeParam::AnyInvocableFunTypeNotNoexcept*>::value));
1225   EXPECT_FALSE(
1226       (std::is_assignable<AnyInvType&,
1227                           typename TypeParam::IncompatibleInvocable>::value));
1228 }
1229 
1230 template <class T>
1231 class AnyInvTestNoexceptTrue : public ::testing::Test {};
1232 
1233 TYPED_TEST_SUITE_P(AnyInvTestNoexceptTrue);
1234 
TYPED_TEST_P(AnyInvTestNoexceptTrue,ConversionConstructionConstraints)1235 TYPED_TEST_P(AnyInvTestNoexceptTrue, ConversionConstructionConstraints) {
1236 #if ABSL_INTERNAL_CPLUSPLUS_LANG < 201703L
1237   GTEST_SKIP() << "Noexcept was not part of the type system before C++17.";
1238 #else
1239   using AnyInvType = typename TypeParam::AnyInvType;
1240 
1241   EXPECT_FALSE((std::is_constructible<
1242                 AnyInvType,
1243                 typename TypeParam::AnyInvocableFunTypeNotNoexcept*>::value));
1244   EXPECT_FALSE((
1245       std::is_constructible<AnyInvType,
1246                             typename TypeParam::IncompatibleInvocable>::value));
1247 #endif
1248 }
1249 
TYPED_TEST_P(AnyInvTestNoexceptTrue,ConversionAssignConstraints)1250 TYPED_TEST_P(AnyInvTestNoexceptTrue, ConversionAssignConstraints) {
1251 #if ABSL_INTERNAL_CPLUSPLUS_LANG < 201703L
1252   GTEST_SKIP() << "Noexcept was not part of the type system before C++17.";
1253 #else
1254   using AnyInvType = typename TypeParam::AnyInvType;
1255 
1256   EXPECT_FALSE((std::is_assignable<
1257                 AnyInvType&,
1258                 typename TypeParam::AnyInvocableFunTypeNotNoexcept*>::value));
1259   EXPECT_FALSE(
1260       (std::is_assignable<AnyInvType&,
1261                           typename TypeParam::IncompatibleInvocable>::value));
1262 #endif
1263 }
1264 
1265 template <class T>
1266 class AnyInvTestNonRvalue : public ::testing::Test {};
1267 
1268 TYPED_TEST_SUITE_P(AnyInvTestNonRvalue);
1269 
TYPED_TEST_P(AnyInvTestNonRvalue,ConversionConstructionReferenceWrapper)1270 TYPED_TEST_P(AnyInvTestNonRvalue, ConversionConstructionReferenceWrapper) {
1271   using AnyInvType = typename TypeParam::AnyInvType;
1272   using AddType = typename TypeParam::AddType;
1273 
1274   AddType add(4);
1275   AnyInvType fun = std::ref(add);
1276   add.state = 5;
1277 
1278   EXPECT_TRUE(static_cast<bool>(fun));
1279   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
1280 
1281   EXPECT_TRUE(static_cast<bool>(fun));
1282   EXPECT_EQ(38, TypeParam::ToThisParam(fun)(10, 11, 12).value);
1283 }
1284 
TYPED_TEST_P(AnyInvTestNonRvalue,NonMoveableResultType)1285 TYPED_TEST_P(AnyInvTestNonRvalue, NonMoveableResultType) {
1286 #if ABSL_INTERNAL_CPLUSPLUS_LANG < 201703L
1287   GTEST_SKIP() << "Copy/move elision was not standard before C++17";
1288 #else
1289   // Define a result type that cannot be copy- or move-constructed.
1290   struct Result {
1291     int x;
1292 
1293     explicit Result(const int x_in) : x(x_in) {}
1294     Result(Result&&) = delete;
1295   };
1296 
1297   static_assert(!std::is_move_constructible<Result>::value, "");
1298   static_assert(!std::is_copy_constructible<Result>::value, "");
1299 
1300   // Assumption check: it should nevertheless be possible to use functors that
1301   // return a Result struct according to the language rules.
1302   const auto return_17 = []() noexcept { return Result(17); };
1303   EXPECT_EQ(17, return_17().x);
1304 
1305   // Just like plain functors, it should work fine to use an AnyInvocable that
1306   // returns the non-moveable type.
1307   using UnqualifiedFun =
1308       absl::conditional_t<TypeParam::kIsNoexcept, Result() noexcept, Result()>;
1309 
1310   using Fun =
1311       GiveQualifiersToFun<typename TypeParam::Qualifiers, UnqualifiedFun>;
1312 
1313   AnyInvocable<Fun> any_inv(return_17);
1314   EXPECT_EQ(17, any_inv().x);
1315 #endif
1316 }
1317 
TYPED_TEST_P(AnyInvTestNonRvalue,ConversionAssignReferenceWrapperEmptyLhs)1318 TYPED_TEST_P(AnyInvTestNonRvalue, ConversionAssignReferenceWrapperEmptyLhs) {
1319   using AnyInvType = typename TypeParam::AnyInvType;
1320   using AddType = typename TypeParam::AddType;
1321 
1322   AddType add(4);
1323   AnyInvType fun;
1324   fun = std::ref(add);
1325   add.state = 5;
1326   EXPECT_TRUE(
1327       (std::is_nothrow_assignable<AnyInvType&,
1328                                   std::reference_wrapper<AddType>>::value));
1329 
1330   EXPECT_TRUE(static_cast<bool>(fun));
1331   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
1332 
1333   EXPECT_TRUE(static_cast<bool>(fun));
1334   EXPECT_EQ(38, TypeParam::ToThisParam(fun)(10, 11, 12).value);
1335 }
1336 
TYPED_TEST_P(AnyInvTestNonRvalue,ConversionAssignReferenceWrapperNonemptyLhs)1337 TYPED_TEST_P(AnyInvTestNonRvalue, ConversionAssignReferenceWrapperNonemptyLhs) {
1338   using AnyInvType = typename TypeParam::AnyInvType;
1339   using AddType = typename TypeParam::AddType;
1340 
1341   AddType add(4);
1342   AnyInvType fun = &mult_function;
1343   fun = std::ref(add);
1344   add.state = 5;
1345   EXPECT_TRUE(
1346       (std::is_nothrow_assignable<AnyInvType&,
1347                                   std::reference_wrapper<AddType>>::value));
1348 
1349   EXPECT_TRUE(static_cast<bool>(fun));
1350   EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
1351 
1352   EXPECT_TRUE(static_cast<bool>(fun));
1353   EXPECT_EQ(38, TypeParam::ToThisParam(fun)(10, 11, 12).value);
1354 }
1355 
1356 template <class T>
1357 class AnyInvTestRvalue : public ::testing::Test {};
1358 
1359 TYPED_TEST_SUITE_P(AnyInvTestRvalue);
1360 
TYPED_TEST_P(AnyInvTestRvalue,ConversionConstructionReferenceWrapper)1361 TYPED_TEST_P(AnyInvTestRvalue, ConversionConstructionReferenceWrapper) {
1362   using AnyInvType = typename TypeParam::AnyInvType;
1363   using AddType = typename TypeParam::AddType;
1364 
1365   EXPECT_FALSE((
1366       std::is_convertible<std::reference_wrapper<AddType>, AnyInvType>::value));
1367 }
1368 
TYPED_TEST_P(AnyInvTestRvalue,NonMoveableResultType)1369 TYPED_TEST_P(AnyInvTestRvalue, NonMoveableResultType) {
1370 #if ABSL_INTERNAL_CPLUSPLUS_LANG < 201703L
1371   GTEST_SKIP() << "Copy/move elision was not standard before C++17";
1372 #else
1373   // Define a result type that cannot be copy- or move-constructed.
1374   struct Result {
1375     int x;
1376 
1377     explicit Result(const int x_in) : x(x_in) {}
1378     Result(Result&&) = delete;
1379   };
1380 
1381   static_assert(!std::is_move_constructible<Result>::value, "");
1382   static_assert(!std::is_copy_constructible<Result>::value, "");
1383 
1384   // Assumption check: it should nevertheless be possible to use functors that
1385   // return a Result struct according to the language rules.
1386   const auto return_17 = []() noexcept { return Result(17); };
1387   EXPECT_EQ(17, return_17().x);
1388 
1389   // Just like plain functors, it should work fine to use an AnyInvocable that
1390   // returns the non-moveable type.
1391   using UnqualifiedFun =
1392       absl::conditional_t<TypeParam::kIsNoexcept, Result() noexcept, Result()>;
1393 
1394   using Fun =
1395       GiveQualifiersToFun<typename TypeParam::Qualifiers, UnqualifiedFun>;
1396 
1397   EXPECT_EQ(17, AnyInvocable<Fun>(return_17)().x);
1398 #endif
1399 }
1400 
TYPED_TEST_P(AnyInvTestRvalue,ConversionAssignReferenceWrapper)1401 TYPED_TEST_P(AnyInvTestRvalue, ConversionAssignReferenceWrapper) {
1402   using AnyInvType = typename TypeParam::AnyInvType;
1403   using AddType = typename TypeParam::AddType;
1404 
1405   EXPECT_FALSE((
1406       std::is_assignable<AnyInvType&, std::reference_wrapper<AddType>>::value));
1407 }
1408 
TYPED_TEST_P(AnyInvTestRvalue,NonConstCrashesOnSecondCall)1409 TYPED_TEST_P(AnyInvTestRvalue, NonConstCrashesOnSecondCall) {
1410   using AnyInvType = typename TypeParam::AnyInvType;
1411   using AddType = typename TypeParam::AddType;
1412 
1413   AnyInvType fun(absl::in_place_type<AddType>, 5);
1414 
1415   EXPECT_TRUE(static_cast<bool>(fun));
1416   std::move(fun)(7, 8, 9);
1417 
1418   // Ensure we're still valid
1419   EXPECT_TRUE(static_cast<bool>(fun));  // NOLINT(bugprone-use-after-move)
1420 
1421 #if !defined(NDEBUG)
1422   EXPECT_DEATH_IF_SUPPORTED(std::move(fun)(7, 8, 9), "");
1423 #endif
1424 }
1425 
1426 // Ensure that any qualifiers (in particular &&-qualifiers) do not affect
1427 // when the destructor is actually run.
TYPED_TEST_P(AnyInvTestRvalue,QualifierIndependentObjectLifetime)1428 TYPED_TEST_P(AnyInvTestRvalue, QualifierIndependentObjectLifetime) {
1429   using AnyInvType = typename TypeParam::AnyInvType;
1430 
1431   auto refs = std::make_shared<std::nullptr_t>();
1432   {
1433     AnyInvType fun([refs](auto&&...) noexcept { return 0; });
1434     EXPECT_GT(refs.use_count(), 1);
1435 
1436     std::move(fun)(7, 8, 9);
1437 
1438     // Ensure destructor hasn't run even if rref-qualified
1439     EXPECT_GT(refs.use_count(), 1);
1440   }
1441   EXPECT_EQ(refs.use_count(), 1);
1442 }
1443 
1444 // NOTE: This test suite originally attempted to enumerate all possible
1445 // combinations of type properties but the build-time started getting too large.
1446 // Instead, it is now assumed that certain parameters are orthogonal and so
1447 // some combinations are elided.
1448 
1449 // A metafunction to form a TypeList of all cv and non-rvalue ref combinations,
1450 // coupled with all of the other explicitly specified parameters.
1451 template <Movable Mov, Destructible Dest, NothrowCall CallExceptionSpec,
1452           ObjSize Size, ObjAlign Align>
1453 using NonRvalueQualifiedTestParams = ::testing::Types<               //
1454     TestParams<Mov, Dest, _, CallExceptionSpec, Size, Align>,        //
1455     TestParams<Mov, Dest, const _, CallExceptionSpec, Size, Align>,  //
1456     TestParams<Mov, Dest, _&, CallExceptionSpec, Size, Align>,       //
1457     TestParams<Mov, Dest, const _&, CallExceptionSpec, Size, Align>>;
1458 
1459 // A metafunction to form a TypeList of const and non-const rvalue ref
1460 // qualifiers, coupled with all of the other explicitly specified parameters.
1461 template <Movable Mov, Destructible Dest, NothrowCall CallExceptionSpec,
1462           ObjSize Size, ObjAlign Align>
1463 using RvalueQualifiedTestParams = ::testing::Types<
1464     TestParams<Mov, Dest, _&&, CallExceptionSpec, Size, Align>,       //
1465     TestParams<Mov, Dest, const _&&, CallExceptionSpec, Size, Align>  //
1466     >;
1467 
1468 // All qualifier combinations and a noexcept function type
1469 using TestParameterListNonRvalueQualifiersNothrowCall =
1470     NonRvalueQualifiedTestParams<Movable::trivial, Destructible::trivial,
1471                                  NothrowCall::yes, ObjSize::small,
1472                                  ObjAlign::normal>;
1473 using TestParameterListRvalueQualifiersNothrowCall =
1474     RvalueQualifiedTestParams<Movable::trivial, Destructible::trivial,
1475                               NothrowCall::yes, ObjSize::small,
1476                               ObjAlign::normal>;
1477 
1478 // All qualifier combinations and a non-noexcept function type
1479 using TestParameterListNonRvalueQualifiersCallMayThrow =
1480     NonRvalueQualifiedTestParams<Movable::trivial, Destructible::trivial,
1481                                  NothrowCall::no, ObjSize::small,
1482                                  ObjAlign::normal>;
1483 using TestParameterListRvalueQualifiersCallMayThrow =
1484     RvalueQualifiedTestParams<Movable::trivial, Destructible::trivial,
1485                               NothrowCall::no, ObjSize::small,
1486                               ObjAlign::normal>;
1487 
1488 // Lists of various cases that should lead to remote storage
1489 using TestParameterListRemoteMovable = ::testing::Types<
1490     // "Normal" aligned types that are large and have trivial destructors
1491     TestParams<Movable::trivial, Destructible::trivial, _, NothrowCall::no,
1492                ObjSize::large, ObjAlign::normal>,  //
1493     TestParams<Movable::nothrow, Destructible::trivial, _, NothrowCall::no,
1494                ObjSize::large, ObjAlign::normal>,  //
1495     TestParams<Movable::yes, Destructible::trivial, _, NothrowCall::no,
1496                ObjSize::small, ObjAlign::normal>,  //
1497     TestParams<Movable::yes, Destructible::trivial, _, NothrowCall::no,
1498                ObjSize::large, ObjAlign::normal>,  //
1499 
1500     // Same as above but with non-trivial destructors
1501     TestParams<Movable::trivial, Destructible::nothrow, _, NothrowCall::no,
1502                ObjSize::large, ObjAlign::normal>,  //
1503     TestParams<Movable::nothrow, Destructible::nothrow, _, NothrowCall::no,
1504                ObjSize::large, ObjAlign::normal>,  //
1505     TestParams<Movable::yes, Destructible::nothrow, _, NothrowCall::no,
1506                ObjSize::small, ObjAlign::normal>,  //
1507     TestParams<Movable::yes, Destructible::nothrow, _, NothrowCall::no,
1508                ObjSize::large, ObjAlign::normal>  //
1509 
1510 // Dynamic memory allocation for over-aligned data was introduced in C++17.
1511 // See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0035r4.html
1512 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
1513     // Types that must use remote storage because of a large alignment.
1514     ,
1515     TestParams<Movable::trivial, Destructible::trivial, _, NothrowCall::no,
1516                ObjSize::small, ObjAlign::large>,  //
1517     TestParams<Movable::nothrow, Destructible::trivial, _, NothrowCall::no,
1518                ObjSize::small, ObjAlign::large>,  //
1519     TestParams<Movable::trivial, Destructible::nothrow, _, NothrowCall::no,
1520                ObjSize::small, ObjAlign::large>,  //
1521     TestParams<Movable::nothrow, Destructible::nothrow, _, NothrowCall::no,
1522                ObjSize::small, ObjAlign::large>  //
1523 #endif
1524     >;
1525 using TestParameterListRemoteNonMovable = ::testing::Types<
1526     // "Normal" aligned types that are large and have trivial destructors
1527     TestParams<Movable::no, Destructible::trivial, _, NothrowCall::no,
1528                ObjSize::small, ObjAlign::normal>,  //
1529     TestParams<Movable::no, Destructible::trivial, _, NothrowCall::no,
1530                ObjSize::large, ObjAlign::normal>,  //
1531     // Same as above but with non-trivial destructors
1532     TestParams<Movable::no, Destructible::nothrow, _, NothrowCall::no,
1533                ObjSize::small, ObjAlign::normal>,  //
1534     TestParams<Movable::no, Destructible::nothrow, _, NothrowCall::no,
1535                ObjSize::large, ObjAlign::normal>  //
1536     >;
1537 
1538 // Parameters that lead to local storage
1539 using TestParameterListLocal = ::testing::Types<
1540     // Types that meet the requirements and have trivial destructors
1541     TestParams<Movable::trivial, Destructible::trivial, _, NothrowCall::no,
1542                ObjSize::small, ObjAlign::normal>,  //
1543     TestParams<Movable::nothrow, Destructible::trivial, _, NothrowCall::no,
1544                ObjSize::small, ObjAlign::normal>,  //
1545 
1546     // Same as above but with non-trivial destructors
1547     TestParams<Movable::trivial, Destructible::trivial, _, NothrowCall::no,
1548                ObjSize::small, ObjAlign::normal>,  //
1549     TestParams<Movable::nothrow, Destructible::trivial, _, NothrowCall::no,
1550                ObjSize::small, ObjAlign::normal>  //
1551     >;
1552 
1553 // All of the tests that are run for every possible combination of types.
1554 REGISTER_TYPED_TEST_SUITE_P(
1555     AnyInvTestBasic, DefaultConstruction, ConstructionNullptr,
1556     ConstructionNullFunctionPtr, ConstructionNullMemberFunctionPtr,
1557     ConstructionNullMemberObjectPtr, ConstructionMemberFunctionPtr,
1558     ConstructionMemberObjectPtr, ConstructionFunctionReferenceDecay,
1559     ConstructionCompatibleAnyInvocableEmpty,
1560     ConstructionCompatibleAnyInvocableNonempty, InPlaceConstruction,
1561     ConversionToBool, Invocation, InPlaceConstructionInitializerList,
1562     InPlaceNullFunPtrConstruction, InPlaceNullFunPtrConstructionValueInit,
1563     InPlaceNullMemFunPtrConstruction, InPlaceNullMemFunPtrConstructionValueInit,
1564     InPlaceNullMemObjPtrConstruction, InPlaceNullMemObjPtrConstructionValueInit,
1565     InPlaceVoidCovarianceConstruction, MoveConstructionFromEmpty,
1566     MoveConstructionFromNonEmpty, ComparisonWithNullptrEmpty,
1567     ComparisonWithNullptrNonempty, ResultType);
1568 
1569 INSTANTIATE_TYPED_TEST_SUITE_P(
1570     NonRvalueCallMayThrow, AnyInvTestBasic,
1571     TestParameterListNonRvalueQualifiersCallMayThrow);
1572 INSTANTIATE_TYPED_TEST_SUITE_P(RvalueCallMayThrow, AnyInvTestBasic,
1573                                TestParameterListRvalueQualifiersCallMayThrow);
1574 
1575 INSTANTIATE_TYPED_TEST_SUITE_P(RemoteMovable, AnyInvTestBasic,
1576                                TestParameterListRemoteMovable);
1577 INSTANTIATE_TYPED_TEST_SUITE_P(RemoteNonMovable, AnyInvTestBasic,
1578                                TestParameterListRemoteNonMovable);
1579 
1580 INSTANTIATE_TYPED_TEST_SUITE_P(Local, AnyInvTestBasic, TestParameterListLocal);
1581 
1582 INSTANTIATE_TYPED_TEST_SUITE_P(NonRvalueCallNothrow, AnyInvTestBasic,
1583                                TestParameterListNonRvalueQualifiersNothrowCall);
1584 INSTANTIATE_TYPED_TEST_SUITE_P(CallNothrowRvalue, AnyInvTestBasic,
1585                                TestParameterListRvalueQualifiersNothrowCall);
1586 
1587 // Tests for functions that take two operands.
1588 REGISTER_TYPED_TEST_SUITE_P(
1589     AnyInvTestCombinatoric, MoveAssignEmptyEmptyLhsRhs,
1590     MoveAssignEmptyLhsNonemptyRhs, MoveAssignNonemptyEmptyLhsRhs,
1591     MoveAssignNonemptyLhsNonemptyRhs, SelfMoveAssignEmpty,
1592     SelfMoveAssignNonempty, AssignNullptrEmptyLhs,
1593     AssignNullFunctionPtrEmptyLhs, AssignNullMemberFunctionPtrEmptyLhs,
1594     AssignNullMemberObjectPtrEmptyLhs, AssignMemberFunctionPtrEmptyLhs,
1595     AssignMemberObjectPtrEmptyLhs, AssignFunctionReferenceDecayEmptyLhs,
1596     AssignCompatibleAnyInvocableEmptyLhsEmptyRhs,
1597     AssignCompatibleAnyInvocableEmptyLhsNonemptyRhs, AssignNullptrNonemptyLhs,
1598     AssignNullFunctionPtrNonemptyLhs, AssignNullMemberFunctionPtrNonemptyLhs,
1599     AssignNullMemberObjectPtrNonemptyLhs, AssignMemberFunctionPtrNonemptyLhs,
1600     AssignMemberObjectPtrNonemptyLhs, AssignFunctionReferenceDecayNonemptyLhs,
1601     AssignCompatibleAnyInvocableNonemptyLhsEmptyRhs,
1602     AssignCompatibleAnyInvocableNonemptyLhsNonemptyRhs, SwapEmptyLhsEmptyRhs,
1603     SwapEmptyLhsNonemptyRhs, SwapNonemptyLhsEmptyRhs,
1604     SwapNonemptyLhsNonemptyRhs);
1605 
1606 INSTANTIATE_TYPED_TEST_SUITE_P(
1607     NonRvalueCallMayThrow, AnyInvTestCombinatoric,
1608     TestParameterListNonRvalueQualifiersCallMayThrow);
1609 INSTANTIATE_TYPED_TEST_SUITE_P(RvalueCallMayThrow, AnyInvTestCombinatoric,
1610                                TestParameterListRvalueQualifiersCallMayThrow);
1611 
1612 INSTANTIATE_TYPED_TEST_SUITE_P(RemoteMovable, AnyInvTestCombinatoric,
1613                                TestParameterListRemoteMovable);
1614 INSTANTIATE_TYPED_TEST_SUITE_P(RemoteNonMovable, AnyInvTestCombinatoric,
1615                                TestParameterListRemoteNonMovable);
1616 
1617 INSTANTIATE_TYPED_TEST_SUITE_P(Local, AnyInvTestCombinatoric,
1618                                TestParameterListLocal);
1619 
1620 INSTANTIATE_TYPED_TEST_SUITE_P(NonRvalueCallNothrow, AnyInvTestCombinatoric,
1621                                TestParameterListNonRvalueQualifiersNothrowCall);
1622 INSTANTIATE_TYPED_TEST_SUITE_P(RvalueCallNothrow, AnyInvTestCombinatoric,
1623                                TestParameterListRvalueQualifiersNothrowCall);
1624 
1625 REGISTER_TYPED_TEST_SUITE_P(AnyInvTestMovable,
1626                             ConversionConstructionUserDefinedType,
1627                             ConversionConstructionVoidCovariance,
1628                             ConversionAssignUserDefinedTypeEmptyLhs,
1629                             ConversionAssignUserDefinedTypeNonemptyLhs,
1630                             ConversionAssignVoidCovariance);
1631 
1632 INSTANTIATE_TYPED_TEST_SUITE_P(
1633     NonRvalueCallMayThrow, AnyInvTestMovable,
1634     TestParameterListNonRvalueQualifiersCallMayThrow);
1635 INSTANTIATE_TYPED_TEST_SUITE_P(RvalueCallMayThrow, AnyInvTestMovable,
1636                                TestParameterListRvalueQualifiersCallMayThrow);
1637 
1638 INSTANTIATE_TYPED_TEST_SUITE_P(RemoteMovable, AnyInvTestMovable,
1639                                TestParameterListRemoteMovable);
1640 
1641 INSTANTIATE_TYPED_TEST_SUITE_P(Local, AnyInvTestMovable,
1642                                TestParameterListLocal);
1643 
1644 INSTANTIATE_TYPED_TEST_SUITE_P(NonRvalueCallNothrow, AnyInvTestMovable,
1645                                TestParameterListNonRvalueQualifiersNothrowCall);
1646 INSTANTIATE_TYPED_TEST_SUITE_P(RvalueCallNothrow, AnyInvTestMovable,
1647                                TestParameterListRvalueQualifiersNothrowCall);
1648 
1649 REGISTER_TYPED_TEST_SUITE_P(AnyInvTestNoexceptFalse,
1650                             ConversionConstructionConstraints,
1651                             ConversionAssignConstraints);
1652 
1653 INSTANTIATE_TYPED_TEST_SUITE_P(
1654     NonRvalueCallMayThrow, AnyInvTestNoexceptFalse,
1655     TestParameterListNonRvalueQualifiersCallMayThrow);
1656 INSTANTIATE_TYPED_TEST_SUITE_P(RvalueCallMayThrow, AnyInvTestNoexceptFalse,
1657                                TestParameterListRvalueQualifiersCallMayThrow);
1658 
1659 INSTANTIATE_TYPED_TEST_SUITE_P(RemoteMovable, AnyInvTestNoexceptFalse,
1660                                TestParameterListRemoteMovable);
1661 INSTANTIATE_TYPED_TEST_SUITE_P(RemoteNonMovable, AnyInvTestNoexceptFalse,
1662                                TestParameterListRemoteNonMovable);
1663 
1664 INSTANTIATE_TYPED_TEST_SUITE_P(Local, AnyInvTestNoexceptFalse,
1665                                TestParameterListLocal);
1666 
1667 REGISTER_TYPED_TEST_SUITE_P(AnyInvTestNoexceptTrue,
1668                             ConversionConstructionConstraints,
1669                             ConversionAssignConstraints);
1670 
1671 INSTANTIATE_TYPED_TEST_SUITE_P(NonRvalueCallNothrow, AnyInvTestNoexceptTrue,
1672                                TestParameterListNonRvalueQualifiersNothrowCall);
1673 INSTANTIATE_TYPED_TEST_SUITE_P(RvalueCallNothrow, AnyInvTestNoexceptTrue,
1674                                TestParameterListRvalueQualifiersNothrowCall);
1675 
1676 REGISTER_TYPED_TEST_SUITE_P(AnyInvTestNonRvalue,
1677                             ConversionConstructionReferenceWrapper,
1678                             NonMoveableResultType,
1679                             ConversionAssignReferenceWrapperEmptyLhs,
1680                             ConversionAssignReferenceWrapperNonemptyLhs);
1681 
1682 INSTANTIATE_TYPED_TEST_SUITE_P(
1683     NonRvalueCallMayThrow, AnyInvTestNonRvalue,
1684     TestParameterListNonRvalueQualifiersCallMayThrow);
1685 
1686 INSTANTIATE_TYPED_TEST_SUITE_P(RemoteMovable, AnyInvTestNonRvalue,
1687                                TestParameterListRemoteMovable);
1688 INSTANTIATE_TYPED_TEST_SUITE_P(RemoteNonMovable, AnyInvTestNonRvalue,
1689                                TestParameterListRemoteNonMovable);
1690 
1691 INSTANTIATE_TYPED_TEST_SUITE_P(Local, AnyInvTestNonRvalue,
1692                                TestParameterListLocal);
1693 
1694 INSTANTIATE_TYPED_TEST_SUITE_P(NonRvalueCallNothrow, AnyInvTestNonRvalue,
1695                                TestParameterListNonRvalueQualifiersNothrowCall);
1696 
1697 REGISTER_TYPED_TEST_SUITE_P(AnyInvTestRvalue,
1698                             ConversionConstructionReferenceWrapper,
1699                             NonMoveableResultType,
1700                             ConversionAssignReferenceWrapper,
1701                             NonConstCrashesOnSecondCall,
1702                             QualifierIndependentObjectLifetime);
1703 
1704 INSTANTIATE_TYPED_TEST_SUITE_P(RvalueCallMayThrow, AnyInvTestRvalue,
1705                                TestParameterListRvalueQualifiersCallMayThrow);
1706 
1707 INSTANTIATE_TYPED_TEST_SUITE_P(CallNothrowRvalue, AnyInvTestRvalue,
1708                                TestParameterListRvalueQualifiersNothrowCall);
1709 
1710 // Minimal SFINAE testing for platforms where we can't run the tests, but we can
1711 // build binaries for.
1712 static_assert(
1713     std::is_convertible<void (*)(), absl::AnyInvocable<void() &&>>::value, "");
1714 static_assert(!std::is_convertible<void*, absl::AnyInvocable<void() &&>>::value,
1715               "");
1716 
1717 #undef ABSL_INTERNAL_NOEXCEPT_SPEC
1718 
1719 }  // namespace
1720