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: assert_expected(E const & e,ArgPack const & args_)39 assert_expected(E const& e, ArgPack const& args_) 40 : _expected(e), _args(args_) 41 { 42 } 43 44 template <typename T> check_not_present(T const &)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> check1(K const & k,test::not_present_tag const & t,long) const65 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> check1(K const & k,Expected const & e,int) const73 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) operator ()(K &&) const80 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> check0(E const & e,A const & args)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> check(E const & e,Args const &...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> check(E const & e,A0 const & 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> check(E const & e,A0 const & a0,A1 const & 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> check(E const & e,A0 const & a0,A1 const & a1,A2 const & 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