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,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_