diff --git a/doc/mp11/function.adoc b/doc/mp11/function.adoc index 75c004a..3fa5fc7 100644 --- a/doc/mp11/function.adoc +++ b/doc/mp11/function.adoc @@ -100,6 +100,28 @@ using R4 = mp_any; // compile-time error `mp_same` is `mp_true` if all the types in `T...` are the same type, `mp_false` otherwise. `mp_same<>` is `mp_true`. +## mp_similar + + template using mp_similar = /*...*/; + +`mp_similar` is `mp_true` if all the types in `T...` are the same type, or instantiations of the same class template +whose parameters are all types, `mp_false` otherwise. `mp_similar<>` is `mp_true`. + +.mp_similar +``` +using R1 = mp_similar; // mp_true +using R2 = mp_similar; // mp_true +using R3 = mp_similar; // mp_true +using R4 = mp_similar; // mp_false + +template struct X; +template struct Y; + +using R5 = mp_similar, X, X>; // mp_true +using R6 = mp_similar, Y, Y>; // mp_true +using R7 = mp_similar, Y>; // mp_false +``` + ## mp_plus template using mp_plus = /*...*/; diff --git a/include/boost/mp11/function.hpp b/include/boost/mp11/function.hpp index d0fbb25..005bc58 100644 --- a/include/boost/mp11/function.hpp +++ b/include/boost/mp11/function.hpp @@ -1,12 +1,12 @@ #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED #define BOOST_MP11_FUNCTION_HPP_INCLUDED -// Copyright 2015-2017 Peter Dimov. +// Copyright 2015-2019 Peter Dimov. // -// Distributed under the Boost Software License, Version 1.0. +// 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 +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt #include #include @@ -155,6 +155,46 @@ template struct mp_same_impl template using mp_same = typename detail::mp_same_impl::type; +// mp_similar +namespace detail +{ + +template struct mp_similar_impl; + +template<> struct mp_similar_impl<> +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_false; +}; + +template class L, class... T1, class... T2> struct mp_similar_impl, L> +{ + using type = mp_true; +}; + +template struct mp_similar_impl +{ + using type = mp_all< typename mp_similar_impl::type, typename mp_similar_impl::type, typename mp_similar_impl::type... >; +}; + +} // namespace detail + +template using mp_similar = typename detail::mp_similar_impl::type; + // mp_less template using mp_less = mp_bool<(T1::value < 0 && T2::value >= 0) || ((T1::value < T2::value) && !(T1::value >= 0 && T2::value < 0))>; diff --git a/test/Jamfile b/test/Jamfile index 5c9d59a..735e07c 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -143,6 +143,7 @@ run mp_plus.cpp ; run mp_less.cpp ; run mp_min.cpp ; run mp_max.cpp ; +run mp_similar.cpp ; # map run mp_map_find.cpp ; diff --git a/test/mp_similar.cpp b/test/mp_similar.cpp new file mode 100644 index 0000000..5fb538f --- /dev/null +++ b/test/mp_similar.cpp @@ -0,0 +1,45 @@ + +// Copyright 2019 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 class X; +template class Y; + +int main() +{ + using boost::mp11::mp_similar; + using boost::mp11::mp_true; + using boost::mp11::mp_false; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_true>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_true>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_true>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_true>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_true>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_true>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_false>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_false>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_false>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_false>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_true>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X>, mp_true>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X, X>, mp_true>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_true>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, Y>, mp_true>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, Y, Y>, mp_true>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, Y, Y, Y>, mp_true>)); + + return boost::report_errors(); +}