tuple/value: add zip implementation
This commit is contained in:
parent
5c2b52b30b
commit
8f2f623520
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "tap.hpp"
|
#include "tap.hpp"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <typeindex>
|
#include <typeindex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -64,5 +65,17 @@ main ()
|
|||||||
tap.expect (std::is_same<dst_t, std::tuple<int>>::value, "tuple type mapping");
|
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 ();
|
return tap.status ();
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,58 @@ namespace util::tuple::value {
|
|||||||
{
|
{
|
||||||
return detail::map (IndicesV{}, func, arg);
|
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
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user