tuple/value: add zip implementation
This commit is contained in:
parent
5c2b52b30b
commit
8f2f623520
@ -3,6 +3,7 @@
|
||||
|
||||
#include "tap.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <typeindex>
|
||||
#include <vector>
|
||||
|
||||
@ -64,5 +65,17 @@ main ()
|
||||
tap.expect (std::is_same<dst_t, std::tuple<int>>::value, "tuple type mapping");
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
std::tuple a (1, 2);
|
||||
std::array<char,2> b { 'a', 'b' };
|
||||
std::tuple c (
|
||||
std::tuple(1, 'a'),
|
||||
std::tuple(2, 'b')
|
||||
);
|
||||
|
||||
tap.expect_eq (c, util::tuple::value::zip (a, b), "tuple zipping");
|
||||
}
|
||||
|
||||
return tap.status ();
|
||||
}
|
||||
|
@ -72,7 +72,58 @@ namespace util::tuple::value {
|
||||
{
|
||||
return detail::map (IndicesV{}, func, arg);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// return a tuple that contains the 'nth' element from each of the supplied
|
||||
// tuple-like arguments
|
||||
template <size_t N, typename ...TupleT>
|
||||
auto
|
||||
nth (TupleT&&...args)
|
||||
{
|
||||
return std::make_tuple (
|
||||
std::get<N> (args)...
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail {
|
||||
template <typename ...TupleT, size_t ...Elements>
|
||||
auto
|
||||
zip (std::index_sequence<Elements...>, TupleT &&...args)
|
||||
{
|
||||
return std::make_tuple (
|
||||
nth<Elements> (args...)...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// converts m arguments of n-tuples into one m-tuple of n-tuples by taking
|
||||
/// successive elements from each argument tuple.
|
||||
///
|
||||
/// eg, zip (('a', 1.f), (0, nullptr)) becomes (('a', 0), (1.f, nullptr))
|
||||
template <typename ...Args >
|
||||
auto
|
||||
zip (Args &&...args)
|
||||
{
|
||||
static_assert (sizeof...(args) > 0);
|
||||
// ensure all the types have the same static size
|
||||
using all_t = std::tuple<std::decay_t<Args>...>;
|
||||
using first_t = std::tuple_element_t<0,all_t>;
|
||||
|
||||
static constexpr auto arity = std::tuple_size_v<first_t>;
|
||||
static_assert ((
|
||||
(arity == std::tuple_size_v<std::decay_t<Args>>) && ...
|
||||
));
|
||||
|
||||
return detail::zip (
|
||||
std::make_index_sequence<arity> {},
|
||||
std::forward<Args> (args)...
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user