Skip to content

Instantly share code, notes, and snippets.

@elbeno
Last active November 4, 2016 01:58
Show Gist options
  • Save elbeno/1ef44b594548464c41ee to your computer and use it in GitHub Desktop.
Save elbeno/1ef44b594548464c41ee to your computer and use it in GitHub Desktop.
Tersely copy keys from a map
#include <cstddef>
#include <tuple>
#include <utility>
template <size_t I, typename T>
struct element_get_helper;
template <size_t I, typename... Ts>
struct element_get_helper<I, std::tuple<Ts...>>
{
using T = std::tuple<Ts...>;
constexpr decltype(auto) operator()(const T& t) const {
return std::get<I>(t);
}
constexpr decltype(auto) operator()(T& t) const {
return std::get<I>(t);
}
constexpr decltype(auto) operator()(T&& t) const {
return std::get<I>(std::move(t));
}
};
template <size_t I, typename T, typename U>
struct element_get_helper<I, std::pair<T, U>>
{
using P = std::pair<T, U>;
constexpr decltype(auto) operator()(const P& p) const {
return std::get<I>(p);
}
constexpr decltype(auto) operator()(P& p) const {
return std::get<I>(p);
}
constexpr decltype(auto) operator()(P&& p) const {
return std::get<I>(std::move(p));
}
};
template <size_t I, typename T, size_t N>
struct element_get_helper<I, std::array<T, N>>
{
using A = std::array<T, N>;
constexpr decltype(auto) operator()(const A& a) const {
return std::get<I>(a);
}
constexpr decltype(auto) operator()(A& a) const {
return std::get<I>(a);
}
constexpr decltype(auto) operator()(A&& a) const {
return std::get<I>(std::move(a));
}
};
template <size_t N, typename C>
constexpr inline auto eget(const C&)
{
return element_get_helper<N, typename C::value_type>{};
};
template <typename C>
constexpr inline auto efirst(const C&)
{
return element_get_helper<0, typename C::value_type>{};
}
template <typename C>
constexpr inline auto esecond(const C&)
{
return element_get_helper<1, typename C::value_type>{};
}
// To copy keys out of a map:
//
// map<string, string> m;
// ...
// vector<string> v;
// transform(m.cbegin(), m.cend(), back_inserter(v), efirst(m));
// or to move values:
//
// vector<string> v;
// transform(make_move_iterator(m.begin()),
// make_move_iterator(m.cend()),
// back_inserter(v), esecond(m));
@qicosmos
Copy link

qicosmos commented Nov 4, 2016

eget a tuple compile error, tuple has not value_type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment