Last active
March 4, 2022 16:57
-
-
Save dyigitpolat/0d99b5f6ae182fbcf0716f4c53ad5f02 to your computer and use it in GitHub Desktop.
pack projection with non-evaluated lambda
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <tuple> | |
#include <variant> | |
#include <type_traits> | |
#include <utility> | |
template < | |
template <typename Q> typename MetaProj, | |
typename... Ts> | |
class PackProjector | |
{ | |
using TP = std::tuple<MetaProj<Ts>...>; | |
template <std::size_t idx> | |
using get_type = typename std::tuple_element<idx, TP>::type; | |
template < | |
template <typename... Qs> typename MetaPred, | |
typename... Types> | |
struct Helper { using type = MetaPred<Types...>; }; | |
public: | |
template <typename Q> | |
using projection = MetaProj<Q>; | |
template <template <typename... Qs> typename MetaPred> | |
using apply = decltype( | |
[]<std::size_t ...Idx> (std::index_sequence<Idx...>) | |
{ | |
return Helper<MetaPred, get_type<Idx>... >{}; | |
}(std::make_index_sequence<std::tuple_size<TP>{}>{}))::type; | |
}; | |
/////////// | |
// USAGE // | |
template <typename... Ts> | |
struct A | |
{ | |
// simple projection | |
using PtrsProj = PackProjector<std::add_pointer_t, Ts...>; | |
using tuple_of_ts_ptr = typename PtrsProj::template apply<std::tuple>; | |
using variant_of_ts_ptr = typename PtrsProj::template apply<std::variant>; | |
// nested projection | |
template <typename T> | |
using NewProj1 = std::add_pointer_t<typename PtrsProj::projection<T>>; | |
using Ptrs2Proj = PackProjector<NewProj1, Ts...>; | |
template <typename T> | |
using NewProj2 = std::add_pointer_t<NewProj1<T>>; | |
using Ptrs3Proj = PackProjector<NewProj2, Ts...>; | |
template <typename T> | |
using NewProj3 = std::add_pointer_t<NewProj2<T>>; | |
using Ptrs4Proj = PackProjector<NewProj3, Ts...>; | |
using tuple_of_ts_ptr4 = typename Ptrs4Proj::template apply<std::tuple>; | |
using variant_of_ts_ptr4 = typename Ptrs4Proj::template apply<std::variant>; | |
}; | |
// simple projection | |
static_assert( | |
std::is_same_v< | |
A<int, double>::tuple_of_ts_ptr, | |
std::tuple<int*, double*>>); | |
static_assert( | |
std::is_same_v< | |
A<int, double>::variant_of_ts_ptr, | |
std::variant<int*, double*>>); | |
// nested projection | |
static_assert( | |
std::is_same_v< | |
A<int, double>::tuple_of_ts_ptr4, | |
std::tuple<int****, double****>>); | |
static_assert( | |
std::is_same_v< | |
A<int, double>::variant_of_ts_ptr4, | |
std::variant<int****, double****>>); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment