SST 16.0.0
Structural Simulation Toolkit
serializer.h
1// Copyright 2009-2026 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-2026, 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
33namespace SST::Core::Serialization {
34
35class ObjectMap;
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 */
42class serializer
43{
44public:
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 static_assert(std::is_trivially_copyable_v<T> && std::is_standard_layout_v<T>,
99 "Error: ser.primitive() can only be called on trivially copyable, standard layout types.");
100 switch ( mode() ) {
101 case SIZER:
102 sizer().size(t);
103 break;
104 case PACK:
105 packer().pack(t);
106 break;
107 case UNPACK:
108 unpacker().unpack(t);
109 break;
110 case MAP:
111 break;
112 }
113 }
114
115 template <typename ELEM_T, typename SIZE_T>
116 void binary(ELEM_T*& buffer, SIZE_T& size)
117 {
118 switch ( mode() ) {
119 case SIZER:
120 sizer().size_buffer(buffer, size);
121 break;
122 case PACK:
123 packer().pack_buffer(buffer, size);
124 break;
125 case UNPACK:
126 unpacker().unpack_buffer(buffer, size);
127 break;
128 case MAP:
129 break;
130 }
131 }
132
133 void raw(void* data, size_t size);
134 size_t size();
135 void string(std::string& str);
136
137 void enable_pointer_tracking(bool value = true) { enable_ptr_tracking_ = value; }
138 bool is_pointer_tracking_enabled() const { return enable_ptr_tracking_; }
139 const char* getMapName() const;
140
141private:
142 // Default mode is UNSTARTED=0 with an empty std::monostate class. SIZER=1, PACK=2, UNPACK=3 and MAP=4 modes have
143 // an associated tracking object which is constructed when starting the new mode. finalize() destroys the current
144 // mode's tracking object and goes back to UNSTARTED mode.
145 std::variant<std::monostate, pvt::ser_sizer, pvt::ser_packer, pvt::ser_unpacker, pvt::ser_mapper> ser_;
146
147 bool enable_ptr_tracking_ = false;
148 const ObjectMapContext* mapContext = nullptr;
149 friend class ObjectMapContext;
150}; // class serializer
151
152/**
153 ObjectMap context which is saved in a virtual stack when name or other information changes.
154 When ObjectMapContext is destroyed, the serializer goes back to the previous ObjectMapContext.
155 */
156
157class ObjectMapContext
158{
159 serializer& ser;
160 const ObjectMapContext* const prevContext;
161 const char* const name;
162
163public:
164 ObjectMapContext(serializer& ser, const char* name) :
165 ser(ser),
166 prevContext(ser.mapContext),
167 name(name)
168 {
169 DISABLE_WARN_DANGLING_POINTER // GCC 13 bug causes spurious warning
170 ser.mapContext = this; // change the serializer's context to this new one
171 REENABLE_WARNING
172 }
173 ~ObjectMapContext() { ser.mapContext = prevContext; } // restore the serializer's old context
174 const char* getName() const { return name; }
175}; // class ObjectMapContext
176
177} // namespace SST::Core::Serialization
178
179#endif // SST_CORE_SERIALIZATION_SERIALIZER_H
ObjectMap context which is saved in a virtual stack when name or other information changes.
Definition serializer.h:158
Base class for objects created by the serializer mapping mode used to map the variables for objects.
Definition objectMap.h:188
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition serializer.h:43