1 /*=============================================================================
2 Copyright (C) 2016 Lee Clagett
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
8 #include <boost/config.hpp>
9 #include <boost/detail/lightweight_test.hpp>
10 #include <boost/fusion/container/list.hpp>
11 #include <boost/fusion/container/vector.hpp>
12 #include <boost/type_traits/add_const.hpp>
13 #include <boost/type_traits/add_reference.hpp>
14 #include <boost/type_traits/integral_constant.hpp>
15 #include <boost/type_traits/is_constructible.hpp>
16 #include <boost/type_traits/is_convertible.hpp>
17 #include <boost/type_traits/remove_const.hpp>
18 #include <boost/type_traits/remove_reference.hpp>
25 template <typename From, typename To>
26 bool is_convertible(bool has_conversion)
28 typedef typename boost::remove_reference<
29 typename boost::remove_const<From>::type
31 typedef typename boost::add_reference<from_rvalue>::type from_lvalue;
32 typedef typename boost::add_const<from_lvalue>::type from_const_lvalue;
35 boost::is_convertible<from_rvalue, To>::value == has_conversion &&
36 boost::is_convertible<from_lvalue, To>::value == has_conversion &&
37 boost::is_convertible<from_const_lvalue, To>::value == has_conversion;
40 // is_constructible has a few requirements
41 #if !defined(BOOST_NO_CXX11_DECLTYPE) && \
42 !defined(BOOST_NO_CXX11_TEMPLATES) && \
43 !defined(BOOST_NO_SFINAE_EXPR)
45 #define FUSION_TEST_HAS_CONSTRUCTIBLE
47 template <typename To, typename... Args>
48 bool is_lvalue_constructible(bool has_constructor)
50 return has_constructor ==
51 boost::is_constructible<
53 , typename boost::add_reference<Args>::type...
57 template <typename To, typename... Args>
58 bool is_constructible_impl(bool has_constructor)
61 boost::is_constructible<To, Args...>::value == has_constructor &&
62 is_lvalue_constructible<To, Args...>(has_constructor) &&
63 is_lvalue_constructible<
64 To, typename boost::add_const<Args>::type...
68 template <typename To, typename... Args>
69 bool is_constructible(bool has_constructor)
72 is_constructible_impl<
74 , typename boost::remove_reference<
75 typename boost::remove_const<Args>::type
80 void test_constructible()
82 BOOST_TEST((is_constructible< FUSION_SEQUENCE<> >(true)));
84 BOOST_TEST((is_constructible< FUSION_SEQUENCE<int> >(true)));
85 BOOST_TEST((is_constructible<FUSION_SEQUENCE<int>, int>(true)));
87 BOOST_TEST((is_constructible<FUSION_SEQUENCE<convertible>, int>(true)));
89 is_constructible<FUSION_SEQUENCE<convertible>, convertible>(true)
93 is_constructible<FUSION_SEQUENCE<int, int>, int, int>(true)
97 is_constructible<FUSION_SEQUENCE<convertible, int>, int, int>(true)
101 FUSION_SEQUENCE<convertible, int>, convertible, int
106 is_constructible<FUSION_SEQUENCE<int, convertible>, int, int>(true)
110 FUSION_SEQUENCE<int, convertible>, int, convertible
116 FUSION_SEQUENCE<convertible, convertible>, int, int
121 FUSION_SEQUENCE<convertible, convertible>, convertible, int
126 FUSION_SEQUENCE<convertible, convertible>, int, convertible
131 FUSION_SEQUENCE<convertible, convertible>, convertible, convertible
136 #endif // is_constructible is available
138 void test_convertible(bool has_seq_conversion)
140 BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<> >(false)));
141 BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<int> >(false)));
142 BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<const int&> >(false)));
143 BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<convertible> >(false)));
145 is_convertible<int, FUSION_SEQUENCE<const convertible&> >(false)
147 BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<int, int> >(false)));
149 is_convertible<int, FUSION_SEQUENCE<const int&, const int&> >(false)
151 BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<convertible, int> >(false)));
153 is_convertible<int, FUSION_SEQUENCE<const convertible&, const int&> >(false)
155 BOOST_TEST((is_convertible<int, FUSION_SEQUENCE<int, convertible> >(false)));
157 is_convertible<int, FUSION_SEQUENCE<const int&, const convertible&> >(false)
160 is_convertible<int, FUSION_SEQUENCE<convertible, convertible> >(false)
164 int, FUSION_SEQUENCE<const convertible&, const convertible&>
168 BOOST_TEST((is_convertible<FUSION_SEQUENCE<>, FUSION_SEQUENCE<> >(true)));
170 is_convertible<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<int> >(true)
173 is_convertible<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<const int&> >(true)
176 is_convertible<FUSION_SEQUENCE<int>, FUSION_SEQUENCE<convertible> >(true)
179 is_convertible<FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<int, int> >(true)
183 FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<const int&, const int&>
188 FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<convertible, int>
193 FUSION_SEQUENCE<int, int>, FUSION_SEQUENCE<int, convertible>
198 FUSION_SEQUENCE<int, int>
199 , FUSION_SEQUENCE<convertible, convertible>
205 FUSION_ALT_SEQUENCE<>, FUSION_SEQUENCE<>
206 >(has_seq_conversion)
210 FUSION_ALT_SEQUENCE<int>, FUSION_SEQUENCE<int>
211 >(has_seq_conversion)
215 FUSION_ALT_SEQUENCE<int>, FUSION_SEQUENCE<const int&>
216 >(has_seq_conversion)
220 FUSION_ALT_SEQUENCE<int>, FUSION_SEQUENCE<convertible>
221 >(has_seq_conversion)
225 FUSION_ALT_SEQUENCE<int, int>, FUSION_SEQUENCE<int, int>
226 >(has_seq_conversion)
230 FUSION_ALT_SEQUENCE<int, int>
231 , FUSION_SEQUENCE<const int&, const int&>
232 >(has_seq_conversion)
236 FUSION_ALT_SEQUENCE<int, int>, FUSION_SEQUENCE<convertible, int>
237 >(has_seq_conversion)
241 FUSION_ALT_SEQUENCE<int, int>, FUSION_SEQUENCE<int, convertible>
242 >(has_seq_conversion)
246 FUSION_ALT_SEQUENCE<int, int>
247 , FUSION_SEQUENCE<convertible, convertible>
248 >(has_seq_conversion)