drogon
C++14/17-based HTTP application framework
Loading...
Searching...
No Matches
DrObject.h
Go to the documentation of this file.
1
14
15#pragma once
16
17#include <drogon/exports.h>
18#include <drogon/DrClassMap.h>
19
20#include <string>
21#include <type_traits>
22
23#ifdef _MSC_VER
24#pragma warning(disable : 4250)
25#endif
26
27namespace drogon
28{
33class DROGON_EXPORT DrObjectBase
34{
35 public:
41 virtual const std::string &className() const
42 {
43 static const std::string name{"DrObjectBase"};
44 return name;
45 }
46
50 virtual bool isClass(const std::string &class_name) const
51 {
52 return (className() == class_name);
53 }
54
55 virtual ~DrObjectBase()
56 {
57 }
58};
59
60template <typename T>
62{
63 template <class C>
64 static constexpr auto check(C *) -> std::enable_if_t<
65 std::is_same_v<decltype(C::isAutoCreation), const bool>,
66 bool>
67 {
68 return C::isAutoCreation;
69 }
70
71 template <typename>
72 static constexpr bool check(...)
73 {
74 return false;
75 }
76
77 static constexpr bool value = check<T>(nullptr);
78};
79
84template <typename T>
85class DrObject : public virtual DrObjectBase
86{
87 public:
88 const std::string &className() const override
89 {
90 return alloc_.className();
91 }
92
93 static const std::string &classTypeName()
94 {
95 return alloc_.className();
96 }
97
98 bool isClass(const std::string &class_name) const override
99 {
100 return (className() == class_name);
101 }
102
103 protected:
104 // protect constructor to make this class only inheritable
105 DrObject() = default;
106 ~DrObject() override = default;
107
108 private:
109 class DrAllocator
110 {
111 public:
112 DrAllocator()
113 {
114 registerClass<T>();
115 }
116
117 const std::string &className() const
118 {
119 static std::string className =
120 DrClassMap::demangle(typeid(T).name());
121 return className;
122 }
123
124 template <typename D>
125 void registerClass()
126 {
127 if constexpr (std::is_default_constructible<D>::value)
128 {
130 className(),
131 []() -> DrObjectBase * { return new T; },
132 []() -> std::shared_ptr<DrObjectBase> {
133 return std::make_shared<T>();
134 });
135 }
136 else if constexpr (isAutoCreationClass<D>::value)
137 {
138 static_assert(std::is_default_constructible<D>::value,
139 "Class is not default constructable!");
140 }
141 }
142 };
143
144 // use static val to register allocator function for class T;
145 static DrAllocator alloc_;
146};
147
148template <typename T>
149typename DrObject<T>::DrAllocator DrObject<T>::alloc_;
150
151} // namespace drogon
static std::string demangle(const char *mangled_name)
demangle the type name which is returned by typeid(T).name().
Definition DrClassMap.h:116
static void registerClass(const std::string &className, const DrAllocFunc &func, const DrSharedAllocFunc &sharedFunc=nullptr)
Register a class into the map.
The base class for all drogon reflection classes.
Definition DrObject.h:34
virtual const std::string & className() const
Get the class name.
Definition DrObject.h:41
virtual bool isClass(const std::string &class_name) const
Return true if the class name is 'class_name'.
Definition DrObject.h:50
Definition DrObject.h:86
bool isClass(const std::string &class_name) const override
Return true if the class name is 'class_name'.
Definition DrObject.h:98
const std::string & className() const override
Get the class name.
Definition DrObject.h:88
Drogon Test is a minimal effort test framework developed because the major C++ test frameworks doesn'...
Definition Attribute.h:23
Definition DrObject.h:62