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.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/ext/jsoncons/extconf.rb +43 -0
  3. data/ext/jsoncons/jsoncons.cpp +161 -0
  4. data/ext/jsoncons/jsoncons.h +10 -0
  5. data/jsoncons.gemspec +44 -0
  6. data/lib/jsoncons/jsoncons/examples/input/address-book.json +13 -0
  7. data/lib/jsoncons/jsoncons/examples/input/books.json +28 -0
  8. data/lib/jsoncons/jsoncons/examples/input/countries.json +7 -0
  9. data/lib/jsoncons/jsoncons/examples/input/employees.json +30 -0
  10. data/lib/jsoncons/jsoncons/examples/input/jsonschema/name.json +15 -0
  11. data/lib/jsoncons/jsoncons/examples/input/multiple-json-objects.json +3 -0
  12. data/lib/jsoncons/jsoncons/examples/input/sales.csv +6 -0
  13. data/lib/jsoncons/jsoncons/examples/input/store.json +28 -0
  14. data/lib/jsoncons/jsoncons/examples/input/tasks.csv +6 -0
  15. data/lib/jsoncons/jsoncons/include/jsoncons/allocator_holder.hpp +38 -0
  16. data/lib/jsoncons/jsoncons/include/jsoncons/basic_json.hpp +5905 -0
  17. data/lib/jsoncons/jsoncons/include/jsoncons/bigint.hpp +1611 -0
  18. data/lib/jsoncons/jsoncons/include/jsoncons/byte_string.hpp +820 -0
  19. data/lib/jsoncons/jsoncons/include/jsoncons/config/binary_config.hpp +226 -0
  20. data/lib/jsoncons/jsoncons/include/jsoncons/config/compiler_support.hpp +375 -0
  21. data/lib/jsoncons/jsoncons/include/jsoncons/config/jsoncons_config.hpp +309 -0
  22. data/lib/jsoncons/jsoncons/include/jsoncons/config/version.hpp +40 -0
  23. data/lib/jsoncons/jsoncons/include/jsoncons/conv_error.hpp +218 -0
  24. data/lib/jsoncons/jsoncons/include/jsoncons/decode_json.hpp +209 -0
  25. data/lib/jsoncons/jsoncons/include/jsoncons/decode_traits.hpp +651 -0
  26. data/lib/jsoncons/jsoncons/include/jsoncons/detail/endian.hpp +44 -0
  27. data/lib/jsoncons/jsoncons/include/jsoncons/detail/grisu3.hpp +312 -0
  28. data/lib/jsoncons/jsoncons/include/jsoncons/detail/optional.hpp +483 -0
  29. data/lib/jsoncons/jsoncons/include/jsoncons/detail/parse_number.hpp +1133 -0
  30. data/lib/jsoncons/jsoncons/include/jsoncons/detail/span.hpp +188 -0
  31. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_view.hpp +537 -0
  32. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_wrapper.hpp +370 -0
  33. data/lib/jsoncons/jsoncons/include/jsoncons/detail/write_number.hpp +567 -0
  34. data/lib/jsoncons/jsoncons/include/jsoncons/encode_json.hpp +315 -0
  35. data/lib/jsoncons/jsoncons/include/jsoncons/encode_traits.hpp +378 -0
  36. data/lib/jsoncons/jsoncons/include/jsoncons/json.hpp +18 -0
  37. data/lib/jsoncons/jsoncons/include/jsoncons/json_array.hpp +324 -0
  38. data/lib/jsoncons/jsoncons/include/jsoncons/json_content_handler.hpp +12 -0
  39. data/lib/jsoncons/jsoncons/include/jsoncons/json_cursor.hpp +448 -0
  40. data/lib/jsoncons/jsoncons/include/jsoncons/json_decoder.hpp +420 -0
  41. data/lib/jsoncons/jsoncons/include/jsoncons/json_encoder.hpp +1587 -0
  42. data/lib/jsoncons/jsoncons/include/jsoncons/json_error.hpp +156 -0
  43. data/lib/jsoncons/jsoncons/include/jsoncons/json_exception.hpp +241 -0
  44. data/lib/jsoncons/jsoncons/include/jsoncons/json_filter.hpp +653 -0
  45. data/lib/jsoncons/jsoncons/include/jsoncons/json_fwd.hpp +23 -0
  46. data/lib/jsoncons/jsoncons/include/jsoncons/json_object.hpp +1772 -0
  47. data/lib/jsoncons/jsoncons/include/jsoncons/json_options.hpp +862 -0
  48. data/lib/jsoncons/jsoncons/include/jsoncons/json_parser.hpp +2900 -0
  49. data/lib/jsoncons/jsoncons/include/jsoncons/json_reader.hpp +731 -0
  50. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros.hpp +1072 -0
  51. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros_deprecated.hpp +144 -0
  52. data/lib/jsoncons/jsoncons/include/jsoncons/json_type.hpp +206 -0
  53. data/lib/jsoncons/jsoncons/include/jsoncons/json_type_traits.hpp +1830 -0
  54. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor.hpp +1560 -0
  55. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor2.hpp +2079 -0
  56. data/lib/jsoncons/jsoncons/include/jsoncons/pretty_print.hpp +89 -0
  57. data/lib/jsoncons/jsoncons/include/jsoncons/ser_context.hpp +62 -0
  58. data/lib/jsoncons/jsoncons/include/jsoncons/sink.hpp +289 -0
  59. data/lib/jsoncons/jsoncons/include/jsoncons/source.hpp +777 -0
  60. data/lib/jsoncons/jsoncons/include/jsoncons/source_adaptor.hpp +148 -0
  61. data/lib/jsoncons/jsoncons/include/jsoncons/staj2_cursor.hpp +1189 -0
  62. data/lib/jsoncons/jsoncons/include/jsoncons/staj_cursor.hpp +1254 -0
  63. data/lib/jsoncons/jsoncons/include/jsoncons/staj_iterator.hpp +449 -0
  64. data/lib/jsoncons/jsoncons/include/jsoncons/tag_type.hpp +245 -0
  65. data/lib/jsoncons/jsoncons/include/jsoncons/text_source_adaptor.hpp +144 -0
  66. data/lib/jsoncons/jsoncons/include/jsoncons/traits_extension.hpp +884 -0
  67. data/lib/jsoncons/jsoncons/include/jsoncons/typed_array_view.hpp +250 -0
  68. data/lib/jsoncons/jsoncons/include/jsoncons/unicode_traits.hpp +1330 -0
  69. data/lib/jsoncons/jsoncons/include/jsoncons/uri.hpp +635 -0
  70. data/lib/jsoncons/jsoncons/include/jsoncons/value_converter.hpp +340 -0
  71. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson.hpp +23 -0
  72. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_cursor.hpp +320 -0
  73. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_decimal128.hpp +865 -0
  74. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_encoder.hpp +585 -0
  75. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_error.hpp +103 -0
  76. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_oid.hpp +245 -0
  77. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_options.hpp +75 -0
  78. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_parser.hpp +645 -0
  79. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_reader.hpp +92 -0
  80. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_type.hpp +44 -0
  81. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/decode_bson.hpp +201 -0
  82. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/encode_bson.hpp +144 -0
  83. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor.hpp +26 -0
  84. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor.hpp +351 -0
  85. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor2.hpp +265 -0
  86. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_detail.hpp +93 -0
  87. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_encoder.hpp +1766 -0
  88. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_error.hpp +105 -0
  89. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_options.hpp +113 -0
  90. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_parser.hpp +1942 -0
  91. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_reader.hpp +116 -0
  92. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/decode_cbor.hpp +203 -0
  93. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/encode_cbor.hpp +151 -0
  94. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv.hpp +17 -0
  95. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_cursor.hpp +358 -0
  96. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_encoder.hpp +954 -0
  97. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_error.hpp +85 -0
  98. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_options.hpp +973 -0
  99. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_parser.hpp +2099 -0
  100. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_reader.hpp +348 -0
  101. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_serializer.hpp +12 -0
  102. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/decode_csv.hpp +208 -0
  103. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/encode_csv.hpp +122 -0
  104. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath.hpp +5215 -0
  105. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath_error.hpp +215 -0
  106. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch.hpp +579 -0
  107. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch_error.hpp +121 -0
  108. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/expression.hpp +3329 -0
  109. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/flatten.hpp +432 -0
  110. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_location.hpp +445 -0
  111. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_query.hpp +115 -0
  112. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath.hpp +13 -0
  113. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_error.hpp +240 -0
  114. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_expression.hpp +2612 -0
  115. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +1322 -0
  116. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer.hpp +1577 -0
  117. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer_error.hpp +119 -0
  118. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/format_validator.hpp +968 -0
  119. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/json_validator.hpp +120 -0
  120. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema.hpp +13 -0
  121. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_error.hpp +105 -0
  122. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_version.hpp +18 -0
  123. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator.hpp +1745 -0
  124. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator_factory.hpp +556 -0
  125. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_draft7.hpp +198 -0
  126. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_location.hpp +200 -0
  127. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_version.hpp +35 -0
  128. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/subschema.hpp +144 -0
  129. data/lib/jsoncons/jsoncons/include/jsoncons_ext/mergepatch/mergepatch.hpp +103 -0
  130. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/decode_msgpack.hpp +202 -0
  131. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/encode_msgpack.hpp +142 -0
  132. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack.hpp +24 -0
  133. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor.hpp +343 -0
  134. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor2.hpp +259 -0
  135. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_encoder.hpp +753 -0
  136. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_error.hpp +94 -0
  137. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_options.hpp +74 -0
  138. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp +748 -0
  139. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_reader.hpp +116 -0
  140. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_type.hpp +63 -0
  141. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/decode_ubjson.hpp +201 -0
  142. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/encode_ubjson.hpp +142 -0
  143. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson.hpp +23 -0
  144. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_cursor.hpp +307 -0
  145. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_encoder.hpp +502 -0
  146. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_error.hpp +100 -0
  147. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_options.hpp +87 -0
  148. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_parser.hpp +880 -0
  149. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_reader.hpp +92 -0
  150. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_type.hpp +43 -0
  151. data/lib/jsoncons/version.rb +5 -0
  152. data/lib/jsoncons.rb +33 -0
  153. data/test/jsoncons_test.rb +108 -0
  154. data/test/test_helper.rb +7 -0
  155. metadata +268 -0
@@ -0,0 +1,370 @@
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_DETAIL_STRING_WRAPPER_HPP
8
+ #define JSONCONS_DETAIL_STRING_WRAPPER_HPP
9
+
10
+ #include <stdexcept>
11
+ #include <string>
12
+ #include <exception>
13
+ #include <ostream>
14
+ #include <cstring> // std::memcpy
15
+ #include <memory> // std::allocator
16
+ #include <jsoncons/config/compiler_support.hpp>
17
+
18
+ namespace jsoncons {
19
+ namespace detail {
20
+
21
+ // From boost 1_71
22
+ template <class T, class U>
23
+ T launder_cast(U* u)
24
+ {
25
+ #if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
26
+ return std::launder(reinterpret_cast<T>(u));
27
+ #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) > 800
28
+ return __builtin_launder(reinterpret_cast<T>(u));
29
+ #else
30
+ return reinterpret_cast<T>(u);
31
+ #endif
32
+ }
33
+
34
+ // string_wrapper
35
+
36
+ template <class CharT,class Allocator>
37
+ class string_wrapper
38
+ {
39
+ public:
40
+ using char_type = CharT;
41
+ private:
42
+ struct str_base_t
43
+ {
44
+ Allocator alloc_;
45
+
46
+ Allocator& get_allocator()
47
+ {
48
+ return alloc_;
49
+ }
50
+
51
+ const Allocator& get_allocator() const
52
+ {
53
+ return alloc_;
54
+ }
55
+
56
+ str_base_t(const Allocator& alloc)
57
+ : alloc_(alloc)
58
+ {
59
+ }
60
+
61
+ ~str_base_t() noexcept = default;
62
+ };
63
+
64
+ struct str_t : public str_base_t
65
+ {
66
+ typedef typename std::allocator_traits<Allocator>::template rebind_alloc<CharT> allocator_type;
67
+ using allocator_traits_type = std::allocator_traits<allocator_type>;
68
+ using pointer = typename allocator_traits_type::pointer;
69
+
70
+ pointer p_;
71
+ std::size_t length_;
72
+
73
+ ~str_t() noexcept = default;
74
+
75
+ const char_type* c_str() const { return traits_extension::to_plain_pointer(p_); }
76
+ const char_type* data() const { return traits_extension::to_plain_pointer(p_); }
77
+ std::size_t length() const { return length_; }
78
+
79
+ str_t(const Allocator& alloc)
80
+ : str_base_t(alloc), p_(nullptr), length_(0)
81
+ {
82
+
83
+ }
84
+
85
+ str_t(const str_t&) = delete;
86
+ str_t& operator=(const str_t&) = delete;
87
+
88
+ };
89
+
90
+ typedef typename std::allocator_traits<Allocator>::template rebind_alloc<char> byte_allocator_type;
91
+ using byte_pointer = typename std::allocator_traits<byte_allocator_type>::pointer;
92
+
93
+ typedef typename std::allocator_traits<Allocator>::template rebind_alloc<str_t> string_allocator_type;
94
+ using string_pointer = typename std::allocator_traits<string_allocator_type>::pointer;
95
+
96
+ struct storage_t
97
+ {
98
+ str_t data;
99
+ char_type c[1];
100
+ };
101
+ typedef typename std::aligned_storage<sizeof(storage_t), alignof(storage_t)>::type json_storage_kind;
102
+
103
+ string_pointer ptr_;
104
+ public:
105
+ string_wrapper() = default;
106
+
107
+ string_wrapper(string_pointer ptr)
108
+ : ptr_(ptr)
109
+ {
110
+ }
111
+
112
+ string_wrapper(const char_type* data, std::size_t length, const Allocator& a)
113
+ {
114
+ ptr_ = create(data,length,a);
115
+ }
116
+
117
+ string_wrapper(const string_wrapper& val)
118
+ {
119
+ ptr_ = create(val.data(),val.length(),val.get_allocator());
120
+ }
121
+
122
+ string_wrapper(const string_wrapper& val, const Allocator& a)
123
+ {
124
+ ptr_ = create(val.data(),val.length(),a);
125
+ }
126
+
127
+ ~string_wrapper() noexcept
128
+ {
129
+ if (ptr_ != nullptr)
130
+ {
131
+ destroy(ptr_);
132
+ }
133
+ }
134
+
135
+ void swap(string_wrapper& other) noexcept
136
+ {
137
+ std::swap(ptr_,other.ptr_);
138
+ }
139
+
140
+ const char_type* data() const
141
+ {
142
+ return ptr_->data();
143
+ }
144
+
145
+ const char_type* c_str() const
146
+ {
147
+ return ptr_->c_str();
148
+ }
149
+
150
+ std::size_t length() const
151
+ {
152
+ return ptr_->length();
153
+ }
154
+
155
+ Allocator get_allocator() const
156
+ {
157
+ return ptr_->get_allocator();
158
+ }
159
+ private:
160
+ static size_t aligned_size(std::size_t n)
161
+ {
162
+ return sizeof(json_storage_kind) + n;
163
+ }
164
+
165
+ static string_pointer create(const char_type* s, std::size_t length, const Allocator& alloc)
166
+ {
167
+ std::size_t mem_size = aligned_size(length*sizeof(char_type));
168
+
169
+ byte_allocator_type byte_alloc(alloc);
170
+ byte_pointer ptr = byte_alloc.allocate(mem_size);
171
+
172
+ char* storage = traits_extension::to_plain_pointer(ptr);
173
+ str_t* ps = new(storage)str_t(byte_alloc);
174
+
175
+ auto psa = launder_cast<storage_t*>(storage);
176
+
177
+ CharT* p = new(&psa->c)char_type[length + 1];
178
+ std::memcpy(p, s, length*sizeof(char_type));
179
+ p[length] = 0;
180
+ ps->p_ = std::pointer_traits<typename str_t::pointer>::pointer_to(*p);
181
+ ps->length_ = length;
182
+ return std::pointer_traits<string_pointer>::pointer_to(*ps);
183
+ }
184
+
185
+ static void destroy(string_pointer ptr)
186
+ {
187
+ str_t* rawp = traits_extension::to_plain_pointer(ptr);
188
+
189
+ char* p = launder_cast<char*>(rawp);
190
+
191
+ std::size_t mem_size = aligned_size(ptr->length_*sizeof(char_type));
192
+ byte_allocator_type byte_alloc(ptr->get_allocator());
193
+ byte_alloc.deallocate(p,mem_size);
194
+ }
195
+ };
196
+
197
+ // tagged_string_wrapper
198
+
199
+ template <class CharT,class Allocator>
200
+ class tagged_string_wrapper
201
+ {
202
+ public:
203
+ using char_type = CharT;
204
+ private:
205
+ struct str_base_t
206
+ {
207
+ Allocator alloc_;
208
+
209
+ Allocator& get_allocator()
210
+ {
211
+ return alloc_;
212
+ }
213
+
214
+ const Allocator& get_allocator() const
215
+ {
216
+ return alloc_;
217
+ }
218
+
219
+ str_base_t(const Allocator& alloc)
220
+ : alloc_(alloc)
221
+ {
222
+ }
223
+
224
+ ~str_base_t() noexcept = default;
225
+ };
226
+
227
+ struct str_t : public str_base_t
228
+ {
229
+ typedef typename std::allocator_traits<Allocator>::template rebind_alloc<CharT> allocator_type;
230
+ using allocator_traits_type = std::allocator_traits<allocator_type>;
231
+ using pointer = typename allocator_traits_type::pointer;
232
+
233
+ pointer p_;
234
+ std::size_t length_;
235
+ uint64_t tag_;
236
+
237
+ ~str_t() noexcept = default;
238
+
239
+ const char_type* c_str() const { return traits_extension::to_plain_pointer(p_); }
240
+ const char_type* data() const { return traits_extension::to_plain_pointer(p_); }
241
+ std::size_t length() const { return length_; }
242
+ uint64_t tag() const { return tag_; }
243
+
244
+ str_t(uint64_t tag, const Allocator& alloc)
245
+ : str_base_t(alloc), p_(nullptr), length_(0), tag_(tag)
246
+ {
247
+
248
+ }
249
+
250
+ str_t(const str_t&) = delete;
251
+ str_t& operator=(const str_t&) = delete;
252
+
253
+ };
254
+
255
+ typedef typename std::allocator_traits<Allocator>::template rebind_alloc<char> byte_allocator_type;
256
+ using byte_pointer = typename std::allocator_traits<byte_allocator_type>::pointer;
257
+
258
+ typedef typename std::allocator_traits<Allocator>::template rebind_alloc<str_t> string_allocator_type;
259
+ using string_pointer = typename std::allocator_traits<string_allocator_type>::pointer;
260
+
261
+ struct storage_t
262
+ {
263
+ str_t data;
264
+ char_type c[1];
265
+ };
266
+ typedef typename std::aligned_storage<sizeof(storage_t), alignof(storage_t)>::type json_storage_kind;
267
+
268
+ string_pointer ptr_;
269
+ public:
270
+ tagged_string_wrapper() = default;
271
+
272
+ tagged_string_wrapper(string_pointer ptr)
273
+ : ptr_(ptr)
274
+ {
275
+ }
276
+
277
+ tagged_string_wrapper(const char_type* data, std::size_t length, uint64_t tag, const Allocator& alloc)
278
+ {
279
+ ptr_ = create(data, length, tag, alloc);
280
+ }
281
+
282
+ tagged_string_wrapper(const tagged_string_wrapper& val)
283
+ {
284
+ ptr_ = create(val.data(), val.length(), val.tag(), val.get_allocator());
285
+ }
286
+
287
+ tagged_string_wrapper(const tagged_string_wrapper& val, const Allocator& alloc)
288
+ {
289
+ ptr_ = create(val.data(), val.length(), val.tag(), alloc);
290
+ }
291
+
292
+ ~tagged_string_wrapper() noexcept
293
+ {
294
+ if (ptr_ != nullptr)
295
+ {
296
+ destroy(ptr_);
297
+ }
298
+ }
299
+
300
+ void swap(tagged_string_wrapper& other) noexcept
301
+ {
302
+ std::swap(ptr_,other.ptr_);
303
+ }
304
+
305
+ const char_type* data() const
306
+ {
307
+ return ptr_->data();
308
+ }
309
+
310
+ const char_type* c_str() const
311
+ {
312
+ return ptr_->c_str();
313
+ }
314
+
315
+ std::size_t length() const
316
+ {
317
+ return ptr_->length();
318
+ }
319
+
320
+ uint64_t tag() const
321
+ {
322
+ return ptr_->tag();
323
+ }
324
+
325
+ Allocator get_allocator() const
326
+ {
327
+ return ptr_->get_allocator();
328
+ }
329
+ private:
330
+ static size_t aligned_size(std::size_t n)
331
+ {
332
+ return sizeof(json_storage_kind) + n;
333
+ }
334
+
335
+ static string_pointer create(const char_type* s, std::size_t length, uint64_t tag, const Allocator& alloc)
336
+ {
337
+ std::size_t mem_size = aligned_size(length*sizeof(char_type));
338
+
339
+ byte_allocator_type byte_alloc(alloc);
340
+ byte_pointer ptr = byte_alloc.allocate(mem_size);
341
+
342
+ char* storage = traits_extension::to_plain_pointer(ptr);
343
+ str_t* ps = new(storage)str_t(tag, byte_alloc);
344
+
345
+ auto psa = launder_cast<storage_t*>(storage);
346
+
347
+ CharT* p = new(&psa->c)char_type[length + 1];
348
+ std::memcpy(p, s, length*sizeof(char_type));
349
+ p[length] = 0;
350
+ ps->p_ = std::pointer_traits<typename str_t::pointer>::pointer_to(*p);
351
+ ps->length_ = length;
352
+ return std::pointer_traits<string_pointer>::pointer_to(*ps);
353
+ }
354
+
355
+ static void destroy(string_pointer ptr)
356
+ {
357
+ str_t* rawp = traits_extension::to_plain_pointer(ptr);
358
+
359
+ char* p = launder_cast<char*>(rawp);
360
+
361
+ std::size_t mem_size = aligned_size(ptr->length_*sizeof(char_type));
362
+ byte_allocator_type byte_alloc(ptr->get_allocator());
363
+ byte_alloc.deallocate(p,mem_size);
364
+ }
365
+ };
366
+
367
+ } // namespace detail
368
+ } // namespace jsoncons
369
+
370
+ #endif