Skip to content

Instantly share code, notes, and snippets.

@duckie
Created July 26, 2014 14:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save duckie/848affa575e0b490fd1a to your computer and use it in GitHub Desktop.
Save duckie/848affa575e0b490fd1a to your computer and use it in GitHub Desktop.
Virtuality with a variadic interface.
#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