SST  15.1.0
StructuralSimulationToolkit
serializer.h
1 // Copyright 2009-2025 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-2025, 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_SERIALIZER_H
13 #define SST_CORE_SERIALIZATION_SERIALIZER_H
14 
15 // These includes have guards to print warnings if they are included
16 // independent of this file. Set the #define that will disable the warnings.
17 #define SST_INCLUDING_SERIALIZER_H
18 #include "sst/core/serialization/impl/mapper.h"
19 #include "sst/core/serialization/impl/packer.h"
20 #include "sst/core/serialization/impl/sizer.h"
21 #include "sst/core/serialization/impl/unpacker.h"
22 // Reenble warnings for including the above file independent of this file.
23 #undef SST_INCLUDING_SERIALIZER_H
24 
25 #include "sst/core/warnmacros.h"
26 
27 #include <cstddef>
28 #include <cstdint>
29 #include <cstring>
30 #include <string>
31 #include <variant>
32 
33 namespace SST::Core::Serialization {
34 
35 class ObjectMap;
36 class ObjectMapContext;
37 
38 /**
39  * This class is basically a wrapper for objects to declare the order in
40  * which their members should be ser/des
41  */
43 {
44 public:
45  enum SERIALIZE_MODE : size_t { SIZER = 1, PACK, UNPACK, MAP };
46  static constexpr SERIALIZE_MODE UNSTARTED { 0 }; // Defined outside of enum to avoid warnings about switch cases
47 
48  // Current mode is the index of the ser_ variant
49  SERIALIZE_MODE
50  mode() const { return SERIALIZE_MODE(ser_.index()); }
51 
52  // Calling sizer(), packer(), unpacker() or mapper() when the corresponding mode is not active is flagged with a
53  // std::bad_variant_access exception.
54  pvt::ser_sizer& sizer() { return std::get<SIZER>(ser_); }
55  pvt::ser_packer& packer() { return std::get<PACK>(ser_); }
56  pvt::ser_unpacker& unpacker() { return std::get<UNPACK>(ser_); }
57  pvt::ser_mapper& mapper() { return std::get<MAP>(ser_); }
58 
59  // Starting a new mode destroys the tracking object of the current mode and constructs a new tracking object
60  void start_sizing() { ser_.emplace<SIZER>(); }
61  void start_packing(char* buffer, size_t size) { ser_.emplace<PACK>(buffer, size); }
62  void start_unpacking(char* buffer, size_t size) { ser_.emplace<UNPACK>(buffer, size); }
63  void start_mapping(ObjectMap* obj) { ser_.emplace<MAP>(obj); }
64 
65  // finalize() destroys the tracking object of the current mode and switches to UNSTARTED mode. Functionally,
66  // finalize() indicates the end of a serialization sequence, not just the end of the current mode. You do not
67  // need to call finalize() if you are simply changing modes. finalize() can perform any final steps at the end
68  // of a serialization sequence, such as destroying any std::shared_ptr tracking objects or generating a report.
69  void finalize() { ser_.emplace<UNSTARTED>(); }
70 
71  // Standard operators are defaulted or deleted
72  serializer() = default;
73  serializer(const serializer&) = delete;
74  serializer& operator=(const serializer&) = delete;
75  ~serializer() = default;
76 
77  template <typename T>
78  void size(T& t)
79  {
80  sizer().size(t);
81  }
82 
83  template <typename T>
84  void pack(T& t)
85  {
86  packer().pack(t);
87  }
88 
89  template <typename T>
90  void unpack(T& t)
91  {
92  unpacker().unpack(t);
93  }
94 
95  template <typename T>
96  void primitive(T& t)
97  {
98  switch ( mode() ) {
99  case SIZER:
100  sizer().size(t);
101  break;
102  case PACK:
103  packer().pack(t);
104  break;
105  case UNPACK:
106  unpacker().unpack(t);
107  break;
108  case MAP:
109  break;
110  }
111  }
112 
113  template <typename ELEM_T, typename SIZE_T>
114  void binary(ELEM_T*& buffer, SIZE_T& size)
115  {
116  switch ( mode() ) {
117  case SIZER:
118  sizer().size_buffer(buffer, size);
119  break;
120  case PACK:
121  packer().pack_buffer(buffer, size);
122  break;
123  case UNPACK:
124  unpacker().unpack_buffer(buffer, size);
125  break;
126  case MAP:
127  break;
128  }
129  }
130 
131  void raw(void* data, size_t size);
132  size_t size();
133  void string(std::string& str);
134 
135  void enable_pointer_tracking(bool value = true) { enable_ptr_tracking_ = value; }
136  bool is_pointer_tracking_enabled() const { return enable_ptr_tracking_; }
137  const char* getMapName() const;
138 
139 private:
140  // Default mode is UNSTARTED=0 with an empty std::monostate class. SIZER=1, PACK=2, UNPACK=3 and MAP=4 modes have
141  // an associated tracking object which is constructed when starting the new mode. finalize() destroys the current
142  // mode's tracking object and goes back to UNSTARTED mode.
143  std::variant<std::monostate, pvt::ser_sizer, pvt::ser_packer, pvt::ser_unpacker, pvt::ser_mapper> ser_;
144 
145  bool enable_ptr_tracking_ = false;
146  const ObjectMapContext* mapContext = nullptr;
147  friend class ObjectMapContext;
148 }; // class serializer
149 
150 /**
151  ObjectMap context which is saved in a virtual stack when name or other information changes.
152  When ObjectMapContext is destroyed, the serializer goes back to the previous ObjectMapContext.
153  */
154 
156 {
157  serializer& ser;
158  const ObjectMapContext* const prevContext;
159  const char* const name;
160 
161 public:
162  ObjectMapContext(serializer& ser, const char* name) :
163  ser(ser),
164  prevContext(ser.mapContext),
165  name(name)
166  {
167  DISABLE_WARN_DANGLING_POINTER // GCC 13 bug causes spurious warning
168  ser.mapContext = this; // change the serializer's context to this new one
169  REENABLE_WARNING
170  }
171  ~ObjectMapContext() { ser.mapContext = prevContext; } // restore the serializer's old context
172  const char* getName() const { return name; }
173 }; // class ObjectMapContext
174 
175 } // namespace SST::Core::Serialization
176 
177 #endif // SST_CORE_SERIALIZATION_SERIALIZER_H
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:42
Base class for objects created by the serializer mapping mode used to map the variables for objects...
Definition: objectMap.h:158
ObjectMap context which is saved in a virtual stack when name or other information changes...
Definition: serializer.h:155