SST  14.1.0
StructuralSimulationToolkit
serializable_base.h
1 // Copyright 2009-2024 NTESS. Under the terms
2 // of Contract DE-NA0003525 with NTESS, the U.S.
3 // Government retains certain rights in this software.
4 //
5 // Copyright (c) 2009-2024, NTESS
6 // All rights reserved.
7 //
8 // This file is part of the SST software package. For license
9 // information, see the LICENSE file in the top level directory of the
10 // distribution.
11 
12 #ifndef SST_CORE_SERIALIZATION_SERIALIZABLE_BASE_H
13 #define SST_CORE_SERIALIZATION_SERIALIZABLE_BASE_H
14 
15 #include "sst/core/serialization/serializer.h"
16 #include "sst/core/warnmacros.h"
17 
18 #include <limits>
19 #include <stdint.h>
20 #include <typeinfo>
21 #include <unordered_map>
22 
23 namespace SST {
24 namespace Core {
25 namespace Serialization {
26 
27 namespace pvt {
28 
29 // Functions to implement the hash for cls_id at compile time. The
30 // hash function being implemented is:
31 
32 inline uint32_t
33 type_hash(const char* key)
34 {
35  int len = ::strlen(key);
36  uint32_t hash = 0;
37  for ( int i = 0; i < len; ++i ) {
38  hash += key[i];
39  hash += (hash << 10);
40  hash ^= (hash >> 6);
41  }
42  hash += (hash << 3);
43  hash ^= (hash >> 11);
44  hash += (hash << 15);
45 
46  return hash;
47 }
48 
49 // Using constexpr is very limited, so the implementation is a bit
50 // convoluted. May be able to streamline later.
51 
52 // computes hash ^= (hash >> 6)
53 constexpr uint32_t
54 B(const uint32_t b)
55 {
56  return b ^ (b >> 6);
57 }
58 
59 // computes hash += (hash << 10)
60 constexpr uint32_t
61 A(const uint32_t a)
62 {
63  return B((a << 10) + a);
64 }
65 
66 // recursive piece that computes the for loop
67 template <size_t idx>
68 constexpr uint32_t
69 ct_hash_rec(const char* str)
70 {
71  return A(str[idx] + ct_hash_rec<idx - 1>(str));
72 }
73 
74 // End of the recursion (i.e. when you've walked back off the front of
75 // the string
76 template <>
77 constexpr uint32_t
78 ct_hash_rec<size_t(-1)>(const char* UNUSED(str))
79 {
80  return 0;
81 }
82 
83 // computes hash += (hash << 15)
84 constexpr uint32_t
85 E(const uint32_t e)
86 {
87  return (e << 15) + e;
88 }
89 
90 // computes hash ^= (hash >> 11)
91 constexpr uint32_t
92 D(const uint32_t d)
93 {
94  return E((d >> 11) ^ d);
95 }
96 
97 // computes hash += (hash << 3)
98 constexpr uint32_t
99 C(const uint32_t c)
100 {
101  return D((c << 3) + c);
102 }
103 
104 // Main function that computes the final manipulations after calling
105 // the recursive function to compute the for loop.
106 template <size_t idx>
107 constexpr uint32_t
108 ct_hash(const char* str)
109 {
110  return C(ct_hash_rec<idx>(str));
111 }
112 
113 // Macro that should be used to call the compile time hash function
114 #define COMPILE_TIME_HASH(x) (::SST::Core::Serialization::pvt::ct_hash<sizeof(x) - 2>(x))
115 
116 } // namespace pvt
117 
119 {
120 public:
121  static constexpr uint32_t NullClsId = std::numeric_limits<uint32_t>::max();
122 
123  virtual const char* cls_name() const = 0;
124 
125  virtual void serialize_order(serializer& ser) = 0;
126 
127  virtual uint32_t cls_id() const = 0;
128  virtual std::string serialization_name() const = 0;
129 
130  virtual ~serializable_base() {}
131 
132 protected:
133  typedef enum { ConstructorFlag } cxn_flag_t;
134  static void serializable_abort(uint32_t line, const char* file, const char* func, const char* obj);
135 };
136 
137 
138 template <class T>
140 {};
141 
142 #define ImplementVirtualSerializable(obj) \
143 public: \
144  static void throw_exc() \
145  { \
146  ::SST::Core::Serialization::serializable_base::serializable_abort(__LINE__, __FILE__, __FUNCTION__, #obj); \
147  } \
148  virtual const char* cls_name() const override { return #obj; } \
149  virtual uint32_t cls_id() const override \
150  { \
151  throw_exc(); \
152  return 0; \
153  } \
154  virtual std::string serialization_name() const override \
155  { \
156  throw_exc(); \
157  return ""; \
158  }
159 
160 #define NotSerializable(obj) \
161 public: \
162  static void throw_exc() \
163  { \
164  ::SST::Core::Serialization::serializable_base::serializable_abort(__LINE__, __FILE__, __FUNCTION__, #obj); \
165  } \
166  virtual void serialize_order(SST::Core::Serialization::serializer& UNUSED(sst)) override { throw_exc(); } \
167  virtual uint32_t cls_id() const override \
168  { \
169  throw_exc(); \
170  return ::SST::Core::Serialization::serializable_base::NullClsId; \
171  } \
172  static obj* construct_deserialize_stub() \
173  { \
174  throw_exc(); \
175  return 0; \
176  } \
177  virtual std::string serialization_name() const override \
178  { \
179  throw_exc(); \
180  return ""; \
181  } \
182  virtual const char* cls_name() const override { return #obj; }
183 
184 // virtual const char* cls_name() const override { return obj_str; }
185 #define ImplementSerializableDefaultConstructor(obj, obj_str) \
186 public: \
187  virtual const char* cls_name() const override \
188  { \
189  return SST::Core::Serialization::serializable_builder_impl<obj>::static_name(); \
190  } \
191  virtual uint32_t cls_id() const override \
192  { \
193  return SST::Core::Serialization::serializable_builder_impl<obj>::static_cls_id(); \
194  } \
195  static obj* construct_deserialize_stub() { return new obj; } \
196  virtual std::string serialization_name() const override { return obj_str; } \
197  \
198 private: \
199  friend class SST::Core::Serialization::serializable_builder_impl<obj>; \
200  static bool you_forgot_to_add_ImplementSerializable_to_this_class() { return false; }
201 
202 #define SER_FORWARD_AS_ONE(...) __VA_ARGS__
203 
204 #define ImplementSerializable(...) \
205 public: \
206  ImplementSerializableDefaultConstructor(SER_FORWARD_AS_ONE(__VA_ARGS__), #__VA_ARGS__)
207 
209 {
210 public:
211  virtual serializable_base* build() const = 0;
212 
213  virtual ~serializable_builder() {}
214 
215  virtual const char* name() const = 0;
216 
217  virtual uint32_t cls_id() const = 0;
218 
219  virtual bool sanity(serializable_base* ser) = 0;
220 };
221 
222 template <class T>
224 {
225 protected:
226  static const char* name_;
227  static const uint32_t cls_id_;
228 
229 public:
230  serializable_base* build() const override { return T::construct_deserialize_stub(); }
231 
232  const char* name() const override { return name_; }
233 
234  uint32_t cls_id() const override { return cls_id_; }
235 
236  static uint32_t static_cls_id() { return cls_id_; }
237 
238  static const char* static_name() { return name_; }
239 
240  bool sanity(serializable_base* ser) override { return (typeid(T) == typeid(*ser)); }
241 };
242 
244 {
245 protected:
246  typedef std::unordered_map<long, serializable_builder*> builder_map;
247  static builder_map* builders_;
248 
249 public:
250  static serializable_base* get_serializable(uint32_t cls_id);
251 
252  /**
253  @return The cls id for the given builder
254  */
255  static uint32_t
256  // add_builder(serializable_builder* builder, uint32_t cls_id);
257  add_builder(serializable_builder* builder, const char* name);
258 
259  static bool sanity(serializable_base* ser, uint32_t cls_id) { return (*builders_)[cls_id]->sanity(ser); }
260 
261  static void delete_statics();
262 };
263 
264 template <class T>
265 const char* serializable_builder_impl<T>::name_ = typeid(T).name();
266 template <class T>
269 
270 // Hold off on trivially_serializable for now, as it's not really safe
271 // in the case of inheritance
272 //
273 // class trivially_serializable {
274 // };
275 
276 } // namespace Serialization
277 } // namespace Core
278 } // namespace SST
279 
280 #define SerializableName(obj) #obj
281 
282 #define DeclareSerializable(obj)
283 
284 //#include "sst/core/serialization/serialize_serializable_base.h"
285 
286 #endif
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:43
Definition: serializable_base.h:223
Definition: action.cc:18
Definition: serializable_base.h:118
Definition: serializable_base.h:208
static uint32_t add_builder(serializable_builder *builder, const char *name)
Definition: serializable_base.cc:39
Definition: serializable_base.h:243
Definition: serializable_base.h:139