From dcd8d41ffcb227a1a0e29cea048e5be5be9d0922 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 15 Jul 2015 23:38:33 +0300 Subject: [PATCH 1/4] Move implementation details to namespace detail. --- include/boost/mp11/utility.hpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/include/boost/mp11/utility.hpp b/include/boost/mp11/utility.hpp index 213857d..b41d334 100644 --- a/include/boost/mp11/utility.hpp +++ b/include/boost/mp11/utility.hpp @@ -20,7 +20,10 @@ template struct mp_identity // mp_inherit template struct mp_inherit: T... {}; -// mp_if +// mp_if, mp_if_c +namespace detail +{ + template struct mp_if_c_impl; template struct mp_if_c_impl @@ -33,11 +36,15 @@ template struct mp_if_c_impl using type = E; }; -template using mp_if_c = typename mp_if_c_impl::type; +} // namespace detail -template using mp_if = typename mp_if_c_impl( C::value ), T, E>::type; +template using mp_if_c = typename detail::mp_if_c_impl::type; +template using mp_if = typename detail::mp_if_c_impl(C::value), T, E>::type; + +// mp_eval_if, mp_eval_if_c +namespace detail +{ -// mp_eval_if template class F, class... U> struct mp_eval_if_c_impl; template class F, class... U> struct mp_eval_if_c_impl @@ -50,9 +57,14 @@ template class F, class... U> struct mp_eval_if_c_im using type = F; }; -template class F, class... U> using mp_eval_if_c = typename mp_eval_if_c_impl::type; +} // namespace detail -template class F, class... U> using mp_eval_if = typename mp_eval_if_c_impl( C::value ), T, F, U...>::type; +template class F, class... U> using mp_eval_if_c = typename detail::mp_eval_if_c_impl::type; +template class F, class... U> using mp_eval_if = typename detail::mp_eval_if_c_impl(C::value), T, F, U...>::type; + +// mp_valid +// mp_defer +// mp_defer_if_valid } // namespace boost From 12387884c53012392e0887df94cf629820ebdbb6 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 15 Jul 2015 23:52:39 +0300 Subject: [PATCH 2/4] Fix include order. --- test/integral.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integral.cpp b/test/integral.cpp index 92e9bc4..6935aad 100644 --- a/test/integral.cpp +++ b/test/integral.cpp @@ -7,8 +7,8 @@ // http://www.boost.org/LICENSE_1_0.txt -#include #include +#include #include #include From a5dd767f93d790878d6c5ac2934d9240ab14bcb5 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 16 Jul 2015 00:39:14 +0300 Subject: [PATCH 3/4] Fix include order. --- test/mp_eval_if.cpp | 2 +- test/mp_if.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/mp_eval_if.cpp b/test/mp_eval_if.cpp index 2f291e9..218b8d1 100644 --- a/test/mp_eval_if.cpp +++ b/test/mp_eval_if.cpp @@ -7,9 +7,9 @@ // http://www.boost.org/LICENSE_1_0.txt -#include #include #include +#include #include int main() diff --git a/test/mp_if.cpp b/test/mp_if.cpp index 96097f6..88036f9 100644 --- a/test/mp_if.cpp +++ b/test/mp_if.cpp @@ -7,9 +7,9 @@ // http://www.boost.org/LICENSE_1_0.txt -#include #include #include +#include #include int main() From 61b897e8572e0ce0d15b17e1fea0e6cc516d3e40 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 16 Jul 2015 00:40:40 +0300 Subject: [PATCH 4/4] Add mp_valid, mp_defer, mp_defer_if_valid. --- include/boost/mp11/utility.hpp | 24 ++++++++++++ test/Jamfile.v2 | 3 ++ test/mp_defer.cpp | 26 ++++++++++++ test/mp_defer_if_valid.cpp | 29 ++++++++++++++ test/mp_valid.cpp | 72 ++++++++++++++++++++++++++++++++++ 5 files changed, 154 insertions(+) create mode 100644 test/mp_defer.cpp create mode 100644 test/mp_defer_if_valid.cpp create mode 100644 test/mp_valid.cpp diff --git a/include/boost/mp11/utility.hpp b/include/boost/mp11/utility.hpp index b41d334..cee33df 100644 --- a/include/boost/mp11/utility.hpp +++ b/include/boost/mp11/utility.hpp @@ -8,6 +8,8 @@ // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt +#include + namespace boost { @@ -63,8 +65,30 @@ template class F, class... U> using mp_eval_ template class F, class... U> using mp_eval_if = typename detail::mp_eval_if_c_impl(C::value), T, F, U...>::type; // mp_valid +// implementation by Bruno Dutra (by the name is_evaluable) +namespace detail +{ + +template class F, class... T> struct mp_valid_impl +{ + template class G, class = G> static mp_true check(int); + template class> static mp_false check(...); + + using type = decltype(check(0)); +}; + +} // namespace detail + +template class F, class... T> using mp_valid = typename detail::mp_valid_impl::type; + // mp_defer +template class F, class... T> struct mp_defer +{ + using type = F; +}; + // mp_defer_if_valid +template class F, class... T> using mp_defer_if_valid = mp_if, mp_defer, mp_inherit<>>; } // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 395aa0d..dfff4fe 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -57,6 +57,9 @@ run mp_identity.cpp : : : $(REQ) ; run mp_inherit.cpp : : : $(REQ) ; run mp_if.cpp : : : $(REQ) ; run mp_eval_if.cpp : : : $(REQ) ; +run mp_valid.cpp : : : $(REQ) ; +run mp_defer.cpp : : : $(REQ) ; +run mp_defer_if_valid.cpp : : : $(REQ) ; # integer_sequence run integer_sequence.cpp : : : $(REQ) ; diff --git a/test/mp_defer.cpp b/test/mp_defer.cpp new file mode 100644 index 0000000..09aa771 --- /dev/null +++ b/test/mp_defer.cpp @@ -0,0 +1,26 @@ + +// Copyright 2015 Peter Dimov. +// +// 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 +#include +#include + +template using add_pointer = T*; + +using boost::mp_defer; + +template using add_pointer_impl = mp_defer; + +int main() +{ + BOOST_TEST_TRAIT_TRUE((std::is_same::type, void*>)); + BOOST_TEST_TRAIT_TRUE((std::is_same::type, int*>)); + + return boost::report_errors(); +} diff --git a/test/mp_defer_if_valid.cpp b/test/mp_defer_if_valid.cpp new file mode 100644 index 0000000..32c449b --- /dev/null +++ b/test/mp_defer_if_valid.cpp @@ -0,0 +1,29 @@ + +// Copyright 2015 Peter Dimov. +// +// 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 +#include +#include + +using boost::mp_defer_if_valid; +using boost::mp_identity; + +template using mp_identity_2 = typename mp_defer_if_valid::type; + +int main() +{ + using boost::mp_valid; + + BOOST_TEST_TRAIT_FALSE((mp_valid)); + BOOST_TEST_TRAIT_TRUE((mp_valid)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_identity>)); + BOOST_TEST_TRAIT_FALSE((mp_valid)); + + return boost::report_errors(); +} diff --git a/test/mp_valid.cpp b/test/mp_valid.cpp new file mode 100644 index 0000000..228d42e --- /dev/null +++ b/test/mp_valid.cpp @@ -0,0 +1,72 @@ + +// Copyright 2015 Peter Dimov. +// +// 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 +#include + +template struct Xi +{ +}; + +template<> struct Xi +{ + using type = void; +}; + +template using X = typename Xi::type; + +template using add_pointer = T*; +template using add_reference = T&; +template using add_extents = T[]; + +int main() +{ + using boost::mp_valid; + using boost::mp_identity; + + BOOST_TEST_TRAIT_FALSE((mp_valid)); + BOOST_TEST_TRAIT_TRUE((mp_valid)); + BOOST_TEST_TRAIT_FALSE((mp_valid)); + + BOOST_TEST_TRAIT_FALSE((mp_valid)); + BOOST_TEST_TRAIT_TRUE((mp_valid)); + BOOST_TEST_TRAIT_FALSE((mp_valid)); + BOOST_TEST_TRAIT_FALSE((mp_valid)); + + BOOST_TEST_TRAIT_FALSE((mp_valid)); + BOOST_TEST_TRAIT_TRUE((mp_valid)); + BOOST_TEST_TRAIT_TRUE((mp_valid)); +#if !defined( BOOST_MSVC ) || !BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + // msvc-12.0 can form pointer to reference + BOOST_TEST_TRAIT_FALSE((mp_valid)); +#endif + BOOST_TEST_TRAIT_FALSE((mp_valid)); + +#if !defined( BOOST_GCC ) || !BOOST_WORKAROUND( BOOST_GCC, <= 40902 ) + // g++ 4.9.2 doesn't like add_reference for some reason or other + BOOST_TEST_TRAIT_FALSE((mp_valid)); +#if !defined( BOOST_MSVC ) || !BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + // msvc-12.0 gives an internal error here + BOOST_TEST_TRAIT_FALSE((mp_valid)); +#endif + BOOST_TEST_TRAIT_TRUE((mp_valid)); + BOOST_TEST_TRAIT_FALSE((mp_valid)); +#endif + + BOOST_TEST_TRAIT_FALSE((mp_valid)); + BOOST_TEST_TRAIT_TRUE((mp_valid)); +#if !defined( BOOST_MSVC ) || !BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + // msvc-12.0 can form arrays to void or int& + BOOST_TEST_TRAIT_FALSE((mp_valid)); + BOOST_TEST_TRAIT_FALSE((mp_valid)); +#endif + BOOST_TEST_TRAIT_FALSE((mp_valid)); + + return boost::report_errors(); +}