Files
parameter/test/preprocessor.cpp
CromwellEnage 278a728906 Restructure tests.
<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.
2018-10-28 13:13:07 -04:00

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();
}