Last active
January 28, 2019 14:58
-
-
Save deni64k/2e118d8274df6d46d990ff2511152a16 to your computer and use it in GitHub Desktop.
This file contains 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 <sstream> | |
#include <string> | |
#include <tuple> | |
#include <array> | |
#include <experimental/array> | |
namespace std { using std::experimental::make_array; } | |
#include <boost/preprocessor.hpp> | |
#define EXPOSE_MEMBERS_Q(M_ignore0, M_ignore1, M_member) \ | |
BOOST_PP_STRINGIZE(M_member) | |
#define EXPOSE_MEMBERS(...) \ | |
auto members() { \ | |
return std::forward_as_tuple(__VA_ARGS__); \ | |
} \ | |
auto members() const { \ | |
return std::forward_as_tuple(__VA_ARGS__); \ | |
} \ | |
static constexpr auto names() { \ | |
return std::make_array( \ | |
BOOST_PP_LIST_ENUM( \ | |
BOOST_PP_LIST_TRANSFORM( \ | |
EXPOSE_MEMBERS_Q, @, \ | |
BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__)))); \ | |
} | |
template <typename T> | |
std::ostream& operator << (std::ostream& os, T const& obj) { | |
using std::operator <<; | |
std::apply([&os](auto const& names, | |
auto const& fst, | |
auto const&... rest) { | |
unsigned int i = 0; | |
os << names[i] << '=' << fst; | |
((os << ", " << names[++i] << '=' << rest), ...); | |
}, std::tuple_cat(std::make_tuple(obj.names()), | |
obj.members())); | |
return os; | |
} | |
template <typename T> | |
std::istream& operator >> (std::istream& is, T& obj) { | |
using std::operator >>; | |
std::apply([&is](auto&... members) { | |
(is >> ... >> members); | |
}, obj.members()); | |
return is; | |
} | |
struct employee { | |
std::string name; | |
int salary; | |
EXPOSE_MEMBERS(name, salary); | |
}; | |
int main(int, char**) { | |
employee e{"Steve Jobs", 1}; | |
std::cout << e << std::endl; | |
std::string input = "Bill-Gates 100"; | |
std::istringstream ss{input}; | |
ss >> e; | |
std::cout << e << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment