Created
January 4, 2019 22:18
-
-
Save mpenick/d4d96d9be192198d9b519750e3f49428 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
| #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