a95a838779
is_constructible on GCC < 4.7 always fail to test non unary ctor
254 lines
7.8 KiB
C++
254 lines
7.8 KiB
C++
/*=============================================================================
|
|
Copyright (C) 2016 Lee Clagett
|
|
Copyright (C) 2018 Kohei Takahashi
|
|
|
|
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/config.hpp>
|
|
#include <boost/detail/lightweight_test.hpp>
|
|
#include <boost/fusion/container/list.hpp>
|
|
#include <boost/fusion/container/vector.hpp>
|
|
#include <boost/type_traits/add_const.hpp>
|
|
#include <boost/type_traits/add_reference.hpp>
|
|
#include <boost/type_traits/integral_constant.hpp>
|
|
#include <boost/type_traits/is_constructible.hpp>
|
|
#include <boost/type_traits/is_convertible.hpp>
|
|
#include <boost/type_traits/remove_const.hpp>
|
|
#include <boost/type_traits/remove_reference.hpp>
|
|
|
|
struct convertible
|
|
{
|
|
convertible(int) {}
|
|
};
|
|
|
|
template <typename From, typename To>
|
|
bool is_convertible(bool has_conversion)
|
|
{
|
|
typedef typename boost::remove_reference<
|
|
typename boost::remove_const<From>::type
|
|
>::type from_rvalue;
|
|
typedef typename boost::add_reference<from_rvalue>::type from_lvalue;
|
|
typedef typename boost::add_const<from_lvalue>::type from_const_lvalue;
|
|
|
|
return
|
|
boost::is_convertible<from_rvalue, To>::value == has_conversion &&
|
|
boost::is_convertible<from_lvalue, To>::value == has_conversion &&
|
|
boost::is_convertible<from_const_lvalue, To>::value == has_conversion;
|
|
}
|
|
|
|
// is_constructible has a few requirements
|
|
#ifdef BOOST_TT_IS_CONSTRUCTIBLE_CONFORMING
|
|
|
|
#define FUSION_TEST_HAS_CONSTRUCTIBLE
|
|
|
|
template <typename To, typename... Args>
|
|
bool is_lvalue_constructible(bool has_constructor)
|
|
{
|
|
return has_constructor ==
|
|
boost::is_constructible<
|
|
To
|
|
, typename boost::add_reference<Args>::type...
|
|
>::value;
|
|
}
|
|
|
|
template <typename To, typename... Args>
|
|
bool is_constructible_impl(bool has_constructor)
|
|
{
|
|
return
|
|
boost::is_constructible<To, Args...>::value == has_constructor &&
|
|
is_lvalue_constructible<To, Args...>(has_constructor) &&
|
|
is_lvalue_constructible<
|
|
To, typename boost::add_const<Args>::type...
|
|
>(has_constructor);
|
|
}
|
|
|
|
template <typename To, typename... Args>
|
|
bool is_constructible(bool has_constructor)
|
|
{
|
|
return
|
|
is_constructible_impl<
|
|
To
|
|
, typename boost::remove_reference<
|
|
typename boost::remove_const<Args>::type
|
|
>::type...
|
|
>(has_constructor);
|
|
}
|
|
|
|
void test_constructible()
|
|
{
|
|
BOOST_TEST((is_constructible< FUSION_SEQUENCE<> >(true)));
|
|
|
|
BOOST_TEST((is_constructible< FUSION_SEQUENCE<int> >(true)));
|
|
BOOST_TEST((is_constructible<FUSION_SEQUENCE<int>, int>(true)));
|
|
|
|
BOOST_TEST((is_constructible<FUSION_SEQUENCE<convertible>, int>(true)));
|
|
BOOST_TEST((
|
|
is_constructible<FUSION_SEQUENCE<convertible>, convertible>(true)
|
|
));
|
|
|
|
// boost::is_constructible always fail to test ctor which takes 2 or more arguments on GCC 4.7.
|
|
#if !BOOST_WORKAROUND(BOOST_GCC, < 40700)
|
|
BOOST_TEST((
|
|
is_constructible<FUSION_SEQUENCE<int, int>, int, int>(true)
|
|
));
|
|
|
|
BOOST_TEST((
|
|
is_constructible<FUSION_SEQUENCE<convertible, int>, int, int>(true)
|
|
));
|
|
BOOST_TEST((
|
|
is_constructible<
|
|
FUSION_SEQUENCE<convertible, int>, convertible, int
|
|
>(true)
|
|
));
|
|
|
|
BOOST_TEST((
|
|
is_constructible<FUSION_SEQUENCE<int, convertible>, int, int>(true)
|
|
));
|
|
BOOST_TEST((
|
|
is_constructible<
|
|
FUSION_SEQUENCE<int, convertible>, int, convertible
|
|
>(true)
|
|
));
|
|
|
|
BOOST_TEST((
|
|
is_constructible<
|
|
FUSION_SEQUENCE<convertible, convertible>, int, int
|
|
>(true)
|
|
));
|
|
BOOST_TEST((
|
|
is_constructible<
|
|
FUSION_SEQUENCE<convertible, convertible>, convertible, int
|
|
>(true)
|
|
));
|
|
BOOST_TEST((
|
|
is_constructible<
|
|
FUSION_SEQUENCE<convertible, convertible>, int, convertible
|
|
>(true)
|
|
));
|
|
BOOST_TEST((
|
|
is_constructible<
|
|
FUSION_SEQUENCE<convertible, convertible>, convertible, convertible
|
|
>(true)
|
|
));
|
|
#endif // !(gcc < 4.7)
|
|
}
|
|
|
|
#endif // is_constructible is available
|
|
|
|
void test_convertible(bool has_seq_conversion)
|
|
{
|
|
BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<> >(false)));
|
|
BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<int> >(false)));
|
|
BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<const int&> >(false)));
|
|
BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<convertible> >(false)));
|
|
BOOST_TEST((
|
|
is_convertible<int, FUSION_SEQUENCE<const convertible&> >(false)
|
|
));
|
|
BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<int, int> >(false)));
|
|
BOOST_TEST((
|
|
is_convertible<int, FUSION_SEQUENCE<const int&, const int&> >(false)
|
|
));
|
|
BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<convertible, int> >(false)));
|
|
BOOST_TEST((
|
|
is_convertible<int, FUSION_SEQUENCE<const convertible&, const int&> >(false)
|
|
));
|
|
BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<int, convertible> >(false)));
|
|
BOOST_TEST((
|
|
is_convertible<int, FUSION_SEQUENCE<const int&, const convertible&> >(false)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<int, FUSION_SEQUENCE<convertible, convertible> >(false)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
int, FUSION_SEQUENCE<const convertible&, const convertible&>
|
|
>(false)
|
|
));
|
|
|
|
BOOST_TEST((is_convertible<FUSION_SEQUENCE<>, FUSION_SEQUENCE<> >(true)));
|
|
BOOST_TEST((
|
|
is_convertible<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<int> >(true)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<const int&> >(true)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<convertible> >(true)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<int, int> >(true)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<const int&, const int&>
|
|
>(true)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<convertible, int>
|
|
>(true)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<int, convertible>
|
|
>(true)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_SEQUENCE<int, int>
|
|
, FUSION_SEQUENCE<convertible, convertible>
|
|
>(true)
|
|
));
|
|
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_ALT_SEQUENCE<>, FUSION_SEQUENCE<>
|
|
>(has_seq_conversion)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_ALT_SEQUENCE<int>, FUSION_SEQUENCE<int>
|
|
>(has_seq_conversion)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_ALT_SEQUENCE<int>, FUSION_SEQUENCE<const int&>
|
|
>(has_seq_conversion)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_ALT_SEQUENCE<int>, FUSION_SEQUENCE<convertible>
|
|
>(has_seq_conversion)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_ALT_SEQUENCE<int, int>, FUSION_SEQUENCE<int, int>
|
|
>(has_seq_conversion)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_ALT_SEQUENCE<int, int>
|
|
, FUSION_SEQUENCE<const int&, const int&>
|
|
>(has_seq_conversion)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_ALT_SEQUENCE<int, int>, FUSION_SEQUENCE<convertible, int>
|
|
>(has_seq_conversion)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_ALT_SEQUENCE<int, int>, FUSION_SEQUENCE<int, convertible>
|
|
>(has_seq_conversion)
|
|
));
|
|
BOOST_TEST((
|
|
is_convertible<
|
|
FUSION_ALT_SEQUENCE<int, int>
|
|
, FUSION_SEQUENCE<convertible, convertible>
|
|
>(has_seq_conversion)
|
|
));
|
|
}
|
|
|