Skip to content

Instantly share code, notes, and snippets.

@mpenick
Created January 4, 2019 22:18
Show Gist options
  • Select an option

  • Save mpenick/d4d96d9be192198d9b519750e3f49428 to your computer and use it in GitHub Desktop.

Select an option

Save mpenick/d4d96d9be192198d9b519750e3f49428 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <string>
#include <tuple>
#include <limits>
class StringRef {
public:
StringRef(const char* str) { }
};
struct Printer {
void operator()(size_t index, int i) {
std::cout << index << ": " << i << "\n";
}
void operator()(size_t index, const std::string& s) {
std::cout << index << ": " << s << "\n";
}
void operator()(StringRef name, int i) {
std::cout << "name" << ": " << i << "\n";
}
void operator()(StringRef name, const std::string& s) {
std::cout << "name" << ": " << s << "\n";
}
};
template <size_t I, size_t N, class Tuple, class Func>
struct ForEachHelper {
void operator() (const Tuple& tuple, Func f) {
f(I, std::get<I>(tuple));
ForEachHelper<I + 1, N, Tuple, Func>()(tuple, f);
}
};
template <class Tuple, class Func>
struct ForEachHelper<0, static_cast<size_t>(-1), Tuple, Func> {
void operator() (const Tuple& tuple, Func f) { }
};
template <size_t N, class Tuple, class Func>
struct ForEachHelper<N, N, Tuple, Func> {
void operator() (const Tuple& tuple, Func f) {
f(N, std::get<N>(tuple));
}
};
template <class Func, class... Args>
void for_each(Func f, Args... args) {
ForEachHelper<0, sizeof...(args) - 1, std::tuple<Args...>, Func>()(std::tie(args...), f);
}
template <class T>
struct Named {
Named(StringRef name,
const T& value)
: name(name)
, value(value) { }
StringRef name;
const T& value;
};
template <class T>
Named<T> named(StringRef name, const T& value) {
return Named<T>(name, value);
}
template <size_t I, size_t N, class Tuple, class Func>
struct ForEachNamedHelper {
void operator() (const Tuple& tuple, Func f) {
const auto& entry = std::get<I>(tuple);
f(entry.name, entry.value);
ForEachNamedHelper<I + 1, N, Tuple, Func>()(tuple, f);
}
};
template <class Tuple, class Func>
struct ForEachNamedHelper<0, static_cast<size_t>(-1), Tuple, Func> {
void operator() (const Tuple& tuple, Func f) { }
};
template <size_t N, class Tuple, class Func>
struct ForEachNamedHelper<N, N, Tuple, Func> {
void operator() (const Tuple& tuple, Func f) {
const auto& entry = std::get<N>(tuple);
f(entry.name, entry.value);
}
};
template <class Func, class... Args>
void for_each_named(Func f, Args... args) {
ForEachNamedHelper<0, sizeof...(args) - 1, std::tuple<Args...>, Func>()(std::tie(args...), f);
}
int main() {
//for_each(Printer(), 1, 2, "a");
//for_each(Printer());
for_each_named(Printer(), named("a", 1), named("b", 2));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment