1 | // Copyright Daniel Wallin 2006. |
2 | // Copyright Cromwell D. Enage 2017. |
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 | #ifndef BOOST_DEDUCED_060920_HPP |
8 | #define BOOST_DEDUCED_060920_HPP |
9 | |
10 | #include <boost/parameter/config.hpp> |
11 | #include "basics.hpp" |
12 | |
13 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
14 | #include <boost/mp11/map.hpp> |
15 | #include <boost/mp11/algorithm.hpp> |
16 | #else |
17 | #include <boost/mpl/bool.hpp> |
18 | #include <boost/mpl/if.hpp> |
19 | #include <boost/mpl/for_each.hpp> |
20 | #include <boost/mpl/assert.hpp> |
21 | #include <boost/type_traits/is_same.hpp> |
22 | #endif |
23 | |
24 | namespace test { |
25 | |
26 | struct not_present_tag |
27 | { |
28 | }; |
29 | |
30 | not_present_tag not_present; |
31 | |
32 | template <typename E, typename ArgPack> |
33 | class assert_expected |
34 | { |
35 | E const& _expected; |
36 | ArgPack const& _args; |
37 | |
38 | public: |
39 | assert_expected(E const& e, ArgPack const& args_) |
40 | : _expected(e), _args(args_) |
41 | { |
42 | } |
43 | |
44 | template <typename T> |
45 | static bool check_not_present(T const&) |
46 | { |
47 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
48 | static_assert( |
49 | std::is_same<T,test::not_present_tag>::value |
50 | , "T == test::not_present_tag" |
51 | ); |
52 | #else |
53 | BOOST_MPL_ASSERT(( |
54 | typename boost::mpl::if_< |
55 | boost::is_same<T,test::not_present_tag> |
56 | , boost::mpl::true_ |
57 | , boost::mpl::false_ |
58 | >::type |
59 | )); |
60 | #endif |
61 | return true; |
62 | } |
63 | |
64 | template <typename K> |
65 | bool check1(K const& k, test::not_present_tag const& t, long) const |
66 | { |
67 | return assert_expected<E,ArgPack>::check_not_present( |
68 | this->_args[k | t] |
69 | ); |
70 | } |
71 | |
72 | template <typename K, typename Expected> |
73 | bool check1(K const& k, Expected const& e, int) const |
74 | { |
75 | return test::equal(this->_args[k], e); |
76 | } |
77 | |
78 | template <typename K> |
79 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
80 | void operator()(K&&) const |
81 | #else |
82 | void operator()(K) const |
83 | #endif |
84 | { |
85 | boost::parameter::keyword<K> const& |
86 | k = boost::parameter::keyword<K>::instance; |
87 | BOOST_TEST(this->check1(k, this->_expected[k], 0L)); |
88 | } |
89 | }; |
90 | |
91 | template <typename E, typename A> |
92 | void check0(E const& e, A const& args) |
93 | { |
94 | #if defined(BOOST_PARAMETER_CAN_USE_MP11) |
95 | boost::mp11::mp_for_each<boost::mp11::mp_map_keys<E> >( |
96 | test::assert_expected<E,A>(e, args) |
97 | ); |
98 | #else |
99 | boost::mpl::for_each<E>(test::assert_expected<E,A>(e, args)); |
100 | #endif |
101 | } |
102 | |
103 | #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) |
104 | template <typename P, typename E, typename ...Args> |
105 | void check(E const& e, Args const&... args) |
106 | { |
107 | test::check0(e, P()(args...)); |
108 | } |
109 | #else |
110 | template <typename P, typename E, typename A0> |
111 | void check(E const& e, A0 const& a0) |
112 | { |
113 | test::check0(e, P()(a0)); |
114 | } |
115 | |
116 | template <typename P, typename E, typename A0, typename A1> |
117 | void check(E const& e, A0 const& a0, A1 const& a1) |
118 | { |
119 | test::check0(e, P()(a0, a1)); |
120 | } |
121 | |
122 | template <typename P, typename E, typename A0, typename A1, typename A2> |
123 | void check(E const& e, A0 const& a0, A1 const& a1, A2 const& a2) |
124 | { |
125 | test::check0(e, P()(a0, a1, a2)); |
126 | } |
127 | #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING |
128 | } // namespace test |
129 | |
130 | #endif // include guard |
131 | |
132 | |