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,1019 +0,0 @@
1
- /*! \file json.hpp
2
- \brief JSON input and output archives */
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_ARCHIVES_JSON_HPP_
30
- #define CEREAL_ARCHIVES_JSON_HPP_
31
-
32
- #include "cereal/cereal.hpp"
33
- #include "cereal/details/util.hpp"
34
-
35
- namespace cereal
36
- {
37
- //! An exception thrown when rapidjson fails an internal assertion
38
- /*! @ingroup Utility */
39
- struct RapidJSONException : Exception
40
- { RapidJSONException( const char * what_ ) : Exception( what_ ) {} };
41
- }
42
-
43
- // Inform rapidjson that assert will throw
44
- #ifndef CEREAL_RAPIDJSON_ASSERT_THROWS
45
- #define CEREAL_RAPIDJSON_ASSERT_THROWS
46
- #endif // CEREAL_RAPIDJSON_ASSERT_THROWS
47
-
48
- // Override rapidjson assertions to throw exceptions by default
49
- #ifndef CEREAL_RAPIDJSON_ASSERT
50
- #define CEREAL_RAPIDJSON_ASSERT(x) if(!(x)){ \
51
- throw ::cereal::RapidJSONException("rapidjson internal assertion failure: " #x); }
52
- #endif // RAPIDJSON_ASSERT
53
-
54
- // Enable support for parsing of nan, inf, -inf
55
- #ifndef CEREAL_RAPIDJSON_WRITE_DEFAULT_FLAGS
56
- #define CEREAL_RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNanAndInfFlag
57
- #endif
58
-
59
- // Enable support for parsing of nan, inf, -inf
60
- #ifndef CEREAL_RAPIDJSON_PARSE_DEFAULT_FLAGS
61
- #define CEREAL_RAPIDJSON_PARSE_DEFAULT_FLAGS kParseFullPrecisionFlag | kParseNanAndInfFlag
62
- #endif
63
-
64
- #include "cereal/external/rapidjson/prettywriter.h"
65
- #include "cereal/external/rapidjson/ostreamwrapper.h"
66
- #include "cereal/external/rapidjson/istreamwrapper.h"
67
- #include "cereal/external/rapidjson/document.h"
68
- #include "cereal/external/base64.hpp"
69
-
70
- #include <limits>
71
- #include <sstream>
72
- #include <stack>
73
- #include <vector>
74
- #include <string>
75
-
76
- namespace cereal
77
- {
78
- // ######################################################################
79
- //! An output archive designed to save data to JSON
80
- /*! This archive uses RapidJSON to build serialize data to JSON.
81
-
82
- JSON archives provides a human readable output but at decreased
83
- performance (both in time and space) compared to binary archives.
84
-
85
- JSON archives are only guaranteed to finish flushing their contents
86
- upon destruction and should thus be used in an RAII fashion.
87
-
88
- JSON benefits greatly from name-value pairs, which if present, will
89
- name the nodes in the output. If these are not present, each level
90
- of the output will be given an automatically generated delimited name.
91
-
92
- The precision of the output archive controls the number of decimals output
93
- for floating point numbers and should be sufficiently large (i.e. at least 20)
94
- if there is a desire to have binary equality between the numbers output and
95
- those read in. In general you should expect a loss of precision when going
96
- from floating point to text and back.
97
-
98
- JSON archives do not output the size information for any dynamically sized structure
99
- and instead infer it from the number of children for a node. This means that data
100
- can be hand edited for dynamic sized structures and will still be readable. This
101
- is accomplished through the cereal::SizeTag object, which will cause the archive
102
- to output the data as a JSON array (e.g. marked by [] instead of {}), which indicates
103
- that the container is variable sized and may be edited.
104
-
105
- \ingroup Archives */
106
- class JSONOutputArchive : public OutputArchive<JSONOutputArchive>, public traits::TextArchive
107
- {
108
- enum class NodeType { StartObject, InObject, StartArray, InArray };
109
-
110
- using WriteStream = CEREAL_RAPIDJSON_NAMESPACE::OStreamWrapper;
111
- using JSONWriter = CEREAL_RAPIDJSON_NAMESPACE::PrettyWriter<WriteStream>;
112
-
113
- public:
114
- /*! @name Common Functionality
115
- Common use cases for directly interacting with an JSONOutputArchive */
116
- //! @{
117
-
118
- //! A class containing various advanced options for the JSON archive
119
- class Options
120
- {
121
- public:
122
- //! Default options
123
- static Options Default(){ return Options(); }
124
-
125
- //! Default options with no indentation
126
- static Options NoIndent(){ return Options( JSONWriter::kDefaultMaxDecimalPlaces, IndentChar::space, 0 ); }
127
-
128
- //! The character to use for indenting
129
- enum class IndentChar : char
130
- {
131
- space = ' ',
132
- tab = '\t',
133
- newline = '\n',
134
- carriage_return = '\r'
135
- };
136
-
137
- //! Specify specific options for the JSONOutputArchive
138
- /*! @param precision The precision used for floating point numbers
139
- @param indentChar The type of character to indent with
140
- @param indentLength The number of indentChar to use for indentation
141
- (0 corresponds to no indentation) */
142
- explicit Options( int precision = JSONWriter::kDefaultMaxDecimalPlaces,
143
- IndentChar indentChar = IndentChar::space,
144
- unsigned int indentLength = 4 ) :
145
- itsPrecision( precision ),
146
- itsIndentChar( static_cast<char>(indentChar) ),
147
- itsIndentLength( indentLength ) { }
148
-
149
- private:
150
- friend class JSONOutputArchive;
151
- int itsPrecision;
152
- char itsIndentChar;
153
- unsigned int itsIndentLength;
154
- };
155
-
156
- //! Construct, outputting to the provided stream
157
- /*! @param stream The stream to output to.
158
- @param options The JSON specific options to use. See the Options struct
159
- for the values of default parameters */
160
- JSONOutputArchive(std::ostream & stream, Options const & options = Options::Default() ) :
161
- OutputArchive<JSONOutputArchive>(this),
162
- itsWriteStream(stream),
163
- itsWriter(itsWriteStream),
164
- itsNextName(nullptr)
165
- {
166
- itsWriter.SetMaxDecimalPlaces( options.itsPrecision );
167
- itsWriter.SetIndent( options.itsIndentChar, options.itsIndentLength );
168
- itsNameCounter.push(0);
169
- itsNodeStack.push(NodeType::StartObject);
170
- }
171
-
172
- //! Destructor, flushes the JSON
173
- ~JSONOutputArchive() CEREAL_NOEXCEPT
174
- {
175
- if (itsNodeStack.top() == NodeType::InObject)
176
- itsWriter.EndObject();
177
- else if (itsNodeStack.top() == NodeType::InArray)
178
- itsWriter.EndArray();
179
- }
180
-
181
- //! Saves some binary data, encoded as a base64 string, with an optional name
182
- /*! This will create a new node, optionally named, and insert a value that consists of
183
- the data encoded as a base64 string */
184
- void saveBinaryValue( const void * data, size_t size, const char * name = nullptr )
185
- {
186
- setNextName( name );
187
- writeName();
188
-
189
- auto base64string = base64::encode( reinterpret_cast<const unsigned char *>( data ), size );
190
- saveValue( base64string );
191
- };
192
-
193
- //! @}
194
- /*! @name Internal Functionality
195
- Functionality designed for use by those requiring control over the inner mechanisms of
196
- the JSONOutputArchive */
197
- //! @{
198
-
199
- //! Starts a new node in the JSON output
200
- /*! The node can optionally be given a name by calling setNextName prior
201
- to creating the node
202
-
203
- Nodes only need to be started for types that are themselves objects or arrays */
204
- void startNode()
205
- {
206
- writeName();
207
- itsNodeStack.push(NodeType::StartObject);
208
- itsNameCounter.push(0);
209
- }
210
-
211
- //! Designates the most recently added node as finished
212
- void finishNode()
213
- {
214
- // if we ended up serializing an empty object or array, writeName
215
- // will never have been called - so start and then immediately end
216
- // the object/array.
217
- //
218
- // We'll also end any object/arrays we happen to be in
219
- switch(itsNodeStack.top())
220
- {
221
- case NodeType::StartArray:
222
- itsWriter.StartArray();
223
- // fall through
224
- case NodeType::InArray:
225
- itsWriter.EndArray();
226
- break;
227
- case NodeType::StartObject:
228
- itsWriter.StartObject();
229
- // fall through
230
- case NodeType::InObject:
231
- itsWriter.EndObject();
232
- break;
233
- }
234
-
235
- itsNodeStack.pop();
236
- itsNameCounter.pop();
237
- }
238
-
239
- //! Sets the name for the next node created with startNode
240
- void setNextName( const char * name )
241
- {
242
- itsNextName = name;
243
- }
244
-
245
- //! Saves a bool to the current node
246
- void saveValue(bool b) { itsWriter.Bool(b); }
247
- //! Saves an int to the current node
248
- void saveValue(int i) { itsWriter.Int(i); }
249
- //! Saves a uint to the current node
250
- void saveValue(unsigned u) { itsWriter.Uint(u); }
251
- //! Saves an int64 to the current node
252
- void saveValue(int64_t i64) { itsWriter.Int64(i64); }
253
- //! Saves a uint64 to the current node
254
- void saveValue(uint64_t u64) { itsWriter.Uint64(u64); }
255
- //! Saves a double to the current node
256
- void saveValue(double d) { itsWriter.Double(d); }
257
- //! Saves a string to the current node
258
- void saveValue(std::string const & s) { itsWriter.String(s.c_str(), static_cast<CEREAL_RAPIDJSON_NAMESPACE::SizeType>( s.size() )); }
259
- //! Saves a const char * to the current node
260
- void saveValue(char const * s) { itsWriter.String(s); }
261
- //! Saves a nullptr to the current node
262
- void saveValue(std::nullptr_t) { itsWriter.Null(); }
263
-
264
- private:
265
- // Some compilers/OS have difficulty disambiguating the above for various flavors of longs, so we provide
266
- // special overloads to handle these cases.
267
-
268
- //! 32 bit signed long saving to current node
269
- template <class T, traits::EnableIf<sizeof(T) == sizeof(std::int32_t),
270
- std::is_signed<T>::value> = traits::sfinae> inline
271
- void saveLong(T l){ saveValue( static_cast<std::int32_t>( l ) ); }
272
-
273
- //! non 32 bit signed long saving to current node
274
- template <class T, traits::EnableIf<sizeof(T) != sizeof(std::int32_t),
275
- std::is_signed<T>::value> = traits::sfinae> inline
276
- void saveLong(T l){ saveValue( static_cast<std::int64_t>( l ) ); }
277
-
278
- //! 32 bit unsigned long saving to current node
279
- template <class T, traits::EnableIf<sizeof(T) == sizeof(std::int32_t),
280
- std::is_unsigned<T>::value> = traits::sfinae> inline
281
- void saveLong(T lu){ saveValue( static_cast<std::uint32_t>( lu ) ); }
282
-
283
- //! non 32 bit unsigned long saving to current node
284
- template <class T, traits::EnableIf<sizeof(T) != sizeof(std::int32_t),
285
- std::is_unsigned<T>::value> = traits::sfinae> inline
286
- void saveLong(T lu){ saveValue( static_cast<std::uint64_t>( lu ) ); }
287
-
288
- public:
289
- #ifdef _MSC_VER
290
- //! MSVC only long overload to current node
291
- void saveValue( unsigned long lu ){ saveLong( lu ); };
292
- #else // _MSC_VER
293
- //! Serialize a long if it would not be caught otherwise
294
- template <class T, traits::EnableIf<std::is_same<T, long>::value,
295
- !std::is_same<T, std::int32_t>::value,
296
- !std::is_same<T, std::int64_t>::value> = traits::sfinae> inline
297
- void saveValue( T t ){ saveLong( t ); }
298
-
299
- //! Serialize an unsigned long if it would not be caught otherwise
300
- template <class T, traits::EnableIf<std::is_same<T, unsigned long>::value,
301
- !std::is_same<T, std::uint32_t>::value,
302
- !std::is_same<T, std::uint64_t>::value> = traits::sfinae> inline
303
- void saveValue( T t ){ saveLong( t ); }
304
- #endif // _MSC_VER
305
-
306
- //! Save exotic arithmetic as strings to current node
307
- /*! Handles long long (if distinct from other types), unsigned long (if distinct), and long double */
308
- template <class T, traits::EnableIf<std::is_arithmetic<T>::value,
309
- !std::is_same<T, long>::value,
310
- !std::is_same<T, unsigned long>::value,
311
- !std::is_same<T, std::int64_t>::value,
312
- !std::is_same<T, std::uint64_t>::value,
313
- (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long))> = traits::sfinae> inline
314
- void saveValue(T const & t)
315
- {
316
- std::stringstream ss; ss.precision( std::numeric_limits<long double>::max_digits10 );
317
- ss << t;
318
- saveValue( ss.str() );
319
- }
320
-
321
- //! Write the name of the upcoming node and prepare object/array state
322
- /*! Since writeName is called for every value that is output, regardless of
323
- whether it has a name or not, it is the place where we will do a deferred
324
- check of our node state and decide whether we are in an array or an object.
325
-
326
- The general workflow of saving to the JSON archive is:
327
-
328
- 1. (optional) Set the name for the next node to be created, usually done by an NVP
329
- 2. Start the node
330
- 3. (if there is data to save) Write the name of the node (this function)
331
- 4. (if there is data to save) Save the data (with saveValue)
332
- 5. Finish the node
333
- */
334
- void writeName()
335
- {
336
- NodeType const & nodeType = itsNodeStack.top();
337
-
338
- // Start up either an object or an array, depending on state
339
- if(nodeType == NodeType::StartArray)
340
- {
341
- itsWriter.StartArray();
342
- itsNodeStack.top() = NodeType::InArray;
343
- }
344
- else if(nodeType == NodeType::StartObject)
345
- {
346
- itsNodeStack.top() = NodeType::InObject;
347
- itsWriter.StartObject();
348
- }
349
-
350
- // Array types do not output names
351
- if(nodeType == NodeType::InArray) return;
352
-
353
- if(itsNextName == nullptr)
354
- {
355
- std::string name = "value" + std::to_string( itsNameCounter.top()++ ) + "\0";
356
- saveValue(name);
357
- }
358
- else
359
- {
360
- saveValue(itsNextName);
361
- itsNextName = nullptr;
362
- }
363
- }
364
-
365
- //! Designates that the current node should be output as an array, not an object
366
- void makeArray()
367
- {
368
- itsNodeStack.top() = NodeType::StartArray;
369
- }
370
-
371
- //! @}
372
-
373
- private:
374
- WriteStream itsWriteStream; //!< Rapidjson write stream
375
- JSONWriter itsWriter; //!< Rapidjson writer
376
- char const * itsNextName; //!< The next name
377
- std::stack<uint32_t> itsNameCounter; //!< Counter for creating unique names for unnamed nodes
378
- std::stack<NodeType> itsNodeStack;
379
- }; // JSONOutputArchive
380
-
381
- // ######################################################################
382
- //! An input archive designed to load data from JSON
383
- /*! This archive uses RapidJSON to read in a JSON archive.
384
-
385
- As with the output JSON archive, the preferred way to use this archive is in
386
- an RAII fashion, ensuring its destruction after all data has been read.
387
-
388
- Input JSON should have been produced by the JSONOutputArchive. Data can
389
- only be added to dynamically sized containers (marked by JSON arrays) -
390
- the input archive will determine their size by looking at the number of child nodes.
391
- Only JSON originating from a JSONOutputArchive is officially supported, but data
392
- from other sources may work if properly formatted.
393
-
394
- The JSONInputArchive does not require that nodes are loaded in the same
395
- order they were saved by JSONOutputArchive. Using name value pairs (NVPs),
396
- it is possible to load in an out of order fashion or otherwise skip/select
397
- specific nodes to load.
398
-
399
- The default behavior of the input archive is to read sequentially starting
400
- with the first node and exploring its children. When a given NVP does
401
- not match the read in name for a node, the archive will search for that
402
- node at the current level and load it if it exists. After loading an out of
403
- order node, the archive will then proceed back to loading sequentially from
404
- its new position.
405
-
406
- Consider this simple example where loading of some data is skipped:
407
-
408
- @code{cpp}
409
- // imagine the input file has someData(1-9) saved in order at the top level node
410
- ar( someData1, someData2, someData3 ); // XML loads in the order it sees in the file
411
- ar( cereal::make_nvp( "hello", someData6 ) ); // NVP given does not
412
- // match expected NVP name, so we search
413
- // for the given NVP and load that value
414
- ar( someData7, someData8, someData9 ); // with no NVP given, loading resumes at its
415
- // current location, proceeding sequentially
416
- @endcode
417
-
418
- \ingroup Archives */
419
- class JSONInputArchive : public InputArchive<JSONInputArchive>, public traits::TextArchive
420
- {
421
- private:
422
- using ReadStream = CEREAL_RAPIDJSON_NAMESPACE::IStreamWrapper;
423
- typedef CEREAL_RAPIDJSON_NAMESPACE::GenericValue<CEREAL_RAPIDJSON_NAMESPACE::UTF8<>> JSONValue;
424
- typedef JSONValue::ConstMemberIterator MemberIterator;
425
- typedef JSONValue::ConstValueIterator ValueIterator;
426
- typedef CEREAL_RAPIDJSON_NAMESPACE::Document::GenericValue GenericValue;
427
-
428
- public:
429
- /*! @name Common Functionality
430
- Common use cases for directly interacting with an JSONInputArchive */
431
- //! @{
432
-
433
- //! Construct, reading from the provided stream
434
- /*! @param stream The stream to read from */
435
- JSONInputArchive(std::istream & stream) :
436
- InputArchive<JSONInputArchive>(this),
437
- itsNextName( nullptr ),
438
- itsReadStream(stream)
439
- {
440
- itsDocument.ParseStream<>(itsReadStream);
441
- if (itsDocument.IsArray())
442
- itsIteratorStack.emplace_back(itsDocument.Begin(), itsDocument.End());
443
- else
444
- itsIteratorStack.emplace_back(itsDocument.MemberBegin(), itsDocument.MemberEnd());
445
- }
446
-
447
- ~JSONInputArchive() CEREAL_NOEXCEPT = default;
448
-
449
- //! Loads some binary data, encoded as a base64 string
450
- /*! This will automatically start and finish a node to load the data, and can be called directly by
451
- users.
452
-
453
- Note that this follows the same ordering rules specified in the class description in regards
454
- to loading in/out of order */
455
- void loadBinaryValue( void * data, size_t size, const char * name = nullptr )
456
- {
457
- itsNextName = name;
458
-
459
- std::string encoded;
460
- loadValue( encoded );
461
- auto decoded = base64::decode( encoded );
462
-
463
- if( size != decoded.size() )
464
- throw Exception("Decoded binary data size does not match specified size");
465
-
466
- std::memcpy( data, decoded.data(), decoded.size() );
467
- itsNextName = nullptr;
468
- };
469
-
470
- private:
471
- //! @}
472
- /*! @name Internal Functionality
473
- Functionality designed for use by those requiring control over the inner mechanisms of
474
- the JSONInputArchive */
475
- //! @{
476
-
477
- //! An internal iterator that handles both array and object types
478
- /*! This class is a variant and holds both types of iterators that
479
- rapidJSON supports - one for arrays and one for objects. */
480
- class Iterator
481
- {
482
- public:
483
- Iterator() : itsIndex( 0 ), itsType(Null_) {}
484
-
485
- Iterator(MemberIterator begin, MemberIterator end) :
486
- itsMemberItBegin(begin), itsMemberItEnd(end), itsIndex(0), itsType(Member)
487
- {
488
- if( std::distance( begin, end ) == 0 )
489
- itsType = Null_;
490
- }
491
-
492
- Iterator(ValueIterator begin, ValueIterator end) :
493
- itsValueItBegin(begin), itsIndex(0), itsType(Value)
494
- {
495
- if( std::distance( begin, end ) == 0 )
496
- itsType = Null_;
497
- }
498
-
499
- //! Advance to the next node
500
- Iterator & operator++()
501
- {
502
- ++itsIndex;
503
- return *this;
504
- }
505
-
506
- //! Get the value of the current node
507
- GenericValue const & value()
508
- {
509
- switch(itsType)
510
- {
511
- case Value : return itsValueItBegin[itsIndex];
512
- case Member: return itsMemberItBegin[itsIndex].value;
513
- default: throw cereal::Exception("JSONInputArchive internal error: null or empty iterator to object or array!");
514
- }
515
- }
516
-
517
- //! Get the name of the current node, or nullptr if it has no name
518
- const char * name() const
519
- {
520
- if( itsType == Member && (itsMemberItBegin + itsIndex) != itsMemberItEnd )
521
- return itsMemberItBegin[itsIndex].name.GetString();
522
- else
523
- return nullptr;
524
- }
525
-
526
- //! Adjust our position such that we are at the node with the given name
527
- /*! @throws Exception if no such named node exists */
528
- inline void search( const char * searchName )
529
- {
530
- const auto len = std::strlen( searchName );
531
- size_t index = 0;
532
- for( auto it = itsMemberItBegin; it != itsMemberItEnd; ++it, ++index )
533
- {
534
- const auto currentName = it->name.GetString();
535
- if( ( std::strncmp( searchName, currentName, len ) == 0 ) &&
536
- ( std::strlen( currentName ) == len ) )
537
- {
538
- itsIndex = index;
539
- return;
540
- }
541
- }
542
-
543
- throw Exception("JSON Parsing failed - provided NVP (" + std::string(searchName) + ") not found");
544
- }
545
-
546
- private:
547
- MemberIterator itsMemberItBegin, itsMemberItEnd; //!< The member iterator (object)
548
- ValueIterator itsValueItBegin; //!< The value iterator (array)
549
- size_t itsIndex; //!< The current index of this iterator
550
- enum Type {Value, Member, Null_} itsType; //!< Whether this holds values (array) or members (objects) or nothing
551
- };
552
-
553
- //! Searches for the expectedName node if it doesn't match the actualName
554
- /*! This needs to be called before every load or node start occurs. This function will
555
- check to see if an NVP has been provided (with setNextName) and if so, see if that name matches the actual
556
- next name given. If the names do not match, it will search in the current level of the JSON for that name.
557
- If the name is not found, an exception will be thrown.
558
-
559
- Resets the NVP name after called.
560
-
561
- @throws Exception if an expectedName is given and not found */
562
- inline void search()
563
- {
564
- // The name an NVP provided with setNextName()
565
- if( itsNextName )
566
- {
567
- // The actual name of the current node
568
- auto const actualName = itsIteratorStack.back().name();
569
-
570
- // Do a search if we don't see a name coming up, or if the names don't match
571
- if( !actualName || std::strcmp( itsNextName, actualName ) != 0 )
572
- itsIteratorStack.back().search( itsNextName );
573
- }
574
-
575
- itsNextName = nullptr;
576
- }
577
-
578
- public:
579
- //! Starts a new node, going into its proper iterator
580
- /*! This places an iterator for the next node to be parsed onto the iterator stack. If the next
581
- node is an array, this will be a value iterator, otherwise it will be a member iterator.
582
-
583
- By default our strategy is to start with the document root node and then recursively iterate through
584
- all children in the order they show up in the document.
585
- We don't need to know NVPs to do this; we'll just blindly load in the order things appear in.
586
-
587
- If we were given an NVP, we will search for it if it does not match our the name of the next node
588
- that would normally be loaded. This functionality is provided by search(). */
589
- void startNode()
590
- {
591
- search();
592
-
593
- if(itsIteratorStack.back().value().IsArray())
594
- itsIteratorStack.emplace_back(itsIteratorStack.back().value().Begin(), itsIteratorStack.back().value().End());
595
- else
596
- itsIteratorStack.emplace_back(itsIteratorStack.back().value().MemberBegin(), itsIteratorStack.back().value().MemberEnd());
597
- }
598
-
599
- //! Finishes the most recently started node
600
- void finishNode()
601
- {
602
- itsIteratorStack.pop_back();
603
- ++itsIteratorStack.back();
604
- }
605
-
606
- //! Retrieves the current node name
607
- /*! @return nullptr if no name exists */
608
- const char * getNodeName() const
609
- {
610
- return itsIteratorStack.back().name();
611
- }
612
-
613
- //! Sets the name for the next node created with startNode
614
- void setNextName( const char * name )
615
- {
616
- itsNextName = name;
617
- }
618
-
619
- //! Loads a value from the current node - small signed overload
620
- template <class T, traits::EnableIf<std::is_signed<T>::value,
621
- sizeof(T) < sizeof(int64_t)> = traits::sfinae> inline
622
- void loadValue(T & val)
623
- {
624
- search();
625
-
626
- val = static_cast<T>( itsIteratorStack.back().value().GetInt() );
627
- ++itsIteratorStack.back();
628
- }
629
-
630
- //! Loads a value from the current node - small unsigned overload
631
- template <class T, traits::EnableIf<std::is_unsigned<T>::value,
632
- sizeof(T) < sizeof(uint64_t),
633
- !std::is_same<bool, T>::value> = traits::sfinae> inline
634
- void loadValue(T & val)
635
- {
636
- search();
637
-
638
- val = static_cast<T>( itsIteratorStack.back().value().GetUint() );
639
- ++itsIteratorStack.back();
640
- }
641
-
642
- //! Loads a value from the current node - bool overload
643
- void loadValue(bool & val) { search(); val = itsIteratorStack.back().value().GetBool(); ++itsIteratorStack.back(); }
644
- //! Loads a value from the current node - int64 overload
645
- void loadValue(int64_t & val) { search(); val = itsIteratorStack.back().value().GetInt64(); ++itsIteratorStack.back(); }
646
- //! Loads a value from the current node - uint64 overload
647
- void loadValue(uint64_t & val) { search(); val = itsIteratorStack.back().value().GetUint64(); ++itsIteratorStack.back(); }
648
- //! Loads a value from the current node - float overload
649
- void loadValue(float & val) { search(); val = static_cast<float>(itsIteratorStack.back().value().GetDouble()); ++itsIteratorStack.back(); }
650
- //! Loads a value from the current node - double overload
651
- void loadValue(double & val) { search(); val = itsIteratorStack.back().value().GetDouble(); ++itsIteratorStack.back(); }
652
- //! Loads a value from the current node - string overload
653
- void loadValue(std::string & val) { search(); val = itsIteratorStack.back().value().GetString(); ++itsIteratorStack.back(); }
654
- //! Loads a nullptr from the current node
655
- void loadValue(std::nullptr_t&) { search(); CEREAL_RAPIDJSON_ASSERT(itsIteratorStack.back().value().IsNull()); ++itsIteratorStack.back(); }
656
-
657
- // Special cases to handle various flavors of long, which tend to conflict with
658
- // the int32_t or int64_t on various compiler/OS combinations. MSVC doesn't need any of this.
659
- #ifndef _MSC_VER
660
- private:
661
- //! 32 bit signed long loading from current node
662
- template <class T> inline
663
- typename std::enable_if<sizeof(T) == sizeof(std::int32_t) && std::is_signed<T>::value, void>::type
664
- loadLong(T & l){ loadValue( reinterpret_cast<std::int32_t&>( l ) ); }
665
-
666
- //! non 32 bit signed long loading from current node
667
- template <class T> inline
668
- typename std::enable_if<sizeof(T) == sizeof(std::int64_t) && std::is_signed<T>::value, void>::type
669
- loadLong(T & l){ loadValue( reinterpret_cast<std::int64_t&>( l ) ); }
670
-
671
- //! 32 bit unsigned long loading from current node
672
- template <class T> inline
673
- typename std::enable_if<sizeof(T) == sizeof(std::uint32_t) && !std::is_signed<T>::value, void>::type
674
- loadLong(T & lu){ loadValue( reinterpret_cast<std::uint32_t&>( lu ) ); }
675
-
676
- //! non 32 bit unsigned long loading from current node
677
- template <class T> inline
678
- typename std::enable_if<sizeof(T) == sizeof(std::uint64_t) && !std::is_signed<T>::value, void>::type
679
- loadLong(T & lu){ loadValue( reinterpret_cast<std::uint64_t&>( lu ) ); }
680
-
681
- public:
682
- //! Serialize a long if it would not be caught otherwise
683
- template <class T> inline
684
- typename std::enable_if<std::is_same<T, long>::value &&
685
- sizeof(T) >= sizeof(std::int64_t) &&
686
- !std::is_same<T, std::int64_t>::value, void>::type
687
- loadValue( T & t ){ loadLong(t); }
688
-
689
- //! Serialize an unsigned long if it would not be caught otherwise
690
- template <class T> inline
691
- typename std::enable_if<std::is_same<T, unsigned long>::value &&
692
- sizeof(T) >= sizeof(std::uint64_t) &&
693
- !std::is_same<T, std::uint64_t>::value, void>::type
694
- loadValue( T & t ){ loadLong(t); }
695
- #endif // _MSC_VER
696
-
697
- private:
698
- //! Convert a string to a long long
699
- void stringToNumber( std::string const & str, long long & val ) { val = std::stoll( str ); }
700
- //! Convert a string to an unsigned long long
701
- void stringToNumber( std::string const & str, unsigned long long & val ) { val = std::stoull( str ); }
702
- //! Convert a string to a long double
703
- void stringToNumber( std::string const & str, long double & val ) { val = std::stold( str ); }
704
-
705
- public:
706
- //! Loads a value from the current node - long double and long long overloads
707
- template <class T, traits::EnableIf<std::is_arithmetic<T>::value,
708
- !std::is_same<T, long>::value,
709
- !std::is_same<T, unsigned long>::value,
710
- !std::is_same<T, std::int64_t>::value,
711
- !std::is_same<T, std::uint64_t>::value,
712
- (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long))> = traits::sfinae>
713
- inline void loadValue(T & val)
714
- {
715
- std::string encoded;
716
- loadValue( encoded );
717
- stringToNumber( encoded, val );
718
- }
719
-
720
- //! Loads the size for a SizeTag
721
- void loadSize(size_type & size)
722
- {
723
- if (itsIteratorStack.size() == 1)
724
- size = itsDocument.Size();
725
- else
726
- size = (itsIteratorStack.rbegin() + 1)->value().Size();
727
- }
728
-
729
- //! @}
730
-
731
- private:
732
- const char * itsNextName; //!< Next name set by NVP
733
- ReadStream itsReadStream; //!< Rapidjson write stream
734
- std::vector<Iterator> itsIteratorStack; //!< 'Stack' of rapidJSON iterators
735
- CEREAL_RAPIDJSON_NAMESPACE::Document itsDocument; //!< Rapidjson document
736
- };
737
-
738
- // ######################################################################
739
- // JSONArchive prologue and epilogue functions
740
- // ######################################################################
741
-
742
- // ######################################################################
743
- //! Prologue for NVPs for JSON archives
744
- /*! NVPs do not start or finish nodes - they just set up the names */
745
- template <class T> inline
746
- void prologue( JSONOutputArchive &, NameValuePair<T> const & )
747
- { }
748
-
749
- //! Prologue for NVPs for JSON archives
750
- template <class T> inline
751
- void prologue( JSONInputArchive &, NameValuePair<T> const & )
752
- { }
753
-
754
- // ######################################################################
755
- //! Epilogue for NVPs for JSON archives
756
- /*! NVPs do not start or finish nodes - they just set up the names */
757
- template <class T> inline
758
- void epilogue( JSONOutputArchive &, NameValuePair<T> const & )
759
- { }
760
-
761
- //! Epilogue for NVPs for JSON archives
762
- /*! NVPs do not start or finish nodes - they just set up the names */
763
- template <class T> inline
764
- void epilogue( JSONInputArchive &, NameValuePair<T> const & )
765
- { }
766
-
767
- // ######################################################################
768
- //! Prologue for deferred data for JSON archives
769
- /*! Do nothing for the defer wrapper */
770
- template <class T> inline
771
- void prologue( JSONOutputArchive &, DeferredData<T> const & )
772
- { }
773
-
774
- //! Prologue for deferred data for JSON archives
775
- template <class T> inline
776
- void prologue( JSONInputArchive &, DeferredData<T> const & )
777
- { }
778
-
779
- // ######################################################################
780
- //! Epilogue for deferred for JSON archives
781
- /*! NVPs do not start or finish nodes - they just set up the names */
782
- template <class T> inline
783
- void epilogue( JSONOutputArchive &, DeferredData<T> const & )
784
- { }
785
-
786
- //! Epilogue for deferred for JSON archives
787
- /*! Do nothing for the defer wrapper */
788
- template <class T> inline
789
- void epilogue( JSONInputArchive &, DeferredData<T> const & )
790
- { }
791
-
792
- // ######################################################################
793
- //! Prologue for SizeTags for JSON archives
794
- /*! SizeTags are strictly ignored for JSON, they just indicate
795
- that the current node should be made into an array */
796
- template <class T> inline
797
- void prologue( JSONOutputArchive & ar, SizeTag<T> const & )
798
- {
799
- ar.makeArray();
800
- }
801
-
802
- //! Prologue for SizeTags for JSON archives
803
- template <class T> inline
804
- void prologue( JSONInputArchive &, SizeTag<T> const & )
805
- { }
806
-
807
- // ######################################################################
808
- //! Epilogue for SizeTags for JSON archives
809
- /*! SizeTags are strictly ignored for JSON */
810
- template <class T> inline
811
- void epilogue( JSONOutputArchive &, SizeTag<T> const & )
812
- { }
813
-
814
- //! Epilogue for SizeTags for JSON archives
815
- template <class T> inline
816
- void epilogue( JSONInputArchive &, SizeTag<T> const & )
817
- { }
818
-
819
- // ######################################################################
820
- //! Prologue for all other types for JSON archives (except minimal types)
821
- /*! Starts a new node, named either automatically or by some NVP,
822
- that may be given data by the type about to be archived
823
-
824
- Minimal types do not start or finish nodes */
825
- template <class T, traits::EnableIf<!std::is_arithmetic<T>::value,
826
- !traits::has_minimal_base_class_serialization<T, traits::has_minimal_output_serialization, JSONOutputArchive>::value,
827
- !traits::has_minimal_output_serialization<T, JSONOutputArchive>::value> = traits::sfinae>
828
- inline void prologue( JSONOutputArchive & ar, T const & )
829
- {
830
- ar.startNode();
831
- }
832
-
833
- //! Prologue for all other types for JSON archives
834
- template <class T, traits::EnableIf<!std::is_arithmetic<T>::value,
835
- !traits::has_minimal_base_class_serialization<T, traits::has_minimal_input_serialization, JSONInputArchive>::value,
836
- !traits::has_minimal_input_serialization<T, JSONInputArchive>::value> = traits::sfinae>
837
- inline void prologue( JSONInputArchive & ar, T const & )
838
- {
839
- ar.startNode();
840
- }
841
-
842
- // ######################################################################
843
- //! Epilogue for all other types other for JSON archives (except minimal types)
844
- /*! Finishes the node created in the prologue
845
-
846
- Minimal types do not start or finish nodes */
847
- template <class T, traits::EnableIf<!std::is_arithmetic<T>::value,
848
- !traits::has_minimal_base_class_serialization<T, traits::has_minimal_output_serialization, JSONOutputArchive>::value,
849
- !traits::has_minimal_output_serialization<T, JSONOutputArchive>::value> = traits::sfinae>
850
- inline void epilogue( JSONOutputArchive & ar, T const & )
851
- {
852
- ar.finishNode();
853
- }
854
-
855
- //! Epilogue for all other types other for JSON archives
856
- template <class T, traits::EnableIf<!std::is_arithmetic<T>::value,
857
- !traits::has_minimal_base_class_serialization<T, traits::has_minimal_input_serialization, JSONInputArchive>::value,
858
- !traits::has_minimal_input_serialization<T, JSONInputArchive>::value> = traits::sfinae>
859
- inline void epilogue( JSONInputArchive & ar, T const & )
860
- {
861
- ar.finishNode();
862
- }
863
-
864
- // ######################################################################
865
- //! Prologue for arithmetic types for JSON archives
866
- inline
867
- void prologue( JSONOutputArchive & ar, std::nullptr_t const & )
868
- {
869
- ar.writeName();
870
- }
871
-
872
- //! Prologue for arithmetic types for JSON archives
873
- inline
874
- void prologue( JSONInputArchive &, std::nullptr_t const & )
875
- { }
876
-
877
- // ######################################################################
878
- //! Epilogue for arithmetic types for JSON archives
879
- inline
880
- void epilogue( JSONOutputArchive &, std::nullptr_t const & )
881
- { }
882
-
883
- //! Epilogue for arithmetic types for JSON archives
884
- inline
885
- void epilogue( JSONInputArchive &, std::nullptr_t const & )
886
- { }
887
-
888
- // ######################################################################
889
- //! Prologue for arithmetic types for JSON archives
890
- template <class T, traits::EnableIf<std::is_arithmetic<T>::value> = traits::sfinae> inline
891
- void prologue( JSONOutputArchive & ar, T const & )
892
- {
893
- ar.writeName();
894
- }
895
-
896
- //! Prologue for arithmetic types for JSON archives
897
- template <class T, traits::EnableIf<std::is_arithmetic<T>::value> = traits::sfinae> inline
898
- void prologue( JSONInputArchive &, T const & )
899
- { }
900
-
901
- // ######################################################################
902
- //! Epilogue for arithmetic types for JSON archives
903
- template <class T, traits::EnableIf<std::is_arithmetic<T>::value> = traits::sfinae> inline
904
- void epilogue( JSONOutputArchive &, T const & )
905
- { }
906
-
907
- //! Epilogue for arithmetic types for JSON archives
908
- template <class T, traits::EnableIf<std::is_arithmetic<T>::value> = traits::sfinae> inline
909
- void epilogue( JSONInputArchive &, T const & )
910
- { }
911
-
912
- // ######################################################################
913
- //! Prologue for strings for JSON archives
914
- template<class CharT, class Traits, class Alloc> inline
915
- void prologue(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const &)
916
- {
917
- ar.writeName();
918
- }
919
-
920
- //! Prologue for strings for JSON archives
921
- template<class CharT, class Traits, class Alloc> inline
922
- void prologue(JSONInputArchive &, std::basic_string<CharT, Traits, Alloc> const &)
923
- { }
924
-
925
- // ######################################################################
926
- //! Epilogue for strings for JSON archives
927
- template<class CharT, class Traits, class Alloc> inline
928
- void epilogue(JSONOutputArchive &, std::basic_string<CharT, Traits, Alloc> const &)
929
- { }
930
-
931
- //! Epilogue for strings for JSON archives
932
- template<class CharT, class Traits, class Alloc> inline
933
- void epilogue(JSONInputArchive &, std::basic_string<CharT, Traits, Alloc> const &)
934
- { }
935
-
936
- // ######################################################################
937
- // Common JSONArchive serialization functions
938
- // ######################################################################
939
- //! Serializing NVP types to JSON
940
- template <class T> inline
941
- void CEREAL_SAVE_FUNCTION_NAME( JSONOutputArchive & ar, NameValuePair<T> const & t )
942
- {
943
- ar.setNextName( t.name );
944
- ar( t.value );
945
- }
946
-
947
- template <class T> inline
948
- void CEREAL_LOAD_FUNCTION_NAME( JSONInputArchive & ar, NameValuePair<T> & t )
949
- {
950
- ar.setNextName( t.name );
951
- ar( t.value );
952
- }
953
-
954
- //! Saving for nullptr to JSON
955
- inline
956
- void CEREAL_SAVE_FUNCTION_NAME(JSONOutputArchive & ar, std::nullptr_t const & t)
957
- {
958
- ar.saveValue( t );
959
- }
960
-
961
- //! Loading arithmetic from JSON
962
- inline
963
- void CEREAL_LOAD_FUNCTION_NAME(JSONInputArchive & ar, std::nullptr_t & t)
964
- {
965
- ar.loadValue( t );
966
- }
967
-
968
- //! Saving for arithmetic to JSON
969
- template <class T, traits::EnableIf<std::is_arithmetic<T>::value> = traits::sfinae> inline
970
- void CEREAL_SAVE_FUNCTION_NAME(JSONOutputArchive & ar, T const & t)
971
- {
972
- ar.saveValue( t );
973
- }
974
-
975
- //! Loading arithmetic from JSON
976
- template <class T, traits::EnableIf<std::is_arithmetic<T>::value> = traits::sfinae> inline
977
- void CEREAL_LOAD_FUNCTION_NAME(JSONInputArchive & ar, T & t)
978
- {
979
- ar.loadValue( t );
980
- }
981
-
982
- //! saving string to JSON
983
- template<class CharT, class Traits, class Alloc> inline
984
- void CEREAL_SAVE_FUNCTION_NAME(JSONOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
985
- {
986
- ar.saveValue( str );
987
- }
988
-
989
- //! loading string from JSON
990
- template<class CharT, class Traits, class Alloc> inline
991
- void CEREAL_LOAD_FUNCTION_NAME(JSONInputArchive & ar, std::basic_string<CharT, Traits, Alloc> & str)
992
- {
993
- ar.loadValue( str );
994
- }
995
-
996
- // ######################################################################
997
- //! Saving SizeTags to JSON
998
- template <class T> inline
999
- void CEREAL_SAVE_FUNCTION_NAME( JSONOutputArchive &, SizeTag<T> const & )
1000
- {
1001
- // nothing to do here, we don't explicitly save the size
1002
- }
1003
-
1004
- //! Loading SizeTags from JSON
1005
- template <class T> inline
1006
- void CEREAL_LOAD_FUNCTION_NAME( JSONInputArchive & ar, SizeTag<T> & st )
1007
- {
1008
- ar.loadSize( st.size );
1009
- }
1010
- } // namespace cereal
1011
-
1012
- // register archives for polymorphic support
1013
- CEREAL_REGISTER_ARCHIVE(cereal::JSONInputArchive)
1014
- CEREAL_REGISTER_ARCHIVE(cereal::JSONOutputArchive)
1015
-
1016
- // tie input and output archives together
1017
- CEREAL_SETUP_ARCHIVE_TRAITS(cereal::JSONInputArchive, cereal::JSONOutputArchive)
1018
-
1019
- #endif // CEREAL_ARCHIVES_JSON_HPP_