1 | // Copyright David Abrahams 2006. |
2 | // Copyright Cromwell D. Enage 2019. |
3 | // Distributed under the Boost Software License, Version 1.0. |
4 | // (See accompanying file LICENSE_1_0.txt or copy at |
5 | // http://www.boost.org/LICENSE_1_0.txt) |
6 | |
7 | #include <boost/parameter/config.hpp> |
8 | #include <boost/mpl/list.hpp> |
9 | #include <boost/mpl/placeholders.hpp> |
10 | #include <boost/mpl/for_each.hpp> |
11 | #include <boost/mpl/size.hpp> |
12 | #include <boost/mpl/contains.hpp> |
13 | #include <boost/mpl/assert.hpp> |
14 | #include <boost/type_traits/add_pointer.hpp> |
15 | #include "basics.hpp" |
16 | |
17 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
18 | #include <boost/mp11/list.hpp> |
19 | #include <boost/mp11/map.hpp> |
20 | #include <boost/mp11/algorithm.hpp> |
21 | #include <boost/mp11/mpl.hpp> |
22 | #endif |
23 | |
24 | namespace test { |
25 | |
26 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
27 | template <typename Map> |
28 | struct assert_in_map |
29 | { |
30 | template <typename T> |
31 | void operator()(T&&) |
32 | { |
33 | static_assert( |
34 | boost::mp11::mp_map_contains<Map,T>::value |
35 | , "T must be in Map" |
36 | ); |
37 | } |
38 | }; |
39 | |
40 | template <typename Set> |
41 | struct assert_in_set_0 |
42 | { |
43 | template <typename T> |
44 | void operator()(T&&) |
45 | { |
46 | static_assert( |
47 | boost::mp11::mp_contains<Set,T>::value |
48 | , "T must be in Set" |
49 | ); |
50 | } |
51 | }; |
52 | #endif |
53 | |
54 | template <typename Set> |
55 | struct assert_in_set_1 |
56 | { |
57 | template <typename T> |
58 | void operator()(T*) |
59 | { |
60 | BOOST_MPL_ASSERT((boost::mpl::contains<Set,T>)); |
61 | } |
62 | }; |
63 | |
64 | template <typename Expected, typename Args> |
65 | void f_impl(Args const& p BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Expected)) |
66 | { |
67 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
68 | static_assert( |
69 | boost::mp11::mp_size<Expected>::value == boost::mp11::mp_size< |
70 | Args |
71 | >::value |
72 | , "mp_size<Expected>::value == mp_size<Args>::value" |
73 | ); |
74 | |
75 | boost::mp11::mp_for_each<boost::mp11::mp_map_keys<Args> >( |
76 | test::assert_in_set_0<Expected>() |
77 | ); |
78 | boost::mp11::mp_for_each<Expected>(test::assert_in_map<Args>()); |
79 | #endif |
80 | |
81 | BOOST_MPL_ASSERT_RELATION( |
82 | boost::mpl::size<Expected>::value |
83 | , == |
84 | , boost::mpl::size<Args>::value |
85 | ); |
86 | |
87 | boost::mpl::for_each<Args,boost::add_pointer<boost::mpl::_1> >( |
88 | test::assert_in_set_1<Expected>() |
89 | ); |
90 | boost::mpl::for_each<Expected,boost::add_pointer<boost::mpl::_1> >( |
91 | test::assert_in_set_1<Args>() |
92 | ); |
93 | } |
94 | |
95 | template < |
96 | typename Expected |
97 | , typename Tester |
98 | , typename Name |
99 | , typename Value |
100 | , typename Index |
101 | > |
102 | void f( |
103 | Tester const& t |
104 | , Name const& name_ |
105 | , Value const& value_ |
106 | , Index const& index_ |
107 | BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Expected) |
108 | ) |
109 | { |
110 | test::f_impl<Expected>( |
111 | test::f_parameters()(t, name_, value_, index_) |
112 | ); |
113 | } |
114 | |
115 | template < |
116 | typename Expected |
117 | , typename Tester |
118 | , typename Name |
119 | , typename Value |
120 | > |
121 | void f( |
122 | Tester const& t |
123 | , Name const& name_ |
124 | , Value const& value_ |
125 | BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Expected) |
126 | ) |
127 | { |
128 | test::f_impl<Expected>(test::f_parameters()(t, name_, value_)); |
129 | } |
130 | |
131 | template <typename Expected, typename Tester, typename Name> |
132 | void f( |
133 | Tester const& t |
134 | , Name const& name_ |
135 | BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Expected) |
136 | ) |
137 | { |
138 | test::f_impl<Expected>(test::f_parameters()(t, name_)); |
139 | } |
140 | |
141 | void run() |
142 | { |
143 | typedef test::tag::tester tester_; |
144 | typedef test::tag::name name_; |
145 | typedef test::tag::value value_; |
146 | typedef test::tag::index index_; |
147 | |
148 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
149 | test::f< |
150 | boost::mp11::mp_list<tester_,name_,value_,index_> |
151 | >(t: 1, name_: 2, value_: 3, index_: 4); |
152 | test::f< |
153 | boost::mp11::mp_list<tester_,name_,index_> |
154 | >(t: 1, name_: 2, value_: test::_index = 3); |
155 | test::f< |
156 | boost::mp11::mp_list<tester_,name_,index_> |
157 | >(t: 1, name_: test::_index = 2, value_: test::_name = 3); |
158 | test::f< |
159 | boost::mp11::mp_list<name_,value_> |
160 | >(t: test::_name = 3, name_: test::_value = 4); |
161 | test::f_impl<boost::mp11::mp_list<value_> >(p: test::_value = 4); |
162 | #endif |
163 | |
164 | test::f<boost::mpl::list4<tester_,name_,value_,index_> >(t: 1, name_: 2, value_: 3, index_: 4); |
165 | test::f< |
166 | boost::mpl::list3<tester_,name_,index_> |
167 | >(t: 1, name_: 2, value_: test::_index = 3); |
168 | test::f< |
169 | boost::mpl::list3<tester_,name_,index_> |
170 | >(t: 1, name_: test::_index = 2, value_: test::_name = 3); |
171 | test::f< |
172 | boost::mpl::list2<name_,value_> |
173 | >(t: test::_name = 3, name_: test::_value = 4); |
174 | test::f_impl<boost::mpl::list1<value_> >(p: test::_value = 4); |
175 | } |
176 | } |
177 | |
178 | #include <boost/core/lightweight_test.hpp> |
179 | |
180 | int main() |
181 | { |
182 | test::run(); |
183 | return boost::report_errors(); |
184 | } |
185 | |
186 | |