summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/parameter/test/preprocessor_deduced.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/parameter/test/preprocessor_deduced.cpp')
-rw-r--r--src/boost/libs/parameter/test/preprocessor_deduced.cpp443
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();
+}
+