From 138e4de0a8767636ab1ac4fbf289bd54090e9e4c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 22 Jun 2015 00:06:50 +0300 Subject: [PATCH] Add tests for mp_count, mp_count_if. --- include/boost/mp11/algorithm.hpp | 38 ++++++++++++++-- include/boost/mp11/detail/mp_plus.hpp | 32 +++----------- test/Jamfile.v2 | 4 +- test/mp_count.cpp | 63 +++++++++++++++++++++++++++ test/mp_count_if.cpp | 59 +++++++++++++++++++++++++ 5 files changed, 164 insertions(+), 32 deletions(-) create mode 100644 test/mp_count.cpp create mode 100644 test/mp_count_if.cpp diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index 1111370..6a72a52 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -96,11 +96,32 @@ namespace detail template struct mp_count_impl; +#if !defined( BOOST_NO_CXX11_CONSTEXPR ) + +constexpr std::size_t cx_plus() +{ + return 0; +} + +template constexpr std::size_t cx_plus(T1 t1, T... t) +{ + return t1 + cx_plus(t...); +} + template class L, class... T, class V> struct mp_count_impl, V> { - using type = mp_plus...>; + using type = mp_size_t::value...)>; }; +#else + +template class L, class... T, class V> struct mp_count_impl, V> +{ + using type = mp_size_t...>::value>; +}; + +#endif + } // namespace detail template using mp_count = typename detail::mp_count_impl::type; @@ -111,20 +132,31 @@ namespace detail template class P> struct mp_count_if_impl; +#if !defined( BOOST_NO_CXX11_CONSTEXPR ) + +template class L, class... T, template class P> struct mp_count_if_impl, P> +{ + using type = mp_size_t>::value...)>; +}; + +#else + template class L, class... T, template class P> struct mp_count_if_impl, P> { #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) template struct _f { using type = mp_to_bool>; }; - using type = mp_plus::type...>; + using type = mp_size_t::type...>::value>; #else - using type = mp_plus>...>; + using type = mp_size_t>...>::value>; #endif }; +#endif + } // namespace detail template class P> using mp_count_if = typename detail::mp_count_if_impl::type; diff --git a/include/boost/mp11/detail/mp_plus.hpp b/include/boost/mp11/detail/mp_plus.hpp index 1b77783..88e34ef 100644 --- a/include/boost/mp11/detail/mp_plus.hpp +++ b/include/boost/mp11/detail/mp_plus.hpp @@ -20,45 +20,23 @@ namespace detail template struct mp_plus_impl; -#if defined( BOOST_NO_CXX11_CONSTEXPR ) - template<> struct mp_plus_impl<> { - using type = std::integral_constant; + using type = std::integral_constant; }; template struct mp_plus_impl { - static const/*expr*/ auto _v = T1::value + mp_plus::value; - using type = std::integral_constant< typename std::remove_const::type, _v >; + static const/*expr*/ auto _v = T1::value + mp_plus_impl::type::value; + using type = std::integral_constant::type, _v>; }; template struct mp_plus_impl { - static const/*expr*/ auto _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus::value; - using type = std::integral_constant< typename std::remove_const::type, _v >; + static const/*expr*/ auto _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl::type::value; + using type = std::integral_constant::type, _v>; }; -#else - -constexpr int cx_plus() -{ - return 0; -} - -template constexpr auto cx_plus( T1 t1, T... t ) -> decltype( t1 + cx_plus( t... ) ) -{ - return t1 + cx_plus( t... ); -} - -template struct mp_plus_impl -{ - static constexpr auto _v = cx_plus( T::value... ); - using type = std::integral_constant< typename std::remove_const::type, _v >; -}; - -#endif - } // namespace detail template using mp_plus = typename detail::mp_plus_impl::type; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index dc71979..4cd6c40 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -29,8 +29,8 @@ run mp_assign.cpp : : : $(REQ) ; run mp_clear.cpp : : : $(REQ) ; run mp_transform.cpp : : : $(REQ) ; run mp_fill.cpp : : : $(REQ) ; -#run mp_count.cpp : : : $(REQ) ; -#run mp_count_if.cpp : : : $(REQ) ; +run mp_count.cpp : : : $(REQ) ; +run mp_count_if.cpp : : : $(REQ) ; #run mp_contains.cpp : : : $(REQ) ; run mp_repeat.cpp : : : $(REQ) ; diff --git a/test/mp_count.cpp b/test/mp_count.cpp new file mode 100644 index 0000000..15c128a --- /dev/null +++ b/test/mp_count.cpp @@ -0,0 +1,63 @@ + +// 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 +#include +#include +#include +#include + +struct X1 {}; +struct X2 {}; +struct X3 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_count; + using boost::mp_size_t; + + { + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>>)); + } + + { + using L3 = std::tuple<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + + using L4 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>>)); + } + + { + using L5 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>>)); + } + + return boost::report_errors(); +} diff --git a/test/mp_count_if.cpp b/test/mp_count_if.cpp new file mode 100644 index 0000000..311cf12 --- /dev/null +++ b/test/mp_count_if.cpp @@ -0,0 +1,59 @@ + +// 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 +#include +#include +#include +#include + +struct X1 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_count_if; + using boost::mp_size_t; + + { + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>>)); + } + + { + using L1 = std::tuple<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + + using L2 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>>)); + } + + { + using L2 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<0>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>>)); + } + + return boost::report_errors(); +}