diff options
Diffstat (limited to 'src/boost/libs/parameter/test/preprocessor.cpp')
-rw-r--r-- | src/boost/libs/parameter/test/preprocessor.cpp | 689 |
1 files changed, 689 insertions, 0 deletions
diff --git a/src/boost/libs/parameter/test/preprocessor.cpp b/src/boost/libs/parameter/test/preprocessor.cpp new file mode 100644 index 000000000..95071b134 --- /dev/null +++ b/src/boost/libs/parameter/test/preprocessor.cpp @@ -0,0 +1,689 @@ +// Copyright Daniel Wallin 2006. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/parameter/preprocessor.hpp> +#include <boost/parameter/binding.hpp> +#include <boost/parameter/config.hpp> +#include "basics.hpp" + +#if defined(BOOST_PARAMETER_CAN_USE_MP11) +#include <type_traits> +#else +#include <boost/mpl/bool.hpp> +#include <boost/mpl/if.hpp> +#include <boost/type_traits/is_same.hpp> +#endif + +namespace test { + + BOOST_PARAMETER_BASIC_FUNCTION((int), f, test::tag, + (required + (tester, *) + (name, *) + ) + (optional + (value, *) + (index, (int)) + ) + ) + { + typedef typename boost::parameter::binding< + Args,test::tag::index,int& + >::type index_type; + +#if defined(BOOST_PARAMETER_CAN_USE_MP11) + static_assert( + std::is_same<index_type,int&>::value + , "index_type == int&" + ); +#else + BOOST_MPL_ASSERT(( + typename boost::mpl::if_< + boost::is_same<index_type,int&> + , boost::mpl::true_ + , boost::mpl::false_ + >::type + )); +#endif + + args[test::_tester]( + args[test::_name] + , args[test::_value | 1.f] + , args[test::_index | 2] + ); + + return 1; + } +} // namespace test + +#include <boost/parameter/value_type.hpp> + +#if !defined(BOOST_PARAMETER_CAN_USE_MP11) +#include <boost/type_traits/remove_const.hpp> +#endif + +namespace test { + + BOOST_PARAMETER_BASIC_FUNCTION((int), g, test::tag, + (required + (tester, *) + (name, *) + ) + (optional + (value, *) + (index, (int)) + ) + ) + { + typedef typename boost::parameter::value_type< + Args,test::tag::index,int + >::type index_type; + +#if defined(BOOST_PARAMETER_CAN_USE_MP11) + static_assert( + std::is_same< + typename std::remove_const<index_type>::type + , int + >::value + , "remove_const<index_type>::type == int" + ); +#else + BOOST_MPL_ASSERT(( + typename boost::mpl::if_< + boost::is_same< + typename boost::remove_const<index_type>::type + , int + > + , boost::mpl::true_ + , boost::mpl::false_ + >::type + )); +#endif + + args[test::_tester]( + args[test::_name] + , args[test::_value | 1.f] + , args[test::_index | 2] + ); + + return 1; + } +} // namespace test + +#if !defined(BOOST_PARAMETER_CAN_USE_MP11) +#include <boost/type_traits/remove_reference.hpp> +#endif + +namespace test { + + BOOST_PARAMETER_FUNCTION((int), h, test::tag, + (required + (tester, *) + (name, *) + ) + (optional + (value, *, 1.f) + (index, (int), 2) + ) + ) + { +#if defined(BOOST_PARAMETER_CAN_USE_MP11) + static_assert( + std::is_same< + typename std::remove_const< + typename std::remove_reference<index_type>::type + >::type + , int + >::value + , "remove_cref<index_type>::type == int" + ); +#elif !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) && \ + !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + BOOST_MPL_ASSERT(( + typename boost::mpl::if_< + boost::is_same< + typename boost::remove_const< + typename boost::remove_reference<index_type>::type + >::type + , int + > + , boost::mpl::true_ + , boost::mpl::false_ + >::type + )); +#endif // BOOST_PARAMETER_CAN_USE_MP11 || Borland/MSVC workarounds not needed + + tester(name, value, index); + + return 1; + } + + BOOST_PARAMETER_FUNCTION((int), h2, test::tag, + (required + (tester, *) + (name, *) + ) + (optional + (value, *, 1.f) + (index, (int), static_cast<int>(value * 2)) + ) + ) + { +#if defined(BOOST_PARAMETER_CAN_USE_MP11) + static_assert( + std::is_same< + typename std::remove_const< + typename std::remove_reference<index_type>::type + >::type + , int + >::value + , "remove_cref<index_type>::type == int" + ); +#elif !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) && \ + !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) + BOOST_MPL_ASSERT(( + typename boost::mpl::if_< + boost::is_same< + typename boost::remove_const< + typename boost::remove_reference<index_type>::type + >::type + , int + > + , boost::mpl::true_ + , boost::mpl::false_ + >::type + )); +#endif // BOOST_PARAMETER_CAN_USE_MP11 || Borland/MSVC workarounds not needed + + tester(name, value, index); + + return 1; + } +} // namespace test + +#include <string> + +#if !defined(BOOST_NO_SFINAE) +#include <boost/parameter/aux_/preprocessor/nullptr.hpp> +#include <boost/core/enable_if.hpp> +#if !defined(BOOST_PARAMETER_CAN_USE_MP11) +#include <boost/type_traits/is_base_of.hpp> +#include <boost/type_traits/is_convertible.hpp> +#endif +#endif + +namespace test { + + struct base_0 + { + float f; + int i; + + template <typename Args> + explicit base_0( + Args const& args +#if !defined(BOOST_NO_SFINAE) + , typename boost::disable_if< + typename boost::mpl::if_< + boost::is_base_of<base_0,Args> + , boost::mpl::true_ + , boost::mpl::false_ + >::type + >::type* = BOOST_PARAMETER_AUX_PP_NULLPTR +#endif // BOOST_NO_SFINAE + ) : f(args[test::_value | 1.f]), i(args[test::_index | 2]) + { + } + }; + + struct class_0 : test::base_0 + { + BOOST_PARAMETER_CONSTRUCTOR(class_0, (test::base_0), test::tag, + (optional + (value, *) + (index, *) + ) + ) + + BOOST_PARAMETER_BASIC_FUNCTION_CALL_OPERATOR((int), test::tag, + (optional + (value, *) + (index, *) + ) + ) + { + this->f = args[test::_value | 2.f]; + this->i = args[test::_index | 1]; + return 1; + } + }; + + struct base_1 + { + template <typename Args> + explicit base_1( + Args const& args +#if !defined(BOOST_NO_SFINAE) + , typename boost::disable_if< +#if defined(BOOST_PARAMETER_CAN_USE_MP11) + std::is_base_of<base_1,Args> +#else + typename boost::mpl::if_< + boost::is_base_of<base_1,Args> + , boost::mpl::true_ + , boost::mpl::false_ + >::type +#endif + >::type* = BOOST_PARAMETER_AUX_PP_NULLPTR +#endif // BOOST_NO_SFINAE + ) + { + args[test::_tester]( + args[test::_name] + , args[test::_value | 1.f] + , args[test::_index | 2] + ); + } + }; + + struct class_1 : test::base_1 + { + BOOST_PARAMETER_CONSTRUCTOR(class_1, (test::base_1), test::tag, + (required + (tester, *) + (name, *) + ) + (optional + (value, *) + (index, *) + ) + ) + + BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((int), f, test::tag, + (required + (tester, *) + (name, *) + ) + (optional + (value, *) + (index, *) + ) + ) + { + args[test::_tester]( + args[test::_name] + , args[test::_value | 1.f] + , args[test::_index | 2] + ); + + return 1; + } + + BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION((int), f, test::tag, + (required + (tester, *) + (name, *) + ) + (optional + (value, *) + (index, *) + ) + ) + { + args[test::_tester]( + args[test::_name] + , args[test::_value | 1.f] + , args[test::_index | 2] + ); + + return 1; + } + + BOOST_PARAMETER_MEMBER_FUNCTION((int), f2, test::tag, + (required + (tester, *) + (name, *) + ) + (optional + (value, *, 1.f) + (index, *, 2) + ) + ) + { + tester(name, value, index); + return 1; + } + + BOOST_PARAMETER_CONST_MEMBER_FUNCTION((int), f2, test::tag, + (required + (tester, *) + (name, *) + ) + (optional + (value, *, 1.f) + (index, *, 2) + ) + ) + { + tester(name, value, index); + return 1; + } + + BOOST_PARAMETER_MEMBER_FUNCTION((int), static f_static, test::tag, + (required + (tester, *) + (name, *) + ) + (optional + (value, *, 1.f) + (index, *, 2) + ) + ) + { + tester(name, value, index); + return 1; + } + + BOOST_PARAMETER_FUNCTION_CALL_OPERATOR((int), test::tag, + (required + (tester, *) + (name, *) + ) + (optional + (value, *, 1.f) + (index, *, 2) + ) + ) + { + tester(name, value, index); + return 1; + } + + BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR((int), test::tag, + (required + (tester, *) + (name, *) + ) + (optional + (value, *, 1.f) + (index, *, 2) + ) + ) + { + tester(name, value, index); + return 1; + } + }; + + BOOST_PARAMETER_FUNCTION((int), sfinae, test::tag, + (required + (name, (std::string)) + ) + ) + { + return 1; + } + +#if !defined(BOOST_NO_SFINAE) + // On compilers that actually support SFINAE, add another overload + // that is an equally good match and can only be in the overload set + // when the others are not. This tests that the SFINAE is actually + // working. On all other compilers we're just checking that everything + // about SFINAE-enabled code will work, except of course the SFINAE. + template <typename A0> + typename boost::enable_if< +#if defined(BOOST_PARAMETER_CAN_USE_MP11) + std::is_same<int,A0> +#else + typename boost::mpl::if_< + boost::is_same<int,A0> + , boost::mpl::true_ + , boost::mpl::false_ + >::type +#endif + , int + >::type + sfinae(A0 const& a0) + { + return 0; + } +#endif // BOOST_NO_SFINAE + + struct predicate + { + template <typename T, typename Args> +#if defined(BOOST_PARAMETER_CAN_USE_MP11) + using fn = std::is_convertible<T,std::string>; +#else + struct apply + : boost::mpl::if_< + boost::is_convertible<T,std::string> + , boost::mpl::true_ + , boost::mpl::false_ + > + { + }; +#endif + + BOOST_PARAMETER_BASIC_CONST_FUNCTION_CALL_OPERATOR((bool), test::tag, + (required + (value, *) + (index, *) + ) + ) + { + return args[test::_value] < args[test::_index]; + } + }; + + BOOST_PARAMETER_FUNCTION((int), sfinae1, test::tag, + (required + (name, *(test::predicate)) + ) + ) + { + return 1; + } + +#if !defined(BOOST_NO_SFINAE) + // On compilers that actually support SFINAE, add another overload + // that is an equally good match and can only be in the overload set + // when the others are not. This tests that the SFINAE is actually + // working. On all other compilers we're just checking that everything + // about SFINAE-enabled code will work, except of course the SFINAE. + template <typename A0> + typename boost::enable_if< +#if defined(BOOST_PARAMETER_CAN_USE_MP11) + std::is_same<int,A0> +#else + typename boost::mpl::if_< + boost::is_same<int,A0> + , boost::mpl::true_ + , boost::mpl::false_ + >::type +#endif + , int + >::type + sfinae1(A0 const& a0) + { + return 0; + } +#endif // BOOST_NO_SFINAE + + struct udt + { + udt(int foo_, int bar_) : foo(foo_), bar(bar_) + { + } + + int foo; + int bar; + }; + + BOOST_PARAMETER_FUNCTION((int), lazy_defaults, test::tag, + (required + (name, *) + ) + (optional + (value, *, name.foo) + (index, *, name.bar) + ) + ) + { + return 0; + } +} // namespace test + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1300) +#include <boost/parameter/aux_/as_lvalue.hpp> +#endif + +#include <boost/core/lightweight_test.hpp> + +int main() +{ + test::f( + test::values(std::string("foo"), 1.f, 2) + , std::string("foo") + ); + test::f( + test::_tester = test::values(std::string("foo"), 1.f, 2) + , test::_name = std::string("foo") + ); + + int index_lvalue = 2; + + test::f( + test::_tester = test::values(std::string("foo"), 1.f, 2) + , test::_name = std::string("foo") + , test::_value = 1.f + , test::_index = index_lvalue + ); + + test::f( + test::values(std::string("foo"), 1.f, 2) + , std::string("foo") + , 1.f + , index_lvalue + ); + + test::g( + test::values(std::string("foo"), 1.f, 2) + , std::string("foo") + , 1.f +#if BOOST_WORKAROUND(BOOST_MSVC, == 1300) + , boost::parameter::aux::as_lvalue(2) +#else + , 2 +#endif + ); + + test::h( + test::values(std::string("foo"), 1.f, 2) + , std::string("foo") + , 1.f +#if BOOST_WORKAROUND(BOOST_MSVC, == 1300) + , boost::parameter::aux::as_lvalue(2) +#else + , 2 +#endif + ); + + test::h2( + test::_tester = test::values(std::string("foo"), 1.f, 2) + , test::_name = std::string("foo") + , test::_value = 1.f + ); + + test::class_0 u; + + BOOST_TEST(2 == u.i); + BOOST_TEST(1.f == u.f); + + u(); + + BOOST_TEST(1 == u.i); + BOOST_TEST(2.f == u.f); + + test::class_1 x( + test::values(std::string("foo"), 1.f, 2) + , std::string("foo") + , test::_index = 2 + ); + + x.f(test::values(std::string("foo"), 1.f, 2), std::string("foo")); + x.f( + test::_tester = test::values(std::string("foo"), 1.f, 2) + , test::_name = std::string("foo") + ); + x.f2(test::values(std::string("foo"), 1.f, 2), std::string("foo")); + x.f2( + test::_tester = test::values(std::string("foo"), 1.f, 2) + , test::_name = std::string("foo") + ); + x(test::values(std::string("foo"), 1.f, 2), std::string("foo")); + x( + test::_tester = test::values(std::string("foo"), 1.f, 2) + , test::_name = std::string("foo") + ); + + test::class_1 const& x_const = x; + + x_const.f(test::values(std::string("foo"), 1.f, 2), std::string("foo")); + x_const.f( + test::_tester = test::values(std::string("foo"), 1.f, 2) + , test::_name = std::string("foo") + ); + x_const.f2(test::values(std::string("foo"), 1.f, 2), std::string("foo")); + x_const.f2( + test::_tester = test::values(std::string("foo"), 1.f, 2) + , test::_name = std::string("foo") + ); + test::class_1::f_static( + test::values(std::string("foo"), 1.f, 2) + , std::string("foo") + ); + test::class_1::f_static( + test::_tester = test::values(std::string("foo"), 1.f, 2) + , test::_name = std::string("foo") + ); + x_const(test::values(std::string("foo"), 1.f, 2), std::string("foo")); + x_const( + test::_tester = test::values(std::string("foo"), 1.f, 2) + , test::_name = std::string("foo") + ); + + test::predicate p; + test::predicate const& p_const = p; + + BOOST_TEST(p_const(3, 4)); + BOOST_TEST(!p_const(4, 3)); + BOOST_TEST(!p_const(test::_index = 3, test::_value = 4)); + +#if !defined(BOOST_NO_SFINAE) && \ + !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592)) + // GCC 3- tries to bind string literals + // to non-const references to char const*. + // BOOST_TEST(test::sfinae("foo") == 1); + char const* foo_str = "foo"; + BOOST_TEST(test::sfinae(foo_str) == 1); + BOOST_TEST(test::sfinae(1) == 0); + +#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) + // Sun actually eliminates the desired overload for some reason. + // Disabling this part of the test because SFINAE abilities are + // not the point of this test. + BOOST_TEST(test::sfinae1(foo_str) == 1); +#endif + + BOOST_TEST(test::sfinae1(1) == 0); +#endif + + test::lazy_defaults(test::_name = test::udt(0, 1)); + test::lazy_defaults(test::_name = 0, test::_value = 1, test::_index = 2); + + return boost::report_errors(); +} + |