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,1411 +0,0 @@
1
- /*! \file traits.hpp
2
- \brief Internal type trait support
3
- \ingroup Internal */
4
- /*
5
- Copyright (c) 2014, Randolph Voorhies, Shane Grant
6
- All rights reserved.
7
-
8
- Redistribution and use in source and binary forms, with or without
9
- modification, are permitted provided that the following conditions are met:
10
- * Redistributions of source code must retain the above copyright
11
- notice, this list of conditions and the following disclaimer.
12
- * Redistributions in binary form must reproduce the above copyright
13
- notice, this list of conditions and the following disclaimer in the
14
- documentation and/or other materials provided with the distribution.
15
- * Neither the name of cereal nor the
16
- names of its contributors may be used to endorse or promote products
17
- derived from this software without specific prior written permission.
18
-
19
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
- DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
23
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
- */
30
- #ifndef CEREAL_DETAILS_TRAITS_HPP_
31
- #define CEREAL_DETAILS_TRAITS_HPP_
32
-
33
- #ifndef __clang__
34
- #if (__GNUC__ == 4 && __GNUC_MINOR__ <= 7)
35
- #define CEREAL_OLDER_GCC
36
- #endif // gcc 4.7 or earlier
37
- #endif // __clang__
38
-
39
- #include <type_traits>
40
- #include <typeindex>
41
-
42
- #include "cereal/macros.hpp"
43
- #include "cereal/access.hpp"
44
-
45
- namespace cereal
46
- {
47
- namespace traits
48
- {
49
- using yes = std::true_type;
50
- using no = std::false_type;
51
-
52
- namespace detail
53
- {
54
- // ######################################################################
55
- //! Used to delay a static_assert until template instantiation
56
- template <class T>
57
- struct delay_static_assert : std::false_type {};
58
-
59
- // ######################################################################
60
- // SFINAE Helpers
61
- #ifdef CEREAL_OLDER_GCC // when VS supports better SFINAE, we can use this as the default
62
- template<typename> struct Void { typedef void type; };
63
- #endif // CEREAL_OLDER_GCC
64
-
65
- //! Return type for SFINAE Enablers
66
- enum class sfinae {};
67
-
68
- // ######################################################################
69
- // Helper functionality for boolean integral constants and Enable/DisableIf
70
- template <bool H, bool ... T> struct meta_bool_and : std::integral_constant<bool, H && meta_bool_and<T...>::value> {};
71
- template <bool B> struct meta_bool_and<B> : std::integral_constant<bool, B> {};
72
-
73
- template <bool H, bool ... T> struct meta_bool_or : std::integral_constant<bool, H || meta_bool_or<T...>::value> {};
74
- template <bool B> struct meta_bool_or<B> : std::integral_constant<bool, B> {};
75
-
76
- // workaround needed due to bug in MSVC 2013, see
77
- // http://connect.microsoft.com/VisualStudio/feedback/details/800231/c-11-alias-template-issue
78
- template <bool ... Conditions>
79
- struct EnableIfHelper : std::enable_if<meta_bool_and<Conditions...>::value, sfinae> {};
80
-
81
- template <bool ... Conditions>
82
- struct DisableIfHelper : std::enable_if<!meta_bool_or<Conditions...>::value, sfinae> {};
83
- } // namespace detail
84
-
85
- //! Used as the default value for EnableIf and DisableIf template parameters
86
- /*! @relates EnableIf
87
- @relates DisableIf */
88
- static const detail::sfinae sfinae = {};
89
-
90
- // ######################################################################
91
- //! Provides a way to enable a function if conditions are met
92
- /*! This is intended to be used in a near identical fashion to std::enable_if
93
- while being significantly easier to read at the cost of not allowing for as
94
- complicated of a condition.
95
-
96
- This will compile (allow the function) if every condition evaluates to true.
97
- at compile time. This should be used with SFINAE to ensure that at least
98
- one other candidate function works when one fails due to an EnableIf.
99
-
100
- This should be used as the las template parameter to a function as
101
- an unnamed parameter with a default value of cereal::traits::sfinae:
102
-
103
- @code{cpp}
104
- // using by making the last template argument variadic
105
- template <class T, EnableIf<std::is_same<T, bool>::value> = sfinae>
106
- void func(T t );
107
- @endcode
108
-
109
- Note that this performs a logical AND of all conditions, so you will need
110
- to construct more complicated requirements with this fact in mind.
111
-
112
- @relates DisableIf
113
- @relates sfinae
114
- @tparam Conditions The conditions which will be logically ANDed to enable the function. */
115
- template <bool ... Conditions>
116
- using EnableIf = typename detail::EnableIfHelper<Conditions...>::type;
117
-
118
- // ######################################################################
119
- //! Provides a way to disable a function if conditions are met
120
- /*! This is intended to be used in a near identical fashion to std::enable_if
121
- while being significantly easier to read at the cost of not allowing for as
122
- complicated of a condition.
123
-
124
- This will compile (allow the function) if every condition evaluates to false.
125
- This should be used with SFINAE to ensure that at least one other candidate
126
- function works when one fails due to a DisableIf.
127
-
128
- This should be used as the las template parameter to a function as
129
- an unnamed parameter with a default value of cereal::traits::sfinae:
130
-
131
- @code{cpp}
132
- // using by making the last template argument variadic
133
- template <class T, DisableIf<std::is_same<T, bool>::value> = sfinae>
134
- void func(T t );
135
- @endcode
136
-
137
- This is often used in conjunction with EnableIf to form an enable/disable pair of
138
- overloads.
139
-
140
- Note that this performs a logical AND of all conditions, so you will need
141
- to construct more complicated requirements with this fact in mind. If all conditions
142
- hold, the function will be disabled.
143
-
144
- @relates EnableIf
145
- @relates sfinae
146
- @tparam Conditions The conditions which will be logically ANDed to disable the function. */
147
- template <bool ... Conditions>
148
- using DisableIf = typename detail::DisableIfHelper<Conditions...>::type;
149
-
150
- // ######################################################################
151
- namespace detail
152
- {
153
- template <class InputArchive>
154
- struct get_output_from_input : no
155
- {
156
- static_assert( detail::delay_static_assert<InputArchive>::value,
157
- "Could not find an associated output archive for input archive." );
158
- };
159
-
160
- template <class OutputArchive>
161
- struct get_input_from_output : no
162
- {
163
- static_assert( detail::delay_static_assert<OutputArchive>::value,
164
- "Could not find an associated input archive for output archive." );
165
- };
166
- }
167
-
168
- //! Sets up traits that relate an input archive to an output archive
169
- #define CEREAL_SETUP_ARCHIVE_TRAITS(InputArchive, OutputArchive) \
170
- namespace cereal { namespace traits { namespace detail { \
171
- template <> struct get_output_from_input<InputArchive> \
172
- { using type = OutputArchive; }; \
173
- template <> struct get_input_from_output<OutputArchive> \
174
- { using type = InputArchive; }; } } } /* end namespaces */
175
-
176
- // ######################################################################
177
- //! Used to convert a MAKE_HAS_XXX macro into a versioned variant
178
- #define CEREAL_MAKE_VERSIONED_TEST ,0
179
-
180
- // ######################################################################
181
- //! Creates a test for whether a non const member function exists
182
- /*! This creates a class derived from std::integral_constant that will be true if
183
- the type has the proper member function for the given archive.
184
-
185
- @param name The name of the function to test for (e.g. serialize, load, save)
186
- @param test_name The name to give the test for the function being tested for (e.g. serialize, versioned_serialize)
187
- @param versioned Either blank or the macro CEREAL_MAKE_VERSIONED_TEST */
188
- #ifdef CEREAL_OLDER_GCC
189
- #define CEREAL_MAKE_HAS_MEMBER_TEST(name, test_name, versioned) \
190
- template <class T, class A, class SFINAE = void> \
191
- struct has_member_##test_name : no {}; \
192
- template <class T, class A> \
193
- struct has_member_##test_name<T, A, \
194
- typename detail::Void< decltype( cereal::access::member_##name( std::declval<A&>(), std::declval<T&>() versioned ) ) >::type> : yes {}
195
- #else // NOT CEREAL_OLDER_GCC
196
- #define CEREAL_MAKE_HAS_MEMBER_TEST(name, test_name, versioned) \
197
- namespace detail \
198
- { \
199
- template <class T, class A> \
200
- struct has_member_##name##_##versioned##_impl \
201
- { \
202
- template <class TT, class AA> \
203
- static auto test(int) -> decltype( cereal::access::member_##name( std::declval<AA&>(), std::declval<TT&>() versioned ), yes()); \
204
- template <class, class> \
205
- static no test(...); \
206
- static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \
207
- }; \
208
- } /* end namespace detail */ \
209
- template <class T, class A> \
210
- struct has_member_##test_name : std::integral_constant<bool, detail::has_member_##name##_##versioned##_impl<T, A>::value> {}
211
- #endif // NOT CEREAL_OLDER_GCC
212
-
213
- // ######################################################################
214
- //! Creates a test for whether a non const non-member function exists
215
- /*! This creates a class derived from std::integral_constant that will be true if
216
- the type has the proper non-member function for the given archive. */
217
- #define CEREAL_MAKE_HAS_NON_MEMBER_TEST(test_name, func, versioned) \
218
- namespace detail \
219
- { \
220
- template <class T, class A> \
221
- struct has_non_member_##test_name##_impl \
222
- { \
223
- template <class TT, class AA> \
224
- static auto test(int) -> decltype( func( std::declval<AA&>(), std::declval<TT&>() versioned ), yes()); \
225
- template <class, class> \
226
- static no test( ... ); \
227
- static const bool value = std::is_same<decltype( test<T, A>( 0 ) ), yes>::value; \
228
- }; \
229
- } /* end namespace detail */ \
230
- template <class T, class A> \
231
- struct has_non_member_##test_name : std::integral_constant<bool, detail::has_non_member_##test_name##_impl<T, A>::value> {}
232
-
233
- // ######################################################################
234
- // Member Serialize
235
- CEREAL_MAKE_HAS_MEMBER_TEST(serialize, serialize,);
236
-
237
- // ######################################################################
238
- // Member Serialize (versioned)
239
- CEREAL_MAKE_HAS_MEMBER_TEST(serialize, versioned_serialize, CEREAL_MAKE_VERSIONED_TEST);
240
-
241
- // ######################################################################
242
- // Non Member Serialize
243
- CEREAL_MAKE_HAS_NON_MEMBER_TEST(serialize, CEREAL_SERIALIZE_FUNCTION_NAME,);
244
-
245
- // ######################################################################
246
- // Non Member Serialize (versioned)
247
- CEREAL_MAKE_HAS_NON_MEMBER_TEST(versioned_serialize, CEREAL_SERIALIZE_FUNCTION_NAME, CEREAL_MAKE_VERSIONED_TEST);
248
-
249
- // ######################################################################
250
- // Member Load
251
- CEREAL_MAKE_HAS_MEMBER_TEST(load, load,);
252
-
253
- // ######################################################################
254
- // Member Load (versioned)
255
- CEREAL_MAKE_HAS_MEMBER_TEST(load, versioned_load, CEREAL_MAKE_VERSIONED_TEST);
256
-
257
- // ######################################################################
258
- // Non Member Load
259
- CEREAL_MAKE_HAS_NON_MEMBER_TEST(load, CEREAL_LOAD_FUNCTION_NAME,);
260
-
261
- // ######################################################################
262
- // Non Member Load (versioned)
263
- CEREAL_MAKE_HAS_NON_MEMBER_TEST(versioned_load, CEREAL_LOAD_FUNCTION_NAME, CEREAL_MAKE_VERSIONED_TEST);
264
-
265
- // ######################################################################
266
- #undef CEREAL_MAKE_HAS_NON_MEMBER_TEST
267
- #undef CEREAL_MAKE_HAS_MEMBER_TEST
268
-
269
- // ######################################################################
270
- //! Creates a test for whether a member save function exists
271
- /*! This creates a class derived from std::integral_constant that will be true if
272
- the type has the proper member function for the given archive.
273
-
274
- @param test_name The name to give the test (e.g. save or versioned_save)
275
- @param versioned Either blank or the macro CEREAL_MAKE_VERSIONED_TEST */
276
- #ifdef CEREAL_OLDER_GCC
277
- #define CEREAL_MAKE_HAS_MEMBER_SAVE_IMPL(test_name, versioned) \
278
- namespace detail \
279
- { \
280
- template <class T, class A> \
281
- struct has_member_##test_name##_impl \
282
- { \
283
- template <class TT, class AA, class SFINAE = void> struct test : no {}; \
284
- template <class TT, class AA> \
285
- struct test<TT, AA, \
286
- typename detail::Void< decltype( cereal::access::member_save( std::declval<AA&>(), \
287
- std::declval<TT const &>() versioned ) ) >::type> : yes {}; \
288
- static const bool value = test<T, A>(); \
289
- \
290
- template <class TT, class AA, class SFINAE = void> struct test2 : no {}; \
291
- template <class TT, class AA> \
292
- struct test2<TT, AA, \
293
- typename detail::Void< decltype( cereal::access::member_save_non_const( \
294
- std::declval<AA&>(), \
295
- std::declval<typename std::remove_const<TT>::type&>() versioned ) ) >::type> : yes {}; \
296
- static const bool not_const_type = test2<T, A>(); \
297
- }; \
298
- } /* end namespace detail */
299
- #else /* NOT CEREAL_OLDER_GCC =================================== */
300
- #define CEREAL_MAKE_HAS_MEMBER_SAVE_IMPL(test_name, versioned) \
301
- namespace detail \
302
- { \
303
- template <class T, class A> \
304
- struct has_member_##test_name##_impl \
305
- { \
306
- template <class TT, class AA> \
307
- static auto test(int) -> decltype( cereal::access::member_save( std::declval<AA&>(), \
308
- std::declval<TT const &>() versioned ), yes()); \
309
- template <class, class> static no test(...); \
310
- static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \
311
- \
312
- template <class TT, class AA> \
313
- static auto test2(int) -> decltype( cereal::access::member_save_non_const( \
314
- std::declval<AA &>(), \
315
- std::declval<typename std::remove_const<TT>::type&>() versioned ), yes()); \
316
- template <class, class> static no test2(...); \
317
- static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value; \
318
- }; \
319
- } /* end namespace detail */
320
- #endif /* NOT CEREAL_OLDER_GCC */
321
-
322
- // ######################################################################
323
- // Member Save
324
- CEREAL_MAKE_HAS_MEMBER_SAVE_IMPL(save, )
325
-
326
- template <class T, class A>
327
- struct has_member_save : std::integral_constant<bool, detail::has_member_save_impl<T, A>::value>
328
- {
329
- typedef typename detail::has_member_save_impl<T, A> check;
330
- static_assert( check::value || !check::not_const_type,
331
- "cereal detected a non-const save. \n "
332
- "save member functions must always be const" );
333
- };
334
-
335
- // ######################################################################
336
- // Member Save (versioned)
337
- CEREAL_MAKE_HAS_MEMBER_SAVE_IMPL(versioned_save, CEREAL_MAKE_VERSIONED_TEST)
338
-
339
- template <class T, class A>
340
- struct has_member_versioned_save : std::integral_constant<bool, detail::has_member_versioned_save_impl<T, A>::value>
341
- {
342
- typedef typename detail::has_member_versioned_save_impl<T, A> check;
343
- static_assert( check::value || !check::not_const_type,
344
- "cereal detected a versioned non-const save. \n "
345
- "save member functions must always be const" );
346
- };
347
-
348
- // ######################################################################
349
- #undef CEREAL_MAKE_HAS_MEMBER_SAVE_IMPL
350
-
351
- // ######################################################################
352
- //! Creates a test for whether a non-member save function exists
353
- /*! This creates a class derived from std::integral_constant that will be true if
354
- the type has the proper non-member function for the given archive.
355
-
356
- @param test_name The name to give the test (e.g. save or versioned_save)
357
- @param versioned Either blank or the macro CEREAL_MAKE_VERSIONED_TEST */
358
- #define CEREAL_MAKE_HAS_NON_MEMBER_SAVE_TEST(test_name, versioned) \
359
- namespace detail \
360
- { \
361
- template <class T, class A> \
362
- struct has_non_member_##test_name##_impl \
363
- { \
364
- template <class TT, class AA> \
365
- static auto test(int) -> decltype( CEREAL_SAVE_FUNCTION_NAME( \
366
- std::declval<AA&>(), \
367
- std::declval<TT const &>() versioned ), yes()); \
368
- template <class, class> static no test(...); \
369
- static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \
370
- \
371
- template <class TT, class AA> \
372
- static auto test2(int) -> decltype( CEREAL_SAVE_FUNCTION_NAME( \
373
- std::declval<AA &>(), \
374
- std::declval<typename std::remove_const<TT>::type&>() versioned ), yes()); \
375
- template <class, class> static no test2(...); \
376
- static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value; \
377
- }; \
378
- } /* end namespace detail */ \
379
- \
380
- template <class T, class A> \
381
- struct has_non_member_##test_name : std::integral_constant<bool, detail::has_non_member_##test_name##_impl<T, A>::value> \
382
- { \
383
- using check = typename detail::has_non_member_##test_name##_impl<T, A>; \
384
- static_assert( check::value || !check::not_const_type, \
385
- "cereal detected a non-const type parameter in non-member " #test_name ". \n " \
386
- #test_name " non-member functions must always pass their types as const" ); \
387
- };
388
-
389
- // ######################################################################
390
- // Non Member Save
391
- CEREAL_MAKE_HAS_NON_MEMBER_SAVE_TEST(save, )
392
-
393
- // ######################################################################
394
- // Non Member Save (versioned)
395
- CEREAL_MAKE_HAS_NON_MEMBER_SAVE_TEST(versioned_save, CEREAL_MAKE_VERSIONED_TEST)
396
-
397
- // ######################################################################
398
- #undef CEREAL_MAKE_HAS_NON_MEMBER_SAVE_TEST
399
-
400
- // ######################################################################
401
- // Minimal Utilities
402
- namespace detail
403
- {
404
- // Determines if the provided type is an std::string
405
- template <class> struct is_string : std::false_type {};
406
-
407
- template <class CharT, class Traits, class Alloc>
408
- struct is_string<std::basic_string<CharT, Traits, Alloc>> : std::true_type {};
409
- }
410
-
411
- // Determines if the type is valid for use with a minimal serialize function
412
- template <class T>
413
- struct is_minimal_type : std::integral_constant<bool,
414
- detail::is_string<T>::value || std::is_arithmetic<T>::value> {};
415
-
416
- // ######################################################################
417
- //! Creates implementation details for whether a member save_minimal function exists
418
- /*! This creates a class derived from std::integral_constant that will be true if
419
- the type has the proper member function for the given archive.
420
-
421
- @param test_name The name to give the test (e.g. save_minimal or versioned_save_minimal)
422
- @param versioned Either blank or the macro CEREAL_MAKE_VERSIONED_TEST */
423
- #ifdef CEREAL_OLDER_GCC
424
- #define CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_IMPL(test_name, versioned) \
425
- namespace detail \
426
- { \
427
- template <class T, class A> \
428
- struct has_member_##test_name##_impl \
429
- { \
430
- template <class TT, class AA, class SFINAE = void> struct test : no {}; \
431
- template <class TT, class AA> \
432
- struct test<TT, AA, typename detail::Void< decltype( \
433
- cereal::access::member_save_minimal( std::declval<AA const &>(), \
434
- std::declval<TT const &>() versioned ) ) >::type> : yes {}; \
435
- \
436
- static const bool value = test<T, A>(); \
437
- \
438
- template <class TT, class AA, class SFINAE = void> struct test2 : no {}; \
439
- template <class TT, class AA> \
440
- struct test2<TT, AA, typename detail::Void< decltype( \
441
- cereal::access::member_save_minimal_non_const( std::declval<AA const &>(), \
442
- std::declval<typename std::remove_const<TT>::type&>() versioned ) ) >::type> : yes {}; \
443
- static const bool not_const_type = test2<T, A>(); \
444
- \
445
- static const bool valid = value || !not_const_type; \
446
- }; \
447
- } /* end namespace detail */
448
- #else /* NOT CEREAL_OLDER_GCC =================================== */
449
- #define CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_IMPL(test_name, versioned) \
450
- namespace detail \
451
- { \
452
- template <class T, class A> \
453
- struct has_member_##test_name##_impl \
454
- { \
455
- template <class TT, class AA> \
456
- static auto test(int) -> decltype( cereal::access::member_save_minimal( \
457
- std::declval<AA const &>(), \
458
- std::declval<TT const &>() versioned ), yes()); \
459
- template <class, class> static no test(...); \
460
- static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \
461
- \
462
- template <class TT, class AA> \
463
- static auto test2(int) -> decltype( cereal::access::member_save_minimal_non_const( \
464
- std::declval<AA const &>(), \
465
- std::declval<typename std::remove_const<TT>::type&>() versioned ), yes()); \
466
- template <class, class> static no test2(...); \
467
- static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value; \
468
- \
469
- static const bool valid = value || !not_const_type; \
470
- }; \
471
- } /* end namespace detail */
472
- #endif // NOT CEREAL_OLDER_GCC
473
-
474
- // ######################################################################
475
- //! Creates helpers for minimal save functions
476
- /*! The get_member_*_type structs allow access to the return type of a save_minimal,
477
- assuming that the function actually exists. If the function does not
478
- exist, the type will be void.
479
-
480
- @param test_name The name to give the test (e.g. save_minimal or versioned_save_minimal)
481
- @param versioned Either blank or the macro CEREAL_MAKE_VERSIONED_TEST */
482
- #define CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_HELPERS_IMPL(test_name, versioned) \
483
- namespace detail \
484
- { \
485
- template <class T, class A, bool Valid> \
486
- struct get_member_##test_name##_type { using type = void; }; \
487
- \
488
- template <class T, class A> \
489
- struct get_member_##test_name##_type<T, A, true> \
490
- { \
491
- using type = decltype( cereal::access::member_save_minimal( std::declval<A const &>(), \
492
- std::declval<T const &>() versioned ) ); \
493
- }; \
494
- } /* end namespace detail */
495
-
496
- // ######################################################################
497
- //! Creates a test for whether a member save_minimal function exists
498
- /*! This creates a class derived from std::integral_constant that will be true if
499
- the type has the proper member function for the given archive.
500
-
501
- @param test_name The name to give the test (e.g. save_minimal or versioned_save_minimal) */
502
- #define CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_TEST(test_name) \
503
- template <class T, class A> \
504
- struct has_member_##test_name : std::integral_constant<bool, detail::has_member_##test_name##_impl<T, A>::value> \
505
- { \
506
- using check = typename detail::has_member_##test_name##_impl<T, A>; \
507
- static_assert( check::valid, \
508
- "cereal detected a non-const member " #test_name ". \n " \
509
- #test_name " member functions must always be const" ); \
510
- \
511
- using type = typename detail::get_member_##test_name##_type<T, A, check::value>::type; \
512
- static_assert( (check::value && is_minimal_type<type>::value) || !check::value, \
513
- "cereal detected a member " #test_name " with an invalid return type. \n " \
514
- "return type must be arithmetic or string" ); \
515
- };
516
-
517
- // ######################################################################
518
- // Member Save Minimal
519
- CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_IMPL(save_minimal, )
520
- CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_HELPERS_IMPL(save_minimal, )
521
- CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_TEST(save_minimal)
522
-
523
- // ######################################################################
524
- // Member Save Minimal (versioned)
525
- CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_IMPL(versioned_save_minimal, CEREAL_MAKE_VERSIONED_TEST)
526
- CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_HELPERS_IMPL(versioned_save_minimal, CEREAL_MAKE_VERSIONED_TEST)
527
- CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_TEST(versioned_save_minimal)
528
-
529
- // ######################################################################
530
- #undef CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_IMPL
531
- #undef CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_HELPERS_IMPL
532
- #undef CEREAL_MAKE_HAS_MEMBER_SAVE_MINIMAL_TEST
533
-
534
- // ######################################################################
535
- //! Creates a test for whether a non-member save_minimal function exists
536
- /*! This creates a class derived from std::integral_constant that will be true if
537
- the type has the proper member function for the given archive.
538
-
539
- @param test_name The name to give the test (e.g. save_minimal or versioned_save_minimal)
540
- @param versioned Either blank or the macro CEREAL_MAKE_VERSIONED_TEST */
541
- #define CEREAL_MAKE_HAS_NON_MEMBER_SAVE_MINIMAL_TEST(test_name, versioned) \
542
- namespace detail \
543
- { \
544
- template <class T, class A> \
545
- struct has_non_member_##test_name##_impl \
546
- { \
547
- template <class TT, class AA> \
548
- static auto test(int) -> decltype( CEREAL_SAVE_MINIMAL_FUNCTION_NAME( \
549
- std::declval<AA const &>(), \
550
- std::declval<TT const &>() versioned ), yes()); \
551
- template <class, class> static no test(...); \
552
- static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \
553
- \
554
- template <class TT, class AA> \
555
- static auto test2(int) -> decltype( CEREAL_SAVE_MINIMAL_FUNCTION_NAME( \
556
- std::declval<AA const &>(), \
557
- std::declval<typename std::remove_const<TT>::type&>() versioned ), yes()); \
558
- template <class, class> static no test2(...); \
559
- static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value; \
560
- \
561
- static const bool valid = value || !not_const_type; \
562
- }; \
563
- \
564
- template <class T, class A, bool Valid> \
565
- struct get_non_member_##test_name##_type { using type = void; }; \
566
- \
567
- template <class T, class A> \
568
- struct get_non_member_##test_name##_type <T, A, true> \
569
- { \
570
- using type = decltype( CEREAL_SAVE_MINIMAL_FUNCTION_NAME( std::declval<A const &>(), \
571
- std::declval<T const &>() versioned ) ); \
572
- }; \
573
- } /* end namespace detail */ \
574
- \
575
- template <class T, class A> \
576
- struct has_non_member_##test_name : std::integral_constant<bool, detail::has_non_member_##test_name##_impl<T, A>::value> \
577
- { \
578
- using check = typename detail::has_non_member_##test_name##_impl<T, A>; \
579
- static_assert( check::valid, \
580
- "cereal detected a non-const type parameter in non-member " #test_name ". \n " \
581
- #test_name " non-member functions must always pass their types as const" ); \
582
- \
583
- using type = typename detail::get_non_member_##test_name##_type<T, A, check::value>::type; \
584
- static_assert( (check::value && is_minimal_type<type>::value) || !check::value, \
585
- "cereal detected a non-member " #test_name " with an invalid return type. \n " \
586
- "return type must be arithmetic or string" ); \
587
- };
588
-
589
- // ######################################################################
590
- // Non-Member Save Minimal
591
- CEREAL_MAKE_HAS_NON_MEMBER_SAVE_MINIMAL_TEST(save_minimal, )
592
-
593
- // ######################################################################
594
- // Non-Member Save Minimal (versioned)
595
- CEREAL_MAKE_HAS_NON_MEMBER_SAVE_MINIMAL_TEST(versioned_save_minimal, CEREAL_MAKE_VERSIONED_TEST)
596
-
597
- // ######################################################################
598
- #undef CEREAL_MAKE_HAS_NON_MEMBER_SAVE_MINIMAL_TEST
599
-
600
- // ######################################################################
601
- // Load Minimal Utilities
602
- namespace detail
603
- {
604
- //! Used to help strip away conversion wrappers
605
- /*! If someone writes a non-member load/save minimal function that accepts its
606
- parameter as some generic template type and needs to perform trait checks
607
- on that type, our NoConvert wrappers will interfere with this. Using
608
- the struct strip_minmal, users can strip away our wrappers to get to
609
- the underlying type, allowing traits to work properly */
610
- struct NoConvertBase {};
611
-
612
- //! A struct that prevents implicit conversion
613
- /*! Any type instantiated with this struct will be unable to implicitly convert
614
- to another type. Is designed to only allow conversion to Source const &.
615
-
616
- @tparam Source the type of the original source */
617
- template <class Source>
618
- struct NoConvertConstRef : NoConvertBase
619
- {
620
- using type = Source; //!< Used to get underlying type easily
621
-
622
- template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
623
- operator Dest () = delete;
624
-
625
- //! only allow conversion if the types are the same and we are converting into a const reference
626
- template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
627
- operator Dest const & ();
628
- };
629
-
630
- //! A struct that prevents implicit conversion
631
- /*! Any type instantiated with this struct will be unable to implicitly convert
632
- to another type. Is designed to only allow conversion to Source &.
633
-
634
- @tparam Source the type of the original source */
635
- template <class Source>
636
- struct NoConvertRef : NoConvertBase
637
- {
638
- using type = Source; //!< Used to get underlying type easily
639
-
640
- template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
641
- operator Dest () = delete;
642
-
643
- #ifdef __clang__
644
- template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
645
- operator Dest const & () = delete;
646
- #endif // __clang__
647
-
648
- //! only allow conversion if the types are the same and we are converting into a const reference
649
- template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
650
- operator Dest & ();
651
- };
652
-
653
- //! A type that can implicitly convert to anything else
654
- struct AnyConvert
655
- {
656
- template <class Dest>
657
- operator Dest & ();
658
-
659
- template <class Dest>
660
- operator Dest const & () const;
661
- };
662
- } // namespace detail
663
-
664
- // ######################################################################
665
- //! Creates a test for whether a member load_minimal function exists
666
- /*! This creates a class derived from std::integral_constant that will be true if
667
- the type has the proper member function for the given archive.
668
-
669
- Our strategy here is to first check if a function matching the signature more or less exists
670
- (allow anything like load_minimal(xxx) using AnyConvert, and then secondly enforce
671
- that it has the correct signature using NoConvertConstRef
672
-
673
- @param test_name The name to give the test (e.g. load_minimal or versioned_load_minimal)
674
- @param versioned Either blank or the macro CEREAL_MAKE_VERSIONED_TEST */
675
- #ifdef CEREAL_OLDER_GCC
676
- #define CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_IMPL(test_name, versioned) \
677
- namespace detail \
678
- { \
679
- template <class T, class A, class SFINAE = void> struct has_member_##test_name##_impl : no {}; \
680
- template <class T, class A> \
681
- struct has_member_##test_name##_impl<T, A, typename detail::Void< decltype( \
682
- cereal::access::member_load_minimal( std::declval<A const &>(), \
683
- std::declval<T &>(), AnyConvert() versioned ) ) >::type> : yes {}; \
684
- \
685
- template <class T, class A, class U, class SFINAE = void> struct has_member_##test_name##_type_impl : no {}; \
686
- template <class T, class A, class U> \
687
- struct has_member_##test_name##_type_impl<T, A, U, typename detail::Void< decltype( \
688
- cereal::access::member_load_minimal( std::declval<A const &>(), \
689
- std::declval<T &>(), NoConvertConstRef<U>() versioned ) ) >::type> : yes {}; \
690
- } /* end namespace detail */
691
- #else /* NOT CEREAL_OLDER_GCC =================================== */
692
- #define CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_IMPL(test_name, versioned) \
693
- namespace detail \
694
- { \
695
- template <class T, class A> \
696
- struct has_member_##test_name##_impl \
697
- { \
698
- template <class TT, class AA> \
699
- static auto test(int) -> decltype( cereal::access::member_load_minimal( \
700
- std::declval<AA const &>(), \
701
- std::declval<TT &>(), AnyConvert() versioned ), yes()); \
702
- template <class, class> static no test(...); \
703
- static const bool value = std::is_same<decltype(test<T, A>(0)), yes>::value; \
704
- }; \
705
- template <class T, class A, class U> \
706
- struct has_member_##test_name##_type_impl \
707
- { \
708
- template <class TT, class AA, class UU> \
709
- static auto test(int) -> decltype( cereal::access::member_load_minimal( \
710
- std::declval<AA const &>(), \
711
- std::declval<TT &>(), NoConvertConstRef<UU>() versioned ), yes()); \
712
- template <class, class, class> static no test(...); \
713
- static const bool value = std::is_same<decltype(test<T, A, U>(0)), yes>::value; \
714
- \
715
- }; \
716
- } /* end namespace detail */
717
- #endif // NOT CEREAL_OLDER_GCC
718
-
719
- // ######################################################################
720
- //! Creates helpers for minimal load functions
721
- /*! The has_member_*_wrapper structs ensure that the load and save types for the
722
- requested function type match appropriately.
723
-
724
- @param load_test_name The name to give the test (e.g. load_minimal or versioned_load_minimal)
725
- @param save_test_name The name to give the test (e.g. save_minimal or versioned_save_minimal,
726
- should match the load name.
727
- @param save_test_prefix The name to give the test (e.g. save_minimal or versioned_save_minimal,
728
- should match the load name, without the trailing "_minimal" (e.g.
729
- save or versioned_save). Needed because the preprocessor is an abomination.
730
- @param versioned Either blank or the macro CEREAL_MAKE_VERSIONED_TEST */
731
- #define CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_HELPERS_IMPL(load_test_name, save_test_name, save_test_prefix, versioned) \
732
- namespace detail \
733
- { \
734
- template <class T, class A, bool Valid> \
735
- struct has_member_##load_test_name##_wrapper : std::false_type {}; \
736
- \
737
- template <class T, class A> \
738
- struct has_member_##load_test_name##_wrapper<T, A, true> \
739
- { \
740
- using AOut = typename detail::get_output_from_input<A>::type; \
741
- \
742
- static_assert( has_member_##save_test_prefix##_minimal<T, AOut>::value, \
743
- "cereal detected member " #load_test_name " but no valid member " #save_test_name ". \n " \
744
- "cannot evaluate correctness of " #load_test_name " without valid " #save_test_name "." ); \
745
- \
746
- using SaveType = typename detail::get_member_##save_test_prefix##_minimal_type<T, AOut, true>::type; \
747
- const static bool value = has_member_##load_test_name##_impl<T, A>::value; \
748
- const static bool valid = has_member_##load_test_name##_type_impl<T, A, SaveType>::value; \
749
- \
750
- static_assert( valid || !value, "cereal detected different or invalid types in corresponding member " \
751
- #load_test_name " and " #save_test_name " functions. \n " \
752
- "the paramater to " #load_test_name " must be a constant reference to the type that " \
753
- #save_test_name " returns." ); \
754
- }; \
755
- } /* end namespace detail */
756
-
757
- // ######################################################################
758
- //! Creates a test for whether a member load_minimal function exists
759
- /*! This creates a class derived from std::integral_constant that will be true if
760
- the type has the proper member function for the given archive.
761
-
762
- @param load_test_name The name to give the test (e.g. load_minimal or versioned_load_minimal)
763
- @param load_test_prefix The above parameter minus the trailing "_minimal" */
764
- #define CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_TEST(load_test_name, load_test_prefix) \
765
- template <class T, class A> \
766
- struct has_member_##load_test_prefix##_minimal : std::integral_constant<bool, \
767
- detail::has_member_##load_test_name##_wrapper<T, A, detail::has_member_##load_test_name##_impl<T, A>::value>::value> {};
768
-
769
- // ######################################################################
770
- // Member Load Minimal
771
- CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_IMPL(load_minimal, )
772
- CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_HELPERS_IMPL(load_minimal, save_minimal, save, )
773
- CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_TEST(load_minimal, load)
774
-
775
- // ######################################################################
776
- // Member Load Minimal (versioned)
777
- CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_IMPL(versioned_load_minimal, CEREAL_MAKE_VERSIONED_TEST)
778
- CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_HELPERS_IMPL(versioned_load_minimal, versioned_save_minimal, versioned_save, CEREAL_MAKE_VERSIONED_TEST)
779
- CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_TEST(versioned_load_minimal, versioned_load)
780
-
781
- // ######################################################################
782
- #undef CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_IMPL
783
- #undef CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_HELPERS_IMPL
784
- #undef CEREAL_MAKE_HAS_MEMBER_LOAD_MINIMAL_TEST
785
-
786
- // ######################################################################
787
- // Non-Member Load Minimal
788
- namespace detail
789
- {
790
- #ifdef CEREAL_OLDER_GCC
791
- void CEREAL_LOAD_MINIMAL_FUNCTION_NAME(); // prevents nonsense complaining about not finding this
792
- void CEREAL_SAVE_MINIMAL_FUNCTION_NAME();
793
- #endif // CEREAL_OLDER_GCC
794
- } // namespace detail
795
-
796
- // ######################################################################
797
- //! Creates a test for whether a non-member load_minimal function exists
798
- /*! This creates a class derived from std::integral_constant that will be true if
799
- the type has the proper member function for the given archive.
800
-
801
- See notes from member load_minimal implementation.
802
-
803
- Note that there should be an additional const check on load_minimal after the valid check,
804
- but this currently interferes with many valid uses of minimal serialization. It has been
805
- removed (see #565 on github) and previously was:
806
-
807
- @code
808
- static_assert( check::const_valid || !check::exists,
809
- "cereal detected an invalid serialization type parameter in non-member " #test_name ". "
810
- #test_name " non-member functions must accept their serialization type by non-const reference" );
811
- @endcode
812
-
813
- See #132, #436, #263, and #565 on https://github.com/USCiLab/cereal for more details.
814
-
815
- @param test_name The name to give the test (e.g. load_minimal or versioned_load_minimal)
816
- @param save_name The corresponding name the save test would have (e.g. save_minimal or versioned_save_minimal)
817
- @param versioned Either blank or the macro CEREAL_MAKE_VERSIONED_TEST */
818
- #define CEREAL_MAKE_HAS_NON_MEMBER_LOAD_MINIMAL_TEST(test_name, save_name, versioned) \
819
- namespace detail \
820
- { \
821
- template <class T, class A, class U = void> \
822
- struct has_non_member_##test_name##_impl \
823
- { \
824
- template <class TT, class AA> \
825
- static auto test(int) -> decltype( CEREAL_LOAD_MINIMAL_FUNCTION_NAME( \
826
- std::declval<AA const &>(), std::declval<TT&>(), AnyConvert() versioned ), yes() ); \
827
- template <class, class> static no test( ... ); \
828
- static const bool exists = std::is_same<decltype( test<T, A>( 0 ) ), yes>::value; \
829
- \
830
- template <class TT, class AA, class UU> \
831
- static auto test2(int) -> decltype( CEREAL_LOAD_MINIMAL_FUNCTION_NAME( \
832
- std::declval<AA const &>(), std::declval<TT&>(), NoConvertConstRef<UU>() versioned ), yes() ); \
833
- template <class, class, class> static no test2( ... ); \
834
- static const bool valid = std::is_same<decltype( test2<T, A, U>( 0 ) ), yes>::value; \
835
- \
836
- template <class TT, class AA> \
837
- static auto test3(int) -> decltype( CEREAL_LOAD_MINIMAL_FUNCTION_NAME( \
838
- std::declval<AA const &>(), NoConvertRef<TT>(), AnyConvert() versioned ), yes() ); \
839
- template <class, class> static no test3( ... ); \
840
- static const bool const_valid = std::is_same<decltype( test3<T, A>( 0 ) ), yes>::value; \
841
- }; \
842
- \
843
- template <class T, class A, bool Valid> \
844
- struct has_non_member_##test_name##_wrapper : std::false_type {}; \
845
- \
846
- template <class T, class A> \
847
- struct has_non_member_##test_name##_wrapper<T, A, true> \
848
- { \
849
- using AOut = typename detail::get_output_from_input<A>::type; \
850
- \
851
- static_assert( detail::has_non_member_##save_name##_impl<T, AOut>::valid, \
852
- "cereal detected non-member " #test_name " but no valid non-member " #save_name ". \n " \
853
- "cannot evaluate correctness of " #test_name " without valid " #save_name "." ); \
854
- \
855
- using SaveType = typename detail::get_non_member_##save_name##_type<T, AOut, true>::type; \
856
- using check = has_non_member_##test_name##_impl<T, A, SaveType>; \
857
- static const bool value = check::exists; \
858
- \
859
- static_assert( check::valid || !check::exists, "cereal detected different types in corresponding non-member " \
860
- #test_name " and " #save_name " functions. \n " \
861
- "the paramater to " #test_name " must be a constant reference to the type that " #save_name " returns." ); \
862
- }; \
863
- } /* namespace detail */ \
864
- \
865
- template <class T, class A> \
866
- struct has_non_member_##test_name : std::integral_constant<bool, \
867
- detail::has_non_member_##test_name##_wrapper<T, A, detail::has_non_member_##test_name##_impl<T, A>::exists>::value> {};
868
-
869
- // ######################################################################
870
- // Non-Member Load Minimal
871
- CEREAL_MAKE_HAS_NON_MEMBER_LOAD_MINIMAL_TEST(load_minimal, save_minimal, )
872
-
873
- // ######################################################################
874
- // Non-Member Load Minimal (versioned)
875
- CEREAL_MAKE_HAS_NON_MEMBER_LOAD_MINIMAL_TEST(versioned_load_minimal, versioned_save_minimal, CEREAL_MAKE_VERSIONED_TEST)
876
-
877
- // ######################################################################
878
- #undef CEREAL_MAKE_HAS_NON_MEMBER_LOAD_MINIMAL_TEST
879
-
880
- // ######################################################################
881
- namespace detail
882
- {
883
- // const stripped away before reaching here, prevents errors on conversion from
884
- // construct<const T> to construct<T>
885
- template<typename T, typename A>
886
- struct has_member_load_and_construct_impl : std::integral_constant<bool,
887
- std::is_same<decltype( access::load_and_construct<T>( std::declval<A&>(), std::declval< ::cereal::construct<T>&>() ) ), void>::value>
888
- { };
889
-
890
- template<typename T, typename A>
891
- struct has_member_versioned_load_and_construct_impl : std::integral_constant<bool,
892
- std::is_same<decltype( access::load_and_construct<T>( std::declval<A&>(), std::declval< ::cereal::construct<T>&>(), 0 ) ), void>::value>
893
- { };
894
- } // namespace detail
895
-
896
- //! Member load and construct check
897
- template<typename T, typename A>
898
- struct has_member_load_and_construct : detail::has_member_load_and_construct_impl<typename std::remove_const<T>::type, A>
899
- { };
900
-
901
- //! Member load and construct check (versioned)
902
- template<typename T, typename A>
903
- struct has_member_versioned_load_and_construct : detail::has_member_versioned_load_and_construct_impl<typename std::remove_const<T>::type, A>
904
- { };
905
-
906
- // ######################################################################
907
- //! Creates a test for whether a non-member load_and_construct specialization exists
908
- /*! This creates a class derived from std::integral_constant that will be true if
909
- the type has the proper non-member function for the given archive. */
910
- #define CEREAL_MAKE_HAS_NON_MEMBER_LOAD_AND_CONSTRUCT_TEST(test_name, versioned) \
911
- namespace detail \
912
- { \
913
- template <class T, class A> \
914
- struct has_non_member_##test_name##_impl \
915
- { \
916
- template <class TT, class AA> \
917
- static auto test(int) -> decltype( LoadAndConstruct<TT>::load_and_construct( \
918
- std::declval<AA&>(), std::declval< ::cereal::construct<TT>&>() versioned ), yes()); \
919
- template <class, class> \
920
- static no test( ... ); \
921
- static const bool value = std::is_same<decltype( test<T, A>( 0 ) ), yes>::value; \
922
- }; \
923
- } /* end namespace detail */ \
924
- template <class T, class A> \
925
- struct has_non_member_##test_name : \
926
- std::integral_constant<bool, detail::has_non_member_##test_name##_impl<typename std::remove_const<T>::type, A>::value> {};
927
-
928
- // ######################################################################
929
- //! Non member load and construct check
930
- CEREAL_MAKE_HAS_NON_MEMBER_LOAD_AND_CONSTRUCT_TEST(load_and_construct, )
931
-
932
- // ######################################################################
933
- //! Non member load and construct check (versioned)
934
- CEREAL_MAKE_HAS_NON_MEMBER_LOAD_AND_CONSTRUCT_TEST(versioned_load_and_construct, CEREAL_MAKE_VERSIONED_TEST)
935
-
936
- // ######################################################################
937
- //! Has either a member or non member load and construct
938
- template<typename T, typename A>
939
- struct has_load_and_construct : std::integral_constant<bool,
940
- has_member_load_and_construct<T, A>::value || has_non_member_load_and_construct<T, A>::value ||
941
- has_member_versioned_load_and_construct<T, A>::value || has_non_member_versioned_load_and_construct<T, A>::value>
942
- { };
943
-
944
- // ######################################################################
945
- #undef CEREAL_MAKE_HAS_NON_MEMBER_LOAD_AND_CONSTRUCT_TEST
946
-
947
- // ######################################################################
948
- // End of serialization existence tests
949
- #undef CEREAL_MAKE_VERSIONED_TEST
950
-
951
- // ######################################################################
952
- template <class T, class InputArchive, class OutputArchive>
953
- struct has_member_split : std::integral_constant<bool,
954
- (has_member_load<T, InputArchive>::value && has_member_save<T, OutputArchive>::value) ||
955
- (has_member_versioned_load<T, InputArchive>::value && has_member_versioned_save<T, OutputArchive>::value)> {};
956
-
957
- // ######################################################################
958
- template <class T, class InputArchive, class OutputArchive>
959
- struct has_non_member_split : std::integral_constant<bool,
960
- (has_non_member_load<T, InputArchive>::value && has_non_member_save<T, OutputArchive>::value) ||
961
- (has_non_member_versioned_load<T, InputArchive>::value && has_non_member_versioned_save<T, OutputArchive>::value)> {};
962
-
963
- // ######################################################################
964
- template <class T, class OutputArchive>
965
- struct has_invalid_output_versioning : std::integral_constant<bool,
966
- (has_member_versioned_save<T, OutputArchive>::value && has_member_save<T, OutputArchive>::value) ||
967
- (has_non_member_versioned_save<T, OutputArchive>::value && has_non_member_save<T, OutputArchive>::value) ||
968
- (has_member_versioned_serialize<T, OutputArchive>::value && has_member_serialize<T, OutputArchive>::value) ||
969
- (has_non_member_versioned_serialize<T, OutputArchive>::value && has_non_member_serialize<T, OutputArchive>::value) ||
970
- (has_member_versioned_save_minimal<T, OutputArchive>::value && has_member_save_minimal<T, OutputArchive>::value) ||
971
- (has_non_member_versioned_save_minimal<T, OutputArchive>::value && has_non_member_save_minimal<T, OutputArchive>::value)> {};
972
-
973
- // ######################################################################
974
- template <class T, class InputArchive>
975
- struct has_invalid_input_versioning : std::integral_constant<bool,
976
- (has_member_versioned_load<T, InputArchive>::value && has_member_load<T, InputArchive>::value) ||
977
- (has_non_member_versioned_load<T, InputArchive>::value && has_non_member_load<T, InputArchive>::value) ||
978
- (has_member_versioned_serialize<T, InputArchive>::value && has_member_serialize<T, InputArchive>::value) ||
979
- (has_non_member_versioned_serialize<T, InputArchive>::value && has_non_member_serialize<T, InputArchive>::value) ||
980
- (has_member_versioned_load_minimal<T, InputArchive>::value && has_member_load_minimal<T, InputArchive>::value) ||
981
- (has_non_member_versioned_load_minimal<T, InputArchive>::value && has_non_member_load_minimal<T, InputArchive>::value)> {};
982
-
983
- // ######################################################################
984
- namespace detail
985
- {
986
- //! Create a test for a cereal::specialization entry
987
- #define CEREAL_MAKE_IS_SPECIALIZED_IMPL(name) \
988
- template <class T, class A> \
989
- struct is_specialized_##name : std::integral_constant<bool, \
990
- !std::is_base_of<std::false_type, specialize<A, T, specialization::name>>::value> {}
991
-
992
- CEREAL_MAKE_IS_SPECIALIZED_IMPL(member_serialize);
993
- CEREAL_MAKE_IS_SPECIALIZED_IMPL(member_load_save);
994
- CEREAL_MAKE_IS_SPECIALIZED_IMPL(member_load_save_minimal);
995
- CEREAL_MAKE_IS_SPECIALIZED_IMPL(non_member_serialize);
996
- CEREAL_MAKE_IS_SPECIALIZED_IMPL(non_member_load_save);
997
- CEREAL_MAKE_IS_SPECIALIZED_IMPL(non_member_load_save_minimal);
998
-
999
- #undef CEREAL_MAKE_IS_SPECIALIZED_IMPL
1000
-
1001
- //! Number of specializations detected
1002
- template <class T, class A>
1003
- struct count_specializations : std::integral_constant<int,
1004
- is_specialized_member_serialize<T, A>::value +
1005
- is_specialized_member_load_save<T, A>::value +
1006
- is_specialized_member_load_save_minimal<T, A>::value +
1007
- is_specialized_non_member_serialize<T, A>::value +
1008
- is_specialized_non_member_load_save<T, A>::value +
1009
- is_specialized_non_member_load_save_minimal<T, A>::value> {};
1010
- } // namespace detail
1011
-
1012
- //! Check if any specialization exists for a type
1013
- template <class T, class A>
1014
- struct is_specialized : std::integral_constant<bool,
1015
- detail::is_specialized_member_serialize<T, A>::value ||
1016
- detail::is_specialized_member_load_save<T, A>::value ||
1017
- detail::is_specialized_member_load_save_minimal<T, A>::value ||
1018
- detail::is_specialized_non_member_serialize<T, A>::value ||
1019
- detail::is_specialized_non_member_load_save<T, A>::value ||
1020
- detail::is_specialized_non_member_load_save_minimal<T, A>::value>
1021
- {
1022
- static_assert(detail::count_specializations<T, A>::value <= 1, "More than one explicit specialization detected for type.");
1023
- };
1024
-
1025
- //! Create the static assertion for some specialization
1026
- /*! This assertion will fail if the type is indeed specialized and does not have the appropriate
1027
- type of serialization functions */
1028
- #define CEREAL_MAKE_IS_SPECIALIZED_ASSERT(name, versioned_name, print_name, spec_name) \
1029
- static_assert( (is_specialized<T, A>::value && detail::is_specialized_##spec_name<T, A>::value && \
1030
- (has_##name<T, A>::value || has_##versioned_name<T, A>::value)) \
1031
- || !(is_specialized<T, A>::value && detail::is_specialized_##spec_name<T, A>::value), \
1032
- "cereal detected " #print_name " specialization but no " #print_name " serialize function" )
1033
-
1034
- //! Generates a test for specialization for versioned and unversioned functions
1035
- /*! This creates checks that can be queried to see if a given type of serialization function
1036
- has been specialized for this type */
1037
- #define CEREAL_MAKE_IS_SPECIALIZED(name, versioned_name, spec_name) \
1038
- template <class T, class A> \
1039
- struct is_specialized_##name : std::integral_constant<bool, \
1040
- is_specialized<T, A>::value && detail::is_specialized_##spec_name<T, A>::value> \
1041
- { CEREAL_MAKE_IS_SPECIALIZED_ASSERT(name, versioned_name, name, spec_name); }; \
1042
- template <class T, class A> \
1043
- struct is_specialized_##versioned_name : std::integral_constant<bool, \
1044
- is_specialized<T, A>::value && detail::is_specialized_##spec_name<T, A>::value> \
1045
- { CEREAL_MAKE_IS_SPECIALIZED_ASSERT(name, versioned_name, versioned_name, spec_name); }
1046
-
1047
- CEREAL_MAKE_IS_SPECIALIZED(member_serialize, member_versioned_serialize, member_serialize);
1048
- CEREAL_MAKE_IS_SPECIALIZED(non_member_serialize, non_member_versioned_serialize, non_member_serialize);
1049
-
1050
- CEREAL_MAKE_IS_SPECIALIZED(member_save, member_versioned_save, member_load_save);
1051
- CEREAL_MAKE_IS_SPECIALIZED(non_member_save, non_member_versioned_save, non_member_load_save);
1052
- CEREAL_MAKE_IS_SPECIALIZED(member_load, member_versioned_load, member_load_save);
1053
- CEREAL_MAKE_IS_SPECIALIZED(non_member_load, non_member_versioned_load, non_member_load_save);
1054
-
1055
- CEREAL_MAKE_IS_SPECIALIZED(member_save_minimal, member_versioned_save_minimal, member_load_save_minimal);
1056
- CEREAL_MAKE_IS_SPECIALIZED(non_member_save_minimal, non_member_versioned_save_minimal, non_member_load_save_minimal);
1057
- CEREAL_MAKE_IS_SPECIALIZED(member_load_minimal, member_versioned_load_minimal, member_load_save_minimal);
1058
- CEREAL_MAKE_IS_SPECIALIZED(non_member_load_minimal, non_member_versioned_load_minimal, non_member_load_save_minimal);
1059
-
1060
- #undef CEREAL_MAKE_IS_SPECIALIZED_ASSERT
1061
- #undef CEREAL_MAKE_IS_SPECIALIZED
1062
-
1063
- // ######################################################################
1064
- // detects if a type has any active minimal output serialization
1065
- template <class T, class OutputArchive>
1066
- struct has_minimal_output_serialization : std::integral_constant<bool,
1067
- is_specialized_member_save_minimal<T, OutputArchive>::value ||
1068
- ((has_member_save_minimal<T, OutputArchive>::value ||
1069
- has_non_member_save_minimal<T, OutputArchive>::value ||
1070
- has_member_versioned_save_minimal<T, OutputArchive>::value ||
1071
- has_non_member_versioned_save_minimal<T, OutputArchive>::value) &&
1072
- !(is_specialized_member_serialize<T, OutputArchive>::value ||
1073
- is_specialized_member_save<T, OutputArchive>::value))> {};
1074
-
1075
- // ######################################################################
1076
- // detects if a type has any active minimal input serialization
1077
- template <class T, class InputArchive>
1078
- struct has_minimal_input_serialization : std::integral_constant<bool,
1079
- is_specialized_member_load_minimal<T, InputArchive>::value ||
1080
- ((has_member_load_minimal<T, InputArchive>::value ||
1081
- has_non_member_load_minimal<T, InputArchive>::value ||
1082
- has_member_versioned_load_minimal<T, InputArchive>::value ||
1083
- has_non_member_versioned_load_minimal<T, InputArchive>::value) &&
1084
- !(is_specialized_member_serialize<T, InputArchive>::value ||
1085
- is_specialized_member_load<T, InputArchive>::value))> {};
1086
-
1087
- // ######################################################################
1088
- namespace detail
1089
- {
1090
- //! The number of output serialization functions available
1091
- /*! If specialization is being used, we'll count only those; otherwise we'll count everything */
1092
- template <class T, class OutputArchive>
1093
- struct count_output_serializers : std::integral_constant<int,
1094
- count_specializations<T, OutputArchive>::value ? count_specializations<T, OutputArchive>::value :
1095
- has_member_save<T, OutputArchive>::value +
1096
- has_non_member_save<T, OutputArchive>::value +
1097
- has_member_serialize<T, OutputArchive>::value +
1098
- has_non_member_serialize<T, OutputArchive>::value +
1099
- has_member_save_minimal<T, OutputArchive>::value +
1100
- has_non_member_save_minimal<T, OutputArchive>::value +
1101
- /*-versioned---------------------------------------------------------*/
1102
- has_member_versioned_save<T, OutputArchive>::value +
1103
- has_non_member_versioned_save<T, OutputArchive>::value +
1104
- has_member_versioned_serialize<T, OutputArchive>::value +
1105
- has_non_member_versioned_serialize<T, OutputArchive>::value +
1106
- has_member_versioned_save_minimal<T, OutputArchive>::value +
1107
- has_non_member_versioned_save_minimal<T, OutputArchive>::value> {};
1108
- }
1109
-
1110
- template <class T, class OutputArchive>
1111
- struct is_output_serializable : std::integral_constant<bool,
1112
- detail::count_output_serializers<T, OutputArchive>::value == 1> {};
1113
-
1114
- // ######################################################################
1115
- namespace detail
1116
- {
1117
- //! The number of input serialization functions available
1118
- /*! If specialization is being used, we'll count only those; otherwise we'll count everything */
1119
- template <class T, class InputArchive>
1120
- struct count_input_serializers : std::integral_constant<int,
1121
- count_specializations<T, InputArchive>::value ? count_specializations<T, InputArchive>::value :
1122
- has_member_load<T, InputArchive>::value +
1123
- has_non_member_load<T, InputArchive>::value +
1124
- has_member_serialize<T, InputArchive>::value +
1125
- has_non_member_serialize<T, InputArchive>::value +
1126
- has_member_load_minimal<T, InputArchive>::value +
1127
- has_non_member_load_minimal<T, InputArchive>::value +
1128
- /*-versioned---------------------------------------------------------*/
1129
- has_member_versioned_load<T, InputArchive>::value +
1130
- has_non_member_versioned_load<T, InputArchive>::value +
1131
- has_member_versioned_serialize<T, InputArchive>::value +
1132
- has_non_member_versioned_serialize<T, InputArchive>::value +
1133
- has_member_versioned_load_minimal<T, InputArchive>::value +
1134
- has_non_member_versioned_load_minimal<T, InputArchive>::value> {};
1135
- }
1136
-
1137
- template <class T, class InputArchive>
1138
- struct is_input_serializable : std::integral_constant<bool,
1139
- detail::count_input_serializers<T, InputArchive>::value == 1> {};
1140
-
1141
- // ######################################################################
1142
- // Base Class Support
1143
- namespace detail
1144
- {
1145
- struct base_class_id
1146
- {
1147
- template<class T>
1148
- base_class_id(T const * const t) :
1149
- type(typeid(T)),
1150
- ptr(t),
1151
- hash(std::hash<std::type_index>()(typeid(T)) ^ (std::hash<void const *>()(t) << 1))
1152
- { }
1153
-
1154
- bool operator==(base_class_id const & other) const
1155
- { return (type == other.type) && (ptr == other.ptr); }
1156
-
1157
- std::type_index type;
1158
- void const * ptr;
1159
- size_t hash;
1160
- };
1161
- struct base_class_id_hash { size_t operator()(base_class_id const & id) const { return id.hash; } };
1162
- } // namespace detail
1163
-
1164
- namespace detail
1165
- {
1166
- //! Common base type for base class casting
1167
- struct BaseCastBase {};
1168
-
1169
- template <class>
1170
- struct get_base_class;
1171
-
1172
- template <template<typename> class Cast, class Base>
1173
- struct get_base_class<Cast<Base>>
1174
- {
1175
- using type = Base;
1176
- };
1177
-
1178
- //! Base class cast, behave as the test
1179
- template <class Cast, template<class, class> class Test, class Archive,
1180
- bool IsBaseCast = std::is_base_of<BaseCastBase, Cast>::value>
1181
- struct has_minimal_base_class_serialization_impl : Test<typename get_base_class<Cast>::type, Archive>
1182
- { };
1183
-
1184
- //! Not a base class cast
1185
- template <class Cast, template<class, class> class Test, class Archive>
1186
- struct has_minimal_base_class_serialization_impl<Cast,Test, Archive, false> : std::false_type
1187
- { };
1188
- }
1189
-
1190
- //! Checks to see if the base class used in a cast has a minimal serialization
1191
- /*! @tparam Cast Either base_class or virtual_base_class wrapped type
1192
- @tparam Test A has_minimal test (for either input or output)
1193
- @tparam Archive The archive to use with the test */
1194
- template <class Cast, template<class, class> class Test, class Archive>
1195
- struct has_minimal_base_class_serialization : detail::has_minimal_base_class_serialization_impl<Cast, Test, Archive>
1196
- { };
1197
-
1198
-
1199
- // ######################################################################
1200
- namespace detail
1201
- {
1202
- struct shared_from_this_wrapper
1203
- {
1204
- template <class U>
1205
- static auto (check)( U const & t ) -> decltype( ::cereal::access::shared_from_this(t), std::true_type() );
1206
-
1207
- static auto (check)( ... ) -> decltype( std::false_type() );
1208
-
1209
- template <class U>
1210
- static auto get( U const & t ) -> decltype( t.shared_from_this() );
1211
- };
1212
- }
1213
-
1214
- //! Determine if T or any base class of T has inherited from std::enable_shared_from_this
1215
- template<class T>
1216
- struct has_shared_from_this : decltype((detail::shared_from_this_wrapper::check)(std::declval<T>()))
1217
- { };
1218
-
1219
- //! Get the type of the base class of T which inherited from std::enable_shared_from_this
1220
- template <class T>
1221
- struct get_shared_from_this_base
1222
- {
1223
- private:
1224
- using PtrType = decltype(detail::shared_from_this_wrapper::get(std::declval<T>()));
1225
- public:
1226
- //! The type of the base of T that inherited from std::enable_shared_from_this
1227
- using type = typename std::decay<typename PtrType::element_type>::type;
1228
- };
1229
-
1230
- // ######################################################################
1231
- //! Extracts the true type from something possibly wrapped in a cereal NoConvert
1232
- /*! Internally cereal uses some wrapper classes to test the validity of non-member
1233
- minimal load and save functions. This can interfere with user type traits on
1234
- templated load and save minimal functions. To get to the correct underlying type,
1235
- users should use strip_minimal when performing any enable_if type type trait checks.
1236
-
1237
- See the enum serialization in types/common.hpp for an example of using this */
1238
- template <class T, bool IsCerealMinimalTrait = std::is_base_of<detail::NoConvertBase, T>::value>
1239
- struct strip_minimal
1240
- {
1241
- using type = T;
1242
- };
1243
-
1244
- //! Specialization for types wrapped in a NoConvert
1245
- template <class T>
1246
- struct strip_minimal<T, true>
1247
- {
1248
- using type = typename T::type;
1249
- };
1250
-
1251
- // ######################################################################
1252
- //! Determines whether the class T can be default constructed by cereal::access
1253
- template <class T>
1254
- struct is_default_constructible
1255
- {
1256
- #ifdef CEREAL_OLDER_GCC
1257
- template <class TT, class SFINAE = void>
1258
- struct test : no {};
1259
- template <class TT>
1260
- struct test<TT, typename detail::Void< decltype( cereal::access::construct<TT>() ) >::type> : yes {};
1261
- static const bool value = test<T>();
1262
- #else // NOT CEREAL_OLDER_GCC =========================================
1263
- template <class TT>
1264
- static auto test(int) -> decltype( cereal::access::construct<TT>(), yes());
1265
- template <class>
1266
- static no test(...);
1267
- static const bool value = std::is_same<decltype(test<T>(0)), yes>::value;
1268
- #endif // NOT CEREAL_OLDER_GCC
1269
- };
1270
-
1271
- // ######################################################################
1272
- namespace detail
1273
- {
1274
- //! Removes all qualifiers and minimal wrappers from an archive
1275
- template <class A>
1276
- using decay_archive = typename std::decay<typename strip_minimal<A>::type>::type;
1277
- }
1278
-
1279
- //! Checks if the provided archive type is equal to some cereal archive type
1280
- /*! This automatically does things such as std::decay and removing any other wrappers that may be
1281
- on the Archive template parameter.
1282
-
1283
- Example use:
1284
- @code{cpp}
1285
- // example use to disable a serialization function
1286
- template <class Archive, EnableIf<cereal::traits::is_same_archive<Archive, cereal::BinaryOutputArchive>::value> = sfinae>
1287
- void save( Archive & ar, MyType const & mt );
1288
- @endcode */
1289
- template <class ArchiveT, class CerealArchiveT>
1290
- struct is_same_archive : std::integral_constant<bool,
1291
- std::is_same<detail::decay_archive<ArchiveT>, CerealArchiveT>::value>
1292
- { };
1293
-
1294
- // ######################################################################
1295
- //! A macro to use to restrict which types of archives your function will work for.
1296
- /*! This requires you to have a template class parameter named Archive and replaces the void return
1297
- type for your function.
1298
-
1299
- INTYPE refers to the input archive type you wish to restrict on.
1300
- OUTTYPE refers to the output archive type you wish to restrict on.
1301
-
1302
- For example, if we want to limit a serialize to only work with binary serialization:
1303
-
1304
- @code{.cpp}
1305
- template <class Archive>
1306
- CEREAL_ARCHIVE_RESTRICT(BinaryInputArchive, BinaryOutputArchive)
1307
- serialize( Archive & ar, MyCoolType & m )
1308
- {
1309
- ar & m;
1310
- }
1311
- @endcode
1312
-
1313
- If you need to do more restrictions in your enable_if, you will need to do this by hand.
1314
- */
1315
- #define CEREAL_ARCHIVE_RESTRICT(INTYPE, OUTTYPE) \
1316
- typename std::enable_if<cereal::traits::is_same_archive<Archive, INTYPE>::value || cereal::traits::is_same_archive<Archive, OUTTYPE>::value, void>::type
1317
-
1318
- //! Type traits only struct used to mark an archive as human readable (text based)
1319
- /*! Archives that wish to identify as text based/human readable should inherit from
1320
- this struct */
1321
- struct TextArchive {};
1322
-
1323
- //! Checks if an archive is a text archive (human readable)
1324
- template <class A>
1325
- struct is_text_archive : std::integral_constant<bool,
1326
- std::is_base_of<TextArchive, detail::decay_archive<A>>::value>
1327
- { };
1328
- } // namespace traits
1329
-
1330
- // ######################################################################
1331
- namespace detail
1332
- {
1333
- template <class T, class A,
1334
- bool Member = traits::has_member_load_and_construct<T, A>::value,
1335
- bool MemberVersioned = traits::has_member_versioned_load_and_construct<T, A>::value,
1336
- bool NonMember = traits::has_non_member_load_and_construct<T, A>::value,
1337
- bool NonMemberVersioned = traits::has_non_member_versioned_load_and_construct<T, A>::value>
1338
- struct Construct
1339
- {
1340
- static_assert( cereal::traits::detail::delay_static_assert<T>::value,
1341
- "cereal found more than one compatible load_and_construct function for the provided type and archive combination. \n\n "
1342
- "Types must either have a member load_and_construct function or a non-member specialization of LoadAndConstruct (you may not mix these). \n "
1343
- "In addition, you may not mix versioned with non-versioned load_and_construct functions. \n\n " );
1344
- static T * load_andor_construct( A & /*ar*/, construct<T> & /*construct*/ )
1345
- { return nullptr; }
1346
- };
1347
-
1348
- // no load and construct case
1349
- template <class T, class A>
1350
- struct Construct<T, A, false, false, false, false>
1351
- {
1352
- static_assert( ::cereal::traits::is_default_constructible<T>::value,
1353
- "Trying to serialize a an object with no default constructor. \n\n "
1354
- "Types must either be default constructible or define either a member or non member Construct function. \n "
1355
- "Construct functions generally have the signature: \n\n "
1356
- "template <class Archive> \n "
1357
- "static void load_and_construct(Archive & ar, cereal::construct<T> & construct) \n "
1358
- "{ \n "
1359
- " var a; \n "
1360
- " ar( a ) \n "
1361
- " construct( a ); \n "
1362
- "} \n\n" );
1363
- static T * load_andor_construct()
1364
- { return ::cereal::access::construct<T>(); }
1365
- };
1366
-
1367
- // member non-versioned
1368
- template <class T, class A>
1369
- struct Construct<T, A, true, false, false, false>
1370
- {
1371
- static void load_andor_construct( A & ar, construct<T> & construct )
1372
- {
1373
- access::load_and_construct<T>( ar, construct );
1374
- }
1375
- };
1376
-
1377
- // member versioned
1378
- template <class T, class A>
1379
- struct Construct<T, A, false, true, false, false>
1380
- {
1381
- static void load_andor_construct( A & ar, construct<T> & construct )
1382
- {
1383
- const auto version = ar.template loadClassVersion<T>();
1384
- access::load_and_construct<T>( ar, construct, version );
1385
- }
1386
- };
1387
-
1388
- // non-member non-versioned
1389
- template <class T, class A>
1390
- struct Construct<T, A, false, false, true, false>
1391
- {
1392
- static void load_andor_construct( A & ar, construct<T> & construct )
1393
- {
1394
- LoadAndConstruct<T>::load_and_construct( ar, construct );
1395
- }
1396
- };
1397
-
1398
- // non-member versioned
1399
- template <class T, class A>
1400
- struct Construct<T, A, false, false, false, true>
1401
- {
1402
- static void load_andor_construct( A & ar, construct<T> & construct )
1403
- {
1404
- const auto version = ar.template loadClassVersion<T>();
1405
- LoadAndConstruct<T>::load_and_construct( ar, construct, version );
1406
- }
1407
- };
1408
- } // namespace detail
1409
- } // namespace cereal
1410
-
1411
- #endif // CEREAL_DETAILS_TRAITS_HPP_