3 #ifndef GRAIL_BLACKBOARD_ENTRY_H
4 #define GRAIL_BLACKBOARD_ENTRY_H
6 #include "../GrailLogger/LoggerManager.hh"
12 #include <type_traits>
29 std::string SerializeData(
const T& element);
40 template <
typename T, std::
size_t N>
52 #define DECLARE_HAS_CONST_ITERATOR(NAME_SUFFIX, ITERATOR_TYPE) \
53 template<typename T> \
54 struct HasConstIterator_##NAME_SUFFIX \
58 typedef struct { char array[2]; } Two; \
60 template<typename C> \
61 static One Test(typename C::ITERATOR_TYPE*); \
62 template<typename C> \
63 static Two Test(...); \
66 static const bool value = sizeof(Test<T>(0)) == sizeof(One);\
70 #define DECLARE_HAS_BEGIN_END(NAME_SUFFIX, ITERATOR_TYPE) \
71 template <typename T>\
72 struct HasBeginEnd_##NAME_SUFFIX\
76 typedef void ITERATOR_TYPE;\
79 typedef typename std::conditional<HasConstIterator_##NAME_SUFFIX<T>::value, T, Dummy>::type TType;\
80 typedef typename TType::ITERATOR_TYPE Iterator;\
84 Iterator begin() const;\
85 Iterator end() const;\
88 struct Derived : TType, Fallback\
92 template<typename C, C> struct ChT;\
94 template<typename C> static char(&f(ChT<Iterator(Fallback::*)() const, &C::begin>*))[1];\
95 template<typename C> static char(&f(...))[2];\
96 template<typename C> static char(&g(ChT<Iterator(Fallback::*)() const, &C::end>*))[1];\
97 template<typename C> static char(&g(...))[2];\
99 static const bool beginValue = sizeof(f<Derived>(0)) == 2;\
100 static const bool endValue = sizeof(g<Derived>(0)) == 2;\
107 template <
typename T,
typename U>
108 struct IsPair<std::pair<T, U>> : std::true_type { };
110 template <
typename>
struct IsTuple : std::false_type {};
112 template <
typename ...T>
struct IsTuple<std::tuple<T...>> : std::true_type {};
114 template <
typename T>
117 template <
typename T>
120 template <
typename T>
123 template <
typename T>
131 #define DECLARE_IS_CONTAINER(NAME_SUFFIX, ITERATOR_TYPE) \
132 DECLARE_HAS_CONST_ITERATOR(NAME_SUFFIX, ITERATOR_TYPE)\
133 DECLARE_HAS_BEGIN_END(NAME_SUFFIX, ITERATOR_TYPE)\
134 template <typename T>\
135 struct IsContainer_##NAME_SUFFIX\
137 static const bool value = HasConstIterator_##NAME_SUFFIX<T>::value &&\
138 HasBeginEnd_##NAME_SUFFIX<T>::beginValue && HasBeginEnd_##NAME_SUFFIX<T>::endValue;\
141 DECLARE_IS_CONTAINER(Std, const_iterator)
143 template<
typename T,
typename =
void>
147 struct CanToString<T, std::void_t<decltype(std::to_string(std::declval<T>()))>> : std::true_type {};
149 template<
typename T,
typename =
void>
155 template<
typename T,
typename =
void>
165 template <
typename T>
166 static std::string Serialize(T& tuple,
size_t index)
170 return SerializeData(std::get<I - 1>(tuple));
182 template <
typename T>
183 static std::string Serialize(T& tuple,
size_t index)
185 return SerializeData(tuple);
189 template <
typename... Ts>
190 std::string ToString(std::tuple<Ts...>
const& tuple,
size_t index)
192 return TupleVisitor<
sizeof...(Ts)>::Serialize(tuple, index);
195 template <
typename... Ts>
196 std::string ToString(std::tuple<Ts...>& tuple,
size_t index)
198 return TupleVisitor<
sizeof...(Ts)>::Serialize(tuple, index);
201 template <
typename T>
202 std::string SerializeContainer(
const T& element)
204 std::string returnable =
"{";
205 for (
const auto& elementPart : element)
207 returnable += SerializeData(elementPart);
211 if (returnable.length() > 1)
213 returnable[returnable.length() - 1]=
'}';
227 std::string SerializeData(
const T& element)
229 if constexpr (std::is_pointer<T>::value || IsSharedPointer<T>::value)
231 if (element ==
nullptr)
236 if (IsRawArrayValue<std::remove_pointer_t<T>>)
238 GRAIL_LOG(consts::DEFAULT_GRAIL_LOG_GROUP, logger::Severity::WARNING,
"Attempted to serialize a raw array. Raw arrays are not supported for serialization.");
239 return "Raw array not supported for serialization";
242 return SerializeData(*element);
244 else if constexpr (IsWeakPointer<T>::value)
246 return SerializeData(element.lock());
248 else if constexpr (IsContainer_Std<T>::value)
250 return SerializeContainer(element);
252 else if constexpr (CanToString<T>::value)
254 return std::to_string(element);
256 else if constexpr (IsPair<T>::value)
258 return "{" + SerializeData(element.first) +
"," + SerializeData(element.second) +
"}";
260 else if constexpr (IsTuple<T>::value)
262 std::string returnable =
"{";
263 for (
int i = 0; i < std::tuple_size<T>::value; ++i)
270 returnable += ToString(element, i);
272 return returnable +
"}";
275 if constexpr (BelongsToLibraryTypeGroup<T>::value)
277 auto returnable = SerializeLibraryType(element);
283 if constexpr (BelongsToUserTypeGroup<T>::value)
285 auto returnable = SerializeUserType(element);
292 return "Serialization function for type not implemented.";
296 std::string SerializeData(
const char(&element)[N]);
299 std::string SerializeData<char*>(
char*
const& element);
302 std::string SerializeData(
const char*
const& element);
305 std::string SerializeData<std::string>(
const std::string& element);
308 std::string SerializeData<Blackboard>(
const Blackboard& element);
319 template <
typename T>
323 std::any any = value;
326 serializationFunction = [](
const std::any& value)
328 return SerializeData<T>(std::any_cast<const T&>(value));
331 auto deleter = [](
void* memory)
333 T* dataPointer =
static_cast<T*
>(memory);
336 auto cloner = [](
void* memory)
338 T* dataPointer =
static_cast<T*
>(memory);
339 return new T{ *dataPointer };
342 data = UnsafeAny(
new T{ value }, deleter, cloner);
343 serializationFunction = [](
const UnsafeAny& value)
345 return SerializeData(*
static_cast<T*
>(value.GetDataPointer()));
355 template <
typename T>
359 return std::any_cast<const T&>(data);
361 return *
static_cast<T*
>(data.GetDataPointer());
372 return serializationFunction(data);
377 std::function<std::string(
const std::any&)> serializationFunction;
381 friend bool operator == (
const UnsafeAny& first,
const UnsafeAny& second);
384 UnsafeAny() =
default;
385 UnsafeAny(
void* dataPointer, std::function<
void(
void*)> deleter, std::function<
void* (
void*)> cloner);
387 UnsafeAny(
const UnsafeAny& other);
388 UnsafeAny(UnsafeAny&& other);
392 UnsafeAny& operator = (
const UnsafeAny& other);
393 UnsafeAny& operator = (UnsafeAny&& other);
395 void* GetDataPointer()
const;
398 void* dataPointer{
nullptr };
399 std::function<void(
void*)> deleter{ [](
void*) {} };
400 std::function<
void* (
void*)> cloner{ [](
void*) {
return nullptr; } };
404 std::function<std::string(
const UnsafeAny&)> serializationFunction;
408 #endif //GRAIL_BLACKBOARD_ENTRY_H