Created
February 4, 2020 22:32
-
-
Save siritori/d16d357e4dec66f0b3e1b1f962ba6b32 to your computer and use it in GitHub Desktop.
SFINEでオーバーロード
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 <functional> | |
#include <iostream> | |
#include <vector> | |
#include <map> | |
#include <initializer_list> | |
class JsonArchive { | |
public: | |
explicit JsonArchive(std::ostream &stream) | |
: m_first(false) | |
, m_stream(stream) | |
{ | |
} | |
void archive(const std::string &value) | |
{ | |
m_stream << '"' << value << '"'; | |
} | |
void archive(const int &value) | |
{ | |
m_stream << value; | |
} | |
void archive(const double &value) | |
{ | |
m_stream << value; | |
} | |
template<typename T> | |
constexpr auto archive(const T& value) -> decltype(value.archive(*this)) | |
{ | |
value.archive(*this); | |
} | |
template<typename T> | |
constexpr void archive(const std::unique_ptr<T> &value) | |
{ | |
archive(*value); | |
} | |
template<typename T> | |
constexpr auto append(const std::string &key, const T &value) -> decltype(archive(value)) | |
{ | |
if (m_first) { | |
m_first = false; | |
} else { | |
m_stream << ","; | |
} | |
archive(key); | |
m_stream << ':'; | |
m_first = false; | |
archive(value); | |
} | |
using ObjectCallback = std::function<void()>; | |
void archive(const ObjectCallback &callback) | |
{ | |
m_first = true; | |
m_stream << '{'; | |
callback(); | |
m_stream << '}'; | |
} | |
template<typename T> | |
constexpr auto archive(const std::map<std::string, T> &values) | |
{ | |
archive([&]() { | |
for (const auto &[key, value] : values) { | |
append(key, value); | |
} | |
}); | |
} | |
template<typename T> | |
constexpr auto archive(const std::vector<T> &values) -> decltype(archive(values.front())) | |
{ | |
m_stream << "["; | |
for (size_t i = 0; i < values.size(); i++) { | |
if (0 < i) { | |
m_stream << ","; | |
} | |
archive(values[i]); | |
} | |
m_stream << "]"; | |
} | |
private: | |
bool m_first; | |
std::ostream &m_stream; | |
}; | |
class Hoge { | |
public: | |
explicit Hoge(int a, double b) | |
: m_a(a) | |
, m_b(b) | |
{ | |
} | |
void archive(JsonArchive &ar) const | |
{ | |
ar.archive([&]() { | |
ar.append("a", m_a); | |
ar.append("xx", [&]() { | |
ar.append("few", 21); | |
ar.append("baha", 213); | |
}); | |
ar.append("b", m_b); | |
}); | |
} | |
private: | |
int m_a; | |
double m_b; | |
}; | |
int main() | |
{ | |
std::vector<int> a = { 43,45,23 }; | |
JsonArchive ar(std::cout); | |
std::vector<std::unique_ptr<Hoge>> values; | |
values.emplace_back(std::make_unique<Hoge>(3, 45)); | |
values.emplace_back(std::make_unique<Hoge>(123, 4.55)); | |
ar.archive(values); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment