Skip to content

Instantly share code, notes, and snippets.

@alexandervanrenen
Created May 12, 2020 13:32
Show Gist options
  • Save alexandervanrenen/c09af12a075a53eba9b6a07d992ed8db to your computer and use it in GitHub Desktop.
Save alexandervanrenen/c09af12a075a53eba9b6a07d992ed8db to your computer and use it in GitHub Desktop.
#include <iostream>
#include <set>
#include <cstddef>
#include <cstdint>
#include <vector>
#include <memory>
#include <iomanip>
#include <cmath>
#include <fstream>
#include <array>
#include <regex>
#include <nmmintrin.h>
#include <fcntl.h>
#include <unordered_map>
#include <array>
#include <map>
using namespace std;
struct Shape {
using deserialize_func = std::function<std::unique_ptr<Shape>(std::istream&)>;
virtual ~Shape() = default;
// protected:
// Prevent anyone from directly inhereting from Shape
virtual void DoNotInheritFromShapeDirectlyButFromShapeInterfaceInstead() = 0;
static std::map<std::string, deserialize_func>& get_registry() {
static std::map<std::string, deserialize_func> registry;
return registry;
}
};
template<class T>
struct ShapeInterface : public Shape {
virtual ~ShapeInterface() { if(!registered_) cout << "bad" << endl; } // registerd_ needs to be accessed somewhere, otherwise it is opted away
static inline bool register_type() {
auto& registry = get_registry();
registry[T::class_identifier] = T::deserialize_func;
return true;
}
static const bool registered_;
protected:
virtual void DoNotInheritFromShapeDirectlyButFromShapeInterfaceInstead() final {}
};
template<class T>
const bool ShapeInterface<T>::registered_ = ShapeInterface<T>::register_type();
struct Rectangle : public ShapeInterface<Rectangle> {
static inline const std::string class_identifier = "rectangle";
static std::unique_ptr<Shape> deserialize_func(std::istream& in) { return make_unique<Rectangle>(); }
};
struct Circle : public ShapeInterface<Circle> {
static inline const std::string class_identifier = "circle";
static std::unique_ptr<Shape> deserialize_func(std::istream& in) { return make_unique<Circle>(); }
};
int main()
{
for(auto& iter : Shape::get_registry()) {
cout << iter.first << endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment