From 30242af2c23932e5eb9b3a81730652c0b5b576fd Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 29 Mar 2024 21:43:34 +0200 Subject: [PATCH] Add constexpr tests for bind_back --- test/Jamfile | 5 + test/bind_back_fn_constexpr_test.cpp | 60 +++++++++++ test/bind_back_md_constexpr_test.cpp | 58 +++++++++++ test/bind_back_mfn_constexpr_test.cpp | 137 ++++++++++++++++++++++++++ test/bind_back_obj_constexpr_test.cpp | 96 ++++++++++++++++++ 5 files changed, 356 insertions(+) create mode 100644 test/bind_back_fn_constexpr_test.cpp create mode 100644 test/bind_back_md_constexpr_test.cpp create mode 100644 test/bind_back_mfn_constexpr_test.cpp create mode 100644 test/bind_back_obj_constexpr_test.cpp diff --git a/test/Jamfile b/test/Jamfile index b0c886d..30aef6d 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -69,3 +69,8 @@ run bind_back_fn_test.cpp ; run bind_back_obj_test.cpp ; run bind_back_mfn_test.cpp ; run bind_back_md_test.cpp ; + +compile bind_back_fn_constexpr_test.cpp ; +compile bind_back_obj_constexpr_test.cpp ; +compile bind_back_mfn_constexpr_test.cpp ; +compile bind_back_md_constexpr_test.cpp ; diff --git a/test/bind_back_fn_constexpr_test.cpp b/test/bind_back_fn_constexpr_test.cpp new file mode 100644 index 0000000..6a25350 --- /dev/null +++ b/test/bind_back_fn_constexpr_test.cpp @@ -0,0 +1,60 @@ +// Copyright 2024 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#if defined(__GNUC__) && __GNUC__ == 7 +# pragma GCC diagnostic ignored "-Wnoexcept-type" +#endif + +#include +#include +#include + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" ) +int main() {} + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y)) + +constexpr int f0() +{ + return -1; +} + +constexpr int f1( int x1 ) noexcept +{ + return x1; +} + +constexpr int f2( int x1, int x2 ) +{ + return 10*x1+x2; +} + +constexpr int f3( int x1, int x2, int x3 ) noexcept +{ + return 100*x1 + 10*x2 + x3; +} + +int main() +{ + BOOST_TEST_EQ( boost::compat::bind_back( f0 )(), -1 ); + BOOST_TEST_EQ( boost::compat::bind_back( f1 )( 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::bind_back( f2 )( 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( f3 )( 1, 2, 3 ), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( f1, 1 )(), 1 ); + BOOST_TEST_EQ( boost::compat::bind_back( f2, 1 )( 2 ), 21 ); + BOOST_TEST_EQ( boost::compat::bind_back( f3, 1 )( 2, 3 ), 231 ); + + BOOST_TEST_EQ( boost::compat::bind_back( f2, 1, 2 )(), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( f3, 1, 2 )( 3 ), 312 ); + + BOOST_TEST_EQ( boost::compat::bind_back( f3, 1, 2, 3 )(), 123 ); +} + +#endif diff --git a/test/bind_back_md_constexpr_test.cpp b/test/bind_back_md_constexpr_test.cpp new file mode 100644 index 0000000..018a155 --- /dev/null +++ b/test/bind_back_md_constexpr_test.cpp @@ -0,0 +1,58 @@ +// Copyright 2024 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" ) +int main() {} + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y)) + +struct X +{ + int m = -1; +}; + +struct Y: public X +{ +}; + +int main() +{ + { + BOOST_TEST_EQ( boost::compat::bind_back( &X::m, X() )(), -1 ); + } + + { + constexpr X x = {}; + + BOOST_TEST_EQ( boost::compat::bind_back( &X::m, x )(), -1 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::m, &x )(), -1 ); + } + +#if !BOOST_WORKAROUND(BOOST_MSVC, >= 1920 && BOOST_MSVC < 1940) + + { + BOOST_TEST_EQ( boost::compat::bind_back( &X::m, Y() )(), -1 ); + } + + { + constexpr Y y = {}; + + BOOST_TEST_EQ( boost::compat::bind_back( &X::m, y )(), -1 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::m, &y )(), -1 ); + } + +#endif +} + +#endif diff --git a/test/bind_back_mfn_constexpr_test.cpp b/test/bind_back_mfn_constexpr_test.cpp new file mode 100644 index 0000000..cba0e94 --- /dev/null +++ b/test/bind_back_mfn_constexpr_test.cpp @@ -0,0 +1,137 @@ +// Copyright 2024 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#if defined(__GNUC__) && __GNUC__ == 7 +# pragma GCC diagnostic ignored "-Wnoexcept-type" +#endif + +#include +#include +#include + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" ) +int main() {} + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y)) + +struct X +{ + constexpr int f0() + { + return -1; + } + + constexpr int f1( int x1 ) noexcept + { + return x1; + } + + constexpr int f2( int x1, int x2 ) const + { + return 10*x1+x2; + } + + constexpr int f3( int x1, int x2, int x3 ) const noexcept + { + return 100*x1 + 10*x2 + x3; + } +}; + +struct Y: public X +{ +}; + +int main() +{ + { + BOOST_TEST_EQ( boost::compat::bind_back( &X::f0 )( X() ), -1 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f1 )( X(), 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( X(), 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( X(), 1, 2, 3 ), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, X(), 1 )(), 1 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, X(), 1, 2 )(), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, X(), 1, 2, 3 )(), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, 1 )( X() ), 1 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( X() ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( X() ), 123 ); + } + + { + BOOST_TEST_EQ( boost::compat::bind_back( &X::f0 )( Y() ), -1 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f1 )( Y(), 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( Y(), 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( Y(), 1, 2, 3 ), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, Y(), 1 )(), 1 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, Y(), 1, 2 )(), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, Y(), 1, 2, 3 )(), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f1, 1 )( Y() ), 1 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( Y() ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( Y() ), 123 ); + } + + { + constexpr X x = {}; + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( x, 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( x, 1, 2, 3 ), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, x, 1, 2 )(), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, x, 1, 2, 3 )(), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( x ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( x ), 123 ); + } + + { + constexpr Y x = {}; + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( x, 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( x, 1, 2, 3 ), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, x, 1, 2 )(), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, x, 1, 2, 3 )(), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( x ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( x ), 123 ); + } + + { + constexpr X x = {}; + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( &x, 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( &x, 1, 2, 3 ), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, &x, 1, 2 )(), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, &x, 1, 2, 3 )(), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( &x ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( &x ), 123 ); + } + + { + constexpr Y x = {}; + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2 )( &x, 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3 )( &x, 1, 2, 3 ), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, &x, 1, 2 )(), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, &x, 1, 2, 3 )(), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( &X::f2, 1, 2 )( &x ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( &X::f3, 1, 2, 3 )( &x ), 123 ); + } +} + +#endif diff --git a/test/bind_back_obj_constexpr_test.cpp b/test/bind_back_obj_constexpr_test.cpp new file mode 100644 index 0000000..3b25b36 --- /dev/null +++ b/test/bind_back_obj_constexpr_test.cpp @@ -0,0 +1,96 @@ +// Copyright 2024 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +#if defined(BOOST_NO_CXX14_CONSTEXPR) + +BOOST_PRAGMA_MESSAGE( "Test skipped because BOOST_NO_CXX14_CONSTEXPR is defined" ) +int main() {} + +#else + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y)) + +struct F1 +{ + constexpr int operator()() + { + return -1; + } + + constexpr int operator()( int x1 ) noexcept + { + return x1; + } + + constexpr int operator()( int x1, int x2 ) const + { + return 10*x1+x2; + } + + constexpr int operator()( int x1, int x2, int x3 ) const noexcept + { + return 100*x1 + 10*x2 + x3; + } +}; + +struct F2 +{ + constexpr int operator()( int x1, int x2 ) & + { + return 100*x1 + 10*x2 + 1; + } + + constexpr int operator()( int x1, int x2 ) const & + { + return 100*x1 + 10*x2 + 2; + } + constexpr int operator()( int x1, int x2 ) && + { + return 100*x1 + 10*x2 + 3; + } + constexpr int operator()( int x1, int x2 ) const && + { + return 100*x1 + 10*x2 + 4; + } +}; + +int main() +{ + { + BOOST_TEST_EQ( boost::compat::bind_back( F1() )(), -1 ); + BOOST_TEST_EQ( boost::compat::bind_back( F1() )( 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::bind_back( F1() )( 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( F1() )( 1, 2, 3 ), 123 ); + + BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1 )(), 1 ); + BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1 )( 2 ), 21 ); + BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1 )( 2, 3 ), 231 ); + + BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1, 2 )(), 12 ); + BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1, 2 )( 3 ), 312 ); + + BOOST_TEST_EQ( boost::compat::bind_back( F1(), 1, 2, 3 )(), 123 ); + } + + { + BOOST_TEST_EQ( boost::compat::bind_back( F2(), 9 )( 8 ), 893 ); + } + + { + constexpr auto fn = boost::compat::bind_back( F2(), 9 ); + BOOST_TEST_EQ( fn( 8 ), 892 ); + } + + { + constexpr auto fn = boost::compat::bind_back( F2(), 9 ); + BOOST_TEST_EQ( std::move( fn )( 8 ), 894 ); + } +} + +#endif