From e6c28a0848704c5246c27414ca522e7a6e413b8d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 31 May 2017 19:56:18 +0300 Subject: [PATCH 1/5] Add mp_for_index --- doc/html/mp11.html | 31 +- doc/mp11/algorithm.qbk | 12 + doc/mp11/tuple_for_each.qbk | 2 +- include/boost/mp11/algorithm.hpp | 1 + include/boost/mp11/detail/mp_for_index.hpp | 365 +++++++++++++++++++++ test/Jamfile.v2 | 1 + test/mp_for_index.cpp | 90 +++++ 7 files changed, 498 insertions(+), 4 deletions(-) create mode 100644 include/boost/mp11/detail/mp_for_index.hpp create mode 100644 test/mp_for_index.cpp diff --git a/doc/html/mp11.html b/doc/html/mp11.html index 2c2c378..90c528f 100644 --- a/doc/html/mp11.html +++ b/doc/html/mp11.html @@ -148,6 +148,8 @@
mp_none_of<L, P>
mp_any_of<L, P>
mp_for_each<L>(f)
+
mp_for_index_c<N>(i, f)
+
mp_for_index<N>(i, f)
Set Operations, <boost/mp11/set.hpp>
@@ -200,7 +202,7 @@
A "for each" algorithm for tuple-like types, <boost/mp11/tuple_for_each.hpp>
-
tuple_for_each
+
tuple_for_each(tp, f)
@@ -2036,6 +2038,29 @@ Returns std::forward<F>(f).

+
+ +
template<std::size_t N, class F> decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_for_index( std::size_t i, F && f );
+
+

+ mp_for_index_c<N>(i, f) calls f + with mp_size_t<i>() + and returns the result. i + must be less than N. +

+
+
+ +
template<class N, class F> decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_for_index( std::size_t i, F && f );
+
+

+ Returns mp_for_index_c<N::value>(i, f). +

+

@@ -2484,7 +2509,7 @@

template<class Tp, class F> constexpr F tuple_for_each(Tp&& tp, F&& f);
 
@@ -2504,7 +2529,7 @@
- +

Last revised: May 28, 2017 at 23:51:44 GMT

Last revised: May 31, 2017 at 16:52:56 GMT


diff --git a/doc/mp11/algorithm.qbk b/doc/mp11/algorithm.qbk index 08f7a53..8fa6d63 100644 --- a/doc/mp11/algorithm.qbk +++ b/doc/mp11/algorithm.qbk @@ -289,4 +289,16 @@ is `mp_size`. Returns `std::forward(f)`. [endsect] +[section `mp_for_index_c(i, f)`] + template decltype(std::declval()(std::declval>())) mp_for_index( std::size_t i, F && f ); + +`mp_for_index_c(i, f)` calls `f` with `mp_size_t()` and returns the result. `i` must be less than `N`. +[endsect] + +[section `mp_for_index(i, f)`] + template decltype(std::declval()(std::declval>())) mp_for_index( std::size_t i, F && f ); + +Returns `mp_for_index_c(i, f)`. +[endsect] + [endsect:algorithm] diff --git a/doc/mp11/tuple_for_each.qbk b/doc/mp11/tuple_for_each.qbk index 7b1f53e..9ba4c5b 100644 --- a/doc/mp11/tuple_for_each.qbk +++ b/doc/mp11/tuple_for_each.qbk @@ -8,7 +8,7 @@ [section:tuple_for_each A "for each" algorithm for tuple-like types, ``] -[section `tuple_for_each`] +[section `tuple_for_each(tp, f)`] template constexpr F tuple_for_each(Tp&& tp, F&& f); `tuple_for_each(tp, f)` applies the function object `f` to each element of `tp` by evaluating the diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index 5d27cba..f9e409f 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/mp11/detail/mp_for_index.hpp b/include/boost/mp11/detail/mp_for_index.hpp new file mode 100644 index 0000000..ca7eb83 --- /dev/null +++ b/include/boost/mp11/detail/mp_for_index.hpp @@ -0,0 +1,365 @@ +#ifndef BOOST_MP11_DETAIL_MP_FOR_INDEX_HPP_INCLUDED +#define BOOST_MP11_DETAIL_MP_FOR_INDEX_HPP_INCLUDED + +// Copyright 2017 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 + +namespace boost +{ +namespace mp11 +{ + +namespace detail +{ + +template struct mp_for_index_impl_ +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + case 14: return std::forward(f)( mp_size_t() ); + case 15: return std::forward(f)( mp_size_t() ); + } + + return mp_for_index_impl_::template call( i-16, std::forward(f) ); + } +}; + +template<> struct mp_for_index_impl_<0> +{ +}; + +template<> struct mp_for_index_impl_<1> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + return std::forward(f)( mp_size_t() ); + } +}; + +template<> struct mp_for_index_impl_<2> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<3> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<4> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<5> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<6> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<7> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<8> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<9> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<10> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<11> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<12> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<13> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<14> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<15> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + case 14: return std::forward(f)( mp_size_t() ); + } + } +}; + +template<> struct mp_for_index_impl_<16> +{ + template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + { + switch( i ) + { + case 0: return std::forward(f)( mp_size_t() ); + case 1: return std::forward(f)( mp_size_t() ); + case 2: return std::forward(f)( mp_size_t() ); + case 3: return std::forward(f)( mp_size_t() ); + case 4: return std::forward(f)( mp_size_t() ); + case 5: return std::forward(f)( mp_size_t() ); + case 6: return std::forward(f)( mp_size_t() ); + case 7: return std::forward(f)( mp_size_t() ); + case 8: return std::forward(f)( mp_size_t() ); + case 9: return std::forward(f)( mp_size_t() ); + case 10: return std::forward(f)( mp_size_t() ); + case 11: return std::forward(f)( mp_size_t() ); + case 12: return std::forward(f)( mp_size_t() ); + case 13: return std::forward(f)( mp_size_t() ); + case 14: return std::forward(f)( mp_size_t() ); + case 15: return std::forward(f)( mp_size_t() ); + } + } +}; + +} // namespace detail + +template inline decltype(std::declval()(std::declval>())) mp_for_index_c( std::size_t i, F && f ) +{ + assert( i < N ); + return detail::mp_for_index_impl_::template call<0>( i, std::forward(f) ); +} + +template inline decltype(std::declval()(std::declval>())) mp_for_index( std::size_t i, F && f ) +{ + return mp_for_index_c( i, std::forward(f) ); +} + +} // namespace mp11 +} // namespace boost + +#endif // #ifndef BOOST_MP11_DETAIL_MP_FIND_INDEX_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index b086740..c9b8fc8 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -71,6 +71,7 @@ run mp_replace_at_c.cpp : : : $(REQ) ; run mp_for_each.cpp : : : $(REQ) ; run mp_insert.cpp : : : $(REQ) ; run mp_erase.cpp : : : $(REQ) ; +run mp_for_index.cpp : : : $(REQ) ; # integral run integral.cpp : : : $(REQ) ; diff --git a/test/mp_for_index.cpp b/test/mp_for_index.cpp new file mode 100644 index 0000000..d700cad --- /dev/null +++ b/test/mp_for_index.cpp @@ -0,0 +1,90 @@ + +// Copyright 2017 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 + +using boost::mp11::mp_size_t; +using boost::mp11::mp_for_each; +using boost::mp11::mp_for_index; +using boost::mp11::mp_for_index_c; +using boost::mp11::mp_iota_c; + +struct F +{ + int i_; + + explicit F( int i ): i_( i ) {} + + template void operator()( mp_size_t ) const + { + BOOST_TEST_EQ( I, i_ ); + } +}; + +struct G +{ + void operator()( mp_size_t<0> ) const + { + } + + template void operator()( mp_size_t ) const + { + for( std::size_t i = 0; i < N; ++i ) + { + mp_for_index_c( i, F(i) ); + mp_for_index>( i, F(i) ); + } + } +}; + +int main() +{ +#if BOOST_WORKAROUND( BOOST_MSVC, < 1900 ) + + G()( mp_size_t<1>{} ); + G()( mp_size_t<2>{} ); + G()( mp_size_t<3>{} ); + G()( mp_size_t<4>{} ); + G()( mp_size_t<5>{} ); + G()( mp_size_t<6>{} ); + G()( mp_size_t<7>{} ); + G()( mp_size_t<8>{} ); + G()( mp_size_t<9>{} ); + G()( mp_size_t<10>{} ); + G()( mp_size_t<11>{} ); + G()( mp_size_t<12>{} ); + G()( mp_size_t<13>{} ); + G()( mp_size_t<14>{} ); + G()( mp_size_t<15>{} ); + G()( mp_size_t<16>{} ); + + G()( mp_size_t<32+1>{} ); + + G()( mp_size_t<48+2>{} ); + + G()( mp_size_t<64+3>{} ); + + G()( mp_size_t<96+4>{} ); + + G()( mp_size_t<112+5>{} ); + + G()( mp_size_t<128+6>{} ); + +#else + + mp_for_each>( G() ); + +#endif + + return boost::report_errors(); +} From 1bd4b670ce743a9fbc495285afca0815cf762716 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 31 May 2017 20:16:41 +0300 Subject: [PATCH 2/5] Avoid control reaches end of non-void function warnings --- include/boost/mp11/detail/mp_for_index.hpp | 30 +++++++++++----------- test/mp_for_index.cpp | 3 ++- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/include/boost/mp11/detail/mp_for_index.hpp b/include/boost/mp11/detail/mp_for_index.hpp index ca7eb83..ae4ea42 100644 --- a/include/boost/mp11/detail/mp_for_index.hpp +++ b/include/boost/mp11/detail/mp_for_index.hpp @@ -68,7 +68,7 @@ template<> struct mp_for_index_impl_<2> switch( i ) { case 0: return std::forward(f)( mp_size_t() ); - case 1: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -81,7 +81,7 @@ template<> struct mp_for_index_impl_<3> { case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); - case 2: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -95,7 +95,7 @@ template<> struct mp_for_index_impl_<4> case 0: return std::forward(f)( mp_size_t() ); case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); - case 3: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -110,7 +110,7 @@ template<> struct mp_for_index_impl_<5> case 1: return std::forward(f)( mp_size_t() ); case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); - case 4: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -126,7 +126,7 @@ template<> struct mp_for_index_impl_<6> case 2: return std::forward(f)( mp_size_t() ); case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); - case 5: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -143,7 +143,7 @@ template<> struct mp_for_index_impl_<7> case 3: return std::forward(f)( mp_size_t() ); case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); - case 6: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -161,7 +161,7 @@ template<> struct mp_for_index_impl_<8> case 4: return std::forward(f)( mp_size_t() ); case 5: return std::forward(f)( mp_size_t() ); case 6: return std::forward(f)( mp_size_t() ); - case 7: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -180,7 +180,7 @@ template<> struct mp_for_index_impl_<9> case 5: return std::forward(f)( mp_size_t() ); case 6: return std::forward(f)( mp_size_t() ); case 7: return std::forward(f)( mp_size_t() ); - case 8: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -200,7 +200,7 @@ template<> struct mp_for_index_impl_<10> case 6: return std::forward(f)( mp_size_t() ); case 7: return std::forward(f)( mp_size_t() ); case 8: return std::forward(f)( mp_size_t() ); - case 9: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -221,7 +221,7 @@ template<> struct mp_for_index_impl_<11> case 7: return std::forward(f)( mp_size_t() ); case 8: return std::forward(f)( mp_size_t() ); case 9: return std::forward(f)( mp_size_t() ); - case 10: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -243,7 +243,7 @@ template<> struct mp_for_index_impl_<12> case 8: return std::forward(f)( mp_size_t() ); case 9: return std::forward(f)( mp_size_t() ); case 10: return std::forward(f)( mp_size_t() ); - case 11: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -266,7 +266,7 @@ template<> struct mp_for_index_impl_<13> case 9: return std::forward(f)( mp_size_t() ); case 10: return std::forward(f)( mp_size_t() ); case 11: return std::forward(f)( mp_size_t() ); - case 12: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -290,7 +290,7 @@ template<> struct mp_for_index_impl_<14> case 10: return std::forward(f)( mp_size_t() ); case 11: return std::forward(f)( mp_size_t() ); case 12: return std::forward(f)( mp_size_t() ); - case 13: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -315,7 +315,7 @@ template<> struct mp_for_index_impl_<15> case 11: return std::forward(f)( mp_size_t() ); case 12: return std::forward(f)( mp_size_t() ); case 13: return std::forward(f)( mp_size_t() ); - case 14: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; @@ -341,7 +341,7 @@ template<> struct mp_for_index_impl_<16> case 12: return std::forward(f)( mp_size_t() ); case 13: return std::forward(f)( mp_size_t() ); case 14: return std::forward(f)( mp_size_t() ); - case 15: return std::forward(f)( mp_size_t() ); + default: return std::forward(f)( mp_size_t() ); } } }; diff --git a/test/mp_for_index.cpp b/test/mp_for_index.cpp index d700cad..c8c7dfb 100644 --- a/test/mp_for_index.cpp +++ b/test/mp_for_index.cpp @@ -25,9 +25,10 @@ struct F explicit F( int i ): i_( i ) {} - template void operator()( mp_size_t ) const + template bool operator()( mp_size_t ) const { BOOST_TEST_EQ( I, i_ ); + return false; } }; From 3cce995877efd6ad9cd44975201b34b333b7720a Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 31 May 2017 23:18:08 +0300 Subject: [PATCH 3/5] Rename mp_for_index_c to mp_for_index --- doc/html/mp11.html | 14 ++++---------- doc/mp11/algorithm.qbk | 8 +++----- include/boost/mp11/detail/mp_for_index.hpp | 4 ++-- test/mp_for_index.cpp | 3 +-- 4 files changed, 10 insertions(+), 19 deletions(-) diff --git a/doc/html/mp11.html b/doc/html/mp11.html index 90c528f..0e58619 100644 --- a/doc/html/mp11.html +++ b/doc/html/mp11.html @@ -148,7 +148,6 @@
mp_none_of<L, P>
mp_any_of<L, P>
mp_for_each<L>(f)
-
mp_for_index_c<N>(i, f)
mp_for_index<N>(i, f)
Set Operations, <boost/mp11/set.hpp>
@@ -2040,25 +2039,20 @@
template<std::size_t N, class F> decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_for_index( std::size_t i, F && f );
 

- mp_for_index_c<N>(i, f) calls f + mp_for_index<N>(i, f) calls f with mp_size_t<i>() and returns the result. i must be less than N.

-
-
-
template<class N, class F> decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_for_index( std::size_t i, F && f );
 

- Returns mp_for_index_c<N::value>(i, f). + Returns mp_for_index<N::value>(i, f).

@@ -2529,7 +2523,7 @@ - +

Last revised: May 31, 2017 at 16:52:56 GMT

Last revised: May 31, 2017 at 20:15:36 GMT


diff --git a/doc/mp11/algorithm.qbk b/doc/mp11/algorithm.qbk index 8fa6d63..a4251bb 100644 --- a/doc/mp11/algorithm.qbk +++ b/doc/mp11/algorithm.qbk @@ -289,16 +289,14 @@ is `mp_size`. Returns `std::forward(f)`. [endsect] -[section `mp_for_index_c(i, f)`] +[section `mp_for_index(i, f)`] template decltype(std::declval()(std::declval>())) mp_for_index( std::size_t i, F && f ); -`mp_for_index_c(i, f)` calls `f` with `mp_size_t()` and returns the result. `i` must be less than `N`. -[endsect] +`mp_for_index(i, f)` calls `f` with `mp_size_t()` and returns the result. `i` must be less than `N`. -[section `mp_for_index(i, f)`] template decltype(std::declval()(std::declval>())) mp_for_index( std::size_t i, F && f ); -Returns `mp_for_index_c(i, f)`. +Returns `mp_for_index(i, f)`. [endsect] [endsect:algorithm] diff --git a/include/boost/mp11/detail/mp_for_index.hpp b/include/boost/mp11/detail/mp_for_index.hpp index ae4ea42..85f3c45 100644 --- a/include/boost/mp11/detail/mp_for_index.hpp +++ b/include/boost/mp11/detail/mp_for_index.hpp @@ -348,7 +348,7 @@ template<> struct mp_for_index_impl_<16> } // namespace detail -template inline decltype(std::declval()(std::declval>())) mp_for_index_c( std::size_t i, F && f ) +template inline decltype(std::declval()(std::declval>())) mp_for_index( std::size_t i, F && f ) { assert( i < N ); return detail::mp_for_index_impl_::template call<0>( i, std::forward(f) ); @@ -356,7 +356,7 @@ template inline decltype(std::declval()(std::declval< template inline decltype(std::declval()(std::declval>())) mp_for_index( std::size_t i, F && f ) { - return mp_for_index_c( i, std::forward(f) ); + return mp_for_index( i, std::forward(f) ); } } // namespace mp11 diff --git a/test/mp_for_index.cpp b/test/mp_for_index.cpp index c8c7dfb..d00e77c 100644 --- a/test/mp_for_index.cpp +++ b/test/mp_for_index.cpp @@ -16,7 +16,6 @@ using boost::mp11::mp_size_t; using boost::mp11::mp_for_each; using boost::mp11::mp_for_index; -using boost::mp11::mp_for_index_c; using boost::mp11::mp_iota_c; struct F @@ -42,7 +41,7 @@ struct G { for( std::size_t i = 0; i < N; ++i ) { - mp_for_index_c( i, F(i) ); + mp_for_index( i, F(i) ); mp_for_index>( i, F(i) ); } } From b8bbd279b2cf5403bf3cbd767db23e46cde7c5d9 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 31 May 2017 23:44:24 +0300 Subject: [PATCH 4/5] Make mp_for_each constexpr under C++14 --- include/boost/mp11/detail/mp_for_index.hpp | 47 +++++++++++++--------- test/Jamfile.v2 | 1 + test/mp_for_index_cx.cpp | 41 +++++++++++++++++++ 3 files changed, 70 insertions(+), 19 deletions(-) create mode 100644 test/mp_for_index_cx.cpp diff --git a/include/boost/mp11/detail/mp_for_index.hpp b/include/boost/mp11/detail/mp_for_index.hpp index 85f3c45..88a3293 100644 --- a/include/boost/mp11/detail/mp_for_index.hpp +++ b/include/boost/mp11/detail/mp_for_index.hpp @@ -9,10 +9,17 @@ // http://www.boost.org/LICENSE_1_0.txt #include +#include #include #include #include +#if !defined( BOOST_NO_CXX14_CONSTEXPR ) +# define BOOST_MP11_CONSTEXPR14 constexpr +#else +# define BOOST_MP11_CONSTEXPR14 +#endif + namespace boost { namespace mp11 @@ -23,7 +30,7 @@ namespace detail template struct mp_for_index_impl_ { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -55,7 +62,7 @@ template<> struct mp_for_index_impl_<0> template<> struct mp_for_index_impl_<1> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { return std::forward(f)( mp_size_t() ); } @@ -63,7 +70,7 @@ template<> struct mp_for_index_impl_<1> template<> struct mp_for_index_impl_<2> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -75,7 +82,7 @@ template<> struct mp_for_index_impl_<2> template<> struct mp_for_index_impl_<3> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -88,7 +95,7 @@ template<> struct mp_for_index_impl_<3> template<> struct mp_for_index_impl_<4> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -102,7 +109,7 @@ template<> struct mp_for_index_impl_<4> template<> struct mp_for_index_impl_<5> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -117,7 +124,7 @@ template<> struct mp_for_index_impl_<5> template<> struct mp_for_index_impl_<6> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -133,7 +140,7 @@ template<> struct mp_for_index_impl_<6> template<> struct mp_for_index_impl_<7> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -150,7 +157,7 @@ template<> struct mp_for_index_impl_<7> template<> struct mp_for_index_impl_<8> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -168,7 +175,7 @@ template<> struct mp_for_index_impl_<8> template<> struct mp_for_index_impl_<9> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -187,7 +194,7 @@ template<> struct mp_for_index_impl_<9> template<> struct mp_for_index_impl_<10> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -207,7 +214,7 @@ template<> struct mp_for_index_impl_<10> template<> struct mp_for_index_impl_<11> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -228,7 +235,7 @@ template<> struct mp_for_index_impl_<11> template<> struct mp_for_index_impl_<12> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -250,7 +257,7 @@ template<> struct mp_for_index_impl_<12> template<> struct mp_for_index_impl_<13> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -273,7 +280,7 @@ template<> struct mp_for_index_impl_<13> template<> struct mp_for_index_impl_<14> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -297,7 +304,7 @@ template<> struct mp_for_index_impl_<14> template<> struct mp_for_index_impl_<15> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -322,7 +329,7 @@ template<> struct mp_for_index_impl_<15> template<> struct mp_for_index_impl_<16> { - template static decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) + template static BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) call( std::size_t i, F && f ) { switch( i ) { @@ -348,17 +355,19 @@ template<> struct mp_for_index_impl_<16> } // namespace detail -template inline decltype(std::declval()(std::declval>())) mp_for_index( std::size_t i, F && f ) +template inline BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) mp_for_index( std::size_t i, F && f ) { assert( i < N ); return detail::mp_for_index_impl_::template call<0>( i, std::forward(f) ); } -template inline decltype(std::declval()(std::declval>())) mp_for_index( std::size_t i, F && f ) +template inline BOOST_MP11_CONSTEXPR14 decltype(std::declval()(std::declval>())) mp_for_index( std::size_t i, F && f ) { return mp_for_index( i, std::forward(f) ); } +#undef BOOST_MP11_CONSTEXPR14 + } // namespace mp11 } // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index c9b8fc8..f5c3753 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -72,6 +72,7 @@ run mp_for_each.cpp : : : $(REQ) ; run mp_insert.cpp : : : $(REQ) ; run mp_erase.cpp : : : $(REQ) ; run mp_for_index.cpp : : : $(REQ) ; +run mp_for_index_cx.cpp : : : $(REQ) ; # integral run integral.cpp : : : $(REQ) ; diff --git a/test/mp_for_index_cx.cpp b/test/mp_for_index_cx.cpp new file mode 100644 index 0000000..db8d180 --- /dev/null +++ b/test/mp_for_index_cx.cpp @@ -0,0 +1,41 @@ + +// Copyright 2017 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 + +#if defined( BOOST_NO_CXX14_CONSTEXPR ) + +int main() {} + +#else + +#include +#include +#include +#include + +using boost::mp11::mp_size_t; +using boost::mp11::mp_for_index; + +struct F +{ + template constexpr std::size_t operator()( mp_size_t ) const + { + return I; + } +}; + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + +int main() +{ + constexpr std::size_t i = mp_for_index<64>( 57, F{} ); + STATIC_ASSERT( i == 57 ); +} + +#endif From f70a5e7bdbf36599d523bc4866c1d12e477d9575 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 1 Jun 2017 01:01:49 +0300 Subject: [PATCH 5/5] Test mp_product with one list --- test/mp_product.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/mp_product.cpp b/test/mp_product.cpp index 25ef40f..3d3d2ad 100644 --- a/test/mp_product.cpp +++ b/test/mp_product.cpp @@ -26,6 +26,8 @@ struct Z2 {}; template struct F {}; +template struct F1 {}; + int main() { using boost::mp11::mp_list; @@ -51,5 +53,16 @@ int main() BOOST_TEST_TRAIT_TRUE((std::is_same, L1, L2, L3>, std::tuple<>>)); } + { + using L1 = std::tuple; + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple, F1, F1>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>, std::tuple, F1, F1>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, F1, F1>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>, mp_list, F1, F1>>)); + } + return boost::report_errors(); }