diff --git a/test/Jamfile b/test/Jamfile index a451e8a..da3d38c 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -41,3 +41,8 @@ run invoke_fn_noexcept_test.cpp ; run invoke_obj_noexcept_test.cpp ; run invoke_mfn_noexcept_test.cpp ; run invoke_md_noexcept_test.cpp ; + +compile invoke_fn_constexpr_test.cpp ; +compile invoke_obj_constexpr_test.cpp ; +compile invoke_mfn_constexpr_test.cpp ; +compile invoke_md_constexpr_test.cpp ; diff --git a/test/invoke_fn_constexpr_test.cpp b/test/invoke_fn_constexpr_test.cpp new file mode 100644 index 0000000..95f56ff --- /dev/null +++ b/test/invoke_fn_constexpr_test.cpp @@ -0,0 +1,40 @@ +// 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 + +#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::invoke( f0 ), -1 ); + BOOST_TEST_EQ( boost::compat::invoke( f1, 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::invoke( f2, 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::invoke( f3, 1, 2, 3 ), 123 ); +} diff --git a/test/invoke_md_constexpr_test.cpp b/test/invoke_md_constexpr_test.cpp new file mode 100644 index 0000000..9f8013e --- /dev/null +++ b/test/invoke_md_constexpr_test.cpp @@ -0,0 +1,43 @@ +// 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 + +#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::invoke( &X::m, X() ), -1 ); + + constexpr X x = {}; + + BOOST_TEST_EQ( boost::compat::invoke( &X::m, x ), -1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::m, &x ), -1 ); + } + +#if !BOOST_WORKAROUND(BOOST_MSVC, >= 1920 && BOOST_MSVC < 1940) + { + BOOST_TEST_EQ( boost::compat::invoke( &X::m, Y() ), -1 ); + + constexpr Y y = {}; + + BOOST_TEST_EQ( boost::compat::invoke( &X::m, y ), -1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::m, &y ), -1 ); + } +#endif +} diff --git a/test/invoke_mfn_constexpr_test.cpp b/test/invoke_mfn_constexpr_test.cpp new file mode 100644 index 0000000..62c2b22 --- /dev/null +++ b/test/invoke_mfn_constexpr_test.cpp @@ -0,0 +1,89 @@ +// 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 +#include + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y)) + +struct X +{ + constexpr int f0() const + { + return -1; + } + + constexpr int f1( int x1 ) const 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::invoke( &X::f0, X() ), -1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f1, X(), 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f2, X(), 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f3, X(), 1, 2, 3 ), 123 ); + } + + { + BOOST_TEST_EQ( boost::compat::invoke( &X::f0, Y() ), -1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f1, Y(), 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f2, Y(), 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f3, Y(), 1, 2, 3 ), 123 ); + } + + { + constexpr X x = {}; + + BOOST_TEST_EQ( boost::compat::invoke( &X::f0, x ), -1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f1, x, 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f2, x, 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f3, x, 1, 2, 3 ), 123 ); + + BOOST_TEST_EQ( boost::compat::invoke( &X::f0, &x ), -1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f1, &x, 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f2, &x, 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f3, &x, 1, 2, 3 ), 123 ); + } + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910) + { + constexpr Y y = {}; + + BOOST_TEST_EQ( boost::compat::invoke( &X::f0, y ), -1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f1, y, 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f2, y, 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f3, y, 1, 2, 3 ), 123 ); + + BOOST_TEST_EQ( boost::compat::invoke( &X::f0, &y ), -1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f1, &y, 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f2, &y, 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::invoke( &X::f3, &y, 1, 2, 3 ), 123 ); + } +#endif +} diff --git a/test/invoke_obj_constexpr_test.cpp b/test/invoke_obj_constexpr_test.cpp new file mode 100644 index 0000000..26368ec --- /dev/null +++ b/test/invoke_obj_constexpr_test.cpp @@ -0,0 +1,50 @@ +// Copyright 2024 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +#define BOOST_TEST_EQ(x, y) STATIC_ASSERT((x) == (y)) + +struct F +{ + constexpr int operator()() const + { + return -1; + } + + constexpr int operator()( int x1 ) const 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; + } +}; + +int main() +{ + { + BOOST_TEST_EQ( boost::compat::invoke( F() ), -1 ); + BOOST_TEST_EQ( boost::compat::invoke( F(), 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::invoke( F(), 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::invoke( F(), 1, 2, 3 ), 123 ); + } + + { + constexpr F f = {}; + + BOOST_TEST_EQ( boost::compat::invoke( f ), -1 ); + BOOST_TEST_EQ( boost::compat::invoke( f, 1 ), 1 ); + BOOST_TEST_EQ( boost::compat::invoke( f, 1, 2 ), 12 ); + BOOST_TEST_EQ( boost::compat::invoke( f, 1, 2, 3 ), 123 ); + } +}