Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <utility>
- template <class Base1, class Base2>
- struct OverloadSet
- : public Base1
- , public Base2
- {
- OverloadSet(Base1 const& b1, Base2 const& b2) : Base1(b1), Base2(b2) {}
- OverloadSet(Base1&& b1, Base2&& b2)
- : Base1(std::move(b1)), Base2(std::move(b2))
- {
- }
- using Base1::operator();
- using Base2::operator();
- };
- template <class F1, class F2>
- auto overload_set(F1&& func1, F2&& func2)
- -> OverloadSet<typename std::decay<F1>::type, typename std::decay<F2>::type>
- {
- return {std::forward<F1>(func1), std::forward<F2>(func2)};
- }
- class read_name_t
- {
- };
- #define READ_FIELD(name, field) \
- overload_set( \
- [](auto&& object) -> decltype(object.field) { return object.field; }, \
- [](read_name_t) -> decltype(auto) { return name; })
- template <class Reader>
- class OptionalReader
- {
- public:
- Reader read;
- template <class Consumer, class Object>
- void maybeConsume(Consumer&& consume, Object&& obj) const
- {
- maybeConsume(consume, obj, 0);
- }
- private:
- template <class...>
- using ignore_t = void;
- template <class Consumer, class Object>
- auto maybeConsume(Consumer& consume, Object& obj, int) const
- -> ignore_t<decltype(consume(read(read_name_t()), read(obj)))>
- {
- consume(read(read_name_t()), read(obj));
- }
- template <class Consumer, class Object>
- auto maybeConsume(Consumer&, Object&, long) const -> void
- {
- }
- };
- template <class... OptionalApplier>
- class Translator : public OptionalApplier...
- {
- public:
- Translator(OptionalApplier const&... appliers)
- : OptionalApplier(appliers)...
- {
- }
- Translator(OptionalApplier&&... appliers) : OptionalApplier(appliers)... {}
- template <class Consumer, class Object>
- void translate(Consumer&& consume, Object&& o) const
- {
- char _[] = {((void)OptionalApplier::maybeConsume(consume, o), '\0')...};
- (void)_;
- }
- };
- template <class... Reader>
- auto makeTranslator(Reader const&... readers)
- -> Translator<OptionalReader<Reader>...>
- {
- return {OptionalReader<Reader>{readers}...};
- }
- int main()
- {
- struct Car1
- {
- std::string getMake() { return "Toyota"; }
- std::string getModel() { return "Prius"; }
- };
- struct Car2
- {
- std::string getMake() { return "Toyota"; }
- int getYear() { return 2017; };
- };
- struct Car3
- {
- std::string getModel() { return "Prius"; }
- int getYear() { return 2017; }
- };
- struct Car4
- {
- long long getSerial() { return 2039809809820390; }
- };
- auto translator = makeTranslator(READ_FIELD("getMake()", getMake()),
- READ_FIELD("getYear()", getYear()),
- READ_FIELD("getModel()", getModel()),
- READ_FIELD("getSerial()", getSerial()));
- auto processField = [](std::string const& field, auto const& value) {
- std::cout << " \"" << field << "\": " << value << "\n";
- };
- Car1 car1;
- std::cout << "Reading car 1: \n";
- translator.translate(processField, car1);
- Car2 car2;
- std::cout << "Reading car 2: \n";
- translator.translate(processField, car2);
- Car3 car3;
- std::cout << "Reading car 3: \n";
- translator.translate(processField, car3);
- Car4 car4;
- std::cout << "Reading car 4: \n";
- translator.translate(processField, car4);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement