From 4094f2f73f0cdcad97d58545da0511eef2046f65 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 22 Jun 2015 03:37:15 +0300 Subject: [PATCH] Add mp_iota, mp_at, mp_take. --- include/boost/integer_sequence.hpp | 2 + include/boost/mp11/algorithm.hpp | 62 ++++++++++++++++- include/boost/mp11/detail/mp_map_find.hpp | 40 +++++++++++ test/Jamfile.v2 | 5 +- test/mp_at.cpp | 74 ++++++++++++++++++++ test/mp_iota.cpp | 42 +++++++++++ test/mp_take.cpp | 85 +++++++++++++++++++++++ 7 files changed, 308 insertions(+), 2 deletions(-) create mode 100644 include/boost/mp11/detail/mp_map_find.hpp create mode 100644 test/mp_at.cpp create mode 100644 test/mp_iota.cpp create mode 100644 test/mp_take.cpp diff --git a/include/boost/integer_sequence.hpp b/include/boost/integer_sequence.hpp index 3fc5175..9ddfc99 100644 --- a/include/boost/integer_sequence.hpp +++ b/include/boost/integer_sequence.hpp @@ -49,6 +49,8 @@ template struct make_integer_sequence_impl_ { private: + static_assert( N >= 0, "make_integer_sequence: N must not be negative" ); + static T const M = N / 2; static T const R = N % 2; diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index d28088c..80a09c0 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include #include @@ -247,8 +249,66 @@ template using mp_drop_c = typename detail::mp_drop_impl template using mp_drop = typename detail::mp_drop_impl, N>>::type; -// mp_take(_c) +// mp_iota(_c) +namespace detail +{ + +template struct mp_from_sequence_impl; + +template class S, class U, U... J> struct mp_from_sequence_impl> +{ + using type = mp_list...>; +}; + +template using mp_from_sequence = typename mp_from_sequence_impl::type; + +} // namespace detail + +template using mp_iota_c = detail::mp_from_sequence>; +template using mp_iota = detail::mp_from_sequence::type, N::value>>; + // mp_at(_c) +namespace detail +{ + +template struct mp_at_impl +{ + static_assert( I::value >= 0, "mp_at: I must not be negative" ); + + using _map = mp_transform>, L>; + + using type = mp_second>>; +}; + +} // namespace detail + +template using mp_at_c = typename detail::mp_at_impl>::type; + +template using mp_at = typename detail::mp_at_impl::type; + +// mp_take(_c) +namespace detail +{ + +template struct mp_take_impl +{ + static_assert( N::value >= 0, "mp_take: N must not be negative" ); + + using _map = mp_transform>, L>; + + template using _f = mp_second>; + + using _ind = mp_iota_c; + + using type = mp_assign>; +}; + +} // namespace detail + +template using mp_take_c = typename detail::mp_take_impl>::type; + +template using mp_take = typename detail::mp_take_impl::type; + // mp_find // mp_find_if // mp_find_index diff --git a/include/boost/mp11/detail/mp_map_find.hpp b/include/boost/mp11/detail/mp_map_find.hpp new file mode 100644 index 0000000..6c01e45 --- /dev/null +++ b/include/boost/mp11/detail/mp_map_find.hpp @@ -0,0 +1,40 @@ +#ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED + +// 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 + +namespace boost +{ + +// mp_map_find +namespace detail +{ + +template struct mp_map_find_impl; + +template class M, class... T, class K> struct mp_map_find_impl, K> +{ + using U = mp_inherit...>; + + template class L, class... U> static mp_identity> f( mp_identity>* ); + static mp_identity f( ... ); + + using V = decltype( f((U*)0) ); + + using type = typename V::type; +}; + +} // namespace detail + +template using mp_map_find = typename detail::mp_map_find_impl::type; + +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 41f4d74..e351fc4 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -9,7 +9,7 @@ import testing ; import ../../config/checks/config : requires ; -REQ = ; #[ requires cxx11_variadic_templates cxx11_template_aliases cxx11_hdr_type_traits cxx11_hdr_tuple ] ; +REQ = ; #[ requires cxx11_variadic_templates cxx11_template_aliases cxx11_decltype cxx11_hdr_type_traits cxx11_hdr_tuple ] ; # include-only compile mp11.cpp : : : $(REQ) ; @@ -35,6 +35,9 @@ run mp_contains.cpp : : : $(REQ) ; run mp_repeat.cpp : : : $(REQ) ; run mp_product.cpp : : : $(REQ) ; run mp_drop.cpp : : : $(REQ) ; +run mp_iota.cpp : : : $(REQ) ; +run mp_at.cpp : : : $(REQ) ; +run mp_take.cpp : : : $(REQ) ; # integral run integral.cpp : : : $(REQ) ; diff --git a/test/mp_at.cpp b/test/mp_at.cpp new file mode 100644 index 0000000..ef22280 --- /dev/null +++ b/test/mp_at.cpp @@ -0,0 +1,74 @@ + +// 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 {}; +struct X4 {}; +struct X5 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_at; + using boost::mp_at_c; + using boost::mp_size_t; + + { + using L1 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, X1>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X2>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X3>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X4>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X5>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same>, X1>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, X2>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, X3>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, X4>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, X5>)); + } + + { + using L1 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, X1>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X2>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X3>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X4>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X5>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same>, X1>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, X2>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, X3>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, X4>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, X5>)); + } + + { + using L1 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, X1>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, X2>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same>, X1>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, X2>)); + } + + return boost::report_errors(); +} diff --git a/test/mp_iota.cpp b/test/mp_iota.cpp new file mode 100644 index 0000000..a1eadfc --- /dev/null +++ b/test/mp_iota.cpp @@ -0,0 +1,42 @@ + +// 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 + +int main() +{ + using boost::mp_list; + using boost::mp_iota; + using boost::mp_iota_c; + using boost::mp_int; + using boost::mp_size_t; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, mp_size_t<1>>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, mp_size_t<1>, mp_size_t<2>>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, mp_size_t<1>, mp_size_t<2>, mp_size_t<3>>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list, mp_size_t<1>>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list, mp_size_t<1>, mp_size_t<2>>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list, mp_size_t<1>, mp_size_t<2>, mp_size_t<3>>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list, mp_int<1>>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list, mp_int<1>, mp_int<2>>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list, mp_int<1>, mp_int<2>, mp_int<3>>>)); + + return boost::report_errors(); +} diff --git a/test/mp_take.cpp b/test/mp_take.cpp new file mode 100644 index 0000000..eac3f12 --- /dev/null +++ b/test/mp_take.cpp @@ -0,0 +1,85 @@ + +// 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 {}; +struct X4 {}; +struct X5 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_take; + using boost::mp_take_c; + using boost::mp_size_t; + + { + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, L1>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list>)); + } + + { + using L1 = std::tuple<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, L1>)); + + using L2 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::tuple<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::tuple>)); + } + + { + using L1 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, L1>)); + } + + return boost::report_errors(); +}