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 988d3f8..95d0e7f 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -10,7 +10,10 @@ #include #include +#include #include +#include +#include #include #include #include @@ -199,7 +202,6 @@ template using mp_repeat_c = typename detail::mp_repeat_ template using mp_repeat = typename detail::mp_repeat_impl::type; // mp_product - namespace detail { @@ -227,8 +229,131 @@ template class F, class L1, class... L> struct mp_product_imp template class F, class... L> using mp_product = typename detail::mp_product_impl::type; // mp_drop(_c) -// mp_take(_c) +namespace detail +{ + +template struct mp_drop_impl; + +template class L, class... T, template class L2, class... U> struct mp_drop_impl, L2> +{ + template static mp_identity> f( U*..., mp_identity*... ); + + using R = decltype( f( (mp_identity*)0 ... ) ); + + using type = typename R::type; +}; + +} // namespace detail + +template using mp_drop_c = typename detail::mp_drop_impl, N>>::type; + +template using mp_drop = typename detail::mp_drop_impl, N>>::type; + +// 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_replace +namespace detail +{ + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + +template struct mp_replace_impl; + +template class L, class... T, class V, class W> struct mp_replace_impl, V, W> +{ + template struct _f { using type = mp_if, W, A>; }; + + using type = L::type...>; +}; + +#else + +template struct mp_replace_impl +{ + template using _f = mp_if, W, A>; + + using type = mp_transform<_f, L>; +}; + +#endif + +} // namespace detail + +template using mp_replace = typename detail::mp_replace_impl::type; + +// mp_replace_if +namespace detail +{ + +template class P, class W> struct mp_replace_if_impl +{ + template using _f = mp_if, W, T>; + + using type = mp_transform<_f, L>; +}; + +} // namespace detail + +template class P, class W> using mp_replace_if = typename detail::mp_replace_if_impl::type; + // mp_find // mp_find_if // mp_find_index @@ -238,8 +363,6 @@ template class F, class... L> using mp_product = typename det // mp_remove_if // mp_fold // mp_reverse_fold -// mp_replace? -// mp_replace_if? // mp_partition // mp_sort 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/include/boost/tuple_for_each.hpp b/include/boost/tuple_for_each.hpp new file mode 100644 index 0000000..35d2b7a --- /dev/null +++ b/include/boost/tuple_for_each.hpp @@ -0,0 +1,33 @@ +#ifndef BOOST_TUPLE_FOR_EACH_HPP_INCLUDED +#define BOOST_TUPLE_FOR_EACH_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include + +namespace boost +{ + +namespace detail +{ + +template BOOST_CONSTEXPR F tuple_for_each_impl( Tp && tp, boost::integer_sequence, F && f ) +{ + using A = int[sizeof...(J)]; + return (void)A{ (f(std::get(std::forward(tp))), 0)... }, std::forward(f); +} + +} // namespace detail + +template BOOST_CONSTEXPR F tuple_for_each( Tp && tp, F && f ) +{ + using seq = boost::make_index_sequence::type>::value>; + return detail::tuple_for_each_impl( std::forward(tp), seq(), std::forward(f) ); +} + +} // namespace boost + +#endif // #ifndef BOOST_TUPLE_FOR_EACH_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index de0a1ce..9118ff4 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) ; @@ -34,6 +34,12 @@ run mp_count_if.cpp : : : $(REQ) ; 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) ; +run mp_replace.cpp : : : $(REQ) ; +run mp_replace_if.cpp : : : $(REQ) ; # integral run integral.cpp : : : $(REQ) ; @@ -46,3 +52,7 @@ run mp_eval_if.cpp : : : $(REQ) ; # integer_sequence run integer_sequence.cpp : : : $(REQ) ; + +# tuple_for_each +run tuple_for_each.cpp : : : $(REQ) ; +run tuple_for_each_cx.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_drop.cpp b/test/mp_drop.cpp new file mode 100644 index 0000000..6cadc27 --- /dev/null +++ b/test/mp_drop.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_drop; + using boost::mp_drop_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(); +} 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_replace.cpp b/test/mp_replace.cpp new file mode 100644 index 0000000..9562bfe --- /dev/null +++ b/test/mp_replace.cpp @@ -0,0 +1,61 @@ + +// 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 + +struct X1 {}; +struct X2 {}; +struct X3 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_replace; + + { + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>)); + 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>)); + + using L2 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>)); + 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 L2 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>)); + } + + return boost::report_errors(); +} diff --git a/test/mp_replace_if.cpp b/test/mp_replace_if.cpp new file mode 100644 index 0000000..c075494 --- /dev/null +++ b/test/mp_replace_if.cpp @@ -0,0 +1,57 @@ + +// 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 + +struct X1 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_replace_if; + + { + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>)); + 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>)); + + using L2 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + } + + { + using L2 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>)); + } + + 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(); +} diff --git a/test/tuple_for_each.cpp b/test/tuple_for_each.cpp new file mode 100644 index 0000000..325a51e --- /dev/null +++ b/test/tuple_for_each.cpp @@ -0,0 +1,90 @@ + +// 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 + +int main() +{ + { + std::tuple tp{ 1, 2, 3 }; + + { + int s = 0; + + boost::tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } ); + + BOOST_TEST_EQ( s, 123 ); + } + + { + int s = 0; + + boost::tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } ); + + BOOST_TEST_EQ( s, 123 ); + } + } + + { + std::tuple, std::unique_ptr, std::unique_ptr> tp{ std::unique_ptr(new int(1)), std::unique_ptr(new int(2)), std::unique_ptr(new int(3)) }; + + int s = 0; + + boost::tuple_for_each( std::move(tp), [&]( std::unique_ptr p ){ s = s * 10 + *p; } ); + + BOOST_TEST_EQ( s, 123 ); + } + + { + std::pair tp{ 1, 2 }; + + { + int s = 0; + + boost::tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } ); + + BOOST_TEST_EQ( s, 12 ); + } + + { + int s = 0; + + boost::tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } ); + + BOOST_TEST_EQ( s, 12 ); + } + } + + { + std::array tp{{ 1, 2, 3 }}; + + { + int s = 0; + + boost::tuple_for_each( tp, [&]( int x ){ s = s * 10 + x; } ); + + BOOST_TEST_EQ( s, 123 ); + } + + { + int s = 0; + + boost::tuple_for_each( std::move(tp), [&]( int x ){ s = s * 10 + x; } ); + + BOOST_TEST_EQ( s, 123 ); + } + } + + return boost::report_errors(); +} diff --git a/test/tuple_for_each_cx.cpp b/test/tuple_for_each_cx.cpp new file mode 100644 index 0000000..220253c --- /dev/null +++ b/test/tuple_for_each_cx.cpp @@ -0,0 +1,37 @@ + +// 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 + +#if defined( BOOST_NO_CXX11_CONSTEXPR ) + +int main() {} + +#else + +#include +#include + +struct assert_is_integral +{ + template constexpr bool operator()( T ) const + { + static_assert( std::is_integral::value, "T must be an integral type" ); + return true; + } +}; + +int main() +{ + constexpr std::tuple tp{ 1, 2, 3 }; + constexpr auto r = boost::tuple_for_each( tp, assert_is_integral() ); + (void)r; +} + +#endif