forked from boostorg/mp11
Add mp_for_each
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@@ -823,6 +824,31 @@ template<class L, class I, class W> struct mp_replace_at_impl
|
|||||||
template<class L, class I, class W> using mp_replace_at = typename detail::mp_replace_at_impl<L, I, W>::type;
|
template<class L, class I, class W> using mp_replace_at = typename detail::mp_replace_at_impl<L, I, W>::type;
|
||||||
template<class L, std::size_t I, class W> using mp_replace_at_c = typename detail::mp_replace_at_impl<L, mp_size_t<I>, W>::type;
|
template<class L, std::size_t I, class W> using mp_replace_at_c = typename detail::mp_replace_at_impl<L, mp_size_t<I>, W>::type;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class... T, class F> BOOST_CONSTEXPR F mp_for_each_impl( mp_list<T...>, F && f )
|
||||||
|
{
|
||||||
|
using A = int[sizeof...(T)];
|
||||||
|
return (void)A{ ((void)f(mp_identity<T>()), 0)... }, std::forward<F>(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND( BOOST_MSVC, <= 1800 )
|
||||||
|
|
||||||
|
template<class F> BOOST_CONSTEXPR F mp_for_each_impl( mp_list<>, F && f )
|
||||||
|
{
|
||||||
|
return std::forward<F>(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class L, class F> BOOST_CONSTEXPR F mp_for_each( F && f )
|
||||||
|
{
|
||||||
|
return detail::mp_for_each_impl( mp_rename<L, mp_list>(), std::forward<F>(f) );
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mp11
|
} // namespace mp11
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
@@ -64,6 +64,7 @@ run mp_any_of.cpp : : : $(REQ) ;
|
|||||||
run mp_none_of.cpp : : : $(REQ) ;
|
run mp_none_of.cpp : : : $(REQ) ;
|
||||||
run mp_replace_at.cpp : : : $(REQ) ;
|
run mp_replace_at.cpp : : : $(REQ) ;
|
||||||
run mp_replace_at_c.cpp : : : $(REQ) ;
|
run mp_replace_at_c.cpp : : : $(REQ) ;
|
||||||
|
run mp_for_each.cpp : : : $(REQ) ;
|
||||||
|
|
||||||
# integral
|
# integral
|
||||||
run integral.cpp : : : $(REQ) ;
|
run integral.cpp : : : $(REQ) ;
|
||||||
|
72
test/mp_for_each.cpp
Normal file
72
test/mp_for_each.cpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
// 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 <boost/mp11/algorithm.hpp>
|
||||||
|
#include <boost/mp11/list.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
using boost::mp11::mp_identity;
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX14_CONSTEXPR )
|
||||||
|
# define CONSTEXPR14 constexpr
|
||||||
|
#else
|
||||||
|
# define CONSTEXPR14
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct F
|
||||||
|
{
|
||||||
|
int s;
|
||||||
|
|
||||||
|
CONSTEXPR14 void operator()( mp_identity<int> ) { s = s * 10 + 1; }
|
||||||
|
CONSTEXPR14 void operator()( mp_identity<short> ) { s = s * 10 + 2; }
|
||||||
|
CONSTEXPR14 void operator()( mp_identity<char> ) { s = s * 10 + 3; }
|
||||||
|
};
|
||||||
|
|
||||||
|
using boost::mp11::mp_list;
|
||||||
|
using boost::mp11::mp_for_each;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
BOOST_TEST_EQ( (mp_for_each<mp_list<>>( 11 )), 11 );
|
||||||
|
BOOST_TEST_EQ( (mp_for_each<mp_list<int>>( F{0} ).s), 1 );
|
||||||
|
BOOST_TEST_EQ( (mp_for_each<mp_list<int, short>>( F{0} ).s), 12 );
|
||||||
|
BOOST_TEST_EQ( (mp_for_each<mp_list<int, short, char>>( F{0} ).s), 123 );
|
||||||
|
|
||||||
|
BOOST_TEST_EQ( (mp_for_each<std::tuple<>>( 11 )), 11 );
|
||||||
|
BOOST_TEST_EQ( (mp_for_each<std::tuple<int>>( F{0} ).s), 1 );
|
||||||
|
BOOST_TEST_EQ( (mp_for_each<std::tuple<int, short>>( F{0} ).s), 12 );
|
||||||
|
BOOST_TEST_EQ( (mp_for_each<std::tuple<int, short, char>>( F{0} ).s), 123 );
|
||||||
|
|
||||||
|
BOOST_TEST_EQ( (mp_for_each<std::pair<int, short>>( F{0} ).s), 12 );
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX11_CONSTEXPR )
|
||||||
|
|
||||||
|
static_assert( mp_for_each<mp_list<>>( 11 ) == 11, "mp_for_each<mp_list<>>( 11 ) == 11" );
|
||||||
|
static_assert( mp_for_each<std::tuple<>>( 12 ) == 12, "mp_for_each<std::tuple<>>( 12 ) == 12" );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined( BOOST_NO_CXX14_CONSTEXPR ) && !BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
|
||||||
|
|
||||||
|
constexpr auto r1 = mp_for_each<mp_list<int, short, char>>( F{0} );
|
||||||
|
static_assert( r1.s == 123, "r1.s == 123" );
|
||||||
|
|
||||||
|
constexpr auto r2 = mp_for_each<std::tuple<int, short, char>>( F{0} );
|
||||||
|
static_assert( r2.s == 123, "r2.s == 123" );
|
||||||
|
|
||||||
|
constexpr auto r3 = mp_for_each<std::pair<int, short>>( F{0} );
|
||||||
|
static_assert( r3.s == 12, "r3.s == 12" );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
Reference in New Issue
Block a user