fb5683766b
Replace BOOST_TTI_DETAIL_NULLPTR with BOOST_PARAMETER_AUX_PP_NULLPTR.
690 lines
17 KiB
C++
690 lines
17 KiB
C++
// 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(__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(__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(__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();
|
|
}
|
|
|