jsoncons 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/jsoncons/extconf.rb +43 -0
- data/ext/jsoncons/jsoncons.cpp +161 -0
- data/ext/jsoncons/jsoncons.h +10 -0
- data/jsoncons.gemspec +44 -0
- data/lib/jsoncons/jsoncons/examples/input/address-book.json +13 -0
- data/lib/jsoncons/jsoncons/examples/input/books.json +28 -0
- data/lib/jsoncons/jsoncons/examples/input/countries.json +7 -0
- data/lib/jsoncons/jsoncons/examples/input/employees.json +30 -0
- data/lib/jsoncons/jsoncons/examples/input/jsonschema/name.json +15 -0
- data/lib/jsoncons/jsoncons/examples/input/multiple-json-objects.json +3 -0
- data/lib/jsoncons/jsoncons/examples/input/sales.csv +6 -0
- data/lib/jsoncons/jsoncons/examples/input/store.json +28 -0
- data/lib/jsoncons/jsoncons/examples/input/tasks.csv +6 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/allocator_holder.hpp +38 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/basic_json.hpp +5905 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/bigint.hpp +1611 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/byte_string.hpp +820 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/binary_config.hpp +226 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/compiler_support.hpp +375 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/jsoncons_config.hpp +309 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/version.hpp +40 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/conv_error.hpp +218 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/decode_json.hpp +209 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/decode_traits.hpp +651 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/endian.hpp +44 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/grisu3.hpp +312 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/optional.hpp +483 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/parse_number.hpp +1133 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/span.hpp +188 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_view.hpp +537 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_wrapper.hpp +370 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/write_number.hpp +567 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/encode_json.hpp +315 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/encode_traits.hpp +378 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json.hpp +18 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_array.hpp +324 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_content_handler.hpp +12 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_cursor.hpp +448 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_decoder.hpp +420 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_encoder.hpp +1587 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_error.hpp +156 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_exception.hpp +241 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_filter.hpp +653 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_fwd.hpp +23 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_object.hpp +1772 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_options.hpp +862 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_parser.hpp +2900 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_reader.hpp +731 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros.hpp +1072 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros_deprecated.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_type.hpp +206 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_type_traits.hpp +1830 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor.hpp +1560 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor2.hpp +2079 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/pretty_print.hpp +89 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/ser_context.hpp +62 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/sink.hpp +289 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/source.hpp +777 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/source_adaptor.hpp +148 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/staj2_cursor.hpp +1189 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/staj_cursor.hpp +1254 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/staj_iterator.hpp +449 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/tag_type.hpp +245 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/text_source_adaptor.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/traits_extension.hpp +884 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/typed_array_view.hpp +250 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/unicode_traits.hpp +1330 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/uri.hpp +635 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/value_converter.hpp +340 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson.hpp +23 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_cursor.hpp +320 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_decimal128.hpp +865 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_encoder.hpp +585 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_error.hpp +103 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_oid.hpp +245 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_options.hpp +75 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_parser.hpp +645 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_reader.hpp +92 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_type.hpp +44 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/decode_bson.hpp +201 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/encode_bson.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor.hpp +26 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor.hpp +351 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor2.hpp +265 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_detail.hpp +93 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_encoder.hpp +1766 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_error.hpp +105 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_options.hpp +113 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_parser.hpp +1942 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_reader.hpp +116 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/decode_cbor.hpp +203 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/encode_cbor.hpp +151 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv.hpp +17 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_cursor.hpp +358 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_encoder.hpp +954 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_error.hpp +85 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_options.hpp +973 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_parser.hpp +2099 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_reader.hpp +348 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_serializer.hpp +12 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/decode_csv.hpp +208 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/encode_csv.hpp +122 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath.hpp +5215 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath_error.hpp +215 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch.hpp +579 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch_error.hpp +121 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/expression.hpp +3329 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/flatten.hpp +432 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_location.hpp +445 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_query.hpp +115 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath.hpp +13 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_error.hpp +240 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_expression.hpp +2612 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +1322 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer.hpp +1577 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer_error.hpp +119 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/format_validator.hpp +968 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/json_validator.hpp +120 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema.hpp +13 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_error.hpp +105 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_version.hpp +18 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator.hpp +1745 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator_factory.hpp +556 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_draft7.hpp +198 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_location.hpp +200 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_version.hpp +35 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/subschema.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/mergepatch/mergepatch.hpp +103 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/decode_msgpack.hpp +202 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/encode_msgpack.hpp +142 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack.hpp +24 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor.hpp +343 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor2.hpp +259 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_encoder.hpp +753 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_error.hpp +94 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_options.hpp +74 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp +748 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_reader.hpp +116 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_type.hpp +63 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/decode_ubjson.hpp +201 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/encode_ubjson.hpp +142 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson.hpp +23 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_cursor.hpp +307 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_encoder.hpp +502 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_error.hpp +100 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_options.hpp +87 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_parser.hpp +880 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_reader.hpp +92 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_type.hpp +43 -0
- data/lib/jsoncons/version.rb +5 -0
- data/lib/jsoncons.rb +33 -0
- data/test/jsoncons_test.rb +108 -0
- data/test/test_helper.rb +7 -0
- metadata +268 -0
|
@@ -0,0 +1,1830 @@
|
|
|
1
|
+
// Copyright 2013 Daniel Parker
|
|
2
|
+
// Distributed under the Boost license, Version 1.0.
|
|
3
|
+
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
4
|
+
|
|
5
|
+
// See https://github.com/danielaparker/jsoncons for latest version
|
|
6
|
+
|
|
7
|
+
#ifndef JSONCONS_JSON_TYPE_TRAITS_HPP
|
|
8
|
+
#define JSONCONS_JSON_TYPE_TRAITS_HPP
|
|
9
|
+
|
|
10
|
+
#include <chrono>
|
|
11
|
+
#include <array>
|
|
12
|
+
#include <string>
|
|
13
|
+
#include <vector>
|
|
14
|
+
#include <valarray>
|
|
15
|
+
#include <exception>
|
|
16
|
+
#include <cstring>
|
|
17
|
+
#include <utility>
|
|
18
|
+
#include <algorithm> // std::swap
|
|
19
|
+
#include <limits> // std::numeric_limits
|
|
20
|
+
#include <type_traits> // std::enable_if
|
|
21
|
+
#include <iterator> // std::iterator_traits, std::input_iterator_tag
|
|
22
|
+
#include <jsoncons/json_type.hpp>
|
|
23
|
+
#include <jsoncons/bigint.hpp>
|
|
24
|
+
#include <jsoncons/json_visitor.hpp>
|
|
25
|
+
#include <jsoncons/traits_extension.hpp>
|
|
26
|
+
#include <string>
|
|
27
|
+
#include <tuple>
|
|
28
|
+
#include <map>
|
|
29
|
+
#include <functional>
|
|
30
|
+
#include <memory>
|
|
31
|
+
#include <bitset> // std::bitset
|
|
32
|
+
#include <jsoncons/conv_error.hpp>
|
|
33
|
+
#include <jsoncons/value_converter.hpp>
|
|
34
|
+
|
|
35
|
+
#if defined(JSONCONS_HAS_STD_VARIANT)
|
|
36
|
+
#include <variant>
|
|
37
|
+
#endif
|
|
38
|
+
|
|
39
|
+
namespace jsoncons {
|
|
40
|
+
|
|
41
|
+
template <class T>
|
|
42
|
+
struct is_json_type_traits_declared : public std::false_type
|
|
43
|
+
{};
|
|
44
|
+
|
|
45
|
+
#if !defined(JSONCONS_NO_DEPRECATED)
|
|
46
|
+
template <class T>
|
|
47
|
+
using is_json_type_traits_impl = is_json_type_traits_declared<T>;
|
|
48
|
+
#endif
|
|
49
|
+
|
|
50
|
+
// json_type_traits
|
|
51
|
+
|
|
52
|
+
template<typename T>
|
|
53
|
+
struct unimplemented : std::false_type
|
|
54
|
+
{};
|
|
55
|
+
|
|
56
|
+
template <class Json, class T, class Enable=void>
|
|
57
|
+
struct json_type_traits
|
|
58
|
+
{
|
|
59
|
+
using allocator_type = typename Json::allocator_type;
|
|
60
|
+
|
|
61
|
+
static constexpr bool is_compatible = false;
|
|
62
|
+
|
|
63
|
+
static constexpr bool is(const Json&) noexcept
|
|
64
|
+
{
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static T as(const Json&)
|
|
69
|
+
{
|
|
70
|
+
static_assert(unimplemented<T>::value, "as not implemented");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static Json to_json(const T&, const allocator_type& = allocator_type())
|
|
74
|
+
{
|
|
75
|
+
static_assert(unimplemented<T>::value, "to_json not implemented");
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
namespace detail {
|
|
80
|
+
|
|
81
|
+
template<class Json, class T>
|
|
82
|
+
using
|
|
83
|
+
traits_can_convert_t = decltype(json_type_traits<Json,T>::can_convert(Json()));
|
|
84
|
+
|
|
85
|
+
template<class Json, class T>
|
|
86
|
+
using
|
|
87
|
+
has_can_convert = traits_extension::is_detected<traits_can_convert_t, Json, T>;
|
|
88
|
+
|
|
89
|
+
template <class T>
|
|
90
|
+
struct invoke_can_convert
|
|
91
|
+
{
|
|
92
|
+
template <class Json>
|
|
93
|
+
static
|
|
94
|
+
typename std::enable_if<has_can_convert<Json,T>::value,bool>::type
|
|
95
|
+
can_convert(const Json& j) noexcept
|
|
96
|
+
{
|
|
97
|
+
return json_type_traits<Json,T>::can_convert(j);
|
|
98
|
+
}
|
|
99
|
+
template <class Json>
|
|
100
|
+
static
|
|
101
|
+
typename std::enable_if<!has_can_convert<Json,T>::value,bool>::type
|
|
102
|
+
can_convert(const Json& j) noexcept
|
|
103
|
+
{
|
|
104
|
+
return json_type_traits<Json,T>::is(j);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// is_json_type_traits_unspecialized
|
|
109
|
+
template<class Json, class T, class Enable = void>
|
|
110
|
+
struct is_json_type_traits_unspecialized : std::false_type {};
|
|
111
|
+
|
|
112
|
+
// is_json_type_traits_unspecialized
|
|
113
|
+
template<class Json, class T>
|
|
114
|
+
struct is_json_type_traits_unspecialized<Json,T,
|
|
115
|
+
typename std::enable_if<!std::integral_constant<bool, json_type_traits<Json, T>::is_compatible>::value>::type
|
|
116
|
+
> : std::true_type {};
|
|
117
|
+
|
|
118
|
+
// is_compatible_array_type
|
|
119
|
+
template<class Json, class T, class Enable=void>
|
|
120
|
+
struct is_compatible_array_type : std::false_type {};
|
|
121
|
+
|
|
122
|
+
template<class Json, class T>
|
|
123
|
+
struct is_compatible_array_type<Json,T,
|
|
124
|
+
typename std::enable_if<!std::is_same<T,typename Json::array>::value &&
|
|
125
|
+
traits_extension::is_list_like<T>::value &&
|
|
126
|
+
!is_json_type_traits_unspecialized<Json,typename std::iterator_traits<typename T::iterator>::value_type>::value
|
|
127
|
+
>::type> : std::true_type {};
|
|
128
|
+
|
|
129
|
+
} // namespace detail
|
|
130
|
+
|
|
131
|
+
// is_json_type_traits_specialized
|
|
132
|
+
template<class Json, class T, class Enable=void>
|
|
133
|
+
struct is_json_type_traits_specialized : std::false_type {};
|
|
134
|
+
|
|
135
|
+
template<class Json, class T>
|
|
136
|
+
struct is_json_type_traits_specialized<Json,T,
|
|
137
|
+
typename std::enable_if<!jsoncons::detail::is_json_type_traits_unspecialized<Json,T>::value
|
|
138
|
+
>::type> : std::true_type {};
|
|
139
|
+
|
|
140
|
+
template<class Json>
|
|
141
|
+
struct json_type_traits<Json, const typename std::decay<typename Json::char_type>::type*>
|
|
142
|
+
{
|
|
143
|
+
using char_type = typename Json::char_type;
|
|
144
|
+
using allocator_type = typename Json::allocator_type;
|
|
145
|
+
|
|
146
|
+
static bool is(const Json& j) noexcept
|
|
147
|
+
{
|
|
148
|
+
return j.is_string();
|
|
149
|
+
}
|
|
150
|
+
static const char_type* as(const Json& j)
|
|
151
|
+
{
|
|
152
|
+
return j.as_cstring();
|
|
153
|
+
}
|
|
154
|
+
template <class ... Args>
|
|
155
|
+
static Json to_json(const char_type* s, Args&&... args)
|
|
156
|
+
{
|
|
157
|
+
return Json(s, semantic_tag::none, std::forward<Args>(args)...);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
template<class Json>
|
|
162
|
+
struct json_type_traits<Json, typename std::decay<typename Json::char_type>::type*>
|
|
163
|
+
{
|
|
164
|
+
using char_type = typename Json::char_type;
|
|
165
|
+
using allocator_type = typename Json::allocator_type;
|
|
166
|
+
|
|
167
|
+
static bool is(const Json& j) noexcept
|
|
168
|
+
{
|
|
169
|
+
return j.is_string();
|
|
170
|
+
}
|
|
171
|
+
template <class ... Args>
|
|
172
|
+
static Json to_json(const char_type* s, Args&&... args)
|
|
173
|
+
{
|
|
174
|
+
return Json(s, semantic_tag::none, std::forward<Args>(args)...);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// integer
|
|
179
|
+
|
|
180
|
+
template<class Json, class T>
|
|
181
|
+
struct json_type_traits<Json, T,
|
|
182
|
+
typename std::enable_if<traits_extension::is_integer<T>::value
|
|
183
|
+
>::type>
|
|
184
|
+
{
|
|
185
|
+
using allocator_type = typename Json::allocator_type;
|
|
186
|
+
|
|
187
|
+
static bool is(const Json& j) noexcept
|
|
188
|
+
{
|
|
189
|
+
return j.template is_integer<T>();
|
|
190
|
+
}
|
|
191
|
+
static T as(const Json& j)
|
|
192
|
+
{
|
|
193
|
+
return j.template as_integer<T>();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
static Json to_json(T val, allocator_type alloc = allocator_type())
|
|
197
|
+
{
|
|
198
|
+
return Json(val, semantic_tag::none, alloc);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
template<class Json, class T>
|
|
203
|
+
struct json_type_traits<Json, T,
|
|
204
|
+
typename std::enable_if<std::is_floating_point<T>::value
|
|
205
|
+
>::type>
|
|
206
|
+
{
|
|
207
|
+
using allocator_type = typename Json::allocator_type;
|
|
208
|
+
|
|
209
|
+
static bool is(const Json& j) noexcept
|
|
210
|
+
{
|
|
211
|
+
return j.is_double();
|
|
212
|
+
}
|
|
213
|
+
static T as(const Json& j)
|
|
214
|
+
{
|
|
215
|
+
return static_cast<T>(j.as_double());
|
|
216
|
+
}
|
|
217
|
+
static Json to_json(T val, allocator_type = allocator_type())
|
|
218
|
+
{
|
|
219
|
+
return Json(val, semantic_tag::none);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
template<class Json>
|
|
224
|
+
struct json_type_traits<Json, typename Json::object>
|
|
225
|
+
{
|
|
226
|
+
using json_object = typename Json::object;
|
|
227
|
+
using allocator_type = typename Json::allocator_type;
|
|
228
|
+
|
|
229
|
+
static bool is(const Json& j) noexcept
|
|
230
|
+
{
|
|
231
|
+
return j.is_object();
|
|
232
|
+
}
|
|
233
|
+
static Json to_json(const json_object& o, const allocator_type& = allocator_type())
|
|
234
|
+
{
|
|
235
|
+
return Json(o,semantic_tag::none);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
template<class Json>
|
|
240
|
+
struct json_type_traits<Json, typename Json::array>
|
|
241
|
+
{
|
|
242
|
+
using json_array = typename Json::array;
|
|
243
|
+
using allocator_type = typename Json::allocator_type;
|
|
244
|
+
|
|
245
|
+
static bool is(const Json& j) noexcept
|
|
246
|
+
{
|
|
247
|
+
return j.is_array();
|
|
248
|
+
}
|
|
249
|
+
static Json to_json(const json_array& a, const allocator_type& = allocator_type())
|
|
250
|
+
{
|
|
251
|
+
return Json(a, semantic_tag::none);
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
template<class Json>
|
|
256
|
+
struct json_type_traits<Json, Json>
|
|
257
|
+
{
|
|
258
|
+
using allocator_type = typename Json::allocator_type;
|
|
259
|
+
|
|
260
|
+
static bool is(const Json&) noexcept
|
|
261
|
+
{
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
264
|
+
static Json as(Json j)
|
|
265
|
+
{
|
|
266
|
+
return j;
|
|
267
|
+
}
|
|
268
|
+
static Json to_json(const Json& val, allocator_type = allocator_type())
|
|
269
|
+
{
|
|
270
|
+
return val;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
template<class Json>
|
|
275
|
+
struct json_type_traits<Json, jsoncons::null_type>
|
|
276
|
+
{
|
|
277
|
+
using allocator_type = typename Json::allocator_type;
|
|
278
|
+
|
|
279
|
+
static bool is(const Json& j) noexcept
|
|
280
|
+
{
|
|
281
|
+
return j.is_null();
|
|
282
|
+
}
|
|
283
|
+
static typename jsoncons::null_type as(const Json& j)
|
|
284
|
+
{
|
|
285
|
+
if (!j.is_null())
|
|
286
|
+
{
|
|
287
|
+
JSONCONS_THROW(conv_error(conv_errc::not_jsoncons_null_type));
|
|
288
|
+
}
|
|
289
|
+
return jsoncons::null_type();
|
|
290
|
+
}
|
|
291
|
+
static Json to_json(jsoncons::null_type, allocator_type = allocator_type())
|
|
292
|
+
{
|
|
293
|
+
return Json::null();
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
template<class Json>
|
|
298
|
+
struct json_type_traits<Json, bool>
|
|
299
|
+
{
|
|
300
|
+
using allocator_type = typename Json::allocator_type;
|
|
301
|
+
|
|
302
|
+
static bool is(const Json& j) noexcept
|
|
303
|
+
{
|
|
304
|
+
return j.is_bool();
|
|
305
|
+
}
|
|
306
|
+
static bool as(const Json& j)
|
|
307
|
+
{
|
|
308
|
+
return j.as_bool();
|
|
309
|
+
}
|
|
310
|
+
static Json to_json(bool val, allocator_type = allocator_type())
|
|
311
|
+
{
|
|
312
|
+
return Json(val, semantic_tag::none);
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
template<class Json, class T>
|
|
317
|
+
struct json_type_traits<Json, T, typename std::enable_if<std::is_same<T,
|
|
318
|
+
std::conditional<!std::is_same<bool,std::vector<bool>::const_reference>::value,
|
|
319
|
+
std::vector<bool>::const_reference,
|
|
320
|
+
void>::type>::value>::type>
|
|
321
|
+
{
|
|
322
|
+
using allocator_type = typename Json::allocator_type;
|
|
323
|
+
|
|
324
|
+
static bool is(const Json& j) noexcept
|
|
325
|
+
{
|
|
326
|
+
return j.is_bool();
|
|
327
|
+
}
|
|
328
|
+
static bool as(const Json& j)
|
|
329
|
+
{
|
|
330
|
+
return j.as_bool();
|
|
331
|
+
}
|
|
332
|
+
static Json to_json(bool val, allocator_type = allocator_type())
|
|
333
|
+
{
|
|
334
|
+
return Json(val, semantic_tag::none);
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
template<class Json>
|
|
339
|
+
struct json_type_traits<Json, std::vector<bool>::reference>
|
|
340
|
+
{
|
|
341
|
+
using allocator_type = typename Json::allocator_type;
|
|
342
|
+
|
|
343
|
+
static bool is(const Json& j) noexcept
|
|
344
|
+
{
|
|
345
|
+
return j.is_bool();
|
|
346
|
+
}
|
|
347
|
+
static bool as(const Json& j)
|
|
348
|
+
{
|
|
349
|
+
return j.as_bool();
|
|
350
|
+
}
|
|
351
|
+
static Json to_json(bool val, allocator_type = allocator_type())
|
|
352
|
+
{
|
|
353
|
+
return Json(val, semantic_tag::none);
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
template<class Json, typename T>
|
|
358
|
+
struct json_type_traits<Json, T,
|
|
359
|
+
typename std::enable_if<!is_json_type_traits_declared<T>::value &&
|
|
360
|
+
traits_extension::is_string<T>::value &&
|
|
361
|
+
std::is_same<typename Json::char_type,typename T::value_type>::value>::type>
|
|
362
|
+
{
|
|
363
|
+
using allocator_type = typename Json::allocator_type;
|
|
364
|
+
|
|
365
|
+
static bool is(const Json& j) noexcept
|
|
366
|
+
{
|
|
367
|
+
return j.is_string();
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
static T as(const Json& j)
|
|
371
|
+
{
|
|
372
|
+
return T(j.as_string());
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
static Json to_json(const T& val)
|
|
376
|
+
{
|
|
377
|
+
return Json(val, semantic_tag::none);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
static Json to_json(const T& val, const allocator_type& alloc)
|
|
381
|
+
{
|
|
382
|
+
return Json(val, semantic_tag::none, alloc);
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
template<class Json, typename T>
|
|
387
|
+
struct json_type_traits<Json, T,
|
|
388
|
+
typename std::enable_if<!is_json_type_traits_declared<T>::value &&
|
|
389
|
+
traits_extension::is_string<T>::value &&
|
|
390
|
+
!std::is_same<typename Json::char_type,typename T::value_type>::value>::type>
|
|
391
|
+
{
|
|
392
|
+
using char_type = typename Json::char_type;
|
|
393
|
+
using allocator_type = typename Json::allocator_type;
|
|
394
|
+
|
|
395
|
+
static bool is(const Json& j) noexcept
|
|
396
|
+
{
|
|
397
|
+
return j.is_string();
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
static T as(const Json& j)
|
|
401
|
+
{
|
|
402
|
+
auto s = j.as_string();
|
|
403
|
+
T val;
|
|
404
|
+
unicode_traits::convert(s.data(), s.size(), val);
|
|
405
|
+
return val;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
static Json to_json(const T& val)
|
|
409
|
+
{
|
|
410
|
+
std::basic_string<char_type> s;
|
|
411
|
+
unicode_traits::convert(val.data(), val.size(), s);
|
|
412
|
+
|
|
413
|
+
return Json(s, semantic_tag::none);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
static Json to_json(const T& val, const allocator_type& alloc)
|
|
417
|
+
{
|
|
418
|
+
std::basic_string<char_type> s;
|
|
419
|
+
unicode_traits::convert(val.data(), val.size(), s);
|
|
420
|
+
return Json(s, semantic_tag::none, alloc);
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
template<class Json, typename T>
|
|
425
|
+
struct json_type_traits<Json, T,
|
|
426
|
+
typename std::enable_if<!is_json_type_traits_declared<T>::value &&
|
|
427
|
+
traits_extension::is_string_view<T>::value &&
|
|
428
|
+
std::is_same<typename Json::char_type,typename T::value_type>::value>::type>
|
|
429
|
+
{
|
|
430
|
+
using allocator_type = typename Json::allocator_type;
|
|
431
|
+
|
|
432
|
+
static bool is(const Json& j) noexcept
|
|
433
|
+
{
|
|
434
|
+
return j.is_string_view();
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
static T as(const Json& j)
|
|
438
|
+
{
|
|
439
|
+
return T(j.as_string_view().data(),j.as_string_view().size());
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
static Json to_json(const T& val)
|
|
443
|
+
{
|
|
444
|
+
return Json(val, semantic_tag::none);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
static Json to_json(const T& val, const allocator_type& alloc)
|
|
448
|
+
{
|
|
449
|
+
return Json(val, semantic_tag::none, alloc);
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
// array back insertable
|
|
454
|
+
|
|
455
|
+
template<class Json, typename T>
|
|
456
|
+
struct json_type_traits<Json, T,
|
|
457
|
+
typename std::enable_if<!is_json_type_traits_declared<T>::value &&
|
|
458
|
+
jsoncons::detail::is_compatible_array_type<Json,T>::value &&
|
|
459
|
+
traits_extension::is_back_insertable<T>::value
|
|
460
|
+
>::type>
|
|
461
|
+
{
|
|
462
|
+
typedef typename std::iterator_traits<typename T::iterator>::value_type value_type;
|
|
463
|
+
using allocator_type = typename Json::allocator_type;
|
|
464
|
+
|
|
465
|
+
static bool is(const Json& j) noexcept
|
|
466
|
+
{
|
|
467
|
+
bool result = j.is_array();
|
|
468
|
+
if (result)
|
|
469
|
+
{
|
|
470
|
+
for (auto e : j.array_range())
|
|
471
|
+
{
|
|
472
|
+
if (!e.template is<value_type>())
|
|
473
|
+
{
|
|
474
|
+
result = false;
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
return result;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// array back insertable non-byte container
|
|
483
|
+
|
|
484
|
+
template <class Container = T>
|
|
485
|
+
static typename std::enable_if<!traits_extension::is_byte<typename Container::value_type>::value,Container>::type
|
|
486
|
+
as(const Json& j)
|
|
487
|
+
{
|
|
488
|
+
if (j.is_array())
|
|
489
|
+
{
|
|
490
|
+
T result;
|
|
491
|
+
visit_reserve_(typename std::integral_constant<bool, traits_extension::has_reserve<T>::value>::type(),result,j.size());
|
|
492
|
+
for (const auto& item : j.array_range())
|
|
493
|
+
{
|
|
494
|
+
result.push_back(item.template as<value_type>());
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
return result;
|
|
498
|
+
}
|
|
499
|
+
else
|
|
500
|
+
{
|
|
501
|
+
JSONCONS_THROW(conv_error(conv_errc::not_vector));
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// array back insertable byte container
|
|
506
|
+
|
|
507
|
+
template <class Container = T>
|
|
508
|
+
static typename std::enable_if<traits_extension::is_byte<typename Container::value_type>::value,Container>::type
|
|
509
|
+
as(const Json& j)
|
|
510
|
+
{
|
|
511
|
+
std::error_code ec;
|
|
512
|
+
if (j.is_array())
|
|
513
|
+
{
|
|
514
|
+
T result;
|
|
515
|
+
visit_reserve_(typename std::integral_constant<bool, traits_extension::has_reserve<T>::value>::type(),result,j.size());
|
|
516
|
+
for (const auto& item : j.array_range())
|
|
517
|
+
{
|
|
518
|
+
result.push_back(item.template as<value_type>());
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
return result;
|
|
522
|
+
}
|
|
523
|
+
else if (j.is_byte_string_view())
|
|
524
|
+
{
|
|
525
|
+
value_converter<byte_string_view,T> converter;
|
|
526
|
+
auto v = converter.convert(j.as_byte_string_view(),j.tag(), ec);
|
|
527
|
+
if (ec)
|
|
528
|
+
{
|
|
529
|
+
JSONCONS_THROW(conv_error(ec));
|
|
530
|
+
}
|
|
531
|
+
return v;
|
|
532
|
+
}
|
|
533
|
+
else if (j.is_string())
|
|
534
|
+
{
|
|
535
|
+
value_converter<basic_string_view<char>,T> converter;
|
|
536
|
+
auto v = converter.convert(j.as_string_view(),j.tag(), ec);
|
|
537
|
+
if (ec)
|
|
538
|
+
{
|
|
539
|
+
JSONCONS_THROW(conv_error(ec));
|
|
540
|
+
}
|
|
541
|
+
return v;
|
|
542
|
+
}
|
|
543
|
+
else
|
|
544
|
+
{
|
|
545
|
+
JSONCONS_THROW(conv_error(conv_errc::not_vector));
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
template <class Container = T>
|
|
550
|
+
static typename std::enable_if<!traits_extension::is_std_byte<typename Container::value_type>::value,Json>::type
|
|
551
|
+
to_json(const T& val)
|
|
552
|
+
{
|
|
553
|
+
Json j(json_array_arg);
|
|
554
|
+
auto first = std::begin(val);
|
|
555
|
+
auto last = std::end(val);
|
|
556
|
+
std::size_t size = std::distance(first,last);
|
|
557
|
+
j.reserve(size);
|
|
558
|
+
for (auto it = first; it != last; ++it)
|
|
559
|
+
{
|
|
560
|
+
j.push_back(*it);
|
|
561
|
+
}
|
|
562
|
+
return j;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
template <class Container = T>
|
|
566
|
+
static typename std::enable_if<!traits_extension::is_std_byte<typename Container::value_type>::value,Json>::type
|
|
567
|
+
to_json(const T& val, const allocator_type& alloc)
|
|
568
|
+
{
|
|
569
|
+
Json j(json_array_arg, alloc);
|
|
570
|
+
auto first = std::begin(val);
|
|
571
|
+
auto last = std::end(val);
|
|
572
|
+
std::size_t size = std::distance(first, last);
|
|
573
|
+
j.reserve(size);
|
|
574
|
+
for (auto it = first; it != last; ++it)
|
|
575
|
+
{
|
|
576
|
+
j.push_back(*it);
|
|
577
|
+
}
|
|
578
|
+
return j;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
template <class Container = T>
|
|
582
|
+
static typename std::enable_if<traits_extension::is_std_byte<typename Container::value_type>::value,Json>::type
|
|
583
|
+
to_json(const T& val)
|
|
584
|
+
{
|
|
585
|
+
Json j(byte_string_arg, val);
|
|
586
|
+
return j;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
template <class Container = T>
|
|
590
|
+
static typename std::enable_if<traits_extension::is_std_byte<typename Container::value_type>::value,Json>::type
|
|
591
|
+
to_json(const T& val, const allocator_type& alloc)
|
|
592
|
+
{
|
|
593
|
+
Json j(byte_string_arg, val, semantic_tag::none, alloc);
|
|
594
|
+
return j;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
static void visit_reserve_(std::true_type, T& v, std::size_t size)
|
|
598
|
+
{
|
|
599
|
+
v.reserve(size);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
static void visit_reserve_(std::false_type, T&, std::size_t)
|
|
603
|
+
{
|
|
604
|
+
}
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
// array, not back insertable but insertable
|
|
608
|
+
|
|
609
|
+
template<class Json, typename T>
|
|
610
|
+
struct json_type_traits<Json, T,
|
|
611
|
+
typename std::enable_if<!is_json_type_traits_declared<T>::value &&
|
|
612
|
+
jsoncons::detail::is_compatible_array_type<Json,T>::value &&
|
|
613
|
+
!traits_extension::is_back_insertable<T>::value &&
|
|
614
|
+
traits_extension::is_insertable<T>::value>::type>
|
|
615
|
+
{
|
|
616
|
+
typedef typename std::iterator_traits<typename T::iterator>::value_type value_type;
|
|
617
|
+
using allocator_type = typename Json::allocator_type;
|
|
618
|
+
|
|
619
|
+
static bool is(const Json& j) noexcept
|
|
620
|
+
{
|
|
621
|
+
bool result = j.is_array();
|
|
622
|
+
if (result)
|
|
623
|
+
{
|
|
624
|
+
for (auto e : j.array_range())
|
|
625
|
+
{
|
|
626
|
+
if (!e.template is<value_type>())
|
|
627
|
+
{
|
|
628
|
+
result = false;
|
|
629
|
+
break;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
return result;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
static T as(const Json& j)
|
|
637
|
+
{
|
|
638
|
+
if (j.is_array())
|
|
639
|
+
{
|
|
640
|
+
T result;
|
|
641
|
+
for (const auto& item : j.array_range())
|
|
642
|
+
{
|
|
643
|
+
result.insert(item.template as<value_type>());
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
return result;
|
|
647
|
+
}
|
|
648
|
+
else
|
|
649
|
+
{
|
|
650
|
+
JSONCONS_THROW(conv_error(conv_errc::not_vector));
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
static Json to_json(const T& val)
|
|
655
|
+
{
|
|
656
|
+
Json j(json_array_arg);
|
|
657
|
+
auto first = std::begin(val);
|
|
658
|
+
auto last = std::end(val);
|
|
659
|
+
std::size_t size = std::distance(first,last);
|
|
660
|
+
j.reserve(size);
|
|
661
|
+
for (auto it = first; it != last; ++it)
|
|
662
|
+
{
|
|
663
|
+
j.push_back(*it);
|
|
664
|
+
}
|
|
665
|
+
return j;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
static Json to_json(const T& val, const allocator_type& alloc)
|
|
669
|
+
{
|
|
670
|
+
Json j(json_array_arg, alloc);
|
|
671
|
+
auto first = std::begin(val);
|
|
672
|
+
auto last = std::end(val);
|
|
673
|
+
std::size_t size = std::distance(first, last);
|
|
674
|
+
j.reserve(size);
|
|
675
|
+
for (auto it = first; it != last; ++it)
|
|
676
|
+
{
|
|
677
|
+
j.push_back(*it);
|
|
678
|
+
}
|
|
679
|
+
return j;
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
// array not back insertable or insertable, but front insertable
|
|
684
|
+
|
|
685
|
+
template<class Json, typename T>
|
|
686
|
+
struct json_type_traits<Json, T,
|
|
687
|
+
typename std::enable_if<!is_json_type_traits_declared<T>::value &&
|
|
688
|
+
jsoncons::detail::is_compatible_array_type<Json,T>::value &&
|
|
689
|
+
!traits_extension::is_back_insertable<T>::value &&
|
|
690
|
+
!traits_extension::is_insertable<T>::value &&
|
|
691
|
+
traits_extension::is_front_insertable<T>::value>::type>
|
|
692
|
+
{
|
|
693
|
+
typedef typename std::iterator_traits<typename T::iterator>::value_type value_type;
|
|
694
|
+
using allocator_type = typename Json::allocator_type;
|
|
695
|
+
|
|
696
|
+
static bool is(const Json& j) noexcept
|
|
697
|
+
{
|
|
698
|
+
bool result = j.is_array();
|
|
699
|
+
if (result)
|
|
700
|
+
{
|
|
701
|
+
for (auto e : j.array_range())
|
|
702
|
+
{
|
|
703
|
+
if (!e.template is<value_type>())
|
|
704
|
+
{
|
|
705
|
+
result = false;
|
|
706
|
+
break;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
return result;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
static T as(const Json& j)
|
|
714
|
+
{
|
|
715
|
+
if (j.is_array())
|
|
716
|
+
{
|
|
717
|
+
T result;
|
|
718
|
+
|
|
719
|
+
auto it = j.array_range().rbegin();
|
|
720
|
+
auto end = j.array_range().rend();
|
|
721
|
+
for (; it != end; ++it)
|
|
722
|
+
{
|
|
723
|
+
result.push_front((*it).template as<value_type>());
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
return result;
|
|
727
|
+
}
|
|
728
|
+
else
|
|
729
|
+
{
|
|
730
|
+
JSONCONS_THROW(conv_error(conv_errc::not_vector));
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
static Json to_json(const T& val)
|
|
735
|
+
{
|
|
736
|
+
Json j(json_array_arg);
|
|
737
|
+
auto first = std::begin(val);
|
|
738
|
+
auto last = std::end(val);
|
|
739
|
+
std::size_t size = std::distance(first,last);
|
|
740
|
+
j.reserve(size);
|
|
741
|
+
for (auto it = first; it != last; ++it)
|
|
742
|
+
{
|
|
743
|
+
j.push_back(*it);
|
|
744
|
+
}
|
|
745
|
+
return j;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
static Json to_json(const T& val, const allocator_type& alloc)
|
|
749
|
+
{
|
|
750
|
+
Json j(json_array_arg, alloc);
|
|
751
|
+
auto first = std::begin(val);
|
|
752
|
+
auto last = std::end(val);
|
|
753
|
+
std::size_t size = std::distance(first, last);
|
|
754
|
+
j.reserve(size);
|
|
755
|
+
for (auto it = first; it != last; ++it)
|
|
756
|
+
{
|
|
757
|
+
j.push_back(*it);
|
|
758
|
+
}
|
|
759
|
+
return j;
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
// std::array
|
|
764
|
+
|
|
765
|
+
template<class Json, class E, std::size_t N>
|
|
766
|
+
struct json_type_traits<Json, std::array<E, N>>
|
|
767
|
+
{
|
|
768
|
+
using allocator_type = typename Json::allocator_type;
|
|
769
|
+
|
|
770
|
+
using value_type = E;
|
|
771
|
+
|
|
772
|
+
static bool is(const Json& j) noexcept
|
|
773
|
+
{
|
|
774
|
+
bool result = j.is_array() && j.size() == N;
|
|
775
|
+
if (result)
|
|
776
|
+
{
|
|
777
|
+
for (auto e : j.array_range())
|
|
778
|
+
{
|
|
779
|
+
if (!e.template is<value_type>())
|
|
780
|
+
{
|
|
781
|
+
result = false;
|
|
782
|
+
break;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return result;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
static std::array<E, N> as(const Json& j)
|
|
790
|
+
{
|
|
791
|
+
std::array<E, N> buff;
|
|
792
|
+
if (j.size() != N)
|
|
793
|
+
{
|
|
794
|
+
JSONCONS_THROW(conv_error(conv_errc::not_array));
|
|
795
|
+
}
|
|
796
|
+
for (std::size_t i = 0; i < N; i++)
|
|
797
|
+
{
|
|
798
|
+
buff[i] = j[i].template as<E>();
|
|
799
|
+
}
|
|
800
|
+
return buff;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
static Json to_json(const std::array<E, N>& val)
|
|
804
|
+
{
|
|
805
|
+
Json j(json_array_arg);
|
|
806
|
+
j.reserve(N);
|
|
807
|
+
for (auto it = val.begin(); it != val.end(); ++it)
|
|
808
|
+
{
|
|
809
|
+
j.push_back(*it);
|
|
810
|
+
}
|
|
811
|
+
return j;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
static Json to_json(const std::array<E, N>& val,
|
|
815
|
+
const allocator_type& alloc)
|
|
816
|
+
{
|
|
817
|
+
Json j(json_array_arg, alloc);
|
|
818
|
+
j.reserve(N);
|
|
819
|
+
for (auto it = val.begin(); it != val.end(); ++it)
|
|
820
|
+
{
|
|
821
|
+
j.push_back(*it);
|
|
822
|
+
}
|
|
823
|
+
return j;
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
// map like
|
|
828
|
+
template<class Json, typename T>
|
|
829
|
+
struct json_type_traits<Json, T,
|
|
830
|
+
typename std::enable_if<!is_json_type_traits_declared<T>::value &&
|
|
831
|
+
traits_extension::is_map_like<T>::value &&
|
|
832
|
+
traits_extension::is_constructible_from_const_pointer_and_size<typename T::key_type>::value &&
|
|
833
|
+
is_json_type_traits_specialized<Json,typename T::mapped_type>::value>::type
|
|
834
|
+
>
|
|
835
|
+
{
|
|
836
|
+
using mapped_type = typename T::mapped_type;
|
|
837
|
+
using value_type = typename T::value_type;
|
|
838
|
+
using key_type = typename T::key_type;
|
|
839
|
+
using allocator_type = typename Json::allocator_type;
|
|
840
|
+
|
|
841
|
+
static bool is(const Json& j) noexcept
|
|
842
|
+
{
|
|
843
|
+
bool result = j.is_object();
|
|
844
|
+
for (auto member : j.object_range())
|
|
845
|
+
{
|
|
846
|
+
if (!member.value().template is<mapped_type>())
|
|
847
|
+
{
|
|
848
|
+
result = false;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
return result;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
static T as(const Json& j)
|
|
855
|
+
{
|
|
856
|
+
if (!j.is_object())
|
|
857
|
+
{
|
|
858
|
+
JSONCONS_THROW(conv_error(conv_errc::not_map));
|
|
859
|
+
}
|
|
860
|
+
T result;
|
|
861
|
+
for (const auto& item : j.object_range())
|
|
862
|
+
{
|
|
863
|
+
result.emplace(key_type(item.key().data(),item.key().size()), item.value().template as<mapped_type>());
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
return result;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
static Json to_json(const T& val)
|
|
870
|
+
{
|
|
871
|
+
Json j(json_object_arg, val.begin(), val.end());
|
|
872
|
+
return j;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
static Json to_json(const T& val, const allocator_type& alloc)
|
|
876
|
+
{
|
|
877
|
+
Json j(json_object_arg, val.begin(), val.end(), alloc);
|
|
878
|
+
return j;
|
|
879
|
+
}
|
|
880
|
+
};
|
|
881
|
+
|
|
882
|
+
template <class Json, typename T>
|
|
883
|
+
struct json_type_traits<Json, T,
|
|
884
|
+
typename std::enable_if<!is_json_type_traits_declared<T>::value &&
|
|
885
|
+
traits_extension::is_map_like<T>::value &&
|
|
886
|
+
!traits_extension::is_constructible_from_const_pointer_and_size<typename T::key_type>::value &&
|
|
887
|
+
is_json_type_traits_specialized<Json,typename T::key_type>::value &&
|
|
888
|
+
is_json_type_traits_specialized<Json,typename T::mapped_type>::value>::type
|
|
889
|
+
>
|
|
890
|
+
{
|
|
891
|
+
using mapped_type = typename T::mapped_type;
|
|
892
|
+
using value_type = typename T::value_type;
|
|
893
|
+
using key_type = typename T::key_type;
|
|
894
|
+
using allocator_type = typename Json::allocator_type;
|
|
895
|
+
|
|
896
|
+
static bool is(const Json& val) noexcept
|
|
897
|
+
{
|
|
898
|
+
if (!val.is_object())
|
|
899
|
+
return false;
|
|
900
|
+
for (const auto& item : val.object_range())
|
|
901
|
+
{
|
|
902
|
+
Json j(item.key());
|
|
903
|
+
if (!j.template is<key_type>())
|
|
904
|
+
{
|
|
905
|
+
return false;
|
|
906
|
+
}
|
|
907
|
+
if (!item.value().template is<mapped_type>())
|
|
908
|
+
{
|
|
909
|
+
return false;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
return true;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
static T as(const Json& val)
|
|
916
|
+
{
|
|
917
|
+
T result;
|
|
918
|
+
for (const auto& item : val.object_range())
|
|
919
|
+
{
|
|
920
|
+
Json j(item.key());
|
|
921
|
+
auto key = json_type_traits<Json,key_type>::as(j);
|
|
922
|
+
result.emplace(std::move(key), item.value().template as<mapped_type>());
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
return result;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
static Json to_json(const T& val)
|
|
929
|
+
{
|
|
930
|
+
Json j(json_object_arg);
|
|
931
|
+
j.reserve(val.size());
|
|
932
|
+
for (const auto& item : val)
|
|
933
|
+
{
|
|
934
|
+
auto temp = json_type_traits<Json,key_type>::to_json(item.first);
|
|
935
|
+
typename Json::key_type key;
|
|
936
|
+
temp.dump(key);
|
|
937
|
+
j.try_emplace(std::move(key), item.second);
|
|
938
|
+
}
|
|
939
|
+
return j;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
static Json to_json(const T& val, const allocator_type& alloc)
|
|
943
|
+
{
|
|
944
|
+
Json j(json_object_arg, semantic_tag::none, alloc);
|
|
945
|
+
j.reserve(val.size());
|
|
946
|
+
for (const auto& item : val)
|
|
947
|
+
{
|
|
948
|
+
auto temp = json_type_traits<Json,key_type>::to_json(item.first, alloc);
|
|
949
|
+
typename Json::key_type key(alloc);
|
|
950
|
+
temp.dump(key);
|
|
951
|
+
j.try_emplace(std::move(key), item.second, alloc);
|
|
952
|
+
}
|
|
953
|
+
return j;
|
|
954
|
+
}
|
|
955
|
+
};
|
|
956
|
+
|
|
957
|
+
namespace tuple_detail
|
|
958
|
+
{
|
|
959
|
+
template<size_t Pos, std::size_t Size, class Json, class Tuple>
|
|
960
|
+
struct json_tuple_helper
|
|
961
|
+
{
|
|
962
|
+
using element_type = typename std::tuple_element<Size-Pos, Tuple>::type;
|
|
963
|
+
using next = json_tuple_helper<Pos-1, Size, Json, Tuple>;
|
|
964
|
+
|
|
965
|
+
static bool is(const Json& j) noexcept
|
|
966
|
+
{
|
|
967
|
+
if (j[Size-Pos].template is<element_type>())
|
|
968
|
+
{
|
|
969
|
+
return next::is(j);
|
|
970
|
+
}
|
|
971
|
+
else
|
|
972
|
+
{
|
|
973
|
+
return false;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
static void as(Tuple& tuple, const Json& j)
|
|
978
|
+
{
|
|
979
|
+
std::get<Size-Pos>(tuple) = j[Size-Pos].template as<element_type>();
|
|
980
|
+
next::as(tuple, j);
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
static void to_json(const Tuple& tuple, Json& j)
|
|
984
|
+
{
|
|
985
|
+
j.push_back(json_type_traits<Json, element_type>::to_json(std::get<Size-Pos>(tuple)));
|
|
986
|
+
next::to_json(tuple, j);
|
|
987
|
+
}
|
|
988
|
+
};
|
|
989
|
+
|
|
990
|
+
template<size_t Size, class Json, class Tuple>
|
|
991
|
+
struct json_tuple_helper<0, Size, Json, Tuple>
|
|
992
|
+
{
|
|
993
|
+
static bool is(const Json&) noexcept
|
|
994
|
+
{
|
|
995
|
+
return true;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
static void as(Tuple&, const Json&)
|
|
999
|
+
{
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
static void to_json(const Tuple&, Json&)
|
|
1003
|
+
{
|
|
1004
|
+
}
|
|
1005
|
+
};
|
|
1006
|
+
} // namespace detail
|
|
1007
|
+
|
|
1008
|
+
template<class Json, typename... E>
|
|
1009
|
+
struct json_type_traits<Json, std::tuple<E...>>
|
|
1010
|
+
{
|
|
1011
|
+
private:
|
|
1012
|
+
using helper = tuple_detail::json_tuple_helper<sizeof...(E), sizeof...(E), Json, std::tuple<E...>>;
|
|
1013
|
+
|
|
1014
|
+
public:
|
|
1015
|
+
using allocator_type = typename Json::allocator_type;
|
|
1016
|
+
|
|
1017
|
+
static bool is(const Json& j) noexcept
|
|
1018
|
+
{
|
|
1019
|
+
return helper::is(j);
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
static std::tuple<E...> as(const Json& j)
|
|
1023
|
+
{
|
|
1024
|
+
std::tuple<E...> buff;
|
|
1025
|
+
helper::as(buff, j);
|
|
1026
|
+
return buff;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
static Json to_json(const std::tuple<E...>& val)
|
|
1030
|
+
{
|
|
1031
|
+
Json j(json_array_arg);
|
|
1032
|
+
j.reserve(sizeof...(E));
|
|
1033
|
+
helper::to_json(val, j);
|
|
1034
|
+
return j;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
static Json to_json(const std::tuple<E...>& val,
|
|
1038
|
+
const allocator_type& alloc)
|
|
1039
|
+
{
|
|
1040
|
+
Json j(json_array_arg, alloc);
|
|
1041
|
+
j.reserve(sizeof...(E));
|
|
1042
|
+
helper::to_json(val, j);
|
|
1043
|
+
return j;
|
|
1044
|
+
}
|
|
1045
|
+
};
|
|
1046
|
+
|
|
1047
|
+
template<class Json, class T1, class T2>
|
|
1048
|
+
struct json_type_traits<Json, std::pair<T1,T2>>
|
|
1049
|
+
{
|
|
1050
|
+
public:
|
|
1051
|
+
using allocator_type = typename Json::allocator_type;
|
|
1052
|
+
|
|
1053
|
+
static bool is(const Json& j) noexcept
|
|
1054
|
+
{
|
|
1055
|
+
return j.is_array() && j.size() == 2;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
static std::pair<T1,T2> as(const Json& j)
|
|
1059
|
+
{
|
|
1060
|
+
return std::make_pair<T1,T2>(j[0].template as<T1>(),j[1].template as<T2>());
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
static Json to_json(const std::pair<T1,T2>& val)
|
|
1064
|
+
{
|
|
1065
|
+
Json j(json_array_arg);
|
|
1066
|
+
j.reserve(2);
|
|
1067
|
+
j.push_back(val.first);
|
|
1068
|
+
j.push_back(val.second);
|
|
1069
|
+
return j;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
static Json to_json(const std::pair<T1, T2>& val, const allocator_type& alloc)
|
|
1073
|
+
{
|
|
1074
|
+
Json j(json_array_arg, alloc);
|
|
1075
|
+
j.reserve(2);
|
|
1076
|
+
j.push_back(val.first);
|
|
1077
|
+
j.push_back(val.second);
|
|
1078
|
+
return j;
|
|
1079
|
+
}
|
|
1080
|
+
};
|
|
1081
|
+
|
|
1082
|
+
template<class Json, class T>
|
|
1083
|
+
struct json_type_traits<Json, T,
|
|
1084
|
+
typename std::enable_if<traits_extension::is_basic_byte_string<T>::value>::type>
|
|
1085
|
+
{
|
|
1086
|
+
public:
|
|
1087
|
+
using allocator_type = typename Json::allocator_type;
|
|
1088
|
+
|
|
1089
|
+
static bool is(const Json& j) noexcept
|
|
1090
|
+
{
|
|
1091
|
+
return j.is_byte_string();
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
static T as(const Json& j)
|
|
1095
|
+
{
|
|
1096
|
+
return j.template as_byte_string<typename T::allocator_type>();
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
static Json to_json(const T& val,
|
|
1100
|
+
const allocator_type& alloc = allocator_type())
|
|
1101
|
+
{
|
|
1102
|
+
return Json(byte_string_arg, val, semantic_tag::none, alloc);
|
|
1103
|
+
}
|
|
1104
|
+
};
|
|
1105
|
+
|
|
1106
|
+
template<class Json, class ValueType>
|
|
1107
|
+
struct json_type_traits<Json, std::shared_ptr<ValueType>,
|
|
1108
|
+
typename std::enable_if<!is_json_type_traits_declared<std::shared_ptr<ValueType>>::value &&
|
|
1109
|
+
!std::is_polymorphic<ValueType>::value
|
|
1110
|
+
>::type>
|
|
1111
|
+
{
|
|
1112
|
+
static bool is(const Json& j) noexcept
|
|
1113
|
+
{
|
|
1114
|
+
return j.is_null() || j.template is<ValueType>();
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
static std::shared_ptr<ValueType> as(const Json& j)
|
|
1118
|
+
{
|
|
1119
|
+
return j.is_null() ? std::shared_ptr<ValueType>(nullptr) : std::make_shared<ValueType>(j.template as<ValueType>());
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
static Json to_json(const std::shared_ptr<ValueType>& ptr)
|
|
1123
|
+
{
|
|
1124
|
+
if (ptr.get() != nullptr)
|
|
1125
|
+
{
|
|
1126
|
+
Json j(*ptr);
|
|
1127
|
+
return j;
|
|
1128
|
+
}
|
|
1129
|
+
else
|
|
1130
|
+
{
|
|
1131
|
+
return Json::null();
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
};
|
|
1135
|
+
|
|
1136
|
+
template<class Json, class ValueType>
|
|
1137
|
+
struct json_type_traits<Json, std::unique_ptr<ValueType>,
|
|
1138
|
+
typename std::enable_if<!is_json_type_traits_declared<std::unique_ptr<ValueType>>::value &&
|
|
1139
|
+
!std::is_polymorphic<ValueType>::value
|
|
1140
|
+
>::type>
|
|
1141
|
+
{
|
|
1142
|
+
static bool is(const Json& j) noexcept
|
|
1143
|
+
{
|
|
1144
|
+
return j.is_null() || j.template is<ValueType>();
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
static std::unique_ptr<ValueType> as(const Json& j)
|
|
1148
|
+
{
|
|
1149
|
+
return j.is_null() ? std::unique_ptr<ValueType>(nullptr) : jsoncons::make_unique<ValueType>(j.template as<ValueType>());
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
static Json to_json(const std::unique_ptr<ValueType>& ptr)
|
|
1153
|
+
{
|
|
1154
|
+
if (ptr.get() != nullptr)
|
|
1155
|
+
{
|
|
1156
|
+
Json j(*ptr);
|
|
1157
|
+
return j;
|
|
1158
|
+
}
|
|
1159
|
+
else
|
|
1160
|
+
{
|
|
1161
|
+
return Json::null();
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
};
|
|
1165
|
+
|
|
1166
|
+
template<class Json, class T>
|
|
1167
|
+
struct json_type_traits<Json, jsoncons::optional<T>,
|
|
1168
|
+
typename std::enable_if<!is_json_type_traits_declared<jsoncons::optional<T>>::value>::type>
|
|
1169
|
+
{
|
|
1170
|
+
public:
|
|
1171
|
+
static bool is(const Json& j) noexcept
|
|
1172
|
+
{
|
|
1173
|
+
return j.is_null() || j.template is<T>();
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
static jsoncons::optional<T> as(const Json& j)
|
|
1177
|
+
{
|
|
1178
|
+
return j.is_null() ? jsoncons::optional<T>() : jsoncons::optional<T>(j.template as<T>());
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
static Json to_json(const jsoncons::optional<T>& val)
|
|
1182
|
+
{
|
|
1183
|
+
return val.has_value() ? Json(*val) : Json::null();
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
|
|
1187
|
+
template<class Json>
|
|
1188
|
+
struct json_type_traits<Json, byte_string_view>
|
|
1189
|
+
{
|
|
1190
|
+
using allocator_type = typename Json::allocator_type;
|
|
1191
|
+
|
|
1192
|
+
public:
|
|
1193
|
+
static bool is(const Json& j) noexcept
|
|
1194
|
+
{
|
|
1195
|
+
return j.is_byte_string_view();
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
static byte_string_view as(const Json& j)
|
|
1199
|
+
{
|
|
1200
|
+
return j.as_byte_string_view();
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
static Json to_json(const byte_string_view& val, const allocator_type& alloc = allocator_type())
|
|
1204
|
+
{
|
|
1205
|
+
return Json(byte_string_arg, val, semantic_tag::none, alloc);
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
// basic_bigint
|
|
1210
|
+
|
|
1211
|
+
template<class Json, class Allocator>
|
|
1212
|
+
struct json_type_traits<Json, basic_bigint<Allocator>>
|
|
1213
|
+
{
|
|
1214
|
+
public:
|
|
1215
|
+
using char_type = typename Json::char_type;
|
|
1216
|
+
|
|
1217
|
+
static bool is(const Json& j) noexcept
|
|
1218
|
+
{
|
|
1219
|
+
switch (j.type())
|
|
1220
|
+
{
|
|
1221
|
+
case json_type::string_value:
|
|
1222
|
+
return jsoncons::detail::is_base10(j.as_string_view().data(), j.as_string_view().length());
|
|
1223
|
+
case json_type::int64_value:
|
|
1224
|
+
case json_type::uint64_value:
|
|
1225
|
+
return true;
|
|
1226
|
+
default:
|
|
1227
|
+
return false;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
static basic_bigint<Allocator> as(const Json& j)
|
|
1232
|
+
{
|
|
1233
|
+
switch (j.type())
|
|
1234
|
+
{
|
|
1235
|
+
case json_type::string_value:
|
|
1236
|
+
if (!jsoncons::detail::is_base10(j.as_string_view().data(), j.as_string_view().length()))
|
|
1237
|
+
{
|
|
1238
|
+
JSONCONS_THROW(conv_error(conv_errc::not_bigint));
|
|
1239
|
+
}
|
|
1240
|
+
return basic_bigint<Allocator>::from_string(j.as_string_view().data(), j.as_string_view().length());
|
|
1241
|
+
case json_type::half_value:
|
|
1242
|
+
case json_type::double_value:
|
|
1243
|
+
return basic_bigint<Allocator>(j.template as<int64_t>());
|
|
1244
|
+
case json_type::int64_value:
|
|
1245
|
+
return basic_bigint<Allocator>(j.template as<int64_t>());
|
|
1246
|
+
case json_type::uint64_value:
|
|
1247
|
+
return basic_bigint<Allocator>(j.template as<uint64_t>());
|
|
1248
|
+
default:
|
|
1249
|
+
JSONCONS_THROW(conv_error(conv_errc::not_bigint));
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
static Json to_json(const basic_bigint<Allocator>& val)
|
|
1254
|
+
{
|
|
1255
|
+
std::basic_string<char_type> s;
|
|
1256
|
+
val.write_string(s);
|
|
1257
|
+
return Json(s,semantic_tag::bigint);
|
|
1258
|
+
}
|
|
1259
|
+
};
|
|
1260
|
+
|
|
1261
|
+
// std::valarray
|
|
1262
|
+
|
|
1263
|
+
template<class Json, class T>
|
|
1264
|
+
struct json_type_traits<Json, std::valarray<T>>
|
|
1265
|
+
{
|
|
1266
|
+
using allocator_type = typename Json::allocator_type;
|
|
1267
|
+
|
|
1268
|
+
static bool is(const Json& j) noexcept
|
|
1269
|
+
{
|
|
1270
|
+
bool result = j.is_array();
|
|
1271
|
+
if (result)
|
|
1272
|
+
{
|
|
1273
|
+
for (auto e : j.array_range())
|
|
1274
|
+
{
|
|
1275
|
+
if (!e.template is<T>())
|
|
1276
|
+
{
|
|
1277
|
+
result = false;
|
|
1278
|
+
break;
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
return result;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
static std::valarray<T> as(const Json& j)
|
|
1286
|
+
{
|
|
1287
|
+
if (j.is_array())
|
|
1288
|
+
{
|
|
1289
|
+
std::valarray<T> v(j.size());
|
|
1290
|
+
for (std::size_t i = 0; i < j.size(); ++i)
|
|
1291
|
+
{
|
|
1292
|
+
v[i] = j[i].template as<T>();
|
|
1293
|
+
}
|
|
1294
|
+
return v;
|
|
1295
|
+
}
|
|
1296
|
+
else
|
|
1297
|
+
{
|
|
1298
|
+
JSONCONS_THROW(conv_error(conv_errc::not_array));
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
static Json to_json(const std::valarray<T>& val)
|
|
1303
|
+
{
|
|
1304
|
+
Json j(json_array_arg);
|
|
1305
|
+
auto first = std::begin(val);
|
|
1306
|
+
auto last = std::end(val);
|
|
1307
|
+
std::size_t size = std::distance(first,last);
|
|
1308
|
+
j.reserve(size);
|
|
1309
|
+
for (auto it = first; it != last; ++it)
|
|
1310
|
+
{
|
|
1311
|
+
j.push_back(*it);
|
|
1312
|
+
}
|
|
1313
|
+
return j;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
static Json to_json(const std::valarray<T>& val, const allocator_type& alloc)
|
|
1317
|
+
{
|
|
1318
|
+
Json j(json_array_arg, alloc);
|
|
1319
|
+
auto first = std::begin(val);
|
|
1320
|
+
auto last = std::end(val);
|
|
1321
|
+
std::size_t size = std::distance(first,last);
|
|
1322
|
+
j.reserve(size);
|
|
1323
|
+
for (auto it = first; it != last; ++it)
|
|
1324
|
+
{
|
|
1325
|
+
j.push_back(*it);
|
|
1326
|
+
}
|
|
1327
|
+
return j;
|
|
1328
|
+
}
|
|
1329
|
+
};
|
|
1330
|
+
|
|
1331
|
+
#if defined(JSONCONS_HAS_STD_VARIANT)
|
|
1332
|
+
|
|
1333
|
+
namespace variant_detail
|
|
1334
|
+
{
|
|
1335
|
+
template<int N, class Json, class Variant, class ... Args>
|
|
1336
|
+
typename std::enable_if<N == std::variant_size_v<Variant>, bool>::type
|
|
1337
|
+
is_variant(const Json& /*j*/)
|
|
1338
|
+
{
|
|
1339
|
+
return false;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
template<std::size_t N, class Json, class Variant, class T, class ... U>
|
|
1343
|
+
typename std::enable_if<N < std::variant_size_v<Variant>, bool>::type
|
|
1344
|
+
is_variant(const Json& j)
|
|
1345
|
+
{
|
|
1346
|
+
if (j.template is<T>())
|
|
1347
|
+
{
|
|
1348
|
+
return true;
|
|
1349
|
+
}
|
|
1350
|
+
else
|
|
1351
|
+
{
|
|
1352
|
+
return is_variant<N+1, Json, Variant, U...>(j);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
template<int N, class Json, class Variant, class ... Args>
|
|
1357
|
+
typename std::enable_if<N == std::variant_size_v<Variant>, Variant>::type
|
|
1358
|
+
as_variant(const Json& /*j*/)
|
|
1359
|
+
{
|
|
1360
|
+
JSONCONS_THROW(conv_error(conv_errc::not_variant));
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
template<std::size_t N, class Json, class Variant, class T, class ... U>
|
|
1364
|
+
typename std::enable_if<N < std::variant_size_v<Variant>, Variant>::type
|
|
1365
|
+
as_variant(const Json& j)
|
|
1366
|
+
{
|
|
1367
|
+
if (j.template is<T>())
|
|
1368
|
+
{
|
|
1369
|
+
Variant var(j.template as<T>());
|
|
1370
|
+
return var;
|
|
1371
|
+
}
|
|
1372
|
+
else
|
|
1373
|
+
{
|
|
1374
|
+
return as_variant<N+1, Json, Variant, U...>(j);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
template <class Json>
|
|
1379
|
+
struct variant_to_json_visitor
|
|
1380
|
+
{
|
|
1381
|
+
Json& j_;
|
|
1382
|
+
|
|
1383
|
+
variant_to_json_visitor(Json& j) : j_(j) {}
|
|
1384
|
+
|
|
1385
|
+
template<class T>
|
|
1386
|
+
void operator()(const T& value) const
|
|
1387
|
+
{
|
|
1388
|
+
j_ = value;
|
|
1389
|
+
}
|
|
1390
|
+
};
|
|
1391
|
+
|
|
1392
|
+
} // namespace variant_detail
|
|
1393
|
+
|
|
1394
|
+
template<class Json, typename... VariantTypes>
|
|
1395
|
+
struct json_type_traits<Json, std::variant<VariantTypes...>>
|
|
1396
|
+
{
|
|
1397
|
+
public:
|
|
1398
|
+
using variant_type = typename std::variant<VariantTypes...>;
|
|
1399
|
+
using allocator_type = typename Json::allocator_type;
|
|
1400
|
+
|
|
1401
|
+
static bool is(const Json& j) noexcept
|
|
1402
|
+
{
|
|
1403
|
+
return variant_detail::is_variant<0,Json,variant_type, VariantTypes...>(j);
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
static std::variant<VariantTypes...> as(const Json& j)
|
|
1407
|
+
{
|
|
1408
|
+
return variant_detail::as_variant<0,Json,variant_type, VariantTypes...>(j);
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
static Json to_json(const std::variant<VariantTypes...>& var)
|
|
1412
|
+
{
|
|
1413
|
+
Json j(json_array_arg);
|
|
1414
|
+
variant_detail::variant_to_json_visitor<Json> visitor(j);
|
|
1415
|
+
std::visit(visitor, var);
|
|
1416
|
+
return j;
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
static Json to_json(const std::variant<VariantTypes...>& var,
|
|
1420
|
+
const allocator_type& alloc)
|
|
1421
|
+
{
|
|
1422
|
+
Json j(json_array_arg, alloc);
|
|
1423
|
+
variant_detail::variant_to_json_visitor<Json> visitor(j);
|
|
1424
|
+
std::visit(visitor, var);
|
|
1425
|
+
return j;
|
|
1426
|
+
}
|
|
1427
|
+
};
|
|
1428
|
+
#endif
|
|
1429
|
+
|
|
1430
|
+
// std::chrono::duration
|
|
1431
|
+
template<class Json,class Rep,class Period>
|
|
1432
|
+
struct json_type_traits<Json,std::chrono::duration<Rep,Period>>
|
|
1433
|
+
{
|
|
1434
|
+
using duration_type = std::chrono::duration<Rep,Period>;
|
|
1435
|
+
|
|
1436
|
+
using allocator_type = typename Json::allocator_type;
|
|
1437
|
+
|
|
1438
|
+
static constexpr int64_t nanos_in_milli = 1000000;
|
|
1439
|
+
static constexpr int64_t nanos_in_second = 1000000000;
|
|
1440
|
+
static constexpr int64_t millis_in_second = 1000;
|
|
1441
|
+
|
|
1442
|
+
static bool is(const Json& j) noexcept
|
|
1443
|
+
{
|
|
1444
|
+
return (j.tag() == semantic_tag::epoch_second || j.tag() == semantic_tag::epoch_milli || j.tag() == semantic_tag::epoch_nano);
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
static duration_type as(const Json& j)
|
|
1448
|
+
{
|
|
1449
|
+
return from_json_(j);
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
static Json to_json(const duration_type& val, allocator_type = allocator_type())
|
|
1453
|
+
{
|
|
1454
|
+
return to_json_(val);
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
template <class PeriodT=Period>
|
|
1458
|
+
static
|
|
1459
|
+
typename std::enable_if<std::is_same<PeriodT,std::ratio<1>>::value, duration_type>::type
|
|
1460
|
+
from_json_(const Json& j)
|
|
1461
|
+
{
|
|
1462
|
+
if (j.is_int64() || j.is_uint64() || j.is_double())
|
|
1463
|
+
{
|
|
1464
|
+
auto count = j.template as<Rep>();
|
|
1465
|
+
switch (j.tag())
|
|
1466
|
+
{
|
|
1467
|
+
case semantic_tag::epoch_second:
|
|
1468
|
+
return duration_type(count);
|
|
1469
|
+
case semantic_tag::epoch_milli:
|
|
1470
|
+
return duration_type(count == 0 ? 0 : count/millis_in_second);
|
|
1471
|
+
case semantic_tag::epoch_nano:
|
|
1472
|
+
return duration_type(count == 0 ? 0 : count/nanos_in_second);
|
|
1473
|
+
default:
|
|
1474
|
+
return duration_type(count);
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
else if (j.is_string())
|
|
1478
|
+
{
|
|
1479
|
+
switch (j.tag())
|
|
1480
|
+
{
|
|
1481
|
+
case semantic_tag::epoch_second:
|
|
1482
|
+
{
|
|
1483
|
+
auto count = j.template as<Rep>();
|
|
1484
|
+
return duration_type(count);
|
|
1485
|
+
}
|
|
1486
|
+
case semantic_tag::epoch_milli:
|
|
1487
|
+
{
|
|
1488
|
+
auto sv = j.as_string_view();
|
|
1489
|
+
bigint n = bigint::from_string(sv.data(), sv.length());
|
|
1490
|
+
if (n != 0)
|
|
1491
|
+
{
|
|
1492
|
+
n = n / millis_in_second;
|
|
1493
|
+
}
|
|
1494
|
+
return duration_type(static_cast<Rep>(n));
|
|
1495
|
+
}
|
|
1496
|
+
case semantic_tag::epoch_nano:
|
|
1497
|
+
{
|
|
1498
|
+
auto sv = j.as_string_view();
|
|
1499
|
+
bigint n = bigint::from_string(sv.data(), sv.length());
|
|
1500
|
+
if (n != 0)
|
|
1501
|
+
{
|
|
1502
|
+
n = n / nanos_in_second;
|
|
1503
|
+
}
|
|
1504
|
+
return duration_type(static_cast<Rep>(n));
|
|
1505
|
+
}
|
|
1506
|
+
default:
|
|
1507
|
+
{
|
|
1508
|
+
auto count = j.template as<Rep>();
|
|
1509
|
+
return duration_type(count);
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
else
|
|
1514
|
+
{
|
|
1515
|
+
return duration_type();
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
template <class PeriodT=Period>
|
|
1520
|
+
static
|
|
1521
|
+
typename std::enable_if<std::is_same<PeriodT,std::milli>::value, duration_type>::type
|
|
1522
|
+
from_json_(const Json& j)
|
|
1523
|
+
{
|
|
1524
|
+
if (j.is_int64() || j.is_uint64())
|
|
1525
|
+
{
|
|
1526
|
+
auto count = j.template as<Rep>();
|
|
1527
|
+
switch (j.tag())
|
|
1528
|
+
{
|
|
1529
|
+
case semantic_tag::epoch_second:
|
|
1530
|
+
return duration_type(count*millis_in_second);
|
|
1531
|
+
case semantic_tag::epoch_milli:
|
|
1532
|
+
return duration_type(count);
|
|
1533
|
+
case semantic_tag::epoch_nano:
|
|
1534
|
+
return duration_type(count == 0 ? 0 : count/nanos_in_milli);
|
|
1535
|
+
default:
|
|
1536
|
+
return duration_type(count);
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
else if (j.is_double())
|
|
1540
|
+
{
|
|
1541
|
+
auto count = j.template as<double>();
|
|
1542
|
+
switch (j.tag())
|
|
1543
|
+
{
|
|
1544
|
+
case semantic_tag::epoch_second:
|
|
1545
|
+
return duration_type(static_cast<Rep>(count * millis_in_second));
|
|
1546
|
+
case semantic_tag::epoch_milli:
|
|
1547
|
+
return duration_type(static_cast<Rep>(count));
|
|
1548
|
+
case semantic_tag::epoch_nano:
|
|
1549
|
+
return duration_type(count == 0 ? 0 : static_cast<Rep>(count / nanos_in_milli));
|
|
1550
|
+
default:
|
|
1551
|
+
return duration_type(static_cast<Rep>(count));
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
else if (j.is_string())
|
|
1555
|
+
{
|
|
1556
|
+
switch (j.tag())
|
|
1557
|
+
{
|
|
1558
|
+
case semantic_tag::epoch_second:
|
|
1559
|
+
{
|
|
1560
|
+
auto count = j.template as<Rep>();
|
|
1561
|
+
return duration_type(count*millis_in_second);
|
|
1562
|
+
}
|
|
1563
|
+
case semantic_tag::epoch_milli:
|
|
1564
|
+
{
|
|
1565
|
+
auto sv = j.as_string_view();
|
|
1566
|
+
Rep n{0};
|
|
1567
|
+
auto result = jsoncons::detail::to_integer_decimal(sv.data(), sv.size(), n);
|
|
1568
|
+
if (!result)
|
|
1569
|
+
{
|
|
1570
|
+
return duration_type();
|
|
1571
|
+
}
|
|
1572
|
+
return duration_type(n);
|
|
1573
|
+
}
|
|
1574
|
+
case semantic_tag::epoch_nano:
|
|
1575
|
+
{
|
|
1576
|
+
auto sv = j.as_string_view();
|
|
1577
|
+
bigint n = bigint::from_string(sv.data(), sv.length());
|
|
1578
|
+
if (n != 0)
|
|
1579
|
+
{
|
|
1580
|
+
n = n / nanos_in_milli;
|
|
1581
|
+
}
|
|
1582
|
+
return duration_type(static_cast<Rep>(n));
|
|
1583
|
+
}
|
|
1584
|
+
default:
|
|
1585
|
+
{
|
|
1586
|
+
auto count = j.template as<Rep>();
|
|
1587
|
+
return duration_type(count);
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
else
|
|
1592
|
+
{
|
|
1593
|
+
return duration_type();
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
template <class PeriodT=Period>
|
|
1598
|
+
static
|
|
1599
|
+
typename std::enable_if<std::is_same<PeriodT,std::nano>::value, duration_type>::type
|
|
1600
|
+
from_json_(const Json& j)
|
|
1601
|
+
{
|
|
1602
|
+
if (j.is_int64() || j.is_uint64() || j.is_double())
|
|
1603
|
+
{
|
|
1604
|
+
auto count = j.template as<Rep>();
|
|
1605
|
+
switch (j.tag())
|
|
1606
|
+
{
|
|
1607
|
+
case semantic_tag::epoch_second:
|
|
1608
|
+
return duration_type(count*nanos_in_second);
|
|
1609
|
+
case semantic_tag::epoch_milli:
|
|
1610
|
+
return duration_type(count*nanos_in_milli);
|
|
1611
|
+
case semantic_tag::epoch_nano:
|
|
1612
|
+
return duration_type(count);
|
|
1613
|
+
default:
|
|
1614
|
+
return duration_type(count);
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
else if (j.is_double())
|
|
1618
|
+
{
|
|
1619
|
+
auto count = j.template as<double>();
|
|
1620
|
+
switch (j.tag())
|
|
1621
|
+
{
|
|
1622
|
+
case semantic_tag::epoch_second:
|
|
1623
|
+
return duration_type(static_cast<Rep>(count * nanos_in_second));
|
|
1624
|
+
case semantic_tag::epoch_milli:
|
|
1625
|
+
return duration_type(static_cast<Rep>(count * nanos_in_milli));
|
|
1626
|
+
case semantic_tag::epoch_nano:
|
|
1627
|
+
return duration_type(static_cast<Rep>(count));
|
|
1628
|
+
default:
|
|
1629
|
+
return duration_type(static_cast<Rep>(count));
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
else if (j.is_string())
|
|
1633
|
+
{
|
|
1634
|
+
auto count = j.template as<Rep>();
|
|
1635
|
+
switch (j.tag())
|
|
1636
|
+
{
|
|
1637
|
+
case semantic_tag::epoch_second:
|
|
1638
|
+
return duration_type(count*nanos_in_second);
|
|
1639
|
+
case semantic_tag::epoch_milli:
|
|
1640
|
+
return duration_type(count*nanos_in_milli);
|
|
1641
|
+
case semantic_tag::epoch_nano:
|
|
1642
|
+
return duration_type(count);
|
|
1643
|
+
default:
|
|
1644
|
+
return duration_type(count);
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
else
|
|
1648
|
+
{
|
|
1649
|
+
return duration_type();
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
template <class PeriodT=Period>
|
|
1654
|
+
static
|
|
1655
|
+
typename std::enable_if<std::is_same<PeriodT,std::ratio<1>>::value,Json>::type
|
|
1656
|
+
to_json_(const duration_type& val)
|
|
1657
|
+
{
|
|
1658
|
+
return Json(val.count(), semantic_tag::epoch_second);
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
template <class PeriodT=Period>
|
|
1662
|
+
static
|
|
1663
|
+
typename std::enable_if<std::is_same<PeriodT,std::milli>::value,Json>::type
|
|
1664
|
+
to_json_(const duration_type& val)
|
|
1665
|
+
{
|
|
1666
|
+
return Json(val.count(), semantic_tag::epoch_milli);
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
template <class PeriodT=Period>
|
|
1670
|
+
static
|
|
1671
|
+
typename std::enable_if<std::is_same<PeriodT,std::nano>::value,Json>::type
|
|
1672
|
+
to_json_(const duration_type& val)
|
|
1673
|
+
{
|
|
1674
|
+
return Json(val.count(), semantic_tag::epoch_nano);
|
|
1675
|
+
}
|
|
1676
|
+
};
|
|
1677
|
+
|
|
1678
|
+
// std::nullptr_t
|
|
1679
|
+
template <class Json>
|
|
1680
|
+
struct json_type_traits<Json,std::nullptr_t>
|
|
1681
|
+
{
|
|
1682
|
+
using allocator_type = typename Json::allocator_type;
|
|
1683
|
+
|
|
1684
|
+
static bool is(const Json& j) noexcept
|
|
1685
|
+
{
|
|
1686
|
+
return j.is_null();
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
static std::nullptr_t as(const Json& j)
|
|
1690
|
+
{
|
|
1691
|
+
if (!j.is_null())
|
|
1692
|
+
{
|
|
1693
|
+
JSONCONS_THROW(conv_error(conv_errc::not_nullptr));
|
|
1694
|
+
}
|
|
1695
|
+
return nullptr;
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
static Json to_json(const std::nullptr_t&, allocator_type = allocator_type())
|
|
1699
|
+
{
|
|
1700
|
+
return Json::null();
|
|
1701
|
+
}
|
|
1702
|
+
};
|
|
1703
|
+
|
|
1704
|
+
// std::bitset
|
|
1705
|
+
|
|
1706
|
+
struct null_back_insertable_byte_container
|
|
1707
|
+
{
|
|
1708
|
+
using value_type = uint8_t;
|
|
1709
|
+
|
|
1710
|
+
void push_back(value_type)
|
|
1711
|
+
{
|
|
1712
|
+
}
|
|
1713
|
+
};
|
|
1714
|
+
|
|
1715
|
+
template<class Json, std::size_t N>
|
|
1716
|
+
struct json_type_traits<Json, std::bitset<N>>
|
|
1717
|
+
{
|
|
1718
|
+
using allocator_type = typename Json::allocator_type;
|
|
1719
|
+
|
|
1720
|
+
static bool is(const Json& j) noexcept
|
|
1721
|
+
{
|
|
1722
|
+
if (j.is_byte_string())
|
|
1723
|
+
{
|
|
1724
|
+
return true;
|
|
1725
|
+
}
|
|
1726
|
+
else if (j.is_string())
|
|
1727
|
+
{
|
|
1728
|
+
jsoncons::string_view sv = j.as_string_view();
|
|
1729
|
+
null_back_insertable_byte_container cont;
|
|
1730
|
+
auto result = decode_base16(sv.begin(), sv.end(), cont);
|
|
1731
|
+
return result.ec == conv_errc::success ? true : false;
|
|
1732
|
+
}
|
|
1733
|
+
return false;
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
static std::bitset<N> as(const Json& j)
|
|
1737
|
+
{
|
|
1738
|
+
if (j.template is<uint64_t>())
|
|
1739
|
+
{
|
|
1740
|
+
auto bits = j.template as<uint64_t>();
|
|
1741
|
+
std::bitset<N> bs = static_cast<unsigned long long>(bits);
|
|
1742
|
+
return bs;
|
|
1743
|
+
}
|
|
1744
|
+
else if (j.is_byte_string() || j.is_string())
|
|
1745
|
+
{
|
|
1746
|
+
std::bitset<N> bs;
|
|
1747
|
+
std::vector<uint8_t> bits;
|
|
1748
|
+
if (j.is_byte_string())
|
|
1749
|
+
{
|
|
1750
|
+
bits = j.template as<std::vector<uint8_t>>();
|
|
1751
|
+
}
|
|
1752
|
+
else
|
|
1753
|
+
{
|
|
1754
|
+
jsoncons::string_view sv = j.as_string_view();
|
|
1755
|
+
auto result = decode_base16(sv.begin(), sv.end(), bits);
|
|
1756
|
+
if (result.ec != conv_errc::success)
|
|
1757
|
+
{
|
|
1758
|
+
JSONCONS_THROW(conv_error(conv_errc::not_bitset));
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
std::uint8_t byte = 0;
|
|
1762
|
+
std::uint8_t mask = 0;
|
|
1763
|
+
|
|
1764
|
+
std::size_t pos = 0;
|
|
1765
|
+
for (std::size_t i = 0; i < N; ++i)
|
|
1766
|
+
{
|
|
1767
|
+
if (mask == 0)
|
|
1768
|
+
{
|
|
1769
|
+
if (pos >= bits.size())
|
|
1770
|
+
{
|
|
1771
|
+
JSONCONS_THROW(conv_error(conv_errc::not_bitset));
|
|
1772
|
+
}
|
|
1773
|
+
byte = bits.at(pos++);
|
|
1774
|
+
mask = 0x80;
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
if (byte & mask)
|
|
1778
|
+
{
|
|
1779
|
+
bs[i] = 1;
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
mask = static_cast<std::uint8_t>(mask >> 1);
|
|
1783
|
+
}
|
|
1784
|
+
return bs;
|
|
1785
|
+
}
|
|
1786
|
+
else
|
|
1787
|
+
{
|
|
1788
|
+
JSONCONS_THROW(conv_error(conv_errc::not_bitset));
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
static Json to_json(const std::bitset<N>& val,
|
|
1793
|
+
const allocator_type& alloc = allocator_type())
|
|
1794
|
+
{
|
|
1795
|
+
std::vector<uint8_t> bits;
|
|
1796
|
+
|
|
1797
|
+
uint8_t byte = 0;
|
|
1798
|
+
uint8_t mask = 0x80;
|
|
1799
|
+
|
|
1800
|
+
for (std::size_t i = 0; i < N; ++i)
|
|
1801
|
+
{
|
|
1802
|
+
if (val[i])
|
|
1803
|
+
{
|
|
1804
|
+
byte |= mask;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
mask = static_cast<uint8_t>(mask >> 1);
|
|
1808
|
+
|
|
1809
|
+
if (mask == 0)
|
|
1810
|
+
{
|
|
1811
|
+
bits.push_back(byte);
|
|
1812
|
+
byte = 0;
|
|
1813
|
+
mask = 0x80;
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
// Encode remainder
|
|
1818
|
+
if (mask != 0x80)
|
|
1819
|
+
{
|
|
1820
|
+
bits.push_back(byte);
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1823
|
+
Json j(byte_string_arg, bits, semantic_tag::base16, alloc);
|
|
1824
|
+
return j;
|
|
1825
|
+
}
|
|
1826
|
+
};
|
|
1827
|
+
|
|
1828
|
+
} // jsoncons
|
|
1829
|
+
|
|
1830
|
+
#endif
|