@@ -174,6 +174,7 @@ TEST_P(DerivedTest, DoesBlah) {
174
174
175
175
#endif // 0
176
176
177
+ #include < functional>
177
178
#include < iterator>
178
179
#include < utility>
179
180
@@ -413,7 +414,8 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
413
414
// Synopsis:
414
415
// ConvertGenerator<T>(gen)
415
416
// - returns a generator producing the same elements as generated by gen, but
416
- // each element is static_cast to type T before being returned
417
+ // each T-typed element is static_cast to a type deduced from the interface
418
+ // that accepts this generator, and then returned
417
419
//
418
420
// It is useful when using the Combine() function to get the generated
419
421
// parameters in a custom type instead of std::tuple
@@ -441,10 +443,65 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
441
443
// Combine(Values("cat", "dog"),
442
444
// Values(BLACK, WHITE))));
443
445
//
444
- template <typename T>
445
- internal::ParamConverterGenerator<T> ConvertGenerator (
446
- internal::ParamGenerator<T> gen) {
447
- return internal::ParamConverterGenerator<T>(gen);
446
+ template <typename RequestedT>
447
+ internal::ParamConverterGenerator<RequestedT> ConvertGenerator (
448
+ internal::ParamGenerator<RequestedT> gen) {
449
+ return internal::ParamConverterGenerator<RequestedT>(std::move (gen));
450
+ }
451
+
452
+ // As above, but takes a callable as a second argument. The callable converts
453
+ // the generated parameter to the test fixture's parameter type. This allows you
454
+ // to use a parameter type that does not have a converting constructor from the
455
+ // generated type.
456
+ //
457
+ // Example:
458
+ //
459
+ // This will instantiate tests in test suite AnimalTest each one with
460
+ // the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
461
+ // tuple("dog", BLACK), and tuple("dog", WHITE):
462
+ //
463
+ // enum Color { BLACK, GRAY, WHITE };
464
+ // struct ParamType {
465
+ // std::string animal;
466
+ // Color color;
467
+ // };
468
+ // class AnimalTest
469
+ // : public testing::TestWithParam<ParamType> {...};
470
+ //
471
+ // TEST_P(AnimalTest, AnimalLooksNice) {...}
472
+ //
473
+ // INSTANTIATE_TEST_SUITE_P(
474
+ // AnimalVariations, AnimalTest,
475
+ // ConvertGenerator(Combine(Values("cat", "dog"), Values(BLACK, WHITE)),
476
+ // [](std::tuple<std::string, Color> t) {
477
+ // return ParamType{.animal = std::get<0>(t),
478
+ // .color = std::get<1>(t)};
479
+ // }));
480
+ //
481
+ template <typename T, int &... ExplicitArgumentBarrier, typename Gen,
482
+ typename Func,
483
+ typename StdFunction = decltype(std::function(std::declval<Func>()))>
484
+ internal::ParamConverterGenerator<T, StdFunction> ConvertGenerator(Gen&& gen,
485
+ Func&& f) {
486
+ return internal::ParamConverterGenerator<T, StdFunction>(
487
+ std::forward<Gen>(gen), std::forward<Func>(f));
488
+ }
489
+
490
+ // As above, but infers the T from the supplied std::function instead of
491
+ // having the caller specify it.
492
+ template <int &... ExplicitArgumentBarrier, typename Gen, typename Func,
493
+ typename StdFunction = decltype(std::function(std::declval<Func>()))>
494
+ auto ConvertGenerator (Gen&& gen, Func&& f) {
495
+ constexpr bool is_single_arg_std_function =
496
+ internal::IsSingleArgStdFunction<StdFunction>::value;
497
+ if constexpr (is_single_arg_std_function) {
498
+ return ConvertGenerator<
499
+ typename internal::FuncSingleParamType<StdFunction>::type>(
500
+ std::forward<Gen>(gen), std::forward<Func>(f));
501
+ } else {
502
+ static_assert (is_single_arg_std_function,
503
+ " The call signature must contain a single argument." );
504
+ }
448
505
}
449
506
450
507
#define TEST_P (test_suite_name, test_name ) \
@@ -469,7 +526,7 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
469
526
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
470
527
return 0 ; \
471
528
} \
472
- GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int gtest_registering_dummy_; \
529
+ [[maybe_unused]] static int gtest_registering_dummy_; \
473
530
}; \
474
531
int GTEST_TEST_CLASS_NAME_ (test_suite_name, \
475
532
test_name)::gtest_registering_dummy_ = \
@@ -493,39 +550,38 @@ internal::ParamConverterGenerator<T> ConvertGenerator(
493
550
#define GTEST_GET_FIRST_ (first, ...) first
494
551
#define GTEST_GET_SECOND_ (first, second, ...) second
495
552
496
- #define INSTANTIATE_TEST_SUITE_P (prefix, test_suite_name, ...) \
497
- static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
498
- gtest_##prefix##test_suite_name##_EvalGenerator_() { \
499
- return GTEST_EXPAND_ (GTEST_GET_FIRST_ (__VA_ARGS__, DUMMY_PARAM_)); \
500
- } \
501
- static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
502
- const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
503
- if (::testing::internal::AlwaysFalse ()) { \
504
- ::testing::internal::TestNotEmpty (GTEST_EXPAND_(GTEST_GET_SECOND_( \
505
- __VA_ARGS__, \
506
- ::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
507
- DUMMY_PARAM_))); \
508
- auto t = std::make_tuple (__VA_ARGS__); \
509
- static_assert (std::tuple_size<decltype (t)>::value <= 2 , \
510
- " Too Many Args!" ); \
511
- } \
512
- return ((GTEST_EXPAND_ (GTEST_GET_SECOND_ ( \
513
- __VA_ARGS__, \
514
- ::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
515
- DUMMY_PARAM_))))(info); \
516
- } \
517
- GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int \
518
- gtest_##prefix##test_suite_name##_dummy_ = \
519
- ::testing::UnitTest::GetInstance () \
520
- ->parameterized_test_registry() \
521
- .GetTestSuitePatternHolder<test_suite_name>( \
522
- GTEST_STRINGIFY_ (test_suite_name), \
523
- ::testing::internal::CodeLocation(__FILE__, __LINE__)) \
524
- ->AddTestSuiteInstantiation( \
525
- GTEST_STRINGIFY_ (prefix), \
526
- >est_##prefix##test_suite_name##_EvalGenerator_, \
527
- >est_##prefix##test_suite_name##_EvalGenerateName_, \
528
- __FILE__, __LINE__)
553
+ #define INSTANTIATE_TEST_SUITE_P (prefix, test_suite_name, ...) \
554
+ static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
555
+ gtest_##prefix##test_suite_name##_EvalGenerator_() { \
556
+ return GTEST_EXPAND_ (GTEST_GET_FIRST_ (__VA_ARGS__, DUMMY_PARAM_)); \
557
+ } \
558
+ static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
559
+ const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
560
+ if (::testing::internal::AlwaysFalse ()) { \
561
+ ::testing::internal::TestNotEmpty (GTEST_EXPAND_(GTEST_GET_SECOND_( \
562
+ __VA_ARGS__, \
563
+ ::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
564
+ DUMMY_PARAM_))); \
565
+ auto t = std::make_tuple (__VA_ARGS__); \
566
+ static_assert (std::tuple_size<decltype (t)>::value <= 2 , \
567
+ " Too Many Args!" ); \
568
+ } \
569
+ return ((GTEST_EXPAND_ (GTEST_GET_SECOND_ ( \
570
+ __VA_ARGS__, \
571
+ ::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
572
+ DUMMY_PARAM_))))(info); \
573
+ } \
574
+ [[maybe_unused]] static int gtest_##prefix##test_suite_name##_dummy_ = \
575
+ ::testing::UnitTest::GetInstance () \
576
+ ->parameterized_test_registry() \
577
+ .GetTestSuitePatternHolder<test_suite_name>( \
578
+ GTEST_STRINGIFY_ (test_suite_name), \
579
+ ::testing::internal::CodeLocation(__FILE__, __LINE__)) \
580
+ ->AddTestSuiteInstantiation( \
581
+ GTEST_STRINGIFY_ (prefix), \
582
+ >est_##prefix##test_suite_name##_EvalGenerator_, \
583
+ >est_##prefix##test_suite_name##_EvalGenerateName_, __FILE__, \
584
+ __LINE__)
529
585
530
586
// Allow Marking a Parameterized test class as not needing to be instantiated.
531
587
#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST (T ) \
0 commit comments