mirror of
https://github.com/boostorg/parameter.git
synced 2026-01-19 04:22:13 +00:00
<boost/parameter/parameters.hpp>: * Add preprocessor conditional statement to prevent generation of ill-formed function call operator overloads. "test/maybe.cpp" "test/singular.cpp" "test/tutorial.cpp" "test/sfinae.cpp" "test/earwicker.cpp" * Replace BOOST_PARAMETER_KEYWORD statements with BOOST_PARAMETER_NAME statements. "test/optional_deduced_sfinae.cpp" "test/normalized_argument_types.cpp" "test/literate/*.cpp" * Use Boost.Core.LightweightTest where int main() is available. * Replace assert statements with BOOST_TEST_EQ statements. "test/basics.hpp" * Remove preprocessor statements regarding borland, gcc-2, and msvc workarounds. "test/ntp.cpp" "test/sfinae.cpp" "test/earwicker.cpp" "test/normalized_argument_types.cpp" "test/basics.hpp" * Add preprocessor conditional statement to #error out if BOOST_PARAMETER_MAX_ARITY is set to an insufficient value. "test/basics.cpp" "test/deduced.cpp" "test/macros.cpp" "test/preprocessor.cpp" "test/preprocessor_deduced.cpp" * Replace S and char const* expressions with boost::container::string expressions. * Uncomment any code that fails to compile, but add preprocessor conditional statement so that test suites can incorporate compile-fail statements regarding the code in question. * Ensure that int main() returns boost::process_errors(). "test/literate/deduced-template-parameters0.cpp": "test/literate/exercising-the-code-so-far0.cpp": * Enclose BOOST_MPL_ASSERT statements within MPL_TEST_CASE block. "test/literate/defining-the-keywords1.cpp": * Add graphs::tag::graph::qualifier type definition because perfect forwarding code will check for it. * Replace deprecated keyword::get() invocation with keyword::instance invocation. test/Jamfile.v2: * Add modifier <define>BOOST_PARAMETER_MAX_ARITY=# to run, run-fail, compile, and compile-fail statements to conserve compiler memory usage on GitHub's side. * Add modifier <preserve-target-tests>off to run and run-fail statements to conserve executable space on GitHub's side. * Separate bpl-test statement into its own target, parameter_python_test, which fails on xcode8.3 as well as on mingw and msvc compilers with address-model=64. * The next commit (which will implement perfect forwarding) will subsume test/literate/Jamfile.v2 into this file. Strangely enough, attempting to do so now will result in compiler errors. .travis.yml: * Add g++-4.7, g++-4.8, g++-4.9, clang++-3.5, clang++-3.6, clang++-3.7, clang++-3.8, clang++-3.9, clang++-4.0, xcode7.3, and xcode8.3 compiler configurations. * Split compiler configurations by available CXXSTD values. (This will keep the job times within limits for the next commit.) * Ensure that the xcode8.3 compiler configurations exclude parameter_python_test from the test suite. appveyor.yml: * Add compiler configurations that support address-model=64 to the test matrix. * Ensure that the new configurations exclude parameter_python_test from the test suite.
645 lines
15 KiB
C++
645 lines
15 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/config.hpp>
|
|
#include <boost/parameter/preprocessor.hpp>
|
|
#include <boost/parameter/keyword.hpp>
|
|
#include <boost/mpl/bool.hpp>
|
|
#include <boost/mpl/if.hpp>
|
|
#include <boost/type_traits/is_same.hpp>
|
|
#include "basics.hpp"
|
|
|
|
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;
|
|
|
|
BOOST_MPL_ASSERT((
|
|
typename boost::mpl::if_<
|
|
boost::is_same<index_type,int&>
|
|
, boost::mpl::true_
|
|
, boost::mpl::false_
|
|
>::type
|
|
));
|
|
|
|
args[test::_tester](
|
|
args[test::_name]
|
|
, args[test::_value | 1.f]
|
|
, args[test::_index | 2]
|
|
);
|
|
|
|
return 1;
|
|
}
|
|
} // namespace test
|
|
|
|
#include <boost/type_traits/remove_const.hpp>
|
|
|
|
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;
|
|
|
|
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
|
|
));
|
|
|
|
args[test::_tester](
|
|
args[test::_name]
|
|
, args[test::_value | 1.f]
|
|
, args[test::_index | 2]
|
|
);
|
|
|
|
return 1;
|
|
}
|
|
} // namespace test
|
|
|
|
#include <boost/type_traits/remove_reference.hpp>
|
|
|
|
namespace test {
|
|
|
|
BOOST_PARAMETER_FUNCTION((int), h, test::tag,
|
|
(required
|
|
(tester, *)
|
|
(name, *)
|
|
)
|
|
(optional
|
|
(value, *, 1.f)
|
|
(index, (int), 2)
|
|
)
|
|
)
|
|
{
|
|
#if !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 // 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 !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 // Borland/MSVC workarounds not needed.
|
|
|
|
tester(name, value, index);
|
|
|
|
return 1;
|
|
}
|
|
} // namespace test
|
|
|
|
#if !defined(BOOST_NO_SFINAE)
|
|
#include <boost/tti/detail/dnullptr.hpp>
|
|
#include <boost/core/enable_if.hpp>
|
|
#include <boost/type_traits/is_base_of.hpp>
|
|
#include <string>
|
|
#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_TTI_DETAIL_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, *)
|
|
)
|
|
)
|
|
};
|
|
|
|
struct base_1
|
|
{
|
|
template <typename Args>
|
|
explicit base_1(
|
|
Args const& args
|
|
#if !defined(BOOST_NO_SFINAE)
|
|
, typename boost::disable_if<
|
|
typename boost::mpl::if_<
|
|
boost::is_base_of<base_1,Args>
|
|
, boost::mpl::true_
|
|
, boost::mpl::false_
|
|
>::type
|
|
>::type* = BOOST_TTI_DETAIL_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<
|
|
typename boost::mpl::if_<
|
|
boost::is_same<int,A0>
|
|
, boost::mpl::true_
|
|
, boost::mpl::false_
|
|
>::type
|
|
, int
|
|
>::type
|
|
sfinae(A0 const& a0)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif // BOOST_NO_SFINAE
|
|
|
|
struct predicate
|
|
{
|
|
template <typename T, typename Args>
|
|
struct apply
|
|
: boost::mpl::if_<
|
|
boost::is_convertible<T,std::string>
|
|
, boost::mpl::true_
|
|
, boost::mpl::false_
|
|
>
|
|
{
|
|
};
|
|
};
|
|
|
|
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<
|
|
typename boost::mpl::if_<
|
|
boost::is_same<int,A0>
|
|
, boost::mpl::true_
|
|
, boost::mpl::false_
|
|
>::type
|
|
, int
|
|
>::type
|
|
sfinae1(A0 const& a0)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif // BOOST_NO_SFINAE
|
|
|
|
template <typename T>
|
|
T const& as_lvalue(T const& x)
|
|
{
|
|
return x;
|
|
}
|
|
|
|
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
|
|
|
|
#include <boost/container/string.hpp>
|
|
#include <boost/core/lightweight_test.hpp>
|
|
|
|
int main()
|
|
{
|
|
test::f(
|
|
test::values(boost::container::string("foo"), 1.f, 2)
|
|
, boost::container::string("foo")
|
|
);
|
|
test::f(
|
|
test::_tester = test::values(
|
|
boost::container::string("foo")
|
|
, 1.f
|
|
, 2
|
|
)
|
|
, test::_name = boost::container::string("foo")
|
|
);
|
|
|
|
int index_lvalue = 2;
|
|
|
|
test::f(
|
|
test::_tester = test::values(
|
|
boost::container::string("foo")
|
|
, 1.f
|
|
, 2
|
|
)
|
|
, test::_name = boost::container::string("foo")
|
|
, test::_value = 1.f
|
|
, test::_index = index_lvalue
|
|
);
|
|
|
|
test::f(
|
|
test::values(boost::container::string("foo"), 1.f, 2)
|
|
, boost::container::string("foo")
|
|
, 1.f
|
|
, index_lvalue
|
|
);
|
|
|
|
test::g(
|
|
test::values(boost::container::string("foo"), 1.f, 2)
|
|
, boost::container::string("foo")
|
|
, 1.f
|
|
#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
|
|
, test::as_lvalue(2)
|
|
#else
|
|
, 2
|
|
#endif
|
|
);
|
|
|
|
test::h(
|
|
test::values(boost::container::string("foo"), 1.f, 2)
|
|
, boost::container::string("foo")
|
|
, 1.f
|
|
#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
|
|
, test::as_lvalue(2)
|
|
#else
|
|
, 2
|
|
#endif
|
|
);
|
|
|
|
test::h2(
|
|
test::_tester = test::values(
|
|
boost::container::string("foo")
|
|
, 1.f
|
|
, 2
|
|
)
|
|
, test::_name = boost::container::string("foo")
|
|
, test::_value = 1.f
|
|
);
|
|
|
|
test::class_0 u;
|
|
|
|
BOOST_TEST(2 == u.i);
|
|
BOOST_TEST(1.f == u.f);
|
|
|
|
test::class_1 x(
|
|
test::values(boost::container::string("foo"), 1.f, 2)
|
|
, boost::container::string("foo")
|
|
, test::_index = 2
|
|
);
|
|
|
|
x.f(
|
|
test::values(boost::container::string("foo"), 1.f, 2)
|
|
, boost::container::string("foo")
|
|
);
|
|
x.f(
|
|
test::_tester = test::values(
|
|
boost::container::string("foo")
|
|
, 1.f
|
|
, 2
|
|
)
|
|
, test::_name = boost::container::string("foo")
|
|
);
|
|
x.f2(
|
|
test::values(boost::container::string("foo"), 1.f, 2)
|
|
, boost::container::string("foo")
|
|
);
|
|
x.f2(
|
|
test::_tester = test::values(
|
|
boost::container::string("foo")
|
|
, 1.f
|
|
, 2
|
|
)
|
|
, test::_name = boost::container::string("foo")
|
|
);
|
|
x(
|
|
test::values(boost::container::string("foo"), 1.f, 2)
|
|
, boost::container::string("foo")
|
|
);
|
|
x(
|
|
test::_tester = test::values(
|
|
boost::container::string("foo")
|
|
, 1.f
|
|
, 2
|
|
)
|
|
, test::_name = boost::container::string("foo")
|
|
);
|
|
|
|
test::class_1 const& x_const = x;
|
|
|
|
x_const.f(
|
|
test::values(boost::container::string("foo"), 1.f, 2)
|
|
, boost::container::string("foo")
|
|
);
|
|
x_const.f(
|
|
test::_tester = test::values(
|
|
boost::container::string("foo")
|
|
, 1.f
|
|
, 2
|
|
)
|
|
, test::_name = boost::container::string("foo")
|
|
);
|
|
x_const.f2(
|
|
test::values(boost::container::string("foo"), 1.f, 2)
|
|
, boost::container::string("foo")
|
|
);
|
|
x_const.f2(
|
|
test::_tester = test::values(
|
|
boost::container::string("foo")
|
|
, 1.f
|
|
, 2
|
|
)
|
|
, test::_name = boost::container::string("foo")
|
|
);
|
|
test::class_1::f_static(
|
|
test::values(boost::container::string("foo"), 1.f, 2)
|
|
, boost::container::string("foo")
|
|
);
|
|
test::class_1::f_static(
|
|
test::_tester = test::values(
|
|
boost::container::string("foo")
|
|
, 1.f
|
|
, 2
|
|
)
|
|
, test::_name = boost::container::string("foo")
|
|
);
|
|
x_const(
|
|
test::values(boost::container::string("foo"), 1.f, 2)
|
|
, boost::container::string("foo")
|
|
);
|
|
x_const(
|
|
test::_tester = test::values(
|
|
boost::container::string("foo")
|
|
, 1.f
|
|
, 2
|
|
)
|
|
, test::_name = boost::container::string("foo")
|
|
);
|
|
|
|
#if !defined(BOOST_NO_SFINAE) && \
|
|
!BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
|
|
BOOST_TEST(test::sfinae("foo") == 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") == 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();
|
|
}
|
|
|