diff options
Diffstat (limited to 'src/boost/libs/parameter/test/preprocessor_deduced.cpp')
-rw-r--r-- | src/boost/libs/parameter/test/preprocessor_deduced.cpp | 443 |
1 files changed, 443 insertions, 0 deletions
diff --git a/src/boost/libs/parameter/test/preprocessor_deduced.cpp b/src/boost/libs/parameter/test/preprocessor_deduced.cpp new file mode 100644 index 000000000..f3c89172d --- /dev/null +++ b/src/boost/libs/parameter/test/preprocessor_deduced.cpp @@ -0,0 +1,443 @@ +// 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/config.hpp> +#include <boost/parameter/preprocessor.hpp> +#include <boost/parameter/name.hpp> +#include <boost/tuple/tuple.hpp> +#include <map> +#include <string> +#include "basics.hpp" + +#if defined(BOOST_PARAMETER_CAN_USE_MP11) +#include <boost/parameter/value_type.hpp> +#include <boost/mp11/map.hpp> +#include <boost/core/enable_if.hpp> +#include <type_traits> +#else +#include <boost/mpl/bool.hpp> +#include <boost/mpl/if.hpp> +#include <boost/type_traits/is_convertible.hpp> +#if !defined(BOOST_NO_SFINAE) +#include <boost/parameter/value_type.hpp> +#include <boost/mpl/has_key.hpp> +#include <boost/core/enable_if.hpp> +#include <boost/type_traits/is_same.hpp> +#endif +#endif + +namespace test { + + BOOST_PARAMETER_NAME(expected) + BOOST_PARAMETER_NAME(x) + BOOST_PARAMETER_NAME(y) + BOOST_PARAMETER_NAME(z) + +#if defined(BOOST_PARAMETER_CAN_USE_MP11) + template <typename To> + struct predicate + { + template <typename From, typename Args> + using fn = std::is_convertible<From,To>; + }; + + BOOST_PARAMETER_FUNCTION((int), f, test::tag, + (required + (expected, *) + ) + (deduced + (required + (x, *(test::predicate<int>)) + (y, *(test::predicate<std::string>)) + ) + ) + ) +#else // !defined(BOOST_PARAMETER_CAN_USE_MP11) + struct predicate_int + { + template <typename From, typename Args> + struct apply + : boost::mpl::if_< + boost::is_convertible<From,int> + , boost::mpl::true_ + , boost::mpl::false_ + > + { + }; + }; + + struct predicate_string + { + template <typename From, typename Args> + struct apply + : boost::mpl::if_< + boost::is_convertible<From,std::string> + , boost::mpl::true_ + , boost::mpl::false_ + > + { + }; + }; + + BOOST_PARAMETER_FUNCTION((int), f, test::tag, + (required + (expected, *) + ) + (deduced + (required + (x, *(test::predicate_int)) + (y, *(test::predicate_string)) + ) + ) + ) +#endif // BOOST_PARAMETER_CAN_USE_MP11 + { + BOOST_TEST(test::equal(x, boost::tuples::get<0>(expected))); + BOOST_TEST(test::equal(y, boost::tuples::get<1>(expected))); + return 1; + } + + struct X + { + X(int x_ = -1) : x(x_) + { + } + + bool operator==(X const& other) const + { + return this->x == other.x; + } + + int x; + }; + +#if defined(BOOST_PARAMETER_CAN_USE_MP11) + BOOST_PARAMETER_FUNCTION((int), g, test::tag, + (required + (expected, *) + ) + (deduced + (required + (x, *(test::predicate<int>)) + (y, *(test::predicate<std::string>)) + ) + (optional + (z, *(test::predicate<test::X>), test::X()) + ) + ) + ) +#else // !defined(BOOST_PARAMETER_CAN_USE_MP11) + struct predicate_X + { + template <typename From, typename Args> + struct apply + : boost::mpl::if_< + boost::is_convertible<From,test::X> + , boost::mpl::true_ + , boost::mpl::false_ + > + { + }; + }; + + BOOST_PARAMETER_FUNCTION((int), g, tag, + (required + (expected, *) + ) + (deduced + (required + (x, *(test::predicate_int)) + (y, *(test::predicate_string)) + ) + (optional + (z, *(test::predicate_X), test::X()) + ) + ) + ) +#endif // BOOST_PARAMETER_CAN_USE_MP11 + { + BOOST_TEST(test::equal(x, boost::tuples::get<0>(expected))); + BOOST_TEST(test::equal(y, boost::tuples::get<1>(expected))); + BOOST_TEST(test::equal(z, boost::tuples::get<2>(expected))); + return 1; + } + +#if defined(BOOST_PARAMETER_CAN_USE_MP11) + BOOST_PARAMETER_FUNCTION((int), sfinae, test::tag, + (deduced + (required + (x, *(test::predicate<std::string>)) + ) + ) + ) +#else + BOOST_PARAMETER_FUNCTION((int), sfinae, test::tag, + (deduced + (required + (x, *(test::predicate_string)) + ) + ) + ) +#endif + { + 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; + } + +#if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) || \ + !BOOST_WORKAROUND(BOOST_MSVC, < 1800) + // Test support for two different Boost.Parameter-enabled + // function call operator overloads. + class char_read_base + { + int index; + char const* key; + + public: + template <typename Args> + explicit char_read_base(Args const& args) + : index(args[test::_y]), key(args[test::_z]) + { + } + + BOOST_PARAMETER_FUNCTION_CALL_OPERATOR((void), test::tag, + (deduced + (required + (y, (int)) + (z, (char const*)) + ) + ) + ) + { + this->index = y; + this->key = z; + } + + BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR((char), test::tag, + (deduced + (required + (y, (bool)) + (z, (std::map<char const*,std::string>)) + ) + ) + ) + { + return y ? ( + (z.find(this->key)->second)[this->index] + ) : this->key[this->index]; + } + }; + + struct char_reader : public char_read_base + { + BOOST_PARAMETER_CONSTRUCTOR(char_reader, (char_read_base), test::tag, + (deduced + (required + (y, (int)) + (z, (char const*)) + ) + ) + ) + }; +#endif // MSVC-11.0- + + // Test Boost.Parameter-enabled functions + // with parameter-dependent return types. +#if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE) +#if defined(BOOST_PARAMETER_CAN_USE_MP11) + BOOST_PARAMETER_FUNCTION( + ( + boost::lazy_enable_if< + boost::mp11::mp_map_contains<Args,test::tag::y> + , boost::parameter::value_type<Args,test::tag::y> + > + ), return_y, test::tag, + (deduced + (required + (x, (std::map<char const*,std::string>)) + (y, (char const*)) + ) + (optional + (z, (int), 4) + ) + ) + ) +#else // !defined(BOOST_PARAMETER_CAN_USE_MP11) + BOOST_PARAMETER_FUNCTION( + ( + boost::lazy_enable_if< + typename boost::mpl::has_key<Args,test::tag::y>::type + , boost::parameter::value_type<Args,test::tag::y> + > + ), return_y, test::tag, + (deduced + (required + (x, (std::map<char const*,std::string>)) + (y, (char const*)) + ) + (optional + (z, (int), 4) + ) + ) + ) +#endif // BOOST_PARAMETER_CAN_USE_MP11 + { + return y; + } +#endif // LIBS_PARAMETER_TEST_COMPILE_FAILURE +#endif // BOOST_NO_SFINAE + +#if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE) + BOOST_PARAMETER_FUNCTION( + (typename boost::parameter::value_type<Args,test::tag::y>::type), + return_y, test::tag, + (deduced + (required + (x, (std::map<char const*,std::string>)) + (y, (char const*)) + ) + (optional + (z, (int), 4) + ) + ) + ) + { + return y; + } +#endif // defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE) +} // namespace test + +#include <boost/core/lightweight_test.hpp> + +int main() +{ + test::f( + boost::make_tuple(0, std::string("foo")) + , test::_x = 0 + , test::_y = std::string("foo") + ); + test::f( + boost::make_tuple(0, std::string("foo")) + , 0 + , std::string("foo") + ); + test::f( + boost::make_tuple(0, std::string("foo")) + , std::string("foo") + , 0 + ); + test::f( + boost::make_tuple(0, std::string("foo")) + , test::_y = std::string("foo") + , 0 + ); + test::f( + boost::make_tuple(0, std::string("foo")) + , test::_x = 0 + , std::string("foo") + ); + test::f( + boost::make_tuple(0, std::string("foo")) + , 0 + , test::_y = std::string("foo") + ); + test::g( + boost::make_tuple(0, std::string("foo"), test::X()) + , test::_x = 0 + , test::_y = std::string("foo") + ); + test::g( + boost::make_tuple(0, std::string("foo"), test::X()) + , 0 + , std::string("foo") + ); + test::g( + boost::make_tuple(0, std::string("foo"), test::X()) + , std::string("foo") + , 0 + ); + test::g( + boost::make_tuple(0, std::string("foo"), test::X()) + , test::_y = std::string("foo") + , 0 + ); + test::g( + boost::make_tuple(0, std::string("foo"), test::X()) + , test::_x = 0 + , std::string("foo") + ); + test::g( + boost::make_tuple(0, std::string("foo"), test::X()) + , 0 + , test::_y = std::string("foo") + ); + test::g( + boost::make_tuple(0, std::string("foo"), test::X(1)) + , 0 + , test::_y = std::string("foo") + , test::X(1) + ); + test::g( + boost::make_tuple(0, std::string("foo"), test::X(1)) + , test::X(1) + , 0 + , test::_y = std::string("foo") + ); + + std::map<char const*,std::string> k2s; +#if !defined(BOOST_NO_SFINAE) + char const* keys[] = {"foo", "bar", "baz"}; + BOOST_TEST_EQ(1, test::sfinae(keys[0])); + BOOST_TEST_EQ(0, test::sfinae(0)); +#if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) || \ + !BOOST_WORKAROUND(BOOST_MSVC, < 1800) + k2s[keys[0]] = std::string("qux"); + k2s[keys[1]] = std::string("wmb"); + k2s[keys[2]] = std::string("zxc"); + test::char_reader r(keys[0], 0); + BOOST_TEST_EQ('q', (r(k2s, true))); + BOOST_TEST_EQ('f', (r(k2s, false))); + r(keys[1], 1); + BOOST_TEST_EQ('m', (r(k2s, true))); + BOOST_TEST_EQ('a', (r(k2s, false))); + r(keys[2], 2); + BOOST_TEST_EQ('c', (r(k2s, true))); + BOOST_TEST_EQ('z', (r(k2s, false))); +#endif // MSVC-11.0- +#if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE) + BOOST_TEST_EQ(keys[1], test::return_y(2, k2s, keys[1])); +#endif +#endif // BOOST_NO_SFINAE + +#if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE) + BOOST_TEST_EQ(keys[1], test::return_y(2, k2s, keys[1])); +#endif + + return boost::report_errors(); +} + |