12#ifndef SST_CORE_SERIALIZATION_IMPL_SERIALIZE_INSERTABLE_H
13#define SST_CORE_SERIALIZATION_IMPL_SERIALIZE_INSERTABLE_H
15#ifndef SST_INCLUDING_SERIALIZE_H
17 "The header file sst/core/serialization/impl/serialize_insertable.h should not be directly included as it is not part of the stable public API. The file is included in sst/core/serialization/serialize.h"
20#include "sst/core/serialization/serializer.h"
24#include <forward_list>
31#include <unordered_map>
32#include <unordered_set>
36namespace SST::Core::Serialization {
45template <
typename KEY,
typename VALUE>
48 using type = std::pair<KEY, VALUE>;
52template <
typename,
typename =
void>
53constexpr bool has_size_v =
false;
56constexpr bool has_size_v<T, std::void_t<decltype(std::declval<T>().size())>> =
true;
59template <
typename,
typename =
void>
60constexpr bool has_distance_v =
false;
64 has_distance_v<T, std::void_t<decltype(std::distance(std::declval<T>().begin(), std::declval<T>().end()))>> =
true;
68std::enable_if_t<has_size_v<T> || has_distance_v<T>,
size_t>
71 if constexpr ( has_size_v<T> )
74 return std::distance(t.begin(), t.end());
79constexpr bool is_vector_bool_v =
false;
81template <
typename... Ts>
82constexpr bool is_vector_bool_v<std::vector<bool, Ts...>> =
true;
86constexpr bool is_simple_map_v =
false;
88template <
template <
typename...>
class MAP,
typename KEY,
typename... REST>
89constexpr bool is_simple_map_v<MAP<KEY, REST...>> =
90 (is_same_template_v<MAP, std::map> || is_same_template_v<MAP, std::unordered_map>) &&
91 (std::is_arithmetic_v<KEY> || std::is_enum_v<KEY> || std::is_convertible_v<KEY, std::string>);
95constexpr bool is_simple_set_v =
false;
97template <
template <
typename...>
class SET,
typename KEY,
typename... REST>
98constexpr bool is_simple_set_v<SET<KEY, REST...>> =
99 (is_same_template_v<SET, std::set> || is_same_template_v<SET, std::unordered_set>) &&
100 (std::is_arithmetic_v<KEY> || std::is_enum_v<KEY> || std::is_convertible_v<KEY, std::string>);
119constexpr bool is_insertable_v = std::disjunction_v<
120 is_same_type_template<T, std::deque>,
121 is_same_type_template<T, std::forward_list>,
122 is_same_type_template<T, std::list>,
123 is_same_type_template<T, std::map>,
124 is_same_type_template<T, std::multimap>,
125 is_same_type_template<T, std::multiset>,
126 is_same_type_template<T, std::set>,
127 is_same_type_template<T, std::unordered_map>,
128 is_same_type_template<T, std::unordered_multimap>,
129 is_same_type_template<T, std::unordered_multiset>,
130 is_same_type_template<T, std::unordered_set>,
131 is_same_type_template<T, std::vector> >;
134template <
typename OBJ>
138 using value_type =
typename remove_const_key<typename OBJ::value_type>::type;
140 void operator()(OBJ& obj,
serializer& ser, ser_opt_t options)
143 const ser_opt_t UNUSED(opts) =
144 SerOption::is_set(options, SerOption::as_ptr_elem) ? SerOption::as_ptr : SerOption::none;
146 switch (
const auto mode = ser.mode() ) {
147 case serializer::SIZER:
148 case serializer::PACK:
150 size_t size = get_size(obj);
152 if ( mode == serializer::PACK )
157 if constexpr ( is_vector_bool_v<OBJ> ) {
164 for (
auto& e : obj )
165 SST_SER(
const_cast<value_type&
>(
reinterpret_cast<const value_type&
>(e)), opts);
170 case serializer::UNPACK:
179 if constexpr ( is_same_type_template_v<OBJ, std::vector> ) obj.reserve(size);
181 if constexpr ( is_same_type_template_v<OBJ, std::forward_list> ) {
182 auto last = obj.before_begin();
183 for (
size_t i = 0; i < size; ++i ) {
184 last = obj.emplace_after(last);
186 SST_SER(value, opts);
190 for (
size_t i = 0; i < size; ++i ) {
191 if constexpr ( is_same_type_template_v<OBJ, std::map> ||
192 is_same_type_template_v<OBJ, std::unordered_map> ) {
193 typename OBJ::key_type key {};
195 auto& value = obj[std::move(key)];
196 SST_SER(value, opts);
198 else if constexpr ( is_same_type_template_v<OBJ, std::multimap> ||
199 is_same_type_template_v<OBJ, std::unordered_multimap> ) {
200 typename OBJ::key_type key {};
202 auto& value = obj.emplace(std::move(key),
typename OBJ::mapped_type {})->second;
203 SST_SER(value, opts);
205 else if constexpr ( is_same_type_template_v<OBJ, std::set> ||
206 is_same_type_template_v<OBJ, std::unordered_set> ||
207 is_same_type_template_v<OBJ, std::multiset> ||
208 is_same_type_template_v<OBJ, std::unordered_multiset> ) {
209 typename OBJ::key_type key {};
212 obj.emplace(std::move(key));
214 else if constexpr ( is_vector_bool_v<OBJ> ) {
217 obj.push_back(value);
220 auto& value = obj.emplace_back();
221 SST_SER(value, opts);
229 case serializer::MAP:
231 const std::string& name = ser.getMapName();
234 if constexpr ( is_vector_bool_v<OBJ> ) {
237 for (
size_t i = 0; i < obj.size(); ++i )
240 else if constexpr ( is_simple_map_v<OBJ> ) {
242 using SST::Core::to_string;
243 for (
auto& [key, value] : obj )
244 SST_SER_NAME(value, to_string(key).c_str());
252 for (
auto& e : obj )
254 const_cast<value_type&
>(
reinterpret_cast<const value_type&
>(e)), std::to_string(i++).c_str());
256 ser.mapper().map_hierarchy_end();
262 SST_FRIEND_SERIALIZE();
265template <
typename OBJ>
268 void operator()(OBJ*& obj,
serializer& ser, ser_opt_t options)
270 if ( ser.mode() == serializer::UNPACK ) obj =
new OBJ;
271 SST_SER(*obj, options);
274 SST_FRIEND_SERIALIZE();
279template <
typename ALLOC>
284 ser.mapper().map_hierarchy_start(ser.getMapName(),
286 ser.mapper().map_hierarchy_end();
288 SST_FRIEND_SERIALIZE();
Class used to map containers.
Definition objectMap.h:1420
Definition objectMap.h:1455
Base serialize class.
Definition serialize.h:132
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition serializer.h:43
Definition serialize.h:98
Definition serialize_insertable.h:41