diff --git a/tests/std/tests/P0356R5_bind_front/test.cpp b/tests/std/tests/P0356R5_bind_front/test.cpp index c6ad4e785de..8475267b62a 100644 --- a/tests/std/tests/P0356R5_bind_front/test.cpp +++ b/tests/std/tests/P0356R5_bind_front/test.cpp @@ -30,7 +30,7 @@ constexpr int f3(int x, int y, int z) { struct Cat { string name; - string noise(const string& s) const { + constexpr string noise(const string& s) const { return name + " says " + s; } }; @@ -53,6 +53,26 @@ struct DetectQualifiers { } }; +_CONSTEXPR23 void test_movable_only_types() { + auto unique_lambda = [up1 = make_unique(1200)](unique_ptr&& up2) { + if (up1 && up2) { + return make_unique(*up1 + *up2); + } else if (up1) { + return make_unique(*up1 * -1); + } else if (up2) { + return make_unique(*up2 * -10); + } else { + return make_unique(-9000); + } + }; + auto bound6 = bind_front(move(unique_lambda), make_unique(34)); + assert(*unique_lambda(make_unique(56)) == -560); + assert(*move(bound6)() == 1234); + auto bound7 = move(bound6); + assert(*move(bound6)() == -9000); + assert(*move(bound7)() == 1234); +} + constexpr bool test_constexpr() { // Test varying numbers of arguments. assert(bind_front(f0)() == 1729); @@ -92,6 +112,24 @@ constexpr bool test_constexpr() { bound1(4); assert(value == 234); + // Test PMFs. + Cat cat{"Peppermint"}; + auto bound2 = bind_front(&Cat::noise, cat); // stores a copy + assert(bound2("meow") == "Peppermint says meow"); + cat.name = "Fluffy"; + assert(cat.noise("hiss") == "Fluffy says hiss"); + assert(bound2("purr") == "Peppermint says purr"); + + auto bound3 = bind_front(&Cat::noise, &cat); // stores a pointer + assert(bound3("MEOW") == "Fluffy says MEOW"); + cat.name = "Peppermint"; + assert(bound3("PURR") == "Peppermint says PURR"); + + auto bound4 = bind_front(&Cat::noise, ref(cat)); // stores a reference_wrapper + assert(bound4("Why do you keep renaming me?") == "Peppermint says Why do you keep renaming me?"); + cat.name = "Cat"; + assert(bound4("You can't rename me anymore, Human") == "Cat says You can't rename me anymore, Human"); + // Test "perfect forwarding call wrapper" behavior. auto bound5 = bind_front(DetectQualifiers{}); assert(bound5() == "modifiable lvalue"); @@ -99,6 +137,14 @@ constexpr bool test_constexpr() { assert(move(bound5)() == "modifiable rvalue"); assert(move(as_const(bound5))() == "const rvalue"); +#if _HAS_CXX23 + test_movable_only_types(); +#else // _HAS_CXX23 + if (!is_constant_evaluated()) { + test_movable_only_types(); + } +#endif // _HAS_CXX23 + // Test decay when binding. const int arr[] = {11, 22, 33}; const int three = 3; @@ -128,43 +174,6 @@ int main() { assert(test_constexpr()); static_assert(test_constexpr()); - // Test PMFs. - Cat cat{"Peppermint"}; - auto bound2 = bind_front(&Cat::noise, cat); // stores a copy - assert(bound2("meow") == "Peppermint says meow"); - cat.name = "Fluffy"; - assert(cat.noise("hiss") == "Fluffy says hiss"); - assert(bound2("purr") == "Peppermint says purr"); - - auto bound3 = bind_front(&Cat::noise, &cat); // stores a pointer - assert(bound3("MEOW") == "Fluffy says MEOW"); - cat.name = "Peppermint"; - assert(bound3("PURR") == "Peppermint says PURR"); - - auto bound4 = bind_front(&Cat::noise, ref(cat)); // stores a reference_wrapper, uses LWG-2219 - assert(bound4("Why do you keep renaming me?") == "Peppermint says Why do you keep renaming me?"); - cat.name = "Cat"; - assert(bound4("You can't rename me anymore, Human") == "Cat says You can't rename me anymore, Human"); - - // Test movable-only types. - auto unique_lambda = [up1 = make_unique(1200)](unique_ptr&& up2) { - if (up1 && up2) { - return make_unique(*up1 + *up2); - } else if (up1) { - return make_unique(*up1 * -1); - } else if (up2) { - return make_unique(*up2 * -10); - } else { - return make_unique(-9000); - } - }; - auto bound6 = bind_front(move(unique_lambda), make_unique(34)); - assert(*unique_lambda(make_unique(56)) == -560); - assert(*move(bound6)() == 1234); - auto bound7 = move(bound6); - assert(*move(bound6)() == -9000); - assert(*move(bound7)() == 1234); - // Also test GH-1292 "bind_front violates [func.require]p8" in which the return type of bind_front inadvertently // depends on the value category and/or cv-qualification of its arguments. { diff --git a/tests/std/tests/P2387R3_bind_back/test.cpp b/tests/std/tests/P2387R3_bind_back/test.cpp index 175c3497ca0..ab721210e98 100644 --- a/tests/std/tests/P2387R3_bind_back/test.cpp +++ b/tests/std/tests/P2387R3_bind_back/test.cpp @@ -29,11 +29,9 @@ constexpr int f3(int x, int y, int z) { struct Cat { string name; -}; -struct CatNoise { - string noise(const string& s, const Cat& cat) const { - return cat.name + " says " + s; + constexpr string noise(const string& s) const { + return name + " says " + s; } }; @@ -94,6 +92,16 @@ constexpr bool test_constexpr() { bound1(4); assert(value == 74); + // Test PMFs. + Cat cat{"Peppermint"}; + auto bound2 = bind_back(&Cat::noise, "meow"); + assert(bound2(cat) == "Peppermint says meow"); // call with reference + auto bound3 = bind_back(&Cat::noise, "MEOW"); + cat.name = "Fluffy"; + assert(bound3(&cat) == "Fluffy says MEOW"); // call with pointer + auto bound4 = bind_back(&Cat::noise, "HISS"); + assert(bound4(ref(cat)) == "Fluffy says HISS"); // call with reference_wrapper + // Test "perfect forwarding call wrapper" behavior. auto bound5 = bind_back(DetectQualifiers{}); assert(bound5() == "modifiable lvalue"); @@ -101,6 +109,25 @@ constexpr bool test_constexpr() { assert(move(bound5)() == "modifiable rvalue"); assert(move(as_const(bound5))() == "const rvalue"); + // Test movable-only types. + auto unique_lambda = [up1 = make_unique(1200)](unique_ptr&& up2) { + if (up1 && up2) { + return make_unique(*up1 + *up2); + } else if (up1) { + return make_unique(*up1 * -1); + } else if (up2) { + return make_unique(*up2 * -10); + } else { + return make_unique(-9000); + } + }; + auto bound6 = bind_back(move(unique_lambda), make_unique(34)); + assert(*unique_lambda(make_unique(56)) == -560); + assert(*move(bound6)() == 1234); + auto bound7 = move(bound6); + assert(*move(bound6)() == -9000); + assert(*move(bound7)() == 1234); + // Test decay when binding. const int arr[] = {11, 22, 33}; const int three = 3; @@ -126,33 +153,10 @@ constexpr bool test_constexpr() { return true; } -void test_move_only_types() { - // Test movable-only types. - auto unique_lambda = [up1 = make_unique(1200)](unique_ptr&& up2) { - if (up1 && up2) { - return make_unique(*up1 + *up2); - } else if (up1) { - return make_unique(*up1 * -1); - } else if (up2) { - return make_unique(*up2 * -10); - } else { - return make_unique(-9000); - } - }; - auto bound6 = bind_back(move(unique_lambda), make_unique(34)); - assert(*unique_lambda(make_unique(56)) == -560); - assert(*move(bound6)() == 1234); - auto bound7 = move(bound6); - assert(*move(bound6)() == -9000); - assert(*move(bound7)() == 1234); -} - int main() { assert(test_constexpr()); static_assert(test_constexpr()); - test_move_only_types(); - // Also test GH-1292 "bind_front violates [func.require]p8" in which the return type of bind_front inadvertently // depends on the value category and/or cv-qualification of its arguments. {