isotree 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -1
  3. data/LICENSE.txt +2 -2
  4. data/README.md +32 -14
  5. data/ext/isotree/ext.cpp +144 -31
  6. data/ext/isotree/extconf.rb +7 -7
  7. data/lib/isotree/isolation_forest.rb +110 -30
  8. data/lib/isotree/version.rb +1 -1
  9. data/vendor/isotree/LICENSE +1 -1
  10. data/vendor/isotree/README.md +165 -27
  11. data/vendor/isotree/include/isotree.hpp +2111 -0
  12. data/vendor/isotree/include/isotree_oop.hpp +394 -0
  13. data/vendor/isotree/inst/COPYRIGHTS +62 -0
  14. data/vendor/isotree/src/RcppExports.cpp +525 -52
  15. data/vendor/isotree/src/Rwrapper.cpp +1931 -268
  16. data/vendor/isotree/src/c_interface.cpp +953 -0
  17. data/vendor/isotree/src/crit.hpp +4232 -0
  18. data/vendor/isotree/src/dist.hpp +1886 -0
  19. data/vendor/isotree/src/exp_depth_table.hpp +134 -0
  20. data/vendor/isotree/src/extended.hpp +1444 -0
  21. data/vendor/isotree/src/external_facing_generic.hpp +399 -0
  22. data/vendor/isotree/src/fit_model.hpp +2401 -0
  23. data/vendor/isotree/src/{dealloc.cpp → headers_joined.hpp} +38 -22
  24. data/vendor/isotree/src/helpers_iforest.hpp +813 -0
  25. data/vendor/isotree/src/{impute.cpp → impute.hpp} +353 -122
  26. data/vendor/isotree/src/indexer.cpp +515 -0
  27. data/vendor/isotree/src/instantiate_template_headers.cpp +118 -0
  28. data/vendor/isotree/src/instantiate_template_headers.hpp +240 -0
  29. data/vendor/isotree/src/isoforest.hpp +1659 -0
  30. data/vendor/isotree/src/isotree.hpp +1804 -392
  31. data/vendor/isotree/src/isotree_exportable.hpp +99 -0
  32. data/vendor/isotree/src/merge_models.cpp +159 -16
  33. data/vendor/isotree/src/mult.hpp +1321 -0
  34. data/vendor/isotree/src/oop_interface.cpp +842 -0
  35. data/vendor/isotree/src/oop_interface.hpp +278 -0
  36. data/vendor/isotree/src/other_helpers.hpp +219 -0
  37. data/vendor/isotree/src/predict.hpp +1932 -0
  38. data/vendor/isotree/src/python_helpers.hpp +134 -0
  39. data/vendor/isotree/src/ref_indexer.hpp +154 -0
  40. data/vendor/isotree/src/robinmap/LICENSE +21 -0
  41. data/vendor/isotree/src/robinmap/README.md +483 -0
  42. data/vendor/isotree/src/robinmap/include/tsl/robin_growth_policy.h +406 -0
  43. data/vendor/isotree/src/robinmap/include/tsl/robin_hash.h +1620 -0
  44. data/vendor/isotree/src/robinmap/include/tsl/robin_map.h +807 -0
  45. data/vendor/isotree/src/robinmap/include/tsl/robin_set.h +660 -0
  46. data/vendor/isotree/src/serialize.cpp +4300 -139
  47. data/vendor/isotree/src/sql.cpp +141 -59
  48. data/vendor/isotree/src/subset_models.cpp +174 -0
  49. data/vendor/isotree/src/utils.hpp +3808 -0
  50. data/vendor/isotree/src/xoshiro.hpp +467 -0
  51. data/vendor/isotree/src/ziggurat.hpp +405 -0
  52. metadata +38 -104
  53. data/vendor/cereal/LICENSE +0 -24
  54. data/vendor/cereal/README.md +0 -85
  55. data/vendor/cereal/include/cereal/access.hpp +0 -351
  56. data/vendor/cereal/include/cereal/archives/adapters.hpp +0 -163
  57. data/vendor/cereal/include/cereal/archives/binary.hpp +0 -169
  58. data/vendor/cereal/include/cereal/archives/json.hpp +0 -1019
  59. data/vendor/cereal/include/cereal/archives/portable_binary.hpp +0 -334
  60. data/vendor/cereal/include/cereal/archives/xml.hpp +0 -956
  61. data/vendor/cereal/include/cereal/cereal.hpp +0 -1089
  62. data/vendor/cereal/include/cereal/details/helpers.hpp +0 -422
  63. data/vendor/cereal/include/cereal/details/polymorphic_impl.hpp +0 -796
  64. data/vendor/cereal/include/cereal/details/polymorphic_impl_fwd.hpp +0 -65
  65. data/vendor/cereal/include/cereal/details/static_object.hpp +0 -127
  66. data/vendor/cereal/include/cereal/details/traits.hpp +0 -1411
  67. data/vendor/cereal/include/cereal/details/util.hpp +0 -84
  68. data/vendor/cereal/include/cereal/external/base64.hpp +0 -134
  69. data/vendor/cereal/include/cereal/external/rapidjson/allocators.h +0 -284
  70. data/vendor/cereal/include/cereal/external/rapidjson/cursorstreamwrapper.h +0 -78
  71. data/vendor/cereal/include/cereal/external/rapidjson/document.h +0 -2652
  72. data/vendor/cereal/include/cereal/external/rapidjson/encodedstream.h +0 -299
  73. data/vendor/cereal/include/cereal/external/rapidjson/encodings.h +0 -716
  74. data/vendor/cereal/include/cereal/external/rapidjson/error/en.h +0 -74
  75. data/vendor/cereal/include/cereal/external/rapidjson/error/error.h +0 -161
  76. data/vendor/cereal/include/cereal/external/rapidjson/filereadstream.h +0 -99
  77. data/vendor/cereal/include/cereal/external/rapidjson/filewritestream.h +0 -104
  78. data/vendor/cereal/include/cereal/external/rapidjson/fwd.h +0 -151
  79. data/vendor/cereal/include/cereal/external/rapidjson/internal/biginteger.h +0 -290
  80. data/vendor/cereal/include/cereal/external/rapidjson/internal/diyfp.h +0 -271
  81. data/vendor/cereal/include/cereal/external/rapidjson/internal/dtoa.h +0 -245
  82. data/vendor/cereal/include/cereal/external/rapidjson/internal/ieee754.h +0 -78
  83. data/vendor/cereal/include/cereal/external/rapidjson/internal/itoa.h +0 -308
  84. data/vendor/cereal/include/cereal/external/rapidjson/internal/meta.h +0 -186
  85. data/vendor/cereal/include/cereal/external/rapidjson/internal/pow10.h +0 -55
  86. data/vendor/cereal/include/cereal/external/rapidjson/internal/regex.h +0 -740
  87. data/vendor/cereal/include/cereal/external/rapidjson/internal/stack.h +0 -232
  88. data/vendor/cereal/include/cereal/external/rapidjson/internal/strfunc.h +0 -69
  89. data/vendor/cereal/include/cereal/external/rapidjson/internal/strtod.h +0 -290
  90. data/vendor/cereal/include/cereal/external/rapidjson/internal/swap.h +0 -46
  91. data/vendor/cereal/include/cereal/external/rapidjson/istreamwrapper.h +0 -128
  92. data/vendor/cereal/include/cereal/external/rapidjson/memorybuffer.h +0 -70
  93. data/vendor/cereal/include/cereal/external/rapidjson/memorystream.h +0 -71
  94. data/vendor/cereal/include/cereal/external/rapidjson/msinttypes/inttypes.h +0 -316
  95. data/vendor/cereal/include/cereal/external/rapidjson/msinttypes/stdint.h +0 -300
  96. data/vendor/cereal/include/cereal/external/rapidjson/ostreamwrapper.h +0 -81
  97. data/vendor/cereal/include/cereal/external/rapidjson/pointer.h +0 -1414
  98. data/vendor/cereal/include/cereal/external/rapidjson/prettywriter.h +0 -277
  99. data/vendor/cereal/include/cereal/external/rapidjson/rapidjson.h +0 -656
  100. data/vendor/cereal/include/cereal/external/rapidjson/reader.h +0 -2230
  101. data/vendor/cereal/include/cereal/external/rapidjson/schema.h +0 -2497
  102. data/vendor/cereal/include/cereal/external/rapidjson/stream.h +0 -223
  103. data/vendor/cereal/include/cereal/external/rapidjson/stringbuffer.h +0 -121
  104. data/vendor/cereal/include/cereal/external/rapidjson/writer.h +0 -709
  105. data/vendor/cereal/include/cereal/external/rapidxml/license.txt +0 -52
  106. data/vendor/cereal/include/cereal/external/rapidxml/manual.html +0 -406
  107. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml.hpp +0 -2624
  108. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_iterators.hpp +0 -175
  109. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_print.hpp +0 -428
  110. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_utils.hpp +0 -123
  111. data/vendor/cereal/include/cereal/macros.hpp +0 -154
  112. data/vendor/cereal/include/cereal/specialize.hpp +0 -139
  113. data/vendor/cereal/include/cereal/types/array.hpp +0 -79
  114. data/vendor/cereal/include/cereal/types/atomic.hpp +0 -55
  115. data/vendor/cereal/include/cereal/types/base_class.hpp +0 -203
  116. data/vendor/cereal/include/cereal/types/bitset.hpp +0 -176
  117. data/vendor/cereal/include/cereal/types/boost_variant.hpp +0 -164
  118. data/vendor/cereal/include/cereal/types/chrono.hpp +0 -72
  119. data/vendor/cereal/include/cereal/types/common.hpp +0 -129
  120. data/vendor/cereal/include/cereal/types/complex.hpp +0 -56
  121. data/vendor/cereal/include/cereal/types/concepts/pair_associative_container.hpp +0 -73
  122. data/vendor/cereal/include/cereal/types/deque.hpp +0 -62
  123. data/vendor/cereal/include/cereal/types/forward_list.hpp +0 -68
  124. data/vendor/cereal/include/cereal/types/functional.hpp +0 -43
  125. data/vendor/cereal/include/cereal/types/list.hpp +0 -62
  126. data/vendor/cereal/include/cereal/types/map.hpp +0 -36
  127. data/vendor/cereal/include/cereal/types/memory.hpp +0 -425
  128. data/vendor/cereal/include/cereal/types/optional.hpp +0 -66
  129. data/vendor/cereal/include/cereal/types/polymorphic.hpp +0 -483
  130. data/vendor/cereal/include/cereal/types/queue.hpp +0 -132
  131. data/vendor/cereal/include/cereal/types/set.hpp +0 -103
  132. data/vendor/cereal/include/cereal/types/stack.hpp +0 -76
  133. data/vendor/cereal/include/cereal/types/string.hpp +0 -61
  134. data/vendor/cereal/include/cereal/types/tuple.hpp +0 -123
  135. data/vendor/cereal/include/cereal/types/unordered_map.hpp +0 -36
  136. data/vendor/cereal/include/cereal/types/unordered_set.hpp +0 -99
  137. data/vendor/cereal/include/cereal/types/utility.hpp +0 -47
  138. data/vendor/cereal/include/cereal/types/valarray.hpp +0 -89
  139. data/vendor/cereal/include/cereal/types/variant.hpp +0 -109
  140. data/vendor/cereal/include/cereal/types/vector.hpp +0 -112
  141. data/vendor/cereal/include/cereal/version.hpp +0 -52
  142. data/vendor/isotree/src/Makevars +0 -4
  143. data/vendor/isotree/src/crit.cpp +0 -912
  144. data/vendor/isotree/src/dist.cpp +0 -749
  145. data/vendor/isotree/src/extended.cpp +0 -790
  146. data/vendor/isotree/src/fit_model.cpp +0 -1090
  147. data/vendor/isotree/src/helpers_iforest.cpp +0 -324
  148. data/vendor/isotree/src/isoforest.cpp +0 -771
  149. data/vendor/isotree/src/mult.cpp +0 -607
  150. data/vendor/isotree/src/predict.cpp +0 -853
  151. data/vendor/isotree/src/utils.cpp +0 -1566
@@ -1,1089 +0,0 @@
1
- /*! \file cereal.hpp
2
- \brief Main cereal functionality */
3
- /*
4
- Copyright (c) 2014, Randolph Voorhies, Shane Grant
5
- All rights reserved.
6
-
7
- Redistribution and use in source and binary forms, with or without
8
- modification, are permitted provided that the following conditions are met:
9
- * Redistributions of source code must retain the above copyright
10
- notice, this list of conditions and the following disclaimer.
11
- * Redistributions in binary form must reproduce the above copyright
12
- notice, this list of conditions and the following disclaimer in the
13
- documentation and/or other materials provided with the distribution.
14
- * Neither the name of cereal nor the
15
- names of its contributors may be used to endorse or promote products
16
- derived from this software without specific prior written permission.
17
-
18
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
- DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
22
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
- */
29
- #ifndef CEREAL_CEREAL_HPP_
30
- #define CEREAL_CEREAL_HPP_
31
-
32
- #include <type_traits>
33
- #include <string>
34
- #include <memory>
35
- #include <functional>
36
- #include <unordered_map>
37
- #include <unordered_set>
38
- #include <vector>
39
- #include <cstddef>
40
- #include <cstdint>
41
- #include <functional>
42
-
43
- #include "cereal/macros.hpp"
44
- #include "cereal/details/traits.hpp"
45
- #include "cereal/details/helpers.hpp"
46
- #include "cereal/types/base_class.hpp"
47
-
48
- namespace cereal
49
- {
50
- // ######################################################################
51
- //! Creates a name value pair
52
- /*! @relates NameValuePair
53
- @ingroup Utility */
54
- template <class T> inline
55
- NameValuePair<T> make_nvp( std::string const & name, T && value )
56
- {
57
- return {name.c_str(), std::forward<T>(value)};
58
- }
59
-
60
- //! Creates a name value pair
61
- /*! @relates NameValuePair
62
- @ingroup Utility */
63
- template <class T> inline
64
- NameValuePair<T> make_nvp( const char * name, T && value )
65
- {
66
- return {name, std::forward<T>(value)};
67
- }
68
-
69
- //! Creates a name value pair for the variable T with the same name as the variable
70
- /*! @relates NameValuePair
71
- @ingroup Utility */
72
- #define CEREAL_NVP(T) ::cereal::make_nvp(#T, T)
73
-
74
- // ######################################################################
75
- //! Convenience function to create binary data for both const and non const pointers
76
- /*! @param data Pointer to beginning of the data
77
- @param size The size in bytes of the data
78
- @relates BinaryData
79
- @ingroup Utility */
80
- template <class T> inline
81
- BinaryData<T> binary_data( T && data, size_t size )
82
- {
83
- return {std::forward<T>(data), size};
84
- }
85
-
86
- // ######################################################################
87
- //! Creates a size tag from some variable.
88
- /*! Will normally be used to serialize size (e.g. size()) information for
89
- variable size containers. If you have a variable sized container,
90
- the very first thing it serializes should be its size, wrapped in
91
- a SizeTag.
92
-
93
- @relates SizeTag
94
- @ingroup Utility */
95
- template <class T> inline
96
- SizeTag<T> make_size_tag( T && sz )
97
- {
98
- return {std::forward<T>(sz)};
99
- }
100
-
101
- // ######################################################################
102
- //! Marks data for deferred serialization
103
- /*! cereal performs a recursive depth-first traversal of data it serializes. When
104
- serializing smart pointers to large, nested, or cyclical data structures, it
105
- is possible to encounter a stack overflow from excessive recursion when following
106
- a chain of pointers.
107
-
108
- Deferment can help in these situations if the data can be serialized separately from
109
- the pointers used to traverse the structure. For example, a graph structure can have its
110
- nodes serialized before its edges:
111
-
112
- @code{.cpp}
113
- struct MyEdge
114
- {
115
- std::shared_ptr<MyNode> connection;
116
- int some_value;
117
-
118
- template<class Archive>
119
- void serialize(Archive & archive)
120
- {
121
- // when we serialize an edge, we'll defer serializing the associated node
122
- archive( cereal::defer( connection ),
123
- some_value );
124
- }
125
- };
126
-
127
- struct MyGraphStructure
128
- {
129
- std::vector<MyEdge> edges;
130
- std::vector<MyNodes> nodes;
131
-
132
- template<class Archive>
133
- void serialize(Archive & archive)
134
- {
135
- // because of the deferment, we ensure all nodes are fully serialized
136
- // before any connection pointers to those nodes are serialized
137
- archive( edges, nodes );
138
-
139
- // we have to explicitly inform the archive when it is safe to serialize
140
- // the deferred data
141
- archive.serializeDeferments();
142
- }
143
- };
144
- @endcode
145
-
146
- @relates DeferredData
147
- @ingroup Utility */
148
- template <class T> inline
149
- DeferredData<T> defer( T && value )
150
- {
151
- return {std::forward<T>(value)};
152
- }
153
-
154
- // ######################################################################
155
- //! Called before a type is serialized to set up any special archive state
156
- //! for processing some type
157
- /*! If designing a serializer that needs to set up any kind of special
158
- state or output extra information for a type, specialize this function
159
- for the archive type and the types that require the extra information.
160
- @ingroup Internal */
161
- template <class Archive, class T> inline
162
- void prologue( Archive & /* archive */, T const & /* data */)
163
- { }
164
-
165
- //! Called after a type is serialized to tear down any special archive state
166
- //! for processing some type
167
- /*! @ingroup Internal */
168
- template <class Archive, class T> inline
169
- void epilogue( Archive & /* archive */, T const & /* data */)
170
- { }
171
-
172
- // ######################################################################
173
- //! Special flags for archives
174
- /*! AllowEmptyClassElision
175
- This allows for empty classes to be serialized even if they do not provide
176
- a serialization function. Classes with no data members are considered to be
177
- empty. Be warned that if this is enabled and you attempt to serialize an
178
- empty class with improperly formed serialize or load/save functions, no
179
- static error will occur - the error will propogate silently and your
180
- intended serialization functions may not be called. You can manually
181
- ensure that your classes that have custom serialization are correct
182
- by using the traits is_output_serializable and is_input_serializable
183
- in cereal/details/traits.hpp.
184
- @ingroup Internal */
185
- enum Flags { AllowEmptyClassElision = 1 };
186
-
187
- // ######################################################################
188
- //! Registers a specific Archive type with cereal
189
- /*! This registration should be done once per archive. A good place to
190
- put this is immediately following the definition of your archive.
191
- Archive registration is only strictly necessary if you wish to
192
- support pointers to polymorphic data types. All archives that
193
- come with cereal are already registered.
194
- @ingroup Internal */
195
- #define CEREAL_REGISTER_ARCHIVE(Archive) \
196
- namespace cereal { namespace detail { \
197
- template <class T, class BindingTag> \
198
- typename polymorphic_serialization_support<Archive, T>::type \
199
- instantiate_polymorphic_binding( T*, Archive*, BindingTag, adl_tag ); \
200
- } } /* end namespaces */
201
-
202
- //! Helper macro to omit unused warning
203
- #if defined(__GNUC__)
204
- // GCC / clang don't want the function
205
- #define CEREAL_UNUSED_FUNCTION
206
- #else
207
- #define CEREAL_UNUSED_FUNCTION static void unused() { (void)version; }
208
- #endif
209
-
210
- // ######################################################################
211
- //! Defines a class version for some type
212
- /*! Versioning information is optional and adds some small amount of
213
- overhead to serialization. This overhead will occur both in terms of
214
- space in the archive (the version information for each class will be
215
- stored exactly once) as well as runtime (versioned serialization functions
216
- must check to see if they need to load or store version information).
217
-
218
- Versioning is useful if you plan on fundamentally changing the way some
219
- type is serialized in the future. Versioned serialization functions
220
- cannot be used to load non-versioned data.
221
-
222
- By default, all types have an assumed version value of zero. By
223
- using this macro, you may change the version number associated with
224
- some type. cereal will then use this value as a second parameter
225
- to your serialization functions.
226
-
227
- The interface for the serialization functions is nearly identical
228
- to non-versioned serialization with the addition of a second parameter,
229
- const std::uint32_t version, which will be supplied with the correct
230
- version number. Serializing the version number on a save happens
231
- automatically.
232
-
233
- Versioning cannot be mixed with non-versioned serialization functions.
234
- Having both types will result result in a compile time error. Data
235
- serialized without versioning cannot be loaded by a serialization
236
- function with added versioning support.
237
-
238
- Example interface for versioning on a non-member serialize function:
239
-
240
- @code{cpp}
241
- CEREAL_CLASS_VERSION( Mytype, 77 ); // register class version
242
-
243
- template <class Archive>
244
- void serialize( Archive & ar, Mytype & t, const std::uint32_t version )
245
- {
246
- // When performing a load, the version associated with the class
247
- // is whatever it was when that data was originally serialized
248
- //
249
- // When we save, we'll use the version that is defined in the macro
250
-
251
- if( version >= some_number )
252
- // do this
253
- else
254
- // do that
255
- }
256
- @endcode
257
-
258
- Interfaces for other forms of serialization functions is similar. This
259
- macro should be placed at global scope.
260
- @ingroup Utility */
261
- #define CEREAL_CLASS_VERSION(TYPE, VERSION_NUMBER) \
262
- namespace cereal { namespace detail { \
263
- template <> struct Version<TYPE> \
264
- { \
265
- static const std::uint32_t version; \
266
- static std::uint32_t registerVersion() \
267
- { \
268
- ::cereal::detail::StaticObject<Versions>::getInstance().mapping.emplace( \
269
- std::type_index(typeid(TYPE)).hash_code(), VERSION_NUMBER ); \
270
- return VERSION_NUMBER; \
271
- } \
272
- CEREAL_UNUSED_FUNCTION \
273
- }; /* end Version */ \
274
- const std::uint32_t Version<TYPE>::version = \
275
- Version<TYPE>::registerVersion(); \
276
- } } // end namespaces
277
-
278
- // ######################################################################
279
- //! The base output archive class
280
- /*! This is the base output archive for all output archives. If you create
281
- a custom archive class, it should derive from this, passing itself as
282
- a template parameter for the ArchiveType.
283
-
284
- The base class provides all of the functionality necessary to
285
- properly forward data to the correct serialization functions.
286
-
287
- Individual archives should use a combination of prologue and
288
- epilogue functions together with specializations of serialize, save,
289
- and load to alter the functionality of their serialization.
290
-
291
- @tparam ArchiveType The archive type that derives from OutputArchive
292
- @tparam Flags Flags to control advanced functionality. See the Flags
293
- enum for more information.
294
- @ingroup Internal */
295
- template<class ArchiveType, std::uint32_t Flags = 0>
296
- class OutputArchive : public detail::OutputArchiveBase
297
- {
298
- public:
299
- //! Construct the output archive
300
- /*! @param derived A pointer to the derived ArchiveType (pass this from the derived archive) */
301
- OutputArchive(ArchiveType * const derived) : self(derived), itsCurrentPointerId(1), itsCurrentPolymorphicTypeId(1)
302
- { }
303
-
304
- OutputArchive & operator=( OutputArchive const & ) = delete;
305
-
306
- //! Serializes all passed in data
307
- /*! This is the primary interface for serializing data with an archive */
308
- template <class ... Types> inline
309
- ArchiveType & operator()( Types && ... args )
310
- {
311
- self->process( std::forward<Types>( args )... );
312
- return *self;
313
- }
314
-
315
- //! Serializes any data marked for deferment using defer
316
- /*! This will cause any data wrapped in DeferredData to be immediately serialized */
317
- void serializeDeferments()
318
- {
319
- for( auto & deferment : itsDeferments )
320
- deferment();
321
- }
322
-
323
- /*! @name Boost Transition Layer
324
- Functionality that mirrors the syntax for Boost. This is useful if you are transitioning
325
- a large project from Boost to cereal. The preferred interface for cereal is using operator(). */
326
- //! @{
327
-
328
- //! Indicates this archive is not intended for loading
329
- /*! This ensures compatibility with boost archive types. If you are transitioning
330
- from boost, you can check this value within a member or external serialize function
331
- (i.e., Archive::is_loading::value) to disable behavior specific to loading, until
332
- you can transition to split save/load or save_minimal/load_minimal functions */
333
- using is_loading = std::false_type;
334
-
335
- //! Indicates this archive is intended for saving
336
- /*! This ensures compatibility with boost archive types. If you are transitioning
337
- from boost, you can check this value within a member or external serialize function
338
- (i.e., Archive::is_saving::value) to enable behavior specific to loading, until
339
- you can transition to split save/load or save_minimal/load_minimal functions */
340
- using is_saving = std::true_type;
341
-
342
- //! Serializes passed in data
343
- /*! This is a boost compatability layer and is not the preferred way of using
344
- cereal. If you are transitioning from boost, use this until you can
345
- transition to the operator() overload */
346
- template <class T> inline
347
- ArchiveType & operator&( T && arg )
348
- {
349
- self->process( std::forward<T>( arg ) );
350
- return *self;
351
- }
352
-
353
- //! Serializes passed in data
354
- /*! This is a boost compatability layer and is not the preferred way of using
355
- cereal. If you are transitioning from boost, use this until you can
356
- transition to the operator() overload */
357
- template <class T> inline
358
- ArchiveType & operator<<( T && arg )
359
- {
360
- self->process( std::forward<T>( arg ) );
361
- return *self;
362
- }
363
-
364
- //! @}
365
-
366
- //! Registers a shared pointer with the archive
367
- /*! This function is used to track shared pointer targets to prevent
368
- unnecessary saves from taking place if multiple shared pointers
369
- point to the same data.
370
-
371
- @internal
372
- @param addr The address (see shared_ptr get()) pointed to by the shared pointer
373
- @return A key that uniquely identifies the pointer */
374
- inline std::uint32_t registerSharedPointer( void const * addr )
375
- {
376
- // Handle null pointers by just returning 0
377
- if(addr == 0) return 0;
378
-
379
- auto id = itsSharedPointerMap.find( addr );
380
- if( id == itsSharedPointerMap.end() )
381
- {
382
- auto ptrId = itsCurrentPointerId++;
383
- itsSharedPointerMap.insert( {addr, ptrId} );
384
- return ptrId | detail::msb_32bit; // mask MSB to be 1
385
- }
386
- else
387
- return id->second;
388
- }
389
-
390
- //! Registers a polymorphic type name with the archive
391
- /*! This function is used to track polymorphic types to prevent
392
- unnecessary saves of identifying strings used by the polymorphic
393
- support functionality.
394
-
395
- @internal
396
- @param name The name to associate with a polymorphic type
397
- @return A key that uniquely identifies the polymorphic type name */
398
- inline std::uint32_t registerPolymorphicType( char const * name )
399
- {
400
- auto id = itsPolymorphicTypeMap.find( name );
401
- if( id == itsPolymorphicTypeMap.end() )
402
- {
403
- auto polyId = itsCurrentPolymorphicTypeId++;
404
- itsPolymorphicTypeMap.insert( {name, polyId} );
405
- return polyId | detail::msb_32bit; // mask MSB to be 1
406
- }
407
- else
408
- return id->second;
409
- }
410
-
411
- private:
412
- //! Serializes data after calling prologue, then calls epilogue
413
- template <class T> inline
414
- void process( T && head )
415
- {
416
- prologue( *self, head );
417
- self->processImpl( head );
418
- epilogue( *self, head );
419
- }
420
-
421
- //! Unwinds to process all data
422
- template <class T, class ... Other> inline
423
- void process( T && head, Other && ... tail )
424
- {
425
- self->process( std::forward<T>( head ) );
426
- self->process( std::forward<Other>( tail )... );
427
- }
428
-
429
- //! Serialization of a virtual_base_class wrapper
430
- /*! \sa virtual_base_class */
431
- template <class T> inline
432
- ArchiveType & processImpl(virtual_base_class<T> const & b)
433
- {
434
- traits::detail::base_class_id id(b.base_ptr);
435
- if(itsBaseClassSet.count(id) == 0)
436
- {
437
- itsBaseClassSet.insert(id);
438
- self->processImpl( *b.base_ptr );
439
- }
440
- return *self;
441
- }
442
-
443
- //! Serialization of a base_class wrapper
444
- /*! \sa base_class */
445
- template <class T> inline
446
- ArchiveType & processImpl(base_class<T> const & b)
447
- {
448
- self->processImpl( *b.base_ptr );
449
- return *self;
450
- }
451
-
452
- std::vector<std::function<void(void)>> itsDeferments;
453
-
454
- template <class T> inline
455
- ArchiveType & processImpl(DeferredData<T> const & d)
456
- {
457
- std::function<void(void)> deferment( [=](){ self->process( d.value ); } );
458
- itsDeferments.emplace_back( std::move(deferment) );
459
-
460
- return *self;
461
- }
462
-
463
- //! Helper macro that expands the requirements for activating an overload
464
- /*! Requirements:
465
- Has the requested serialization function
466
- Does not have version and unversioned at the same time
467
- Is output serializable AND
468
- is specialized for this type of function OR
469
- has no specialization at all */
470
- #define PROCESS_IF(name) \
471
- traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
472
- !traits::has_invalid_output_versioning<T, ArchiveType>::value, \
473
- (traits::is_output_serializable<T, ArchiveType>::value && \
474
- (traits::is_specialized_##name<T, ArchiveType>::value || \
475
- !traits::is_specialized<T, ArchiveType>::value))> = traits::sfinae
476
-
477
- //! Member serialization
478
- template <class T, PROCESS_IF(member_serialize)> inline
479
- ArchiveType & processImpl(T const & t)
480
- {
481
- access::member_serialize(*self, const_cast<T &>(t));
482
- return *self;
483
- }
484
-
485
- //! Non member serialization
486
- template <class T, PROCESS_IF(non_member_serialize)> inline
487
- ArchiveType & processImpl(T const & t)
488
- {
489
- CEREAL_SERIALIZE_FUNCTION_NAME(*self, const_cast<T &>(t));
490
- return *self;
491
- }
492
-
493
- //! Member split (save)
494
- template <class T, PROCESS_IF(member_save)> inline
495
- ArchiveType & processImpl(T const & t)
496
- {
497
- access::member_save(*self, t);
498
- return *self;
499
- }
500
-
501
- //! Non member split (save)
502
- template <class T, PROCESS_IF(non_member_save)> inline
503
- ArchiveType & processImpl(T const & t)
504
- {
505
- CEREAL_SAVE_FUNCTION_NAME(*self, t);
506
- return *self;
507
- }
508
-
509
- //! Member split (save_minimal)
510
- template <class T, PROCESS_IF(member_save_minimal)> inline
511
- ArchiveType & processImpl(T const & t)
512
- {
513
- self->process( access::member_save_minimal(*self, t) );
514
- return *self;
515
- }
516
-
517
- //! Non member split (save_minimal)
518
- template <class T, PROCESS_IF(non_member_save_minimal)> inline
519
- ArchiveType & processImpl(T const & t)
520
- {
521
- self->process( CEREAL_SAVE_MINIMAL_FUNCTION_NAME(*self, t) );
522
- return *self;
523
- }
524
-
525
- //! Empty class specialization
526
- template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
527
- !traits::is_output_serializable<T, ArchiveType>::value,
528
- std::is_empty<T>::value> = traits::sfinae> inline
529
- ArchiveType & processImpl(T const &)
530
- {
531
- return *self;
532
- }
533
-
534
- //! No matching serialization
535
- /*! Invalid if we have invalid output versioning or
536
- we are not output serializable, and either
537
- don't allow empty class ellision or allow it but are not serializing an empty class */
538
- template <class T, traits::EnableIf<traits::has_invalid_output_versioning<T, ArchiveType>::value ||
539
- (!traits::is_output_serializable<T, ArchiveType>::value &&
540
- (!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)))> = traits::sfinae> inline
541
- ArchiveType & processImpl(T const &)
542
- {
543
- static_assert(traits::detail::count_output_serializers<T, ArchiveType>::value != 0,
544
- "cereal could not find any output serialization functions for the provided type and archive combination. \n\n "
545
- "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
546
- "Serialize functions generally have the following signature: \n\n "
547
- "template<class Archive> \n "
548
- " void serialize(Archive & ar) \n "
549
- " { \n "
550
- " ar( member1, member2, member3 ); \n "
551
- " } \n\n " );
552
-
553
- static_assert(traits::detail::count_output_serializers<T, ArchiveType>::value < 2,
554
- "cereal found more than one compatible output serialization function for the provided type and archive combination. \n\n "
555
- "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
556
- "Use specialization (see access.hpp) if you need to disambiguate between serialize vs load/save functions. \n "
557
- "Note that serialization functions can be inherited which may lead to the aforementioned ambiguities. \n "
558
- "In addition, you may not mix versioned with non-versioned serialization functions. \n\n ");
559
-
560
- return *self;
561
- }
562
-
563
- //! Registers a class version with the archive and serializes it if necessary
564
- /*! If this is the first time this class has been serialized, we will record its
565
- version number and serialize that.
566
-
567
- @tparam T The type of the class being serialized */
568
- template <class T> inline
569
- std::uint32_t registerClassVersion()
570
- {
571
- static const auto hash = std::type_index(typeid(T)).hash_code();
572
- const auto insertResult = itsVersionedTypes.insert( hash );
573
- const auto lock = detail::StaticObject<detail::Versions>::lock();
574
- const auto version =
575
- detail::StaticObject<detail::Versions>::getInstance().find( hash, detail::Version<T>::version );
576
-
577
- if( insertResult.second ) // insertion took place, serialize the version number
578
- process( make_nvp<ArchiveType>("cereal_class_version", version) );
579
-
580
- return version;
581
- }
582
-
583
- //! Member serialization
584
- /*! Versioning implementation */
585
- template <class T, PROCESS_IF(member_versioned_serialize)> inline
586
- ArchiveType & processImpl(T const & t)
587
- {
588
- access::member_serialize(*self, const_cast<T &>(t), registerClassVersion<T>());
589
- return *self;
590
- }
591
-
592
- //! Non member serialization
593
- /*! Versioning implementation */
594
- template <class T, PROCESS_IF(non_member_versioned_serialize)> inline
595
- ArchiveType & processImpl(T const & t)
596
- {
597
- CEREAL_SERIALIZE_FUNCTION_NAME(*self, const_cast<T &>(t), registerClassVersion<T>());
598
- return *self;
599
- }
600
-
601
- //! Member split (save)
602
- /*! Versioning implementation */
603
- template <class T, PROCESS_IF(member_versioned_save)> inline
604
- ArchiveType & processImpl(T const & t)
605
- {
606
- access::member_save(*self, t, registerClassVersion<T>());
607
- return *self;
608
- }
609
-
610
- //! Non member split (save)
611
- /*! Versioning implementation */
612
- template <class T, PROCESS_IF(non_member_versioned_save)> inline
613
- ArchiveType & processImpl(T const & t)
614
- {
615
- CEREAL_SAVE_FUNCTION_NAME(*self, t, registerClassVersion<T>());
616
- return *self;
617
- }
618
-
619
- //! Member split (save_minimal)
620
- /*! Versioning implementation */
621
- template <class T, PROCESS_IF(member_versioned_save_minimal)> inline
622
- ArchiveType & processImpl(T const & t)
623
- {
624
- self->process( access::member_save_minimal(*self, t, registerClassVersion<T>()) );
625
- return *self;
626
- }
627
-
628
- //! Non member split (save_minimal)
629
- /*! Versioning implementation */
630
- template <class T, PROCESS_IF(non_member_versioned_save_minimal)> inline
631
- ArchiveType & processImpl(T const & t)
632
- {
633
- self->process( CEREAL_SAVE_MINIMAL_FUNCTION_NAME(*self, t, registerClassVersion<T>()) );
634
- return *self;
635
- }
636
-
637
- #undef PROCESS_IF
638
-
639
- private:
640
- ArchiveType * const self;
641
-
642
- //! A set of all base classes that have been serialized
643
- std::unordered_set<traits::detail::base_class_id, traits::detail::base_class_id_hash> itsBaseClassSet;
644
-
645
- //! Maps from addresses to pointer ids
646
- std::unordered_map<void const *, std::uint32_t> itsSharedPointerMap;
647
-
648
- //! The id to be given to the next pointer
649
- std::uint32_t itsCurrentPointerId;
650
-
651
- //! Maps from polymorphic type name strings to ids
652
- std::unordered_map<char const *, std::uint32_t> itsPolymorphicTypeMap;
653
-
654
- //! The id to be given to the next polymorphic type name
655
- std::uint32_t itsCurrentPolymorphicTypeId;
656
-
657
- //! Keeps track of classes that have versioning information associated with them
658
- std::unordered_set<size_type> itsVersionedTypes;
659
- }; // class OutputArchive
660
-
661
- // ######################################################################
662
- //! The base input archive class
663
- /*! This is the base input archive for all input archives. If you create
664
- a custom archive class, it should derive from this, passing itself as
665
- a template parameter for the ArchiveType.
666
-
667
- The base class provides all of the functionality necessary to
668
- properly forward data to the correct serialization functions.
669
-
670
- Individual archives should use a combination of prologue and
671
- epilogue functions together with specializations of serialize, save,
672
- and load to alter the functionality of their serialization.
673
-
674
- @tparam ArchiveType The archive type that derives from InputArchive
675
- @tparam Flags Flags to control advanced functionality. See the Flags
676
- enum for more information.
677
- @ingroup Internal */
678
- template<class ArchiveType, std::uint32_t Flags = 0>
679
- class InputArchive : public detail::InputArchiveBase
680
- {
681
- public:
682
- //! Construct the output archive
683
- /*! @param derived A pointer to the derived ArchiveType (pass this from the derived archive) */
684
- InputArchive(ArchiveType * const derived) :
685
- self(derived),
686
- itsBaseClassSet(),
687
- itsSharedPointerMap(),
688
- itsPolymorphicTypeMap(),
689
- itsVersionedTypes()
690
- { }
691
-
692
- InputArchive & operator=( InputArchive const & ) = delete;
693
-
694
- //! Serializes all passed in data
695
- /*! This is the primary interface for serializing data with an archive */
696
- template <class ... Types> inline
697
- ArchiveType & operator()( Types && ... args )
698
- {
699
- process( std::forward<Types>( args )... );
700
- return *self;
701
- }
702
-
703
- //! Serializes any data marked for deferment using defer
704
- /*! This will cause any data wrapped in DeferredData to be immediately serialized */
705
- void serializeDeferments()
706
- {
707
- for( auto & deferment : itsDeferments )
708
- deferment();
709
- }
710
-
711
- /*! @name Boost Transition Layer
712
- Functionality that mirrors the syntax for Boost. This is useful if you are transitioning
713
- a large project from Boost to cereal. The preferred interface for cereal is using operator(). */
714
- //! @{
715
-
716
- //! Indicates this archive is intended for loading
717
- /*! This ensures compatibility with boost archive types. If you are transitioning
718
- from boost, you can check this value within a member or external serialize function
719
- (i.e., Archive::is_loading::value) to enable behavior specific to loading, until
720
- you can transition to split save/load or save_minimal/load_minimal functions */
721
- using is_loading = std::true_type;
722
-
723
- //! Indicates this archive is not intended for saving
724
- /*! This ensures compatibility with boost archive types. If you are transitioning
725
- from boost, you can check this value within a member or external serialize function
726
- (i.e., Archive::is_saving::value) to disable behavior specific to loading, until
727
- you can transition to split save/load or save_minimal/load_minimal functions */
728
- using is_saving = std::false_type;
729
-
730
- //! Serializes passed in data
731
- /*! This is a boost compatability layer and is not the preferred way of using
732
- cereal. If you are transitioning from boost, use this until you can
733
- transition to the operator() overload */
734
- template <class T> inline
735
- ArchiveType & operator&( T && arg )
736
- {
737
- self->process( std::forward<T>( arg ) );
738
- return *self;
739
- }
740
-
741
- //! Serializes passed in data
742
- /*! This is a boost compatability layer and is not the preferred way of using
743
- cereal. If you are transitioning from boost, use this until you can
744
- transition to the operator() overload */
745
- template <class T> inline
746
- ArchiveType & operator>>( T && arg )
747
- {
748
- self->process( std::forward<T>( arg ) );
749
- return *self;
750
- }
751
-
752
- //! @}
753
-
754
- //! Retrieves a shared pointer given a unique key for it
755
- /*! This is used to retrieve a previously registered shared_ptr
756
- which has already been loaded.
757
-
758
- @internal
759
- @param id The unique id that was serialized for the pointer
760
- @return A shared pointer to the data
761
- @throw Exception if the id does not exist */
762
- inline std::shared_ptr<void> getSharedPointer(std::uint32_t const id)
763
- {
764
- if(id == 0) return std::shared_ptr<void>(nullptr);
765
-
766
- auto iter = itsSharedPointerMap.find( id );
767
- if(iter == itsSharedPointerMap.end())
768
- throw Exception("Error while trying to deserialize a smart pointer. Could not find id " + std::to_string(id));
769
-
770
- return iter->second;
771
- }
772
-
773
- //! Registers a shared pointer to its unique identifier
774
- /*! After a shared pointer has been allocated for the first time, it should
775
- be registered with its loaded id for future references to it.
776
-
777
- @internal
778
- @param id The unique identifier for the shared pointer
779
- @param ptr The actual shared pointer */
780
- inline void registerSharedPointer(std::uint32_t const id, std::shared_ptr<void> ptr)
781
- {
782
- std::uint32_t const stripped_id = id & ~detail::msb_32bit;
783
- itsSharedPointerMap[stripped_id] = ptr;
784
- }
785
-
786
- //! Retrieves the string for a polymorphic type given a unique key for it
787
- /*! This is used to retrieve a string previously registered during
788
- a polymorphic load.
789
-
790
- @internal
791
- @param id The unique id that was serialized for the polymorphic type
792
- @return The string identifier for the tyep */
793
- inline std::string getPolymorphicName(std::uint32_t const id)
794
- {
795
- auto name = itsPolymorphicTypeMap.find( id );
796
- if(name == itsPolymorphicTypeMap.end())
797
- {
798
- throw Exception("Error while trying to deserialize a polymorphic pointer. Could not find type id " + std::to_string(id));
799
- }
800
- return name->second;
801
- }
802
-
803
- //! Registers a polymorphic name string to its unique identifier
804
- /*! After a polymorphic type has been loaded for the first time, it should
805
- be registered with its loaded id for future references to it.
806
-
807
- @internal
808
- @param id The unique identifier for the polymorphic type
809
- @param name The name associated with the tyep */
810
- inline void registerPolymorphicName(std::uint32_t const id, std::string const & name)
811
- {
812
- std::uint32_t const stripped_id = id & ~detail::msb_32bit;
813
- itsPolymorphicTypeMap.insert( {stripped_id, name} );
814
- }
815
-
816
- private:
817
- //! Serializes data after calling prologue, then calls epilogue
818
- template <class T> inline
819
- void process( T && head )
820
- {
821
- prologue( *self, head );
822
- self->processImpl( head );
823
- epilogue( *self, head );
824
- }
825
-
826
- //! Unwinds to process all data
827
- template <class T, class ... Other> inline
828
- void process( T && head, Other && ... tail )
829
- {
830
- process( std::forward<T>( head ) );
831
- process( std::forward<Other>( tail )... );
832
- }
833
-
834
- //! Serialization of a virtual_base_class wrapper
835
- /*! \sa virtual_base_class */
836
- template <class T> inline
837
- ArchiveType & processImpl(virtual_base_class<T> & b)
838
- {
839
- traits::detail::base_class_id id(b.base_ptr);
840
- if(itsBaseClassSet.count(id) == 0)
841
- {
842
- itsBaseClassSet.insert(id);
843
- self->processImpl( *b.base_ptr );
844
- }
845
- return *self;
846
- }
847
-
848
- //! Serialization of a base_class wrapper
849
- /*! \sa base_class */
850
- template <class T> inline
851
- ArchiveType & processImpl(base_class<T> & b)
852
- {
853
- self->processImpl( *b.base_ptr );
854
- return *self;
855
- }
856
-
857
- std::vector<std::function<void(void)>> itsDeferments;
858
-
859
- template <class T> inline
860
- ArchiveType & processImpl(DeferredData<T> const & d)
861
- {
862
- std::function<void(void)> deferment( [=](){ self->process( d.value ); } );
863
- itsDeferments.emplace_back( std::move(deferment) );
864
-
865
- return *self;
866
- }
867
-
868
- //! Helper macro that expands the requirements for activating an overload
869
- /*! Requirements:
870
- Has the requested serialization function
871
- Does not have version and unversioned at the same time
872
- Is input serializable AND
873
- is specialized for this type of function OR
874
- has no specialization at all */
875
- #define PROCESS_IF(name) \
876
- traits::EnableIf<traits::has_##name<T, ArchiveType>::value, \
877
- !traits::has_invalid_input_versioning<T, ArchiveType>::value, \
878
- (traits::is_input_serializable<T, ArchiveType>::value && \
879
- (traits::is_specialized_##name<T, ArchiveType>::value || \
880
- !traits::is_specialized<T, ArchiveType>::value))> = traits::sfinae
881
-
882
- //! Member serialization
883
- template <class T, PROCESS_IF(member_serialize)> inline
884
- ArchiveType & processImpl(T & t)
885
- {
886
- access::member_serialize(*self, t);
887
- return *self;
888
- }
889
-
890
- //! Non member serialization
891
- template <class T, PROCESS_IF(non_member_serialize)> inline
892
- ArchiveType & processImpl(T & t)
893
- {
894
- CEREAL_SERIALIZE_FUNCTION_NAME(*self, t);
895
- return *self;
896
- }
897
-
898
- //! Member split (load)
899
- template <class T, PROCESS_IF(member_load)> inline
900
- ArchiveType & processImpl(T & t)
901
- {
902
- access::member_load(*self, t);
903
- return *self;
904
- }
905
-
906
- //! Non member split (load)
907
- template <class T, PROCESS_IF(non_member_load)> inline
908
- ArchiveType & processImpl(T & t)
909
- {
910
- CEREAL_LOAD_FUNCTION_NAME(*self, t);
911
- return *self;
912
- }
913
-
914
- //! Member split (load_minimal)
915
- template <class T, PROCESS_IF(member_load_minimal)> inline
916
- ArchiveType & processImpl(T & t)
917
- {
918
- using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
919
- typename traits::has_member_save_minimal<T, OutArchiveType>::type value;
920
- self->process( value );
921
- access::member_load_minimal(*self, t, value);
922
- return *self;
923
- }
924
-
925
- //! Non member split (load_minimal)
926
- template <class T, PROCESS_IF(non_member_load_minimal)> inline
927
- ArchiveType & processImpl(T & t)
928
- {
929
- using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
930
- typename traits::has_non_member_save_minimal<T, OutArchiveType>::type value;
931
- self->process( value );
932
- CEREAL_LOAD_MINIMAL_FUNCTION_NAME(*self, t, value);
933
- return *self;
934
- }
935
-
936
- //! Empty class specialization
937
- template <class T, traits::EnableIf<(Flags & AllowEmptyClassElision),
938
- !traits::is_input_serializable<T, ArchiveType>::value,
939
- std::is_empty<T>::value> = traits::sfinae> inline
940
- ArchiveType & processImpl(T const &)
941
- {
942
- return *self;
943
- }
944
-
945
- //! No matching serialization
946
- /*! Invalid if we have invalid input versioning or
947
- we are not input serializable, and either
948
- don't allow empty class ellision or allow it but are not serializing an empty class */
949
- template <class T, traits::EnableIf<traits::has_invalid_input_versioning<T, ArchiveType>::value ||
950
- (!traits::is_input_serializable<T, ArchiveType>::value &&
951
- (!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty<T>::value)))> = traits::sfinae> inline
952
- ArchiveType & processImpl(T const &)
953
- {
954
- static_assert(traits::detail::count_input_serializers<T, ArchiveType>::value != 0,
955
- "cereal could not find any input serialization functions for the provided type and archive combination. \n\n "
956
- "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
957
- "Serialize functions generally have the following signature: \n\n "
958
- "template<class Archive> \n "
959
- " void serialize(Archive & ar) \n "
960
- " { \n "
961
- " ar( member1, member2, member3 ); \n "
962
- " } \n\n " );
963
-
964
- static_assert(traits::detail::count_input_serializers<T, ArchiveType>::value < 2,
965
- "cereal found more than one compatible input serialization function for the provided type and archive combination. \n\n "
966
- "Types must either have a serialize function, load/save pair, or load_minimal/save_minimal pair (you may not mix these). \n "
967
- "Use specialization (see access.hpp) if you need to disambiguate between serialize vs load/save functions. \n "
968
- "Note that serialization functions can be inherited which may lead to the aforementioned ambiguities. \n "
969
- "In addition, you may not mix versioned with non-versioned serialization functions. \n\n ");
970
-
971
- return *self;
972
- }
973
-
974
- //! Befriend for versioning in load_and_construct
975
- template <class A, class B, bool C, bool D, bool E, bool F> friend struct detail::Construct;
976
-
977
- //! Registers a class version with the archive and serializes it if necessary
978
- /*! If this is the first time this class has been serialized, we will record its
979
- version number and serialize that.
980
-
981
- @tparam T The type of the class being serialized */
982
- template <class T> inline
983
- std::uint32_t loadClassVersion()
984
- {
985
- static const auto hash = std::type_index(typeid(T)).hash_code();
986
- auto lookupResult = itsVersionedTypes.find( hash );
987
-
988
- if( lookupResult != itsVersionedTypes.end() ) // already exists
989
- return lookupResult->second;
990
- else // need to load
991
- {
992
- std::uint32_t version;
993
-
994
- process( make_nvp<ArchiveType>("cereal_class_version", version) );
995
- itsVersionedTypes.emplace_hint( lookupResult, hash, version );
996
-
997
- return version;
998
- }
999
- }
1000
-
1001
- //! Member serialization
1002
- /*! Versioning implementation */
1003
- template <class T, PROCESS_IF(member_versioned_serialize)> inline
1004
- ArchiveType & processImpl(T & t)
1005
- {
1006
- const auto version = loadClassVersion<T>();
1007
- access::member_serialize(*self, t, version);
1008
- return *self;
1009
- }
1010
-
1011
- //! Non member serialization
1012
- /*! Versioning implementation */
1013
- template <class T, PROCESS_IF(non_member_versioned_serialize)> inline
1014
- ArchiveType & processImpl(T & t)
1015
- {
1016
- const auto version = loadClassVersion<T>();
1017
- CEREAL_SERIALIZE_FUNCTION_NAME(*self, t, version);
1018
- return *self;
1019
- }
1020
-
1021
- //! Member split (load)
1022
- /*! Versioning implementation */
1023
- template <class T, PROCESS_IF(member_versioned_load)> inline
1024
- ArchiveType & processImpl(T & t)
1025
- {
1026
- const auto version = loadClassVersion<T>();
1027
- access::member_load(*self, t, version);
1028
- return *self;
1029
- }
1030
-
1031
- //! Non member split (load)
1032
- /*! Versioning implementation */
1033
- template <class T, PROCESS_IF(non_member_versioned_load)> inline
1034
- ArchiveType & processImpl(T & t)
1035
- {
1036
- const auto version = loadClassVersion<T>();
1037
- CEREAL_LOAD_FUNCTION_NAME(*self, t, version);
1038
- return *self;
1039
- }
1040
-
1041
- //! Member split (load_minimal)
1042
- /*! Versioning implementation */
1043
- template <class T, PROCESS_IF(member_versioned_load_minimal)> inline
1044
- ArchiveType & processImpl(T & t)
1045
- {
1046
- using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
1047
- const auto version = loadClassVersion<T>();
1048
- typename traits::has_member_versioned_save_minimal<T, OutArchiveType>::type value;
1049
- self->process(value);
1050
- access::member_load_minimal(*self, t, value, version);
1051
- return *self;
1052
- }
1053
-
1054
- //! Non member split (load_minimal)
1055
- /*! Versioning implementation */
1056
- template <class T, PROCESS_IF(non_member_versioned_load_minimal)> inline
1057
- ArchiveType & processImpl(T & t)
1058
- {
1059
- using OutArchiveType = typename traits::detail::get_output_from_input<ArchiveType>::type;
1060
- const auto version = loadClassVersion<T>();
1061
- typename traits::has_non_member_versioned_save_minimal<T, OutArchiveType>::type value;
1062
- self->process(value);
1063
- CEREAL_LOAD_MINIMAL_FUNCTION_NAME(*self, t, value, version);
1064
- return *self;
1065
- }
1066
-
1067
- #undef PROCESS_IF
1068
-
1069
- private:
1070
- ArchiveType * const self;
1071
-
1072
- //! A set of all base classes that have been serialized
1073
- std::unordered_set<traits::detail::base_class_id, traits::detail::base_class_id_hash> itsBaseClassSet;
1074
-
1075
- //! Maps from pointer ids to metadata
1076
- std::unordered_map<std::uint32_t, std::shared_ptr<void>> itsSharedPointerMap;
1077
-
1078
- //! Maps from name ids to names
1079
- std::unordered_map<std::uint32_t, std::string> itsPolymorphicTypeMap;
1080
-
1081
- //! Maps from type hash codes to version numbers
1082
- std::unordered_map<std::size_t, std::uint32_t> itsVersionedTypes;
1083
- }; // class InputArchive
1084
- } // namespace cereal
1085
-
1086
- // This include needs to come after things such as binary_data, make_nvp, etc
1087
- #include "cereal/types/common.hpp"
1088
-
1089
- #endif // CEREAL_CEREAL_HPP_