isotree 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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_