Created
July 26, 2014 14:36
-
-
Save duckie/848affa575e0b490fd1a to your computer and use it in GitHub Desktop.
Virtuality with a variadic interface.
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 <string> | |
#include <sstream> | |
#include <iostream> | |
#include <memory> | |
struct Serializer { | |
virtual ~Serializer() {} | |
virtual void StartRecord() = 0; | |
virtual void EndRecord() = 0; | |
virtual std::string GetRecord() const = 0; | |
virtual void Push(int value) = 0; | |
virtual void Push(double value) = 0; | |
virtual void Push(std::string const& value) = 0; | |
// etc avec tous les types possibles | |
}; | |
class SerializerCSV : public Serializer { | |
std::ostringstream record_stream_; | |
std::string result_; | |
bool has_data_ = false; | |
void PushSep() { | |
if (has_data_) record_stream_ << ';'; | |
has_data_ = true; | |
} | |
public: | |
void StartRecord() override { | |
result_ = ""; | |
record_stream_.str(""); | |
has_data_ = false; | |
} | |
void EndRecord() override { result_ = record_stream_.str(); } | |
std::string GetRecord() const override { return result_; } | |
void Push(int value) override { PushSep(); record_stream_ << value; } | |
void Push(double value) override { PushSep(); record_stream_ << value; } | |
void Push(std::string const& value) override { PushSep(); record_stream_ << value; } | |
}; | |
class SerializerJSON : public Serializer { | |
std::ostringstream record_stream_; | |
std::string result_; | |
bool has_data_ = false; | |
void PushSep() { | |
if (has_data_) record_stream_ << ','; | |
has_data_ = true; | |
} | |
public: | |
void StartRecord() override { | |
result_ = ""; | |
record_stream_.str(""); | |
record_stream_ << "["; | |
has_data_ = false; | |
} | |
void EndRecord() override { | |
record_stream_ << ']'; | |
result_ = record_stream_.str(); | |
} | |
std::string GetRecord() const override { return result_; } | |
void Push(int value) override { PushSep(); record_stream_ << value; } | |
void Push(double value) override { PushSep(); record_stream_ << value; } | |
void Push(std::string const& value) override { PushSep(); record_stream_ << '"' << value << '"'; } | |
}; | |
class NetworkSerializer { | |
std::unique_ptr<Serializer> serializer_impl_; | |
void Push() {} | |
template <typename Arg, typename ... Args> void Push(Arg value, Args ... values) { | |
serializer_impl_->Push(value); | |
Push(values ...); | |
} | |
public: | |
void SetSerializerImpl(std::unique_ptr<Serializer>&& serializer) { serializer_impl_ = std::move(serializer); } | |
void SetSerializerImpl(Serializer* serializer) { SetSerializerImpl(std::unique_ptr<Serializer>(serializer)); } | |
template <typename ... Args> std::string Serialize(Args ... values) { | |
serializer_impl_->StartRecord(); | |
Push(values...); | |
serializer_impl_->EndRecord(); | |
return serializer_impl_->GetRecord(); | |
} | |
}; | |
int main() { | |
NetworkSerializer ns_dumper; | |
ns_dumper.SetSerializerImpl(new SerializerCSV); | |
std::cout << ns_dumper.Serialize(1, 2.3,"Roger",4) << "\n"; | |
ns_dumper.SetSerializerImpl(new SerializerJSON); | |
std::cout << ns_dumper.Serialize(2.3, 1,"Roger",4,"Marcel") << "\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment