default_serialize.h Source File

CPP API: default_serialize.h Source File
default_serialize.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2020-2026 MEmilio
3 *
4 * Authors: Rene Schmieding
5 *
6 * Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 #ifndef MIO_IO_DEFAULT_SERIALIZE_H_
21 #define MIO_IO_DEFAULT_SERIALIZE_H_
22 
23 #include "memilio/io/io.h"
24 
25 #include <tuple>
26 
27 namespace mio
28 {
29 
37 template <class ValueType>
38 struct NamedRef {
39  using Reference = ValueType&;
40 
41  const char* name;
43 
50  explicit NamedRef(const char* n, Reference v)
51  : name(n)
52  , value(v)
53  {
54  }
55 };
56 
57 namespace details
58 {
60 template <class IOObject, class Member>
61 void add_named_ref(IOObject& obj, const NamedRef<Member> named_ref)
62 {
63  obj.add_element(named_ref.name, named_ref.value);
64 }
65 
67 template <class IOContext, class... Members>
68 void default_serialize_impl(IOContext& io, const char* name, const NamedRef<Members>... named_refs)
69 {
70  auto obj = io.create_object(name);
71  (add_named_ref(obj, named_refs), ...);
72 }
73 
75 template <class IOObject, class Member>
76 IOResult<Member> expect_named_ref(IOObject& obj, const NamedRef<Member> named_ref)
77 {
78  return obj.expect_element(named_ref.name, Tag<Member>{});
79 }
80 
82 template <class IOContext, class DefaultSerializable, class... Members>
83 IOResult<DefaultSerializable> default_deserialize_impl(IOContext& io, DefaultSerializable& a, const char* name,
84  NamedRef<Members>... named_refs)
85 {
86  auto obj = io.expect_object(name);
87 
88  // we cannot use expect_named_ref directly in apply, as function arguments have no guarantueed order of evaluation
89  std::tuple<IOResult<Members>...> results{expect_named_ref(obj, named_refs)...};
90 
91  return apply(
92  io,
93  [&a, &named_refs...](const Members&... result_values) {
94  // if all results are successfully deserialized, they are unpacked into result_values
95  // then all class variables are overwritten (via the named_refs) with these values
96  ((named_refs.value = result_values), ...);
97  return a;
98  },
99  results);
100 }
101 
102 } // namespace details
103 
112 template <class... ValueTypes>
113 struct Members {
114  // allow other Members access to the private constructor
115  template <class...>
116  friend struct Members;
117 
122  Members(const char* class_name)
123  : name(class_name)
124  , named_refs()
125  {
126  }
127 
138  template <class T>
139  [[nodiscard]] Members<ValueTypes..., T> add(const char* member_name, T& member)
140  {
141  return Members<ValueTypes..., T>{name, std::tuple_cat(named_refs, std::tuple(NamedRef{member_name, member}))};
142  }
143 
144  const char* name;
145  std::tuple<NamedRef<ValueTypes>...> named_refs;
146 
147 private:
153  Members(const char* class_name, std::tuple<NamedRef<ValueTypes>...> named_references)
154  : name(class_name)
155  , named_refs(named_references)
156  {
157  }
158 };
159 
172 template <class T>
175  static T create()
176  {
177  return T{};
178  }
179 };
180 
186 template <class T, class IOContext>
188  t.default_serialize();
189  !HasSerialize<T, IOContext>;
190 };
191 
197 template <class T, class IOContext>
199  t.default_serialize();
200  !HasDeserialize<T, IOContext>;
201 };
202 
212 template <class IOContext, IsDefaultSerializable<IOContext> T>
213 void serialize_internal(IOContext& io, const T& a)
214 {
215  // Note that the following const_cast is safe as long as we do not modify members.
216  const auto members = const_cast<T&>(a).default_serialize();
217  // unpack members and serialize
218  std::apply(
219  [&io, &members](auto... named_refs) {
220  details::default_serialize_impl(io, members.name, named_refs...);
221  },
222  members.named_refs);
223 }
224 
235 template <class IOContext, IsDefaultDeserializable<IOContext> T>
237 {
238  mio::unused(tag);
240  auto members = a.default_serialize();
241  // unpack members and deserialize
242  return std::apply(
243  [&io, &members, &a](auto... named_refs) {
244  return details::default_deserialize_impl(io, a, members.name, named_refs...);
245  },
246  members.named_refs);
247 }
248 
249 } // namespace mio
250 
251 #endif // MIO_IO_DEFAULT_SERIALIZE_H_
void default_serialize_impl(IOContext &io, const char *name, const NamedRef< Members >... named_refs)
Unpack all name-value pairs from the tuple and add them to a new io object with the given name.
Definition: default_serialize.h:68
IOResult< Member > expect_named_ref(IOObject &obj, const NamedRef< Member > named_ref)
Retrieve a name-value pair from an io object.
Definition: default_serialize.h:76
void add_named_ref(IOObject &obj, const NamedRef< Member > named_ref)
Add a name-value pair to an io object.
Definition: default_serialize.h:61
IOResult< DefaultSerializable > default_deserialize_impl(IOContext &io, DefaultSerializable &a, const char *name, NamedRef< Members >... named_refs)
Read an io object and its members from the io context using the given names and assign the values to ...
Definition: default_serialize.h:83
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
concept IsDefaultDeserializable
Detect whether T has a default_serialize member function, but no deserialize member.
Definition: default_serialize.h:198
boost::outcome_v2::in_place_type_t< T > Tag
Type that is used for overload resolution.
Definition: io.h:407
details::ApplyResultT< F, T... > apply(IOContext &io, F f, const IOResult< T > &... rs)
Evaluate a function with zero or more unpacked IOResults as arguments.
Definition: io.h:481
requires(!std::is_trivial_v< T >) void BinarySerializerObject
Definition: binary_serializer.h:333
void unused(T &&...)
Does nothing, can be used to mark variables as not used.
Definition: compiler_diagnostics.h:30
concept IsDefaultSerializable
Detect whether T has a default_serialize member function, but no serialize member.
Definition: default_serialize.h:187
boost::outcome_v2::unchecked< T, IOStatus > IOResult
Value-or-error type for operations that return a value but can fail.
Definition: io.h:353
IOResult< T > deserialize_internal(IOContext &io, Tag< T > tag)
Deserialization implementation for the default serialization feature.
Definition: default_serialize.h:236
void serialize_internal(IOContext &io, const T &a)
Serialization implementation for the default serialization feature.
Definition: default_serialize.h:213
Creates an instance of T for later initialization.
Definition: default_serialize.h:173
static T create()
Creates a new instance of T.
Definition: default_serialize.h:175
List of a class's members.
Definition: default_serialize.h:113
Members(const char *class_name)
Initialize Members with a class name.
Definition: default_serialize.h:122
std::tuple< NamedRef< ValueTypes >... > named_refs
Names and references to members of the class.
Definition: default_serialize.h:145
Members< ValueTypes..., T > add(const char *member_name, T &member)
Add a class member.
Definition: default_serialize.h:139
friend struct Members
Definition: default_serialize.h:116
const char * name
Name of the class.
Definition: default_serialize.h:144
Members(const char *class_name, std::tuple< NamedRef< ValueTypes >... > named_references)
Initialize Members directly.
Definition: default_serialize.h:153
A pair of name and reference.
Definition: default_serialize.h:38
ValueType & Reference
Definition: default_serialize.h:39
const char * name
Definition: default_serialize.h:41
NamedRef(const char *n, Reference v)
Create a named reference.
Definition: default_serialize.h:50
Reference value
Definition: default_serialize.h:42