Created
March 29, 2019 11:09
-
-
Save kim366/9272b28b6941388f89f56a6d628e4814 to your computer and use it in GitHub Desktop.
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
template<unsigned, typename...> | |
struct ntuple_impl; | |
template<unsigned N, typename E, typename... Es> | |
struct ntuple_impl<N, std::enable_if_t<(N > 1)>, E, Es...> | |
{ | |
using type = typename ntuple_impl<N - 1, void, E, E, Es...>::type; | |
}; | |
template<typename... Es> | |
struct ntuple_impl<1, void, Es...> | |
{ | |
using type = std::tuple<Es...>; | |
}; | |
template<unsigned N, typename T> | |
using ntuple = ntuple_impl<N, void, T>; | |
template<unsigned N, typename T> | |
using ntuple_t = typename ntuple<N, T>::type; | |
template<typename E, typename... Ts> | |
std::tuple<Ts..., E> add_to_tuple_impl(std::tuple<Ts...>); | |
template<typename Tupl, typename E> | |
using add_to_tuple_t = decltype(add_to_tuple_impl<E>(std::declval<Tupl>())); | |
template<unsigned M, unsigned N, typename InputIt, typename Tupl> | |
constexpr void destructure_impl(InputIt& first, InputIt last, Tupl& tuple) | |
{ | |
if constexpr (M < N) | |
{ | |
std::get<M>(tuple) = *first; | |
destructure_impl<M + 1, N>(++first, last, tuple); | |
} | |
} | |
template<typename It> | |
class range | |
{ | |
private: | |
It _first, _last; | |
public: | |
constexpr inline range(It first, It last) : _first{first}, _last{last} {} | |
constexpr range() = default; | |
constexpr inline It begin() const { return _first; } | |
constexpr inline It end() const { return _last; } | |
}; | |
template<unsigned N, typename InputIt> | |
constexpr auto destructure_with_rest(InputIt first, InputIt last) | |
{ | |
auto tuple = add_to_tuple_t<ntuple_t<N, typename std::iterator_traits<InputIt>::value_type>, range<InputIt>>{}; | |
destructure_impl<0, N>(first, last, tuple); | |
std::get<N>(tuple) = {first, last}; | |
return tuple; | |
} | |
template<unsigned N, typename InputIt> | |
constexpr auto destructure(InputIt first, InputIt last) | |
{ | |
auto tuple = ntuple_t<N, typename std::iterator_traits<InputIt>::value_type>{}; | |
destructure_impl<0, N>(first, last, tuple); | |
return tuple; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment