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