1
0
forked from boostorg/mp11

Add test/tuple_transform_2.cpp

This commit is contained in:
Peter Dimov
2020-05-23 21:13:35 +03:00
parent 0ee00ee64a
commit 9349a82e6b
3 changed files with 175 additions and 6 deletions

View File

@@ -42,9 +42,15 @@ Returns `std::forward<F>(f)`.
template<class F, class... Tp> constexpr /*...*/ tuple_transform(F const& f, Tp&&... tp); template<class F, class... Tp> constexpr /*...*/ tuple_transform(F const& f, Tp&&... tp);
`tuple_transform(f, tp...)` accepts a function object `f` followed by one or more tuples of equal length `tuple_transform(f, tp...)` accepts a function object `f` followed by one or more tuples of equal length
(`std::pair` is also accepted). The callable `f` must accept as many arguments as there are tuples. The (`std::tuple`, `std::pair` and `std::array` are considered tuples.)
function object is called with the first elements of each tuple, then with the second element of each tuple,
and so on, by evaluating the expression `f(std::get<J>(std::forward<Tp>(tp))...)` for `J` in 0..`N-1`, where The callable `f` must accept as many arguments as there are tuples. The function object is called with the
`N` is the length of the tuples. The results are returned as a `std::tuple<T...>` with `T...` deduced from the first elements of each tuple, then with the second element of each tuple, and so on, as if by evaluating
return values of `f`. The order in which the elements of the tuples are processed is unspecified. Calling `f` the expression `f(std::get<J>(std::forward<Tp>(tp))...)` for `J` in 0..`N-1`, where `N` is the length of
should not have side effects. the tuples.
The results are returned as a `std::tuple<T...>` with `T...` deduced from the return values of `f` (lvalue
references are preserved, rvalue references are returned by value.)
The order in which the elements of the tuples are processed is unspecified. Calling `f` should not have
side effects.

View File

@@ -157,6 +157,7 @@ compile tuple_apply_cx.cpp ;
run construct_from_tuple.cpp ; run construct_from_tuple.cpp ;
compile construct_from_tuple_cx.cpp ; compile construct_from_tuple_cx.cpp ;
run tuple_transform.cpp ; run tuple_transform.cpp ;
run tuple_transform_2.cpp ;
compile tuple_transform_cx.cpp ; compile tuple_transform_cx.cpp ;
# set # set

162
test/tuple_transform_2.cpp Normal file
View File

@@ -0,0 +1,162 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/mp11/tuple.hpp>
#include <boost/mp11/algorithm.hpp>
#include <boost/core/lightweight_test.hpp>
#include <tuple>
#include <utility>
#include <array>
#include <cstddef>
int f( int x )
{
return x + 1;
}
int g( int x, int y )
{
return x + y;
}
int h( int x, int y, int z )
{
return x + y + z;
}
int q( int x, int y, int z, int v )
{
return x + y + z + v;
}
template<class T1, class... T> std::array<T1, 1 + sizeof...(T)> make_array( T1 t1, T... t )
{
return { { t1, t... } };
}
template<class Tp> struct test_element
{
Tp& tp;
template<int I> void operator()( boost::mp11::mp_int<I> ) const
{
BOOST_TEST_EQ( std::get<I>( tp ), q( I, I, I, I ) );
}
};
int main()
{
using boost::mp11::tuple_transform;
//
{
std::tuple<int> r = tuple_transform( f, std::make_tuple( 1 ) );
BOOST_TEST_EQ( std::get<0>( r ), 2 );
}
{
std::tuple<int> r = tuple_transform( f, ::make_array( 1 ) );
BOOST_TEST_EQ( std::get<0>( r ), 2 );
}
{
std::tuple<int> r = tuple_transform( g, ::make_array( 1 ), std::make_tuple( 2 ) );
BOOST_TEST_EQ( std::get<0>( r ), 3 );
}
{
std::tuple<int> r = tuple_transform( h, ::make_array( 1 ), std::make_tuple( 2 ), ::make_array( 3 ) );
BOOST_TEST_EQ( std::get<0>( r ), 6 );
}
//
{
std::tuple<int, int> r = tuple_transform( f, std::make_tuple( 1, 2 ) );
BOOST_TEST_EQ( std::get<0>( r ), 2 );
BOOST_TEST_EQ( std::get<1>( r ), 3 );
}
{
std::tuple<int, int> r = tuple_transform( f, std::make_pair( 1, 2 ) );
BOOST_TEST_EQ( std::get<0>( r ), 2 );
BOOST_TEST_EQ( std::get<1>( r ), 3 );
}
{
std::tuple<int, int> r = tuple_transform( f, ::make_array( 1, 2 ) );
BOOST_TEST_EQ( std::get<0>( r ), 2 );
BOOST_TEST_EQ( std::get<1>( r ), 3 );
}
{
std::tuple<int, int> r = tuple_transform( g, ::make_array( 1, 2 ), std::make_pair( 3, 4 ) );
BOOST_TEST_EQ( std::get<0>( r ), 4 );
BOOST_TEST_EQ( std::get<1>( r ), 6 );
}
{
std::tuple<int, int> r = tuple_transform( h, ::make_array( 1, 2 ), std::make_pair( 3, 4 ), std::make_tuple( 5, 6 ) );
BOOST_TEST_EQ( std::get<0>( r ), 9 );
BOOST_TEST_EQ( std::get<1>( r ), 12 );
}
//
{
std::tuple<int, int, int> r = tuple_transform( f, std::make_tuple( 1, 2, 3 ) );
BOOST_TEST_EQ( std::get<0>( r ), 2 );
BOOST_TEST_EQ( std::get<1>( r ), 3 );
BOOST_TEST_EQ( std::get<2>( r ), 4 );
}
{
std::tuple<int, int, int> r = tuple_transform( f, ::make_array( 1, 2, 3 ) );
BOOST_TEST_EQ( std::get<0>( r ), 2 );
BOOST_TEST_EQ( std::get<1>( r ), 3 );
BOOST_TEST_EQ( std::get<2>( r ), 4 );
}
{
std::tuple<int, int, int> r = tuple_transform( g, ::make_array( 1, 2, 3 ), std::make_tuple( 4, 5, 6 ) );
BOOST_TEST_EQ( std::get<0>( r ), 5 );
BOOST_TEST_EQ( std::get<1>( r ), 7 );
BOOST_TEST_EQ( std::get<2>( r ), 9 );
}
{
std::tuple<int, int, int> r = tuple_transform( h, ::make_array( 1, 2, 3 ), std::make_tuple( 4, 5, 6 ), ::make_array( 7, 8, 9 ) );
BOOST_TEST_EQ( std::get<0>( r ), 12 );
BOOST_TEST_EQ( std::get<1>( r ), 15 );
BOOST_TEST_EQ( std::get<2>( r ), 18 );
}
{
using namespace boost::mp11;
int const N = 64;
using Tp = mp_rename<mp_iota< mp_int<N> >, std::tuple>;
auto const r = tuple_transform( q, Tp(), Tp(), Tp(), Tp() );
mp_for_each<Tp>( test_element<decltype(r)>{ r } );
}
return boost::report_errors();
}