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,956 +0,0 @@
1
- /*! \file xml.hpp
2
- \brief XML 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_XML_HPP_
30
- #define CEREAL_ARCHIVES_XML_HPP_
31
- #include "cereal/cereal.hpp"
32
- #include "cereal/details/util.hpp"
33
-
34
- #include "cereal/external/rapidxml/rapidxml.hpp"
35
- #include "cereal/external/rapidxml/rapidxml_print.hpp"
36
- #include "cereal/external/base64.hpp"
37
-
38
- #include <sstream>
39
- #include <stack>
40
- #include <vector>
41
- #include <limits>
42
- #include <string>
43
- #include <cstring>
44
- #include <cmath>
45
-
46
- namespace cereal
47
- {
48
- namespace xml_detail
49
- {
50
- #ifndef CEREAL_XML_STRING_VALUE
51
- //! The default name for the root node in a cereal xml archive.
52
- /*! You can define CEREAL_XML_STRING_VALUE to be different assuming you do so
53
- before this file is included. */
54
- #define CEREAL_XML_STRING_VALUE "cereal"
55
- #endif // CEREAL_XML_STRING_VALUE
56
-
57
- //! The name given to the root node in a cereal xml archive
58
- static const char * CEREAL_XML_STRING = CEREAL_XML_STRING_VALUE;
59
-
60
- //! Returns true if the character is whitespace
61
- inline bool isWhitespace( char c )
62
- {
63
- return c == ' ' || c == '\t' || c == '\n' || c == '\r';
64
- }
65
- }
66
-
67
- // ######################################################################
68
- //! An output archive designed to save data to XML
69
- /*! This archive uses RapidXML to build an in memory XML tree of the
70
- data it serializes before outputting it to its stream upon destruction.
71
- This archive should be used in an RAII fashion, letting
72
- the automatic destruction of the object cause the flush to its stream.
73
-
74
- XML archives provides a human readable output but at decreased
75
- performance (both in time and space) compared to binary archives.
76
-
77
- XML benefits greatly from name-value pairs, which if present, will
78
- name the nodes in the output. If these are not present, each level
79
- of the output tree will be given an automatically generated delimited name.
80
-
81
- The precision of the output archive controls the number of decimals output
82
- for floating point numbers and should be sufficiently large (i.e. at least 20)
83
- if there is a desire to have binary equality between the numbers output and
84
- those read in. In general you should expect a loss of precision when going
85
- from floating point to text and back.
86
-
87
- XML archives can optionally print the type of everything they serialize, which
88
- adds an attribute to each node.
89
-
90
- XML archives do not output the size information for any dynamically sized structure
91
- and instead infer it from the number of children for a node. This means that data
92
- can be hand edited for dynamic sized structures and will still be readable. This
93
- is accomplished through the cereal::SizeTag object, which will also add an attribute
94
- to its parent field.
95
- \ingroup Archives */
96
- class XMLOutputArchive : public OutputArchive<XMLOutputArchive>, public traits::TextArchive
97
- {
98
- public:
99
- /*! @name Common Functionality
100
- Common use cases for directly interacting with an XMLOutputArchive */
101
- //! @{
102
-
103
- //! A class containing various advanced options for the XML archive
104
- /*! Options can either be directly passed to the constructor, or chained using the
105
- modifier functions for an interface analogous to named parameters */
106
- class Options
107
- {
108
- public:
109
- //! Default options
110
- static Options Default(){ return Options(); }
111
-
112
- //! Specify specific options for the XMLOutputArchive
113
- /*! @param precision_ The precision used for floating point numbers
114
- @param indent_ Whether to indent each line of XML
115
- @param outputType_ Whether to output the type of each serialized object as an attribute
116
- @param sizeAttributes_ Whether dynamically sized containers output the size=dynamic attribute */
117
- explicit Options( int precision_ = std::numeric_limits<double>::max_digits10,
118
- bool indent_ = true,
119
- bool outputType_ = false,
120
- bool sizeAttributes_ = true ) :
121
- itsPrecision( precision_ ),
122
- itsIndent( indent_ ),
123
- itsOutputType( outputType_ ),
124
- itsSizeAttributes( sizeAttributes_ )
125
- { }
126
-
127
- /*! @name Option Modifiers
128
- An interface for setting option settings analogous to named parameters.
129
-
130
- @code{cpp}
131
- cereal::XMLOutputArchive ar( myStream,
132
- cereal::XMLOutputArchive::Options()
133
- .indent(true)
134
- .sizeAttributes(false) );
135
- @endcode
136
- */
137
- //! @{
138
-
139
- //! Sets the precision used for floaing point numbers
140
- Options & precision( int value ){ itsPrecision = value; return * this; }
141
- //! Whether to indent each line of XML
142
- Options & indent( bool enable ){ itsIndent = enable; return *this; }
143
- //! Whether to output the type of each serialized object as an attribute
144
- Options & outputType( bool enable ){ itsOutputType = enable; return *this; }
145
- //! Whether dynamically sized containers (e.g. vector) output the size=dynamic attribute
146
- Options & sizeAttributes( bool enable ){ itsSizeAttributes = enable; return *this; }
147
-
148
- //! @}
149
-
150
- private:
151
- friend class XMLOutputArchive;
152
- int itsPrecision;
153
- bool itsIndent;
154
- bool itsOutputType;
155
- bool itsSizeAttributes;
156
- };
157
-
158
- //! Construct, outputting to the provided stream upon destruction
159
- /*! @param stream The stream to output to. Note that XML is only guaranteed to flush
160
- its output to the stream upon destruction.
161
- @param options The XML specific options to use. See the Options struct
162
- for the values of default parameters */
163
- XMLOutputArchive( std::ostream & stream, Options const & options = Options::Default() ) :
164
- OutputArchive<XMLOutputArchive>(this),
165
- itsStream(stream),
166
- itsOutputType( options.itsOutputType ),
167
- itsIndent( options.itsIndent ),
168
- itsSizeAttributes(options.itsSizeAttributes)
169
- {
170
- // rapidxml will delete all allocations when xml_document is cleared
171
- auto node = itsXML.allocate_node( rapidxml::node_declaration );
172
- node->append_attribute( itsXML.allocate_attribute( "version", "1.0" ) );
173
- node->append_attribute( itsXML.allocate_attribute( "encoding", "utf-8" ) );
174
- itsXML.append_node( node );
175
-
176
- // allocate root node
177
- auto root = itsXML.allocate_node( rapidxml::node_element, xml_detail::CEREAL_XML_STRING );
178
- itsXML.append_node( root );
179
- itsNodes.emplace( root );
180
-
181
- // set attributes on the streams
182
- itsStream << std::boolalpha;
183
- itsStream.precision( options.itsPrecision );
184
- itsOS << std::boolalpha;
185
- itsOS.precision( options.itsPrecision );
186
- }
187
-
188
- //! Destructor, flushes the XML
189
- ~XMLOutputArchive() CEREAL_NOEXCEPT
190
- {
191
- const int flags = itsIndent ? 0x0 : rapidxml::print_no_indenting;
192
- rapidxml::print( itsStream, itsXML, flags );
193
- itsXML.clear();
194
- }
195
-
196
- //! Saves some binary data, encoded as a base64 string, with an optional name
197
- /*! This can be called directly by users and it will automatically create a child node for
198
- the current XML node, populate it with a base64 encoded string, and optionally name
199
- it. The node will be finished after it has been populated. */
200
- void saveBinaryValue( const void * data, size_t size, const char * name = nullptr )
201
- {
202
- itsNodes.top().name = name;
203
-
204
- startNode();
205
-
206
- auto base64string = base64::encode( reinterpret_cast<const unsigned char *>( data ), size );
207
- saveValue( base64string );
208
-
209
- if( itsOutputType )
210
- itsNodes.top().node->append_attribute( itsXML.allocate_attribute( "type", "cereal binary data" ) );
211
-
212
- finishNode();
213
- }
214
-
215
- //! @}
216
- /*! @name Internal Functionality
217
- Functionality designed for use by those requiring control over the inner mechanisms of
218
- the XMLOutputArchive */
219
- //! @{
220
-
221
- //! Creates a new node that is a child of the node at the top of the stack
222
- /*! Nodes will be given a name that has either been pre-set by a name value pair,
223
- or generated based upon a counter unique to the parent node. If you want to
224
- give a node a specific name, use setNextName prior to calling startNode.
225
-
226
- The node will then be pushed onto the node stack. */
227
- void startNode()
228
- {
229
- // generate a name for this new node
230
- const auto nameString = itsNodes.top().getValueName();
231
-
232
- // allocate strings for all of the data in the XML object
233
- auto namePtr = itsXML.allocate_string( nameString.data(), nameString.length() + 1 );
234
-
235
- // insert into the XML
236
- auto node = itsXML.allocate_node( rapidxml::node_element, namePtr, nullptr, nameString.size() );
237
- itsNodes.top().node->append_node( node );
238
- itsNodes.emplace( node );
239
- }
240
-
241
- //! Designates the most recently added node as finished
242
- void finishNode()
243
- {
244
- itsNodes.pop();
245
- }
246
-
247
- //! Sets the name for the next node created with startNode
248
- void setNextName( const char * name )
249
- {
250
- itsNodes.top().name = name;
251
- }
252
-
253
- //! Saves some data, encoded as a string, into the current top level node
254
- /*! The data will be be named with the most recent name if one exists,
255
- otherwise it will be given some default delimited value that depends upon
256
- the parent node */
257
- template <class T> inline
258
- void saveValue( T const & value )
259
- {
260
- itsOS.clear(); itsOS.seekp( 0, std::ios::beg );
261
- itsOS << value << std::ends;
262
-
263
- auto strValue = itsOS.str();
264
-
265
- // itsOS.str() may contain data from previous calls after the first '\0' that was just inserted
266
- // and this data is counted in the length call. We make sure to remove that section so that the
267
- // whitespace validation is done properly
268
- strValue.resize(std::strlen(strValue.c_str()));
269
-
270
- // If the first or last character is a whitespace, add xml:space attribute
271
- const auto len = strValue.length();
272
- if ( len > 0 && ( xml_detail::isWhitespace( strValue[0] ) || xml_detail::isWhitespace( strValue[len - 1] ) ) )
273
- {
274
- itsNodes.top().node->append_attribute( itsXML.allocate_attribute( "xml:space", "preserve" ) );
275
- }
276
-
277
- // allocate strings for all of the data in the XML object
278
- auto dataPtr = itsXML.allocate_string(strValue.c_str(), strValue.length() + 1 );
279
-
280
- // insert into the XML
281
- itsNodes.top().node->append_node( itsXML.allocate_node( rapidxml::node_data, nullptr, dataPtr ) );
282
- }
283
-
284
- //! Overload for uint8_t prevents them from being serialized as characters
285
- void saveValue( uint8_t const & value )
286
- {
287
- saveValue( static_cast<uint32_t>( value ) );
288
- }
289
-
290
- //! Overload for int8_t prevents them from being serialized as characters
291
- void saveValue( int8_t const & value )
292
- {
293
- saveValue( static_cast<int32_t>( value ) );
294
- }
295
-
296
- //! Causes the type to be appended as an attribute to the most recently made node if output type is set to true
297
- template <class T> inline
298
- void insertType()
299
- {
300
- if( !itsOutputType )
301
- return;
302
-
303
- // generate a name for this new node
304
- const auto nameString = util::demangledName<T>();
305
-
306
- // allocate strings for all of the data in the XML object
307
- auto namePtr = itsXML.allocate_string( nameString.data(), nameString.length() + 1 );
308
-
309
- itsNodes.top().node->append_attribute( itsXML.allocate_attribute( "type", namePtr ) );
310
- }
311
-
312
- //! Appends an attribute to the current top level node
313
- void appendAttribute( const char * name, const char * value )
314
- {
315
- auto namePtr = itsXML.allocate_string( name );
316
- auto valuePtr = itsXML.allocate_string( value );
317
- itsNodes.top().node->append_attribute( itsXML.allocate_attribute( namePtr, valuePtr ) );
318
- }
319
-
320
- bool hasSizeAttributes() const { return itsSizeAttributes; }
321
-
322
- protected:
323
- //! A struct that contains metadata about a node
324
- struct NodeInfo
325
- {
326
- NodeInfo( rapidxml::xml_node<> * n = nullptr,
327
- const char * nm = nullptr ) :
328
- node( n ),
329
- counter( 0 ),
330
- name( nm )
331
- { }
332
-
333
- rapidxml::xml_node<> * node; //!< A pointer to this node
334
- size_t counter; //!< The counter for naming child nodes
335
- const char * name; //!< The name for the next child node
336
-
337
- //! Gets the name for the next child node created from this node
338
- /*! The name will be automatically generated using the counter if
339
- a name has not been previously set. If a name has been previously
340
- set, that name will be returned only once */
341
- std::string getValueName()
342
- {
343
- if( name )
344
- {
345
- auto n = name;
346
- name = nullptr;
347
- return {n};
348
- }
349
- else
350
- return "value" + std::to_string( counter++ ) + "\0";
351
- }
352
- }; // NodeInfo
353
-
354
- //! @}
355
-
356
- private:
357
- std::ostream & itsStream; //!< The output stream
358
- rapidxml::xml_document<> itsXML; //!< The XML document
359
- std::stack<NodeInfo> itsNodes; //!< A stack of nodes added to the document
360
- std::ostringstream itsOS; //!< Used to format strings internally
361
- bool itsOutputType; //!< Controls whether type information is printed
362
- bool itsIndent; //!< Controls whether indenting is used
363
- bool itsSizeAttributes; //!< Controls whether lists have a size attribute
364
- }; // XMLOutputArchive
365
-
366
- // ######################################################################
367
- //! An output archive designed to load data from XML
368
- /*! This archive uses RapidXML to build an in memory XML tree of the
369
- data in the stream it is given before loading any types serialized.
370
-
371
- As with the output XML archive, the preferred way to use this archive is in
372
- an RAII fashion, ensuring its destruction after all data has been read.
373
-
374
- Input XML should have been produced by the XMLOutputArchive. Data can
375
- only be added to dynamically sized containers - the input archive will
376
- determine their size by looking at the number of child nodes. Data that
377
- did not originate from an XMLOutputArchive is not officially supported,
378
- but may be possible to use if properly formatted.
379
-
380
- The XMLInputArchive does not require that nodes are loaded in the same
381
- order they were saved by XMLOutputArchive. Using name value pairs (NVPs),
382
- it is possible to load in an out of order fashion or otherwise skip/select
383
- specific nodes to load.
384
-
385
- The default behavior of the input archive is to read sequentially starting
386
- with the first node and exploring its children. When a given NVP does
387
- not match the read in name for a node, the archive will search for that
388
- node at the current level and load it if it exists. After loading an out of
389
- order node, the archive will then proceed back to loading sequentially from
390
- its new position.
391
-
392
- Consider this simple example where loading of some data is skipped:
393
-
394
- @code{cpp}
395
- // imagine the input file has someData(1-9) saved in order at the top level node
396
- ar( someData1, someData2, someData3 ); // XML loads in the order it sees in the file
397
- ar( cereal::make_nvp( "hello", someData6 ) ); // NVP given does not
398
- // match expected NVP name, so we search
399
- // for the given NVP and load that value
400
- ar( someData7, someData8, someData9 ); // with no NVP given, loading resumes at its
401
- // current location, proceeding sequentially
402
- @endcode
403
-
404
- \ingroup Archives */
405
- class XMLInputArchive : public InputArchive<XMLInputArchive>, public traits::TextArchive
406
- {
407
- public:
408
- /*! @name Common Functionality
409
- Common use cases for directly interacting with an XMLInputArchive */
410
- //! @{
411
-
412
- //! Construct, reading in from the provided stream
413
- /*! Reads in an entire XML document from some stream and parses it as soon
414
- as serialization starts
415
-
416
- @param stream The stream to read from. Can be a stringstream or a file. */
417
- XMLInputArchive( std::istream & stream ) :
418
- InputArchive<XMLInputArchive>( this ),
419
- itsData( std::istreambuf_iterator<char>( stream ), std::istreambuf_iterator<char>() )
420
- {
421
- try
422
- {
423
- itsData.push_back('\0'); // rapidxml will do terrible things without the data being null terminated
424
- itsXML.parse<rapidxml::parse_trim_whitespace | rapidxml::parse_no_data_nodes | rapidxml::parse_declaration_node>( reinterpret_cast<char *>( itsData.data() ) );
425
- }
426
- catch( rapidxml::parse_error const & )
427
- {
428
- //std::cerr << "-----Original-----" << std::endl;
429
- //stream.seekg(0);
430
- //std::cout << std::string( std::istreambuf_iterator<char>( stream ), std::istreambuf_iterator<char>() ) << std::endl;
431
-
432
- //std::cerr << "-----Error-----" << std::endl;
433
- //std::cerr << e.what() << std::endl;
434
- //std::cerr << e.where<char>() << std::endl;
435
- throw Exception("XML Parsing failed - likely due to invalid characters or invalid naming");
436
- }
437
-
438
- // Parse the root
439
- auto root = itsXML.first_node( xml_detail::CEREAL_XML_STRING );
440
- if( root == nullptr )
441
- throw Exception("Could not detect cereal root node - likely due to empty or invalid input");
442
- else
443
- itsNodes.emplace( root );
444
- }
445
-
446
- ~XMLInputArchive() CEREAL_NOEXCEPT = default;
447
-
448
- //! Loads some binary data, encoded as a base64 string, optionally specified by some name
449
- /*! This will automatically start and finish a node to load the data, and can be called directly by
450
- users.
451
-
452
- Note that this follows the same ordering rules specified in the class description in regards
453
- to loading in/out of order */
454
- void loadBinaryValue( void * data, size_t size, const char * name = nullptr )
455
- {
456
- setNextName( name );
457
- startNode();
458
-
459
- std::string encoded;
460
- loadValue( encoded );
461
-
462
- auto decoded = base64::decode( encoded );
463
-
464
- if( size != decoded.size() )
465
- throw Exception("Decoded binary data size does not match specified size");
466
-
467
- std::memcpy( data, decoded.data(), decoded.size() );
468
-
469
- finishNode();
470
- }
471
-
472
- //! @}
473
- /*! @name Internal Functionality
474
- Functionality designed for use by those requiring control over the inner mechanisms of
475
- the XMLInputArchive */
476
- //! @{
477
-
478
- //! Prepares to start reading the next node
479
- /*! This places the next node to be parsed onto the nodes stack.
480
-
481
- By default our strategy is to start with the document root node and then
482
- recursively iterate through all children in the order they show up in the document.
483
- We don't need to know NVPs do to this; we'll just blindly load in the order things appear in.
484
-
485
- We check to see if the specified NVP matches what the next automatically loaded node is. If they
486
- match, we just continue as normal, going in order. If they don't match, we attempt to find a node
487
- named after the NVP that is being loaded. If that NVP does not exist, we throw an exception. */
488
- void startNode()
489
- {
490
- auto next = itsNodes.top().child; // By default we would move to the next child node
491
- auto const expectedName = itsNodes.top().name; // this is the expected name from the NVP, if provided
492
-
493
- // If we were given an NVP name, look for it in the current level of the document.
494
- // We only need to do this if either we have exhausted the siblings of the current level or
495
- // the NVP name does not match the name of the node we would normally read next
496
- if( expectedName && ( next == nullptr || std::strcmp( next->name(), expectedName ) != 0 ) )
497
- {
498
- next = itsNodes.top().search( expectedName );
499
-
500
- if( next == nullptr )
501
- throw Exception("XML Parsing failed - provided NVP (" + std::string(expectedName) + ") not found");
502
- }
503
-
504
- itsNodes.emplace( next );
505
- }
506
-
507
- //! Finishes reading the current node
508
- void finishNode()
509
- {
510
- // remove current
511
- itsNodes.pop();
512
-
513
- // advance parent
514
- itsNodes.top().advance();
515
-
516
- // Reset name
517
- itsNodes.top().name = nullptr;
518
- }
519
-
520
- //! Retrieves the current node name
521
- //! will return @c nullptr if the node does not have a name
522
- const char * getNodeName() const
523
- {
524
- return itsNodes.top().getChildName();
525
- }
526
-
527
- //! Sets the name for the next node created with startNode
528
- void setNextName( const char * name )
529
- {
530
- itsNodes.top().name = name;
531
- }
532
-
533
- //! Loads a bool from the current top node
534
- template <class T, traits::EnableIf<std::is_unsigned<T>::value,
535
- std::is_same<T, bool>::value> = traits::sfinae> inline
536
- void loadValue( T & value )
537
- {
538
- std::istringstream is( itsNodes.top().node->value() );
539
- is.setf( std::ios::boolalpha );
540
- is >> value;
541
- }
542
-
543
- //! Loads a char (signed or unsigned) from the current top node
544
- template <class T, traits::EnableIf<std::is_integral<T>::value,
545
- !std::is_same<T, bool>::value,
546
- sizeof(T) == sizeof(char)> = traits::sfinae> inline
547
- void loadValue( T & value )
548
- {
549
- value = *reinterpret_cast<T*>( itsNodes.top().node->value() );
550
- }
551
-
552
- //! Load an int8_t from the current top node (ensures we parse entire number)
553
- void loadValue( int8_t & value )
554
- {
555
- int32_t val; loadValue( val ); value = static_cast<int8_t>( val );
556
- }
557
-
558
- //! Load a uint8_t from the current top node (ensures we parse entire number)
559
- void loadValue( uint8_t & value )
560
- {
561
- uint32_t val; loadValue( val ); value = static_cast<uint8_t>( val );
562
- }
563
-
564
- //! Loads a type best represented as an unsigned long from the current top node
565
- template <class T, traits::EnableIf<std::is_unsigned<T>::value,
566
- !std::is_same<T, bool>::value,
567
- !std::is_same<T, char>::value,
568
- !std::is_same<T, unsigned char>::value,
569
- sizeof(T) < sizeof(long long)> = traits::sfinae> inline
570
- void loadValue( T & value )
571
- {
572
- value = static_cast<T>( std::stoul( itsNodes.top().node->value() ) );
573
- }
574
-
575
- //! Loads a type best represented as an unsigned long long from the current top node
576
- template <class T, traits::EnableIf<std::is_unsigned<T>::value,
577
- !std::is_same<T, bool>::value,
578
- sizeof(T) >= sizeof(long long)> = traits::sfinae> inline
579
- void loadValue( T & value )
580
- {
581
- value = static_cast<T>( std::stoull( itsNodes.top().node->value() ) );
582
- }
583
-
584
- //! Loads a type best represented as an int from the current top node
585
- template <class T, traits::EnableIf<std::is_signed<T>::value,
586
- !std::is_same<T, char>::value,
587
- sizeof(T) <= sizeof(int)> = traits::sfinae> inline
588
- void loadValue( T & value )
589
- {
590
- value = static_cast<T>( std::stoi( itsNodes.top().node->value() ) );
591
- }
592
-
593
- //! Loads a type best represented as a long from the current top node
594
- template <class T, traits::EnableIf<std::is_signed<T>::value,
595
- (sizeof(T) > sizeof(int)),
596
- sizeof(T) <= sizeof(long)> = traits::sfinae> inline
597
- void loadValue( T & value )
598
- {
599
- value = static_cast<T>( std::stol( itsNodes.top().node->value() ) );
600
- }
601
-
602
- //! Loads a type best represented as a long long from the current top node
603
- template <class T, traits::EnableIf<std::is_signed<T>::value,
604
- (sizeof(T) > sizeof(long)),
605
- sizeof(T) <= sizeof(long long)> = traits::sfinae> inline
606
- void loadValue( T & value )
607
- {
608
- value = static_cast<T>( std::stoll( itsNodes.top().node->value() ) );
609
- }
610
-
611
- //! Loads a type best represented as a float from the current top node
612
- void loadValue( float & value )
613
- {
614
- try
615
- {
616
- value = std::stof( itsNodes.top().node->value() );
617
- }
618
- catch( std::out_of_range const & )
619
- {
620
- // special case for denormalized values
621
- std::istringstream is( itsNodes.top().node->value() );
622
- is >> value;
623
- if( std::fpclassify( value ) != FP_SUBNORMAL )
624
- throw;
625
- }
626
- }
627
-
628
- //! Loads a type best represented as a double from the current top node
629
- void loadValue( double & value )
630
- {
631
- try
632
- {
633
- value = std::stod( itsNodes.top().node->value() );
634
- }
635
- catch( std::out_of_range const & )
636
- {
637
- // special case for denormalized values
638
- std::istringstream is( itsNodes.top().node->value() );
639
- is >> value;
640
- if( std::fpclassify( value ) != FP_SUBNORMAL )
641
- throw;
642
- }
643
- }
644
-
645
- //! Loads a type best represented as a long double from the current top node
646
- void loadValue( long double & value )
647
- {
648
- try
649
- {
650
- value = std::stold( itsNodes.top().node->value() );
651
- }
652
- catch( std::out_of_range const & )
653
- {
654
- // special case for denormalized values
655
- std::istringstream is( itsNodes.top().node->value() );
656
- is >> value;
657
- if( std::fpclassify( value ) != FP_SUBNORMAL )
658
- throw;
659
- }
660
- }
661
-
662
- //! Loads a string from the current node from the current top node
663
- template<class CharT, class Traits, class Alloc> inline
664
- void loadValue( std::basic_string<CharT, Traits, Alloc> & str )
665
- {
666
- std::basic_istringstream<CharT, Traits> is( itsNodes.top().node->value() );
667
-
668
- str.assign( std::istreambuf_iterator<CharT, Traits>( is ),
669
- std::istreambuf_iterator<CharT, Traits>() );
670
- }
671
-
672
- //! Loads the size of the current top node
673
- template <class T> inline
674
- void loadSize( T & value )
675
- {
676
- value = getNumChildren( itsNodes.top().node );
677
- }
678
-
679
- protected:
680
- //! Gets the number of children (usually interpreted as size) for the specified node
681
- static size_t getNumChildren( rapidxml::xml_node<> * node )
682
- {
683
- size_t size = 0;
684
- node = node->first_node(); // get first child
685
-
686
- while( node != nullptr )
687
- {
688
- ++size;
689
- node = node->next_sibling();
690
- }
691
-
692
- return size;
693
- }
694
-
695
- //! A struct that contains metadata about a node
696
- /*! Keeps track of some top level node, its number of
697
- remaining children, and the current active child node */
698
- struct NodeInfo
699
- {
700
- NodeInfo( rapidxml::xml_node<> * n = nullptr ) :
701
- node( n ),
702
- child( n->first_node() ),
703
- size( XMLInputArchive::getNumChildren( n ) ),
704
- name( nullptr )
705
- { }
706
-
707
- //! Advances to the next sibling node of the child
708
- /*! If this is the last sibling child will be null after calling */
709
- void advance()
710
- {
711
- if( size > 0 )
712
- {
713
- --size;
714
- child = child->next_sibling();
715
- }
716
- }
717
-
718
- //! Searches for a child with the given name in this node
719
- /*! @param searchName The name to search for (must be null terminated)
720
- @return The node if found, nullptr otherwise */
721
- rapidxml::xml_node<> * search( const char * searchName )
722
- {
723
- if( searchName )
724
- {
725
- size_t new_size = XMLInputArchive::getNumChildren( node );
726
- const size_t name_size = rapidxml::internal::measure( searchName );
727
-
728
- for( auto new_child = node->first_node(); new_child != nullptr; new_child = new_child->next_sibling() )
729
- {
730
- if( rapidxml::internal::compare( new_child->name(), new_child->name_size(), searchName, name_size, true ) )
731
- {
732
- size = new_size;
733
- child = new_child;
734
-
735
- return new_child;
736
- }
737
- --new_size;
738
- }
739
- }
740
-
741
- return nullptr;
742
- }
743
-
744
- //! Returns the actual name of the next child node, if it exists
745
- const char * getChildName() const
746
- {
747
- return child ? child->name() : nullptr;
748
- }
749
-
750
- rapidxml::xml_node<> * node; //!< A pointer to this node
751
- rapidxml::xml_node<> * child; //!< A pointer to its current child
752
- size_t size; //!< The remaining number of children for this node
753
- const char * name; //!< The NVP name for next child node
754
- }; // NodeInfo
755
-
756
- //! @}
757
-
758
- private:
759
- std::vector<char> itsData; //!< The raw data loaded
760
- rapidxml::xml_document<> itsXML; //!< The XML document
761
- std::stack<NodeInfo> itsNodes; //!< A stack of nodes read from the document
762
- };
763
-
764
- // ######################################################################
765
- // XMLArchive prologue and epilogue functions
766
- // ######################################################################
767
-
768
- // ######################################################################
769
- //! Prologue for NVPs for XML output archives
770
- /*! NVPs do not start or finish nodes - they just set up the names */
771
- template <class T> inline
772
- void prologue( XMLOutputArchive &, NameValuePair<T> const & )
773
- { }
774
-
775
- //! Prologue for NVPs for XML input archives
776
- template <class T> inline
777
- void prologue( XMLInputArchive &, NameValuePair<T> const & )
778
- { }
779
-
780
- // ######################################################################
781
- //! Epilogue for NVPs for XML output archives
782
- /*! NVPs do not start or finish nodes - they just set up the names */
783
- template <class T> inline
784
- void epilogue( XMLOutputArchive &, NameValuePair<T> const & )
785
- { }
786
-
787
- //! Epilogue for NVPs for XML input archives
788
- template <class T> inline
789
- void epilogue( XMLInputArchive &, NameValuePair<T> const & )
790
- { }
791
-
792
- // ######################################################################
793
- //! Prologue for deferred data for XML archives
794
- /*! Do nothing for the defer wrapper */
795
- template <class T> inline
796
- void prologue( XMLOutputArchive &, DeferredData<T> const & )
797
- { }
798
-
799
- //! Prologue for deferred data for XML archives
800
- template <class T> inline
801
- void prologue( XMLInputArchive &, DeferredData<T> const & )
802
- { }
803
-
804
- // ######################################################################
805
- //! Epilogue for deferred for XML archives
806
- /*! NVPs do not start or finish nodes - they just set up the names */
807
- template <class T> inline
808
- void epilogue( XMLOutputArchive &, DeferredData<T> const & )
809
- { }
810
-
811
- //! Epilogue for deferred for XML archives
812
- /*! Do nothing for the defer wrapper */
813
- template <class T> inline
814
- void epilogue( XMLInputArchive &, DeferredData<T> const & )
815
- { }
816
-
817
- // ######################################################################
818
- //! Prologue for SizeTags for XML output archives
819
- /*! SizeTags do not start or finish nodes */
820
- template <class T> inline
821
- void prologue( XMLOutputArchive & ar, SizeTag<T> const & )
822
- {
823
- if (ar.hasSizeAttributes())
824
- {
825
- ar.appendAttribute("size", "dynamic");
826
- }
827
- }
828
-
829
- template <class T> inline
830
- void prologue( XMLInputArchive &, SizeTag<T> const & )
831
- { }
832
-
833
- //! Epilogue for SizeTags for XML output archives
834
- /*! SizeTags do not start or finish nodes */
835
- template <class T> inline
836
- void epilogue( XMLOutputArchive &, SizeTag<T> const & )
837
- { }
838
-
839
- template <class T> inline
840
- void epilogue( XMLInputArchive &, SizeTag<T> const & )
841
- { }
842
-
843
- // ######################################################################
844
- //! Prologue for all other types for XML output archives (except minimal types)
845
- /*! Starts a new node, named either automatically or by some NVP,
846
- that may be given data by the type about to be archived
847
-
848
- Minimal types do not start or end nodes */
849
- template <class T, traits::DisableIf<traits::has_minimal_base_class_serialization<T, traits::has_minimal_output_serialization, XMLOutputArchive>::value ||
850
- traits::has_minimal_output_serialization<T, XMLOutputArchive>::value> = traits::sfinae> inline
851
- void prologue( XMLOutputArchive & ar, T const & )
852
- {
853
- ar.startNode();
854
- ar.insertType<T>();
855
- }
856
-
857
- //! Prologue for all other types for XML input archives (except minimal types)
858
- template <class T, traits::DisableIf<traits::has_minimal_base_class_serialization<T, traits::has_minimal_input_serialization, XMLInputArchive>::value ||
859
- traits::has_minimal_input_serialization<T, XMLInputArchive>::value> = traits::sfinae> inline
860
- void prologue( XMLInputArchive & ar, T const & )
861
- {
862
- ar.startNode();
863
- }
864
-
865
- // ######################################################################
866
- //! Epilogue for all other types other for XML output archives (except minimal types)
867
- /*! Finishes the node created in the prologue
868
-
869
- Minimal types do not start or end nodes */
870
- template <class T, traits::DisableIf<traits::has_minimal_base_class_serialization<T, traits::has_minimal_output_serialization, XMLOutputArchive>::value ||
871
- traits::has_minimal_output_serialization<T, XMLOutputArchive>::value> = traits::sfinae> inline
872
- void epilogue( XMLOutputArchive & ar, T const & )
873
- {
874
- ar.finishNode();
875
- }
876
-
877
- //! Epilogue for all other types other for XML output archives (except minimal types)
878
- template <class T, traits::DisableIf<traits::has_minimal_base_class_serialization<T, traits::has_minimal_input_serialization, XMLInputArchive>::value ||
879
- traits::has_minimal_input_serialization<T, XMLInputArchive>::value> = traits::sfinae> inline
880
- void epilogue( XMLInputArchive & ar, T const & )
881
- {
882
- ar.finishNode();
883
- }
884
-
885
- // ######################################################################
886
- // Common XMLArchive serialization functions
887
- // ######################################################################
888
-
889
- //! Saving NVP types to XML
890
- template <class T> inline
891
- void CEREAL_SAVE_FUNCTION_NAME( XMLOutputArchive & ar, NameValuePair<T> const & t )
892
- {
893
- ar.setNextName( t.name );
894
- ar( t.value );
895
- }
896
-
897
- //! Loading NVP types from XML
898
- template <class T> inline
899
- void CEREAL_LOAD_FUNCTION_NAME( XMLInputArchive & ar, NameValuePair<T> & t )
900
- {
901
- ar.setNextName( t.name );
902
- ar( t.value );
903
- }
904
-
905
- // ######################################################################
906
- //! Saving SizeTags to XML
907
- template <class T> inline
908
- void CEREAL_SAVE_FUNCTION_NAME( XMLOutputArchive &, SizeTag<T> const & )
909
- { }
910
-
911
- //! Loading SizeTags from XML
912
- template <class T> inline
913
- void CEREAL_LOAD_FUNCTION_NAME( XMLInputArchive & ar, SizeTag<T> & st )
914
- {
915
- ar.loadSize( st.size );
916
- }
917
-
918
- // ######################################################################
919
- //! Saving for POD types to xml
920
- template <class T, traits::EnableIf<std::is_arithmetic<T>::value> = traits::sfinae> inline
921
- void CEREAL_SAVE_FUNCTION_NAME(XMLOutputArchive & ar, T const & t)
922
- {
923
- ar.saveValue( t );
924
- }
925
-
926
- //! Loading for POD types from xml
927
- template <class T, traits::EnableIf<std::is_arithmetic<T>::value> = traits::sfinae> inline
928
- void CEREAL_LOAD_FUNCTION_NAME(XMLInputArchive & ar, T & t)
929
- {
930
- ar.loadValue( t );
931
- }
932
-
933
- // ######################################################################
934
- //! saving string to xml
935
- template<class CharT, class Traits, class Alloc> inline
936
- void CEREAL_SAVE_FUNCTION_NAME(XMLOutputArchive & ar, std::basic_string<CharT, Traits, Alloc> const & str)
937
- {
938
- ar.saveValue( str );
939
- }
940
-
941
- //! loading string from xml
942
- template<class CharT, class Traits, class Alloc> inline
943
- void CEREAL_LOAD_FUNCTION_NAME(XMLInputArchive & ar, std::basic_string<CharT, Traits, Alloc> & str)
944
- {
945
- ar.loadValue( str );
946
- }
947
- } // namespace cereal
948
-
949
- // register archives for polymorphic support
950
- CEREAL_REGISTER_ARCHIVE(cereal::XMLOutputArchive)
951
- CEREAL_REGISTER_ARCHIVE(cereal::XMLInputArchive)
952
-
953
- // tie input and output archives together
954
- CEREAL_SETUP_ARCHIVE_TRAITS(cereal::XMLInputArchive, cereal::XMLOutputArchive)
955
-
956
- #endif // CEREAL_ARCHIVES_XML_HPP_