From 67d165471a1d874d51291fe3c1aea676a6c2991a Mon Sep 17 00:00:00 2001 From: Jakub Mazurkiewicz Date: Tue, 20 Sep 2022 21:28:29 +0200 Subject: [PATCH 1/5] Constexprize `bind_front` tests --- tests/std/tests/P0356R5_bind_front/test.cpp | 85 ++++++++++++--------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/tests/std/tests/P0356R5_bind_front/test.cpp b/tests/std/tests/P0356R5_bind_front/test.cpp index c6ad4e785de..c701ff9720f 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, 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 "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 + 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. { From dd185bf52f474f80e0c5dff3d53276c33a7eec68 Mon Sep 17 00:00:00 2001 From: Jakub Mazurkiewicz Date: Tue, 20 Sep 2022 21:31:35 +0200 Subject: [PATCH 2/5] Constexprize (and enhance!) `bind_back` tests --- tests/std/tests/P2387R3_bind_back/test.cpp | 56 +++++++++++----------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/tests/std/tests/P2387R3_bind_back/test.cpp b/tests/std/tests/P2387R3_bind_back/test.cpp index 175c3497ca0..aaec8c2e231 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; } }; @@ -101,6 +99,33 @@ constexpr bool test_constexpr() { assert(move(bound5)() == "modifiable rvalue"); assert(move(as_const(bound5))() == "const rvalue"); + // 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 + + // 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 +151,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. { From c0e1cd31be18bc6138afab579f026cf7aaf70574 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 21 Sep 2022 19:27:21 -0700 Subject: [PATCH 3/5] Comment nitpicks. --- tests/std/tests/P0356R5_bind_front/test.cpp | 4 ++-- tests/std/tests/P2387R3_bind_back/test.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/std/tests/P0356R5_bind_front/test.cpp b/tests/std/tests/P0356R5_bind_front/test.cpp index c701ff9720f..8475267b62a 100644 --- a/tests/std/tests/P0356R5_bind_front/test.cpp +++ b/tests/std/tests/P0356R5_bind_front/test.cpp @@ -125,7 +125,7 @@ constexpr bool test_constexpr() { cat.name = "Peppermint"; assert(bound3("PURR") == "Peppermint says PURR"); - auto bound4 = bind_front(&Cat::noise, ref(cat)); // stores a reference_wrapper, uses LWG-2219 + 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"); @@ -139,7 +139,7 @@ constexpr bool test_constexpr() { #if _HAS_CXX23 test_movable_only_types(); -#else +#else // _HAS_CXX23 if (!is_constant_evaluated()) { test_movable_only_types(); } diff --git a/tests/std/tests/P2387R3_bind_back/test.cpp b/tests/std/tests/P2387R3_bind_back/test.cpp index aaec8c2e231..fdd335882d4 100644 --- a/tests/std/tests/P2387R3_bind_back/test.cpp +++ b/tests/std/tests/P2387R3_bind_back/test.cpp @@ -102,7 +102,7 @@ constexpr bool test_constexpr() { // Test PMFs. Cat cat{"Peppermint"}; auto bound2 = bind_back(&Cat::noise, "meow"); - assert(bound2(cat) == "Peppermint says meow"); // // call with reference + 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 From ad49ed70ae42c05ed1e29b45daad385d98837f15 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 21 Sep 2022 19:28:27 -0700 Subject: [PATCH 4/5] Use numerical order for the bound variables. --- tests/std/tests/P2387R3_bind_back/test.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/std/tests/P2387R3_bind_back/test.cpp b/tests/std/tests/P2387R3_bind_back/test.cpp index fdd335882d4..6bb2917ff28 100644 --- a/tests/std/tests/P2387R3_bind_back/test.cpp +++ b/tests/std/tests/P2387R3_bind_back/test.cpp @@ -92,13 +92,6 @@ constexpr bool test_constexpr() { bound1(4); assert(value == 74); - // Test "perfect forwarding call wrapper" behavior. - auto bound5 = bind_back(DetectQualifiers{}); - assert(bound5() == "modifiable lvalue"); - assert(as_const(bound5)() == "const lvalue"); - assert(move(bound5)() == "modifiable rvalue"); - assert(move(as_const(bound5))() == "const rvalue"); - // Test PMFs. Cat cat{"Peppermint"}; auto bound2 = bind_back(&Cat::noise, "meow"); @@ -107,6 +100,13 @@ constexpr bool test_constexpr() { cat.name = "Fluffy"; assert(bound3(&cat) == "Fluffy says MEOW"); // call with pointer + // Test "perfect forwarding call wrapper" behavior. + auto bound5 = bind_back(DetectQualifiers{}); + assert(bound5() == "modifiable lvalue"); + assert(as_const(bound5)() == "const lvalue"); + 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) { From 7af91ca6933dc337605338b5e794e9b577abdf67 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 21 Sep 2022 19:33:45 -0700 Subject: [PATCH 5/5] Test bind_back with reference_wrapper. --- tests/std/tests/P2387R3_bind_back/test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/std/tests/P2387R3_bind_back/test.cpp b/tests/std/tests/P2387R3_bind_back/test.cpp index 6bb2917ff28..ab721210e98 100644 --- a/tests/std/tests/P2387R3_bind_back/test.cpp +++ b/tests/std/tests/P2387R3_bind_back/test.cpp @@ -99,6 +99,8 @@ constexpr bool test_constexpr() { 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{});