Skip to content

Instantly share code, notes, and snippets.

@kim366
Created March 29, 2019 11:09
Show Gist options
  • Save kim366/9272b28b6941388f89f56a6d628e4814 to your computer and use it in GitHub Desktop.
Save kim366/9272b28b6941388f89f56a6d628e4814 to your computer and use it in GitHub Desktop.
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