jsoncons 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,865 @@
1
+ #ifndef JSONCONS_BSON_BSON_DECIMAL128_HPP
2
+ #define JSONCONS_BSON_BSON_DECIMAL128_HPP
3
+
4
+ /*
5
+ * Implements decimal128_to_chars and decimal128_from_chars
6
+ *
7
+ * Based on the libjson functions bson_decimal128_to_string
8
+ * and bson_decimal128_from_string_w_len, available at
9
+ * https://github.com/mongodb/mongo-c-driver/blob/master/src/libbson/src/bson/bson-decimal128.h
10
+ * and https://github.com/mongodb/mongo-c-driver/blob/master/src/libbson/src/bson/bson-decimal128.c
11
+ *
12
+ */
13
+
14
+ /*
15
+ * Copyright 2015 MongoDB, Inc.
16
+ *
17
+ * Licensed under the Apache License, Version 2.0 (the "License");
18
+ * you may not use this file except in compliance with the License.
19
+ * You may obtain a copy of the License at
20
+ *
21
+ * http://www.apache.org/licenses/LICENSE-2.0
22
+ *
23
+ * Unless required by applicable law or agreed to in writing, software
24
+ * distributed under the License is distributed on an "AS IS" BASIS,
25
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26
+ * See the License for the specific language governing permissions and
27
+ * limitations under the License.
28
+ */
29
+
30
+ #include <stdlib.h>
31
+ #include <string.h>
32
+ #include <cstring>
33
+ #include <ctype.h>
34
+ #include <system_error>
35
+ #include <algorithm>
36
+ #include <jsoncons/config/jsoncons_config.hpp>
37
+
38
+ namespace jsoncons { namespace bson {
39
+
40
+ struct decimal128_to_chars_result
41
+ {
42
+ char* ptr;
43
+ std::errc ec;
44
+ };
45
+
46
+ struct decimal128_from_chars_result
47
+ {
48
+ const char* ptr;
49
+ std::errc ec;
50
+ };
51
+
52
+ /**
53
+ * BSON_DECIMAL128_STRING:
54
+ *
55
+ * The length of a decimal128 string (with null terminator).
56
+ *
57
+ * 1 for the sign
58
+ * 35 for digits and radix
59
+ * 2 for exponent indicator and sign
60
+ * 4 for exponent digits
61
+ */
62
+ #define BSON_DECIMAL128_STRING 43
63
+
64
+ struct TP1
65
+ {
66
+ uint64_t low;
67
+ uint64_t high;
68
+
69
+ constexpr TP1() : low(0), high(0) {}
70
+ constexpr TP1(uint64_t hi, uint64_t lo) : low(lo), high(hi) {}
71
+ };
72
+ struct TP2
73
+ {
74
+ uint64_t high;
75
+ uint64_t low;
76
+
77
+ constexpr TP2() : high(0), low(0) {}
78
+ constexpr TP2(uint64_t hi, uint64_t lo) : high(hi), low(lo) {}
79
+ };
80
+
81
+ typedef std::conditional<
82
+ jsoncons::endian::native == jsoncons::endian::little,
83
+ TP1,
84
+ TP2
85
+ >::type decimal128_t;
86
+
87
+ inline
88
+ bool operator==(const decimal128_t& lhs, const decimal128_t& rhs)
89
+ {
90
+ return lhs.high == rhs.high && lhs.low == rhs.low;
91
+ }
92
+
93
+ inline
94
+ bool operator!=(const decimal128_t& lhs, const decimal128_t& rhs)
95
+ {
96
+ return !(lhs == rhs);
97
+ }
98
+
99
+ struct decimal128_limits
100
+ {
101
+ // The length of a decimal128 string (without null terminator).
102
+ //
103
+ // 1 for the sign
104
+ // 35 for digits and radix
105
+ // 2 for exponent indicator and sign
106
+ // 4 for exponent digits
107
+ static constexpr int buf_size = 42;
108
+ static constexpr int exponent_max = 6111;
109
+ static constexpr int exponent_min = -6176;
110
+ static constexpr int exponent_bias = 6176;
111
+ static constexpr int max_digits = 34;
112
+
113
+ static constexpr decimal128_t nan() {return decimal128_t(0x7c00000000000000ull, 0);}
114
+ static constexpr decimal128_t infinity() {return decimal128_t(0x7800000000000000ull, 0);}
115
+ static constexpr decimal128_t neg_infinity() {return decimal128_t(0x7800000000000000ull + 0x8000000000000000ull, 0);}
116
+ };
117
+
118
+ inline
119
+ bool is_nan(decimal128_t dec) { return dec == decimal128_limits::nan(); }
120
+
121
+ inline
122
+ bool is_inf(decimal128_t dec) { return dec == decimal128_limits::infinity(); }
123
+
124
+ inline
125
+ bool is_neg_inf(decimal128_t dec) { return dec == decimal128_limits::neg_infinity(); }
126
+
127
+ /**
128
+ * bson_uint128_t:
129
+ *
130
+ * This struct represents a 128 bit integer.
131
+ */
132
+ typedef struct {
133
+ uint32_t parts[4]; /* 32-bit words stored high to low. */
134
+ } bson_uint128_t;
135
+
136
+ typedef struct {
137
+ uint64_t high, low;
138
+ } bson_uint128_6464_t;
139
+
140
+ namespace detail {
141
+
142
+ /**
143
+ *------------------------------------------------------------------------------
144
+ *
145
+ * bson_uint128_divide1B --
146
+ *
147
+ * This function divides a #bson_uint128_t by 1000000000 (1 billion) and
148
+ * computes the quotient and remainder.
149
+ *
150
+ * The remainder will contain 9 decimal digits for conversion to string.
151
+ *
152
+ * @value The #bson_uint128_t operand.
153
+ * @quotient A pointer to store the #bson_uint128_t quotient.
154
+ * @rem A pointer to store the #uint64_t remainder.
155
+ *
156
+ * Returns:
157
+ * The quotient at @quotient and the remainder at @rem.
158
+ *
159
+ * Side effects:
160
+ * None.
161
+ *
162
+ *------------------------------------------------------------------------------
163
+ */
164
+
165
+ inline
166
+ void bson_uint128_divide1B (bson_uint128_t value, /* IN */
167
+ bson_uint128_t *quotient, /* OUT */
168
+ uint32_t *rem) /* OUT */
169
+ {
170
+ const uint32_t DIVISOR = 1000 * 1000 * 1000;
171
+ uint64_t _rem = 0;
172
+ int i = 0;
173
+
174
+ if (!value.parts[0] && !value.parts[1] && !value.parts[2] &&
175
+ !value.parts[3]) {
176
+ *quotient = value;
177
+ *rem = 0;
178
+ return;
179
+ }
180
+
181
+ for (i = 0; i <= 3; i++) {
182
+ _rem <<= 32; /* Adjust remainder to match value of next dividend */
183
+ _rem += value.parts[i]; /* Add the divided to _rem */
184
+ value.parts[i] = (uint32_t) (_rem / DIVISOR);
185
+ _rem %= DIVISOR; /* Store the remainder */
186
+ }
187
+
188
+ *quotient = value;
189
+ *rem = (uint32_t) _rem;
190
+ }
191
+
192
+ /**
193
+ *-------------------------------------------------------------------------
194
+ *
195
+ * mul64x64 --
196
+ *
197
+ * This function multiplies two &uint64_t into a &bson_uint128_6464_t.
198
+ *
199
+ * Returns:
200
+ * The product of @left and @right.
201
+ *
202
+ * Side Effects:
203
+ * None.
204
+ *
205
+ *-------------------------------------------------------------------------
206
+ */
207
+
208
+ inline
209
+ void mul_64x64 (uint64_t left, /* IN */
210
+ uint64_t right, /* IN */
211
+ bson_uint128_6464_t *product) /* OUT */
212
+ {
213
+ uint64_t left_high, left_low, right_high, right_low, product_high,
214
+ product_mid, product_mid2, product_low;
215
+ bson_uint128_6464_t rt = {0,0};
216
+
217
+ if (!left && !right) {
218
+ *product = rt;
219
+ return;
220
+ }
221
+
222
+ left_high = left >> 32;
223
+ left_low = (uint32_t) left;
224
+ right_high = right >> 32;
225
+ right_low = (uint32_t) right;
226
+
227
+ product_high = left_high * right_high;
228
+ product_mid = left_high * right_low;
229
+ product_mid2 = left_low * right_high;
230
+ product_low = left_low * right_low;
231
+
232
+ product_high += product_mid >> 32;
233
+ product_mid = (uint32_t) product_mid + product_mid2 + (product_low >> 32);
234
+
235
+ product_high = product_high + (product_mid >> 32);
236
+ product_low = (product_mid << 32) + (uint32_t) product_low;
237
+
238
+ rt.high = product_high;
239
+ rt.low = product_low;
240
+ *product = rt;
241
+ }
242
+
243
+ /**
244
+ *------------------------------------------------------------------------------
245
+ *
246
+ * dec128_tolower --
247
+ *
248
+ * This function converts the ASCII character @c to lowercase. It is locale
249
+ * insensitive (unlike the stdlib tolower).
250
+ *
251
+ * Returns:
252
+ * The lowercased character.
253
+ */
254
+
255
+ inline
256
+ char dec128_tolower (char c)
257
+ {
258
+ if (isupper (c)) {
259
+ c += 32;
260
+ }
261
+
262
+ return c;
263
+ }
264
+
265
+ /**
266
+ *------------------------------------------------------------------------------
267
+ *
268
+ * dec128_istreq --
269
+ *
270
+ * This function compares the null-terminated *ASCII* strings @a and @b
271
+ * for case-insensitive equality.
272
+ *
273
+ * Returns:
274
+ * true if the strings are equal, false otherwise.
275
+ */
276
+
277
+ inline
278
+ bool dec128_istreq (const char* a, const char* lasta,
279
+ const char* b, const char* lastb)
280
+ {
281
+ while (!(a == lasta && b == lastb))
282
+ {
283
+ // strings are different lengths
284
+ if (a == lasta || b == lastb)
285
+ {
286
+ return false;
287
+ }
288
+
289
+ if (dec128_tolower (*a) != dec128_tolower (*b)) {
290
+ return false;
291
+ }
292
+
293
+ a++;
294
+ b++;
295
+ }
296
+
297
+ return true;
298
+ }
299
+
300
+ } // namespace detail
301
+
302
+
303
+ /**
304
+ *------------------------------------------------------------------------------
305
+ *
306
+ * decimal128_to_chars --
307
+ *
308
+ * This function converts a BID formatted decimal128 value to string,
309
+ * accepting a &decimal128_t as @dec. The string is stored at @str.
310
+ *
311
+ * @dec : The BID formatted decimal to convert.
312
+ * @str : The output decimal128 string. At least %BSON_DECIMAL128_STRING
313
+ *characters.
314
+ *
315
+ * Returns:
316
+ * None.
317
+ *
318
+ * Side effects:
319
+ * None.
320
+ *
321
+ *------------------------------------------------------------------------------
322
+ */
323
+
324
+ inline
325
+ decimal128_to_chars_result decimal128_to_chars(char* first, char* last, const decimal128_t& dec)
326
+ {
327
+ const std::string bson_decimal128_inf = "Infinity";
328
+ const std::string bson_decimal128_nan = "NaN";
329
+
330
+ const uint32_t combination_mask = 0x1f; /* Extract least significant 5 bits */
331
+ const uint32_t exponent_mask = 0x3fff; /* Extract least significant 14 bits */
332
+ const uint32_t combination_infinity = 30; /* Value of combination field for Inf */
333
+ const uint32_t combination_nan = 31; /* Value of combination field for NaN */
334
+ const uint32_t exponent_bias = 6176; /* decimal128 exponent bias */
335
+
336
+ char* str_out = first; /* output pointer in string */
337
+ char significand_str[35]; /* decoded significand digits */
338
+
339
+ /* Note: bits in this routine are referred to starting at 0, */
340
+ /* from the sign bit, towards the coefficient. */
341
+ uint32_t high; /* bits 0 - 31 */
342
+ uint32_t midh; /* bits 32 - 63 */
343
+ uint32_t midl; /* bits 64 - 95 */
344
+ uint32_t low; /* bits 96 - 127 */
345
+ uint32_t combination; /* bits 1 - 5 */
346
+ uint32_t biased_exponent; /* decoded biased exponent (14 bits) */
347
+ uint32_t significand_digits = 0; /* the number of significand digits */
348
+ uint32_t significand[36] = {0}; /* the base-10 digits in the significand */
349
+ uint32_t *significand_read = significand; /* read pointer into significand */
350
+ int32_t exponent; /* unbiased exponent */
351
+ int32_t scientific_exponent; /* the exponent if scientific notation is
352
+ * used */
353
+ bool is_zero = false; /* true if the number is zero */
354
+
355
+ uint8_t significand_msb; /* the most signifcant significand bits (50-46) */
356
+ bson_uint128_t
357
+ significand128; /* temporary storage for significand decoding */
358
+
359
+ memset (significand_str, 0, sizeof (significand_str));
360
+
361
+ if ((int64_t) dec.high < 0) { /* negative */
362
+ *(str_out++) = '-';
363
+ }
364
+
365
+ low = (uint32_t) dec.low, midl = (uint32_t) (dec.low >> 32),
366
+ midh = (uint32_t) dec.high, high = (uint32_t) (dec.high >> 32);
367
+
368
+ /* Decode combination field and exponent */
369
+ combination = (high >> 26) & combination_mask;
370
+
371
+ if (JSONCONS_UNLIKELY ((combination >> 3) == 3)) {
372
+ /* Check for 'special' values */
373
+ if (combination == combination_infinity) { /* Infinity */
374
+ if (last-str_out >= static_cast<ptrdiff_t >(bson_decimal128_inf.size()))
375
+ {
376
+ std::memcpy(str_out, bson_decimal128_inf.data(), bson_decimal128_inf.size());
377
+ str_out += bson_decimal128_inf.size();
378
+ }
379
+ *str_out = 0;
380
+ //strcpy_s (str_out, last-str_out, bson_decimal128_inf.c_str());
381
+ return decimal128_to_chars_result{str_out, std::errc()};
382
+ } else if (combination == combination_nan) { /* NaN */
383
+ /* first, not str_out, to erase the sign */
384
+ str_out = first;
385
+ if (last-str_out >= static_cast<ptrdiff_t >(bson_decimal128_nan.size()))
386
+ {
387
+ std::memcpy(str_out, bson_decimal128_nan.data(), bson_decimal128_nan.size());
388
+ str_out += bson_decimal128_nan.size();
389
+ }
390
+ *str_out = 0;
391
+ //strcpy_s (first, last-first, bson_decimal128_nan.c_str());
392
+ /* we don't care about the NaN payload. */
393
+ return decimal128_to_chars_result{str_out, std::errc()};
394
+ } else {
395
+ biased_exponent = (high >> 15) & exponent_mask;
396
+ significand_msb = 0x8 + ((high >> 14) & 0x1);
397
+ }
398
+ } else {
399
+ significand_msb = (high >> 14) & 0x7;
400
+ biased_exponent = (high >> 17) & exponent_mask;
401
+ }
402
+
403
+ exponent = biased_exponent - exponent_bias;
404
+ /* Create string of significand digits */
405
+
406
+ /* Convert the 114-bit binary number represented by */
407
+ /* (high, midh, midl, low) to at most 34 decimal */
408
+ /* digits through modulo and division. */
409
+ significand128.parts[0] = (high & 0x3fff) + ((significand_msb & 0xf) << 14);
410
+ significand128.parts[1] = midh;
411
+ significand128.parts[2] = midl;
412
+ significand128.parts[3] = low;
413
+
414
+ if (significand128.parts[0] == 0 && significand128.parts[1] == 0 &&
415
+ significand128.parts[2] == 0 && significand128.parts[3] == 0) {
416
+ is_zero = true;
417
+ } else if (significand128.parts[0] >= (1 << 17)) {
418
+ /* The significand is non-canonical or zero.
419
+ * In order to preserve compatibility with the densely packed decimal
420
+ * format, the maximum value for the significand of decimal128 is
421
+ * 1e34 - 1. If the value is greater than 1e34 - 1, the IEEE 754
422
+ * standard dictates that the significand is interpreted as zero.
423
+ */
424
+ is_zero = true;
425
+ } else {
426
+ for (int k = 3; k >= 0; k--) {
427
+ uint32_t least_digits = 0;
428
+ detail::bson_uint128_divide1B (
429
+ significand128, &significand128, &least_digits);
430
+
431
+ /* We now have the 9 least significant digits (in base 2). */
432
+ /* Convert and output to string. */
433
+ if (!least_digits) {
434
+ continue;
435
+ }
436
+
437
+ for (int j = 8; j >= 0; j--) {
438
+ significand[k * 9 + j] = least_digits % 10;
439
+ least_digits /= 10;
440
+ }
441
+ }
442
+ }
443
+
444
+ /* Output format options: */
445
+ /* Scientific - [-]d.dddE(+/-)dd or [-]dE(+/-)dd */
446
+ /* Regular - ddd.ddd */
447
+
448
+ if (is_zero) {
449
+ significand_digits = 1;
450
+ *significand_read = 0;
451
+ } else {
452
+ significand_digits = 36;
453
+ while (!(*significand_read)) {
454
+ significand_digits--;
455
+ significand_read++;
456
+ }
457
+ }
458
+
459
+ scientific_exponent = significand_digits - 1 + exponent;
460
+
461
+ /* The scientific exponent checks are dictated by the string conversion
462
+ * specification and are somewhat arbitrary cutoffs.
463
+ *
464
+ * We must check exponent > 0, because if this is the case, the number
465
+ * has trailing zeros. However, we *cannot* output these trailing zeros,
466
+ * because doing so would change the precision of the value, and would
467
+ * change stored data if the string converted number is round tripped.
468
+ */
469
+ if (scientific_exponent < -6 || exponent > 0) {
470
+ /* Scientific format */
471
+ *(str_out++) = char(*(significand_read++)) + '0';
472
+ significand_digits--;
473
+
474
+ if (significand_digits) {
475
+ *(str_out++) = '.';
476
+ }
477
+
478
+ for (std::size_t i = 0; i < significand_digits && (str_out - first) < 36; i++) {
479
+ *(str_out++) = char(*(significand_read++)) + '0';
480
+ }
481
+ /* Exponent */
482
+ *(str_out++) = 'E';
483
+
484
+ std::string s;
485
+ if (scientific_exponent >= 0) {
486
+ s.push_back('+');
487
+ }
488
+ jsoncons::detail::from_integer(scientific_exponent, s);
489
+ if (str_out + s.size() < last)
490
+ {
491
+ std::memcpy(str_out, s.data(), s.size());
492
+ }
493
+ else
494
+ {
495
+ return decimal128_to_chars_result{str_out, std::errc::value_too_large};
496
+ }
497
+ str_out += s.size();
498
+ } else {
499
+ /* Regular format with no decimal place */
500
+ if (exponent >= 0) {
501
+ for (std::size_t i = 0; i < significand_digits && (str_out - first) < 36; i++) {
502
+ *(str_out++) = char(*(significand_read++)) + '0';
503
+ }
504
+ } else {
505
+ int32_t radix_position = significand_digits + exponent;
506
+
507
+ if (radix_position > 0) { /* non-zero digits before radix */
508
+ for (int32_t i = 0;
509
+ i < radix_position && (str_out < last);
510
+ i++) {
511
+ *(str_out++) = char(*(significand_read++)) + '0';
512
+ }
513
+ } else { /* leading zero before radix point */
514
+ *(str_out++) = '0';
515
+ }
516
+
517
+ *(str_out++) = '.';
518
+ while (radix_position++ < 0) { /* add leading zeros after radix */
519
+ *(str_out++) = '0';
520
+ }
521
+
522
+ for (std::size_t i = 0;
523
+ (i < significand_digits - (std::max) (radix_position - 1, 0)) &&
524
+ (str_out < last);
525
+ i++) {
526
+ *(str_out++) = char(*(significand_read++)) + '0';
527
+ }
528
+ }
529
+ }
530
+ return decimal128_to_chars_result{str_out, std::errc()};
531
+ }
532
+
533
+
534
+
535
+ /**
536
+ *------------------------------------------------------------------------------
537
+ *
538
+ * bson_decimal128_from_string_w_len --
539
+ *
540
+ * This function converts @string in the format [+-]ddd[.]ddd[E][+-]dddd to
541
+ * decimal128. Out of range values are converted to +/-Infinity. Invalid
542
+ * strings are converted to NaN. @len is the length of the string, or -1
543
+ * meaning the string is null-terminated.
544
+ *
545
+ * If more digits are provided than the available precision allows,
546
+ * round to the nearest expressable decimal128 with ties going to even will
547
+ * occur.
548
+ *
549
+ * Note: @string must be ASCII only!
550
+ *
551
+ * Returns:
552
+ * true on success, or false on failure. @dec will be NaN if @str was invalid
553
+ * The &decimal128_t converted from @string at @dec.
554
+ *
555
+ * Side effects:
556
+ * None.
557
+ *
558
+ *------------------------------------------------------------------------------
559
+ */
560
+
561
+ inline
562
+ decimal128_from_chars_result decimal128_from_chars(const char* first, const char* last, decimal128_t& dec)
563
+ {
564
+ const string_view inf_str = "inf";
565
+ const string_view infinity_str = "infinity";
566
+ const string_view nan_str = "nan";
567
+
568
+ ptrdiff_t len = last - first;
569
+
570
+ bson_uint128_6464_t significand = {0,0};
571
+
572
+ const char* str_read = first; /* Read pointer for consuming str. */
573
+
574
+ /* Parsing state tracking */
575
+ bool is_negative = false;
576
+ bool saw_radix = false;
577
+ bool includes_sign = false; /* True if the input first contains a sign. */
578
+ bool found_nonzero = false;
579
+
580
+ size_t significant_digits = 0; /* Total number of significant digits
581
+ * (no leading or trailing zero) */
582
+ size_t ndigits_read = 0; /* Total number of significand digits read */
583
+ size_t ndigits = 0; /* Total number of digits (no leading zeros) */
584
+ size_t radix_position = 0; /* The number of the digits after radix */
585
+ size_t first_nonzero = 0; /* The index of the first non-zero in *str* */
586
+
587
+ uint16_t digits[decimal128_limits::max_digits] = {0};
588
+ uint16_t ndigits_stored = 0; /* The number of digits in digits */
589
+ uint16_t *digits_insert = digits; /* Insertion pointer for digits */
590
+ size_t first_digit = 0; /* The index of the first non-zero digit */
591
+ size_t last_digit = 0; /* The index of the last digit */
592
+
593
+ int32_t exponent = 0;
594
+ uint64_t significand_high = 0; /* The high 17 digits of the significand */
595
+ uint64_t significand_low = 0; /* The low 17 digits of the significand */
596
+ uint16_t biased_exponent = 0; /* The biased exponent */
597
+
598
+ dec.high = 0;
599
+ dec.low = 0;
600
+
601
+ if (*str_read == '+' || *str_read == '-') {
602
+ is_negative = *(str_read++) == '-';
603
+ includes_sign = true;
604
+ }
605
+
606
+ /* Check for Infinity or NaN */
607
+ if (!isdigit (*str_read) && *str_read != '.') {
608
+ if (detail::dec128_istreq (str_read, last, inf_str.data(), inf_str.data()+inf_str.length()) ||
609
+ detail::dec128_istreq (str_read, last, infinity_str.data(), infinity_str.data()+infinity_str.length()))
610
+ {
611
+ dec = is_negative ? decimal128_limits::neg_infinity() : decimal128_limits::infinity();
612
+ return decimal128_from_chars_result{str_read,std::errc()};
613
+ } else if (detail::dec128_istreq (str_read, last, nan_str.data(), nan_str.data()+nan_str.length())) {
614
+ dec = decimal128_limits::nan();
615
+ return decimal128_from_chars_result{str_read,std::errc()};
616
+ }
617
+
618
+ dec = decimal128_limits::nan();
619
+ return decimal128_from_chars_result{str_read,std::errc::invalid_argument};
620
+ }
621
+
622
+ /* Read digits */
623
+ while (((isdigit (*str_read) || *str_read == '.')) &&
624
+ (len == -1 || str_read < first + len)) {
625
+ if (*str_read == '.') {
626
+ if (saw_radix) {
627
+ dec = decimal128_limits::nan();
628
+ return decimal128_from_chars_result{str_read,std::errc::invalid_argument};
629
+ }
630
+
631
+ saw_radix = true;
632
+ str_read++;
633
+ continue;
634
+ }
635
+
636
+ if (ndigits_stored < 34) {
637
+ if (*str_read != '0' || found_nonzero) {
638
+ if (!found_nonzero) {
639
+ first_nonzero = ndigits_read;
640
+ }
641
+
642
+ found_nonzero = true;
643
+ *(digits_insert++) = *(str_read) - '0'; /* Only store 34 digits */
644
+ ndigits_stored++;
645
+ }
646
+ }
647
+
648
+ if (found_nonzero) {
649
+ ndigits++;
650
+ }
651
+
652
+ if (saw_radix) {
653
+ radix_position++;
654
+ }
655
+
656
+ ndigits_read++;
657
+ str_read++;
658
+ }
659
+
660
+ if (saw_radix && !ndigits_read) {
661
+ dec = decimal128_limits::nan();
662
+ return decimal128_from_chars_result{str_read,std::errc::invalid_argument};
663
+ }
664
+
665
+ /* Read exponent if exists */
666
+ if (*str_read == 'e' || *str_read == 'E') {
667
+ ++str_read;
668
+ if (*str_read == '+') {
669
+ ++str_read;
670
+ }
671
+ auto result = jsoncons::detail::to_integer(str_read, last - str_read, exponent);
672
+ if (result.ec != jsoncons::detail::to_integer_errc())
673
+ {
674
+ dec = decimal128_limits::nan();
675
+ return decimal128_from_chars_result{str_read,std::errc::invalid_argument};
676
+ }
677
+ str_read = result.ptr;
678
+ }
679
+
680
+ if ((len == -1 || str_read < first + len) && *str_read) {
681
+ dec = decimal128_limits::nan();
682
+ return decimal128_from_chars_result{str_read,std::errc::invalid_argument};
683
+ }
684
+
685
+ /* Done reading input. */
686
+ /* Find first non-zero digit in digits */
687
+ first_digit = 0;
688
+
689
+ if (!ndigits_stored) { /* value is zero */
690
+ first_digit = 0;
691
+ last_digit = 0;
692
+ digits[0] = 0;
693
+ ndigits = 1;
694
+ ndigits_stored = 1;
695
+ significant_digits = 0;
696
+ } else {
697
+ last_digit = ndigits_stored - 1;
698
+ significant_digits = ndigits;
699
+ /* Mark trailing zeros as non-significant */
700
+ while (first[first_nonzero + significant_digits - 1 + includes_sign +
701
+ saw_radix] == '0') {
702
+ significant_digits--;
703
+ }
704
+ }
705
+
706
+
707
+ /* Normalization of exponent */
708
+ /* Correct exponent based on radix position, and shift significand as needed
709
+ */
710
+ /* to represent user input */
711
+
712
+ /* Overflow prevention */
713
+ if (exponent <= static_cast<int32_t>(radix_position) && static_cast<int32_t>(radix_position) - exponent > (1 << 14)) {
714
+ exponent = decimal128_limits::exponent_min;
715
+ } else {
716
+ exponent -= static_cast<int32_t>(radix_position);
717
+ }
718
+
719
+ /* Attempt to normalize the exponent */
720
+ while (exponent > decimal128_limits::exponent_max) {
721
+ /* Shift exponent to significand and decrease */
722
+ last_digit++;
723
+
724
+ if (last_digit - first_digit > decimal128_limits::max_digits) {
725
+ /* The exponent is too great to shift into the significand. */
726
+ if (significant_digits == 0) {
727
+ /* Value is zero, we are allowed to clamp the exponent. */
728
+ exponent = decimal128_limits::exponent_max;
729
+ break;
730
+ }
731
+
732
+ /* Overflow is not permitted, error. */
733
+ dec = decimal128_limits::nan();
734
+ return decimal128_from_chars_result{str_read,std::errc::invalid_argument};
735
+ }
736
+
737
+ exponent--;
738
+ }
739
+
740
+ while (exponent < decimal128_limits::exponent_min || ndigits_stored < ndigits) {
741
+ /* Shift last digit */
742
+ if (last_digit == 0) {
743
+ /* underflow is not allowed, but zero clamping is */
744
+ if (significant_digits == 0) {
745
+ exponent = decimal128_limits::exponent_min;
746
+ break;
747
+ }
748
+
749
+ dec = decimal128_limits::nan();
750
+ return decimal128_from_chars_result{str_read,std::errc::invalid_argument};
751
+ }
752
+
753
+ if (ndigits_stored < ndigits) {
754
+ if (first[ndigits - 1 + includes_sign + saw_radix] - '0' != 0 &&
755
+ significant_digits != 0) {
756
+ dec = decimal128_limits::nan();
757
+ return decimal128_from_chars_result{str_read,std::errc::invalid_argument};
758
+ }
759
+
760
+ ndigits--; /* adjust to match digits not stored */
761
+ } else {
762
+ if (digits[last_digit] != 0) {
763
+ /* Inexact rounding is not allowed. */
764
+ dec = decimal128_limits::nan();
765
+ return decimal128_from_chars_result{str_read,std::errc::invalid_argument};
766
+ }
767
+
768
+
769
+ last_digit--; /* adjust to round */
770
+ }
771
+
772
+ if (exponent < decimal128_limits::exponent_max) {
773
+ exponent++;
774
+ } else {
775
+ dec = decimal128_limits::nan();
776
+ return decimal128_from_chars_result{str_read,std::errc::invalid_argument};
777
+ }
778
+ }
779
+
780
+ /* Round */
781
+ /* We've normalized the exponent, but might still need to round. */
782
+ if (last_digit - first_digit + 1 < significant_digits) {
783
+ uint8_t round_digit;
784
+
785
+ /* There are non-zero digits after last_digit that need rounding. */
786
+ /* We round to nearest, ties to even */
787
+ round_digit =
788
+ first[first_nonzero + last_digit + includes_sign + saw_radix + 1] -
789
+ '0';
790
+
791
+ if (round_digit != 0) {
792
+ /* Inexact (non-zero) rounding is not allowed */
793
+ dec = decimal128_limits::nan();
794
+ return decimal128_from_chars_result{str_read,std::errc::invalid_argument};
795
+ }
796
+ }
797
+
798
+ /* Encode significand */
799
+ significand_high = 0, /* The high 17 digits of the significand */
800
+ significand_low = 0; /* The low 17 digits of the significand */
801
+
802
+ if (significant_digits == 0) { /* read a zero */
803
+ significand_high = 0;
804
+ significand_low = 0;
805
+ } else if (last_digit - first_digit < 17) {
806
+ size_t d_idx = first_digit;
807
+ significand_low = digits[d_idx++];
808
+
809
+ for (; d_idx <= last_digit; d_idx++) {
810
+ significand_low *= 10;
811
+ significand_low += digits[d_idx];
812
+ significand_high = 0;
813
+ }
814
+ } else {
815
+ size_t d_idx = first_digit;
816
+ significand_high = digits[d_idx++];
817
+
818
+ for (; d_idx <= last_digit - 17; d_idx++) {
819
+ significand_high *= 10;
820
+ significand_high += digits[d_idx];
821
+ }
822
+
823
+ significand_low = digits[d_idx++];
824
+
825
+ for (; d_idx <= last_digit; d_idx++) {
826
+ significand_low *= 10;
827
+ significand_low += digits[d_idx];
828
+ }
829
+ }
830
+
831
+ detail::mul_64x64 (significand_high, 100000000000000000ull, &significand);
832
+ significand.low += significand_low;
833
+
834
+ if (significand.low < significand_low) {
835
+ significand.high += 1;
836
+ }
837
+
838
+
839
+ biased_exponent = static_cast<uint16_t>(exponent + static_cast<int32_t>(decimal128_limits::exponent_bias));
840
+
841
+ /* Encode combination, exponent, and significand. */
842
+ if ((significand.high >> 49) & 1) {
843
+ /* Encode '11' into bits 1 to 3 */
844
+ dec.high |= (0x3ull << 61);
845
+ dec.high |= (biased_exponent & 0x3fffull) << 47;
846
+ dec.high |= significand.high & 0x7fffffffffffull;
847
+ } else {
848
+ dec.high |= (biased_exponent & 0x3fffull) << 49;
849
+ dec.high |= significand.high & 0x1ffffffffffffull;
850
+ }
851
+
852
+ dec.low = significand.low;
853
+
854
+ /* Encode sign */
855
+ if (is_negative) {
856
+ dec.high |= 0x8000000000000000ull;
857
+ }
858
+
859
+ return decimal128_from_chars_result{str_read,std::errc()};
860
+ }
861
+
862
+ } // namespace bson
863
+ } // namespace jsoncons
864
+
865
+ #endif