Skip to content

Instantly share code, notes, and snippets.

@siritori
Created February 4, 2020 22:32
Show Gist options
  • Save siritori/d16d357e4dec66f0b3e1b1f962ba6b32 to your computer and use it in GitHub Desktop.
Save siritori/d16d357e4dec66f0b3e1b1f962ba6b32 to your computer and use it in GitHub Desktop.
SFINEでオーバーロード
#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