react-native-windows 0.64.22 → 0.64.23

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.
package/CHANGELOG.json CHANGED
@@ -2,7 +2,28 @@
2
2
  "name": "react-native-windows",
3
3
  "entries": [
4
4
  {
5
- "date": "Wed, 13 Oct 2021 20:38:59 GMT",
5
+ "date": "Mon, 18 Oct 2021 15:07:43 GMT",
6
+ "tag": "react-native-windows_v0.64.23",
7
+ "version": "0.64.23",
8
+ "comments": {
9
+ "patch": [
10
+ {
11
+ "comment": "Avoid exporting data as that breaks delay loading",
12
+ "author": "30809111+acoates-ms@users.noreply.github.com",
13
+ "commit": "d6ab3a6fb5a1c5992d295e9cf1d6eacac1696b94",
14
+ "package": "react-native-windows"
15
+ },
16
+ {
17
+ "comment": "Crash using PlatformConstants on Windows 8.1",
18
+ "author": "30809111+acoates-ms@users.noreply.github.com",
19
+ "commit": "7cd470896df06c5196ee37a5d52eb6dc7abe8498",
20
+ "package": "react-native-windows"
21
+ }
22
+ ]
23
+ }
24
+ },
25
+ {
26
+ "date": "Wed, 13 Oct 2021 20:39:16 GMT",
6
27
  "tag": "react-native-windows_v0.64.22",
7
28
  "version": "0.64.22",
8
29
  "comments": {
package/CHANGELOG.md CHANGED
@@ -1,17 +1,26 @@
1
1
  # Change Log - react-native-windows
2
2
 
3
- This log was last generated on Wed, 13 Oct 2021 20:38:59 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 18 Oct 2021 15:07:43 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
- ## 0.64.22
7
+ ## 0.64.23
8
8
 
9
- Wed, 13 Oct 2021 20:38:59 GMT
9
+ Mon, 18 Oct 2021 15:07:43 GMT
10
10
 
11
11
  ### Patches
12
12
 
13
- - Use V8 by default in desktop (if enabled) (anandrag@microsoft.com)
13
+ - Avoid exporting data as that breaks delay loading (30809111+acoates-ms@users.noreply.github.com)
14
+ - Crash using PlatformConstants on Windows 8.1 (30809111+acoates-ms@users.noreply.github.com)
14
15
 
16
+ ## 0.64.22
17
+
18
+ Wed, 13 Oct 2021 20:39:16 GMT
19
+
20
+ ### Patches
21
+
22
+ - Use V8 by default in desktop (if enabled) (anandrag@microsoft.com)
23
+
15
24
  ## 0.64.21
16
25
 
17
26
  Mon, 11 Oct 2021 15:06:31 GMT
@@ -0,0 +1,1221 @@
1
+ /*
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #pragma once
18
+
19
+ #include <functional>
20
+
21
+ #include <folly/CPortability.h>
22
+ #include <folly/Conv.h>
23
+ #include <folly/Format.h>
24
+ #include <folly/Likely.h>
25
+ #include <folly/detail/Iterators.h>
26
+ #include <folly/lang/Exception.h>
27
+
28
+ namespace folly {
29
+ namespace detail {
30
+ struct DynamicHasher {
31
+ using is_transparent = void;
32
+
33
+ size_t operator()(dynamic const &d) const {
34
+ return d.hash();
35
+ }
36
+
37
+ template <typename T>
38
+ std::enable_if_t<std::is_convertible<T, StringPiece>::value, size_t> operator()(T const &val) const {
39
+ // keep consistent with dynamic::hash() for strings
40
+ return Hash()(static_cast<StringPiece>(val));
41
+ }
42
+ };
43
+
44
+ struct DynamicKeyEqual {
45
+ using is_transparent = void;
46
+
47
+ bool operator()(const dynamic &lhs, const dynamic &rhs) const {
48
+ return std::equal_to<dynamic>()(lhs, rhs);
49
+ }
50
+
51
+ // Dynamic objects contains a map<dynamic, dynamic>. At least one of the
52
+ // operands should be a dynamic. Hence, an operator() where both operands are
53
+ // convertible to StringPiece is unnecessary.
54
+ template <typename A, typename B>
55
+ std::enable_if_t<std::is_convertible<A, StringPiece>::value && std::is_convertible<B, StringPiece>::value, bool>
56
+ operator()(A const &lhs, B const &rhs) const = delete;
57
+
58
+ template <typename A>
59
+ std::enable_if_t<std::is_convertible<A, StringPiece>::value, bool> operator()(A const &lhs, dynamic const &rhs)
60
+ const {
61
+ return FOLLY_LIKELY(rhs.type() == dynamic::Type::STRING) && std::equal_to<StringPiece>()(lhs, rhs.stringPiece());
62
+ }
63
+
64
+ template <typename B>
65
+ std::enable_if_t<std::is_convertible<B, StringPiece>::value, bool> operator()(dynamic const &lhs, B const &rhs)
66
+ const {
67
+ return FOLLY_LIKELY(lhs.type() == dynamic::Type::STRING) && std::equal_to<StringPiece>()(lhs.stringPiece(), rhs);
68
+ }
69
+ };
70
+ } // namespace detail
71
+ } // namespace folly
72
+
73
+ //////////////////////////////////////////////////////////////////////
74
+
75
+ namespace std {
76
+
77
+ template <>
78
+ struct hash<::folly::dynamic> {
79
+ size_t operator()(::folly::dynamic const &d) const {
80
+ return d.hash();
81
+ }
82
+ };
83
+
84
+ } // namespace std
85
+
86
+ //////////////////////////////////////////////////////////////////////
87
+
88
+ // This is a higher-order preprocessor macro to aid going from runtime
89
+ // types to the compile time type system.
90
+ #define FB_DYNAMIC_APPLY(type, apply) \
91
+ do { \
92
+ switch ((type)) { \
93
+ case NULLT: \
94
+ apply(std::nullptr_t); \
95
+ break; \
96
+ case ARRAY: \
97
+ apply(Array); \
98
+ break; \
99
+ case BOOL: \
100
+ apply(bool); \
101
+ break; \
102
+ case DOUBLE: \
103
+ apply(double); \
104
+ break; \
105
+ case INT64: \
106
+ apply(int64_t); \
107
+ break; \
108
+ case OBJECT: \
109
+ apply(ObjectImpl); \
110
+ break; \
111
+ case STRING: \
112
+ apply(std::string); \
113
+ break; \
114
+ default: \
115
+ abort(); \
116
+ } \
117
+ } while (0)
118
+
119
+ //////////////////////////////////////////////////////////////////////
120
+
121
+ namespace folly {
122
+
123
+ struct FOLLY_EXPORT TypeError : std::runtime_error {
124
+ explicit TypeError(const std::string &expected, dynamic::Type actual);
125
+ explicit TypeError(const std::string &expected, dynamic::Type actual1, dynamic::Type actual2);
126
+ };
127
+
128
+ //////////////////////////////////////////////////////////////////////
129
+
130
+ namespace detail {
131
+
132
+ // This helper is used in destroy() to be able to run destructors on
133
+ // types like "int64_t" without a compiler error.
134
+ struct Destroy {
135
+ template <class T>
136
+ static void destroy(T *t) {
137
+ t->~T();
138
+ }
139
+ };
140
+
141
+ /*
142
+ * Helper for implementing numeric conversions in operators on
143
+ * numbers. Just promotes to double when one of the arguments is
144
+ * double, or throws if either is not a numeric type.
145
+ */
146
+ template <template <class> class Op>
147
+ dynamic numericOp(dynamic const &a, dynamic const &b) {
148
+ if (!a.isNumber() || !b.isNumber()) {
149
+ throw_exception<TypeError>("numeric", a.type(), b.type());
150
+ }
151
+ if (a.isDouble() || b.isDouble()) {
152
+ return Op<double>()(a.asDouble(), b.asDouble());
153
+ }
154
+ return Op<int64_t>()(a.asInt(), b.asInt());
155
+ }
156
+
157
+ } // namespace detail
158
+
159
+ //////////////////////////////////////////////////////////////////////
160
+
161
+ /*
162
+ * We're doing this instead of a simple member typedef to avoid the
163
+ * undefined behavior of parameterizing F14NodeMap<> with an
164
+ * incomplete type.
165
+ *
166
+ * Note: Later we may add separate order tracking here (a multi-index
167
+ * type of thing.)
168
+ */
169
+ struct dynamic::ObjectImpl : F14NodeMap<dynamic, dynamic, detail::DynamicHasher, detail::DynamicKeyEqual> {};
170
+
171
+ //////////////////////////////////////////////////////////////////////
172
+
173
+ // Helper object for creating objects conveniently. See object and
174
+ // the dynamic::dynamic(ObjectMaker&&) ctor.
175
+ struct dynamic::ObjectMaker {
176
+ friend struct dynamic;
177
+
178
+ explicit ObjectMaker() : val_(dynamic::object) {}
179
+ explicit ObjectMaker(dynamic key, dynamic val) : val_(dynamic::object) {
180
+ val_.insert(std::move(key), std::move(val));
181
+ }
182
+
183
+ // Make sure no one tries to save one of these into an lvalue with
184
+ // auto or anything like that.
185
+ ObjectMaker(ObjectMaker &&) = default;
186
+ ObjectMaker(ObjectMaker const &) = delete;
187
+ ObjectMaker &operator=(ObjectMaker const &) = delete;
188
+ ObjectMaker &operator=(ObjectMaker &&) = delete;
189
+
190
+ // This returns an rvalue-reference instead of an lvalue-reference
191
+ // to allow constructs like this to moved instead of copied:
192
+ // dynamic a = dynamic::object("a", "b")("c", "d")
193
+ ObjectMaker &&operator()(dynamic key, dynamic val) {
194
+ val_.insert(std::move(key), std::move(val));
195
+ return std::move(*this);
196
+ }
197
+
198
+ private:
199
+ dynamic val_;
200
+ };
201
+
202
+ inline void dynamic::array(EmptyArrayTag) {}
203
+
204
+ template <class... Args>
205
+ inline dynamic dynamic::array(Args &&... args) {
206
+ return dynamic(Array{std::forward<Args>(args)...});
207
+ }
208
+
209
+ inline dynamic::ObjectMaker dynamic::object() {
210
+ return ObjectMaker();
211
+ }
212
+ inline dynamic::ObjectMaker dynamic::object(dynamic a, dynamic b) {
213
+ return ObjectMaker(std::move(a), std::move(b));
214
+ }
215
+
216
+ //////////////////////////////////////////////////////////////////////
217
+
218
+ struct dynamic::item_iterator : detail::IteratorAdaptor<
219
+ dynamic::item_iterator,
220
+ dynamic::ObjectImpl::iterator,
221
+ std::pair<dynamic const, dynamic>,
222
+ std::forward_iterator_tag> {
223
+ using Super = detail::IteratorAdaptor<
224
+ dynamic::item_iterator,
225
+ dynamic::ObjectImpl::iterator,
226
+ std::pair<dynamic const, dynamic>,
227
+ std::forward_iterator_tag>;
228
+ /* implicit */ item_iterator(dynamic::ObjectImpl::iterator b) : Super(b) {}
229
+
230
+ using object_type = dynamic::ObjectImpl;
231
+ };
232
+
233
+ struct dynamic::value_iterator
234
+ : detail::
235
+ IteratorAdaptor<dynamic::value_iterator, dynamic::ObjectImpl::iterator, dynamic, std::forward_iterator_tag> {
236
+ using Super = detail::
237
+ IteratorAdaptor<dynamic::value_iterator, dynamic::ObjectImpl::iterator, dynamic, std::forward_iterator_tag>;
238
+ /* implicit */ value_iterator(dynamic::ObjectImpl::iterator b) : Super(b) {}
239
+
240
+ using object_type = dynamic::ObjectImpl;
241
+
242
+ dynamic &dereference() const {
243
+ return base()->second;
244
+ }
245
+ };
246
+
247
+ struct dynamic::const_item_iterator : detail::IteratorAdaptor<
248
+ dynamic::const_item_iterator,
249
+ dynamic::ObjectImpl::const_iterator,
250
+ std::pair<dynamic const, dynamic> const,
251
+ std::forward_iterator_tag> {
252
+ using Super = detail::IteratorAdaptor<
253
+ dynamic::const_item_iterator,
254
+ dynamic::ObjectImpl::const_iterator,
255
+ std::pair<dynamic const, dynamic> const,
256
+ std::forward_iterator_tag>;
257
+ /* implicit */ const_item_iterator(dynamic::ObjectImpl::const_iterator b) : Super(b) {}
258
+ /* implicit */ const_item_iterator(const_item_iterator const &i) : Super(i.base()) {}
259
+ /* implicit */ const_item_iterator(item_iterator i) : Super(i.base()) {}
260
+
261
+ using object_type = dynamic::ObjectImpl const;
262
+ };
263
+
264
+ struct dynamic::const_key_iterator : detail::IteratorAdaptor<
265
+ dynamic::const_key_iterator,
266
+ dynamic::ObjectImpl::const_iterator,
267
+ dynamic const,
268
+ std::forward_iterator_tag> {
269
+ using Super = detail::IteratorAdaptor<
270
+ dynamic::const_key_iterator,
271
+ dynamic::ObjectImpl::const_iterator,
272
+ dynamic const,
273
+ std::forward_iterator_tag>;
274
+ /* implicit */ const_key_iterator(dynamic::ObjectImpl::const_iterator b) : Super(b) {}
275
+
276
+ using object_type = dynamic::ObjectImpl const;
277
+
278
+ dynamic const &dereference() const {
279
+ return base()->first;
280
+ }
281
+ };
282
+
283
+ struct dynamic::const_value_iterator : detail::IteratorAdaptor<
284
+ dynamic::const_value_iterator,
285
+ dynamic::ObjectImpl::const_iterator,
286
+ dynamic const,
287
+ std::forward_iterator_tag> {
288
+ using Super = detail::IteratorAdaptor<
289
+ dynamic::const_value_iterator,
290
+ dynamic::ObjectImpl::const_iterator,
291
+ dynamic const,
292
+ std::forward_iterator_tag>;
293
+ /* implicit */ const_value_iterator(dynamic::ObjectImpl::const_iterator b) : Super(b) {}
294
+ /* implicit */ const_value_iterator(value_iterator i) : Super(i.base()) {}
295
+ /* implicit */ const_value_iterator(dynamic::ObjectImpl::iterator i) : Super(i) {}
296
+
297
+ using object_type = dynamic::ObjectImpl const;
298
+
299
+ dynamic const &dereference() const {
300
+ return base()->second;
301
+ }
302
+ };
303
+
304
+ //////////////////////////////////////////////////////////////////////
305
+
306
+ inline dynamic::dynamic() : dynamic(nullptr) {}
307
+
308
+ inline dynamic::dynamic(std::nullptr_t) : type_(NULLT) {}
309
+
310
+ inline dynamic::dynamic(void (*)(EmptyArrayTag)) : type_(ARRAY) {
311
+ new (&u_.array) Array();
312
+ }
313
+
314
+ inline dynamic::dynamic(ObjectMaker (*)()) : type_(OBJECT) {
315
+ new (getAddress<ObjectImpl>()) ObjectImpl();
316
+ }
317
+
318
+ inline dynamic::dynamic(StringPiece s) : type_(STRING) {
319
+ new (&u_.string) std::string(s.data(), s.size());
320
+ }
321
+
322
+ inline dynamic::dynamic(char const *s) : type_(STRING) {
323
+ new (&u_.string) std::string(s);
324
+ }
325
+
326
+ inline dynamic::dynamic(std::string s) : type_(STRING) {
327
+ new (&u_.string) std::string(std::move(s));
328
+ }
329
+
330
+ inline dynamic::dynamic(ObjectMaker &&maker) : type_(OBJECT) {
331
+ new (getAddress<ObjectImpl>()) ObjectImpl(std::move(*maker.val_.getAddress<ObjectImpl>()));
332
+ }
333
+
334
+ inline dynamic::dynamic(dynamic const &o) : type_(NULLT) {
335
+ *this = o;
336
+ }
337
+
338
+ inline dynamic::dynamic(dynamic &&o) noexcept : type_(NULLT) {
339
+ *this = std::move(o);
340
+ }
341
+
342
+ inline dynamic::~dynamic() noexcept {
343
+ destroy();
344
+ }
345
+
346
+ // Integral types except bool convert to int64_t, float types to double.
347
+ template <class T>
348
+ struct dynamic::NumericTypeHelper<T, typename std::enable_if<std::is_integral<T>::value>::type> {
349
+ static_assert(
350
+ !kIsObjC || sizeof(T) > sizeof(char),
351
+ "char-sized types are ambiguous in objc; cast to bool or wider type");
352
+ using type = int64_t;
353
+ };
354
+ template <>
355
+ struct dynamic::NumericTypeHelper<bool> {
356
+ using type = bool;
357
+ };
358
+ template <>
359
+ struct dynamic::NumericTypeHelper<float> {
360
+ using type = double;
361
+ };
362
+ template <>
363
+ struct dynamic::NumericTypeHelper<double> {
364
+ using type = double;
365
+ };
366
+
367
+ inline dynamic::dynamic(std::vector<bool>::reference b) : dynamic(static_cast<bool>(b)) {}
368
+ inline dynamic::dynamic(VectorBoolConstRefCtorType b) : dynamic(static_cast<bool>(b)) {}
369
+
370
+ template <class T, class NumericType /* = typename NumericTypeHelper<T>::type */>
371
+ dynamic::dynamic(T t) {
372
+ type_ = TypeInfo<NumericType>::type;
373
+ new (getAddress<NumericType>()) NumericType(NumericType(t));
374
+ }
375
+
376
+ template <class Iterator>
377
+ dynamic::dynamic(Iterator first, Iterator last) : type_(ARRAY) {
378
+ new (&u_.array) Array(first, last);
379
+ }
380
+
381
+ //////////////////////////////////////////////////////////////////////
382
+
383
+ inline dynamic::const_iterator dynamic::begin() const {
384
+ return get<Array>().begin();
385
+ }
386
+ inline dynamic::const_iterator dynamic::end() const {
387
+ return get<Array>().end();
388
+ }
389
+
390
+ inline dynamic::iterator dynamic::begin() {
391
+ return get<Array>().begin();
392
+ }
393
+ inline dynamic::iterator dynamic::end() {
394
+ return get<Array>().end();
395
+ }
396
+
397
+ template <class It>
398
+ struct dynamic::IterableProxy {
399
+ typedef It iterator;
400
+ typedef typename It::value_type value_type;
401
+ typedef typename It::object_type object_type;
402
+
403
+ /* implicit */ IterableProxy(object_type *o) : o_(o) {}
404
+
405
+ It begin() const {
406
+ return o_->begin();
407
+ }
408
+
409
+ It end() const {
410
+ return o_->end();
411
+ }
412
+
413
+ private:
414
+ object_type *o_;
415
+ };
416
+
417
+ inline dynamic::IterableProxy<dynamic::const_key_iterator> dynamic::keys() const {
418
+ return &(get<ObjectImpl>());
419
+ }
420
+
421
+ inline dynamic::IterableProxy<dynamic::const_value_iterator> dynamic::values() const {
422
+ return &(get<ObjectImpl>());
423
+ }
424
+
425
+ inline dynamic::IterableProxy<dynamic::const_item_iterator> dynamic::items() const {
426
+ return &(get<ObjectImpl>());
427
+ }
428
+
429
+ inline dynamic::IterableProxy<dynamic::value_iterator> dynamic::values() {
430
+ return &(get<ObjectImpl>());
431
+ }
432
+
433
+ inline dynamic::IterableProxy<dynamic::item_iterator> dynamic::items() {
434
+ return &(get<ObjectImpl>());
435
+ }
436
+
437
+ inline bool dynamic::isString() const {
438
+ return get_nothrow<std::string>() != nullptr;
439
+ }
440
+ inline bool dynamic::isObject() const {
441
+ return get_nothrow<ObjectImpl>() != nullptr;
442
+ }
443
+ inline bool dynamic::isBool() const {
444
+ return get_nothrow<bool>() != nullptr;
445
+ }
446
+ inline bool dynamic::isArray() const {
447
+ return get_nothrow<Array>() != nullptr;
448
+ }
449
+ inline bool dynamic::isDouble() const {
450
+ return get_nothrow<double>() != nullptr;
451
+ }
452
+ inline bool dynamic::isInt() const {
453
+ return get_nothrow<int64_t>() != nullptr;
454
+ }
455
+ inline bool dynamic::isNull() const {
456
+ return get_nothrow<std::nullptr_t>() != nullptr;
457
+ }
458
+ inline bool dynamic::isNumber() const {
459
+ return isInt() || isDouble();
460
+ }
461
+
462
+ inline dynamic::Type dynamic::type() const {
463
+ return type_;
464
+ }
465
+
466
+ inline std::string dynamic::asString() const {
467
+ return asImpl<std::string>();
468
+ }
469
+ inline double dynamic::asDouble() const {
470
+ return asImpl<double>();
471
+ }
472
+ inline int64_t dynamic::asInt() const {
473
+ return asImpl<int64_t>();
474
+ }
475
+ inline bool dynamic::asBool() const {
476
+ return asImpl<bool>();
477
+ }
478
+
479
+ inline const std::string &dynamic::getString() const & {
480
+ return get<std::string>();
481
+ }
482
+ inline double dynamic::getDouble() const & {
483
+ return get<double>();
484
+ }
485
+ inline int64_t dynamic::getInt() const & {
486
+ return get<int64_t>();
487
+ }
488
+ inline bool dynamic::getBool() const & {
489
+ return get<bool>();
490
+ }
491
+
492
+ inline std::string &dynamic::getString() & {
493
+ return get<std::string>();
494
+ }
495
+ inline double &dynamic::getDouble() & {
496
+ return get<double>();
497
+ }
498
+ inline int64_t &dynamic::getInt() & {
499
+ return get<int64_t>();
500
+ }
501
+ inline bool &dynamic::getBool() & {
502
+ return get<bool>();
503
+ }
504
+
505
+ inline std::string &&dynamic::getString() && {
506
+ return std::move(get<std::string>());
507
+ }
508
+ inline double dynamic::getDouble() && {
509
+ return get<double>();
510
+ }
511
+ inline int64_t dynamic::getInt() && {
512
+ return get<int64_t>();
513
+ }
514
+ inline bool dynamic::getBool() && {
515
+ return get<bool>();
516
+ }
517
+
518
+ inline const char *dynamic::data() const & {
519
+ return get<std::string>().data();
520
+ }
521
+ inline const char *dynamic::c_str() const & {
522
+ return get<std::string>().c_str();
523
+ }
524
+ inline StringPiece dynamic::stringPiece() const {
525
+ return get<std::string>();
526
+ }
527
+
528
+ template <class T>
529
+ struct dynamic::CompareOp {
530
+ static bool comp(T const &a, T const &b) {
531
+ return a < b;
532
+ }
533
+ };
534
+ template <>
535
+ struct dynamic::CompareOp<dynamic::ObjectImpl> {
536
+ static bool comp(ObjectImpl const &, ObjectImpl const &) {
537
+ // This code never executes; it is just here for the compiler.
538
+ return false;
539
+ }
540
+ };
541
+ template <>
542
+ struct dynamic::CompareOp<std::nullptr_t> {
543
+ static bool comp(std::nullptr_t const &, std::nullptr_t const &) {
544
+ return true;
545
+ }
546
+ };
547
+
548
+ inline dynamic &dynamic::operator+=(dynamic const &o) {
549
+ if (type() == STRING && o.type() == STRING) {
550
+ *getAddress<std::string>() += *o.getAddress<std::string>();
551
+ return *this;
552
+ }
553
+ *this = detail::numericOp<std::plus>(*this, o);
554
+ return *this;
555
+ }
556
+
557
+ inline dynamic &dynamic::operator-=(dynamic const &o) {
558
+ *this = detail::numericOp<std::minus>(*this, o);
559
+ return *this;
560
+ }
561
+
562
+ inline dynamic &dynamic::operator*=(dynamic const &o) {
563
+ *this = detail::numericOp<std::multiplies>(*this, o);
564
+ return *this;
565
+ }
566
+
567
+ inline dynamic &dynamic::operator/=(dynamic const &o) {
568
+ *this = detail::numericOp<std::divides>(*this, o);
569
+ return *this;
570
+ }
571
+
572
+ #define FB_DYNAMIC_INTEGER_OP(op) \
573
+ inline dynamic &dynamic::operator op(dynamic const &o) { \
574
+ if (!isInt() || !o.isInt()) { \
575
+ throw_exception<TypeError>("int64", type(), o.type()); \
576
+ } \
577
+ *getAddress<int64_t>() op o.asInt(); \
578
+ return *this; \
579
+ }
580
+
581
+ FB_DYNAMIC_INTEGER_OP(%=)
582
+ FB_DYNAMIC_INTEGER_OP(|=)
583
+ FB_DYNAMIC_INTEGER_OP(&=)
584
+ FB_DYNAMIC_INTEGER_OP(^=)
585
+
586
+ #undef FB_DYNAMIC_INTEGER_OP
587
+
588
+ inline dynamic &dynamic::operator++() {
589
+ ++get<int64_t>();
590
+ return *this;
591
+ }
592
+
593
+ inline dynamic &dynamic::operator--() {
594
+ --get<int64_t>();
595
+ return *this;
596
+ }
597
+
598
+ template <typename K>
599
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic const &> dynamic::operator[](K &&idx) const & {
600
+ return at(std::forward<K>(idx));
601
+ }
602
+
603
+ template <typename K>
604
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic &> dynamic::operator[](K &&idx) & {
605
+ if (!isObject() && !isArray()) {
606
+ throw_exception<TypeError>("object/array", type());
607
+ }
608
+ if (isArray()) {
609
+ return at(std::forward<K>(idx));
610
+ }
611
+ auto &obj = get<ObjectImpl>();
612
+ auto ret = obj.emplace(std::forward<K>(idx), nullptr);
613
+ return ret.first->second;
614
+ }
615
+
616
+ template <typename K>
617
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic &&> dynamic::operator[](K &&idx) && {
618
+ return std::move((*this)[std::forward<K>(idx)]);
619
+ }
620
+
621
+ inline dynamic const &dynamic::operator[](StringPiece k) const & {
622
+ return at(k);
623
+ }
624
+
625
+ inline dynamic &&dynamic::operator[](StringPiece k) && {
626
+ return std::move((*this)[k]);
627
+ }
628
+
629
+ template <typename K>
630
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic> dynamic::getDefault(K &&k, const dynamic &v) const & {
631
+ auto &obj = get<ObjectImpl>();
632
+ auto it = obj.find(std::forward<K>(k));
633
+ return it == obj.end() ? v : it->second;
634
+ }
635
+
636
+ template <typename K>
637
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic> dynamic::getDefault(K &&k, dynamic &&v) const & {
638
+ auto &obj = get<ObjectImpl>();
639
+ auto it = obj.find(std::forward<K>(k));
640
+ // Avoid clang bug with ternary
641
+ if (it == obj.end()) {
642
+ return std::move(v);
643
+ } else {
644
+ return it->second;
645
+ }
646
+ }
647
+
648
+ template <typename K>
649
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic> dynamic::getDefault(K &&k, const dynamic &v) && {
650
+ auto &obj = get<ObjectImpl>();
651
+ auto it = obj.find(std::forward<K>(k));
652
+ // Avoid clang bug with ternary
653
+ if (it == obj.end()) {
654
+ return v;
655
+ } else {
656
+ return std::move(it->second);
657
+ }
658
+ }
659
+
660
+ template <typename K>
661
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic> dynamic::getDefault(K &&k, dynamic &&v) && {
662
+ auto &obj = get<ObjectImpl>();
663
+ auto it = obj.find(std::forward<K>(k));
664
+ return std::move(it == obj.end() ? v : it->second);
665
+ }
666
+
667
+ template <typename K, typename V>
668
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic &> dynamic::setDefault(K &&k, V &&v) {
669
+ auto &obj = get<ObjectImpl>();
670
+ return obj.emplace(std::forward<K>(k), std::forward<V>(v)).first->second;
671
+ }
672
+
673
+ template <typename K>
674
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic &> dynamic::setDefault(K &&k, dynamic &&v) {
675
+ auto &obj = get<ObjectImpl>();
676
+ return obj.emplace(std::forward<K>(k), std::move(v)).first->second;
677
+ }
678
+
679
+ template <typename K>
680
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic &> dynamic::setDefault(K &&k, const dynamic &v) {
681
+ auto &obj = get<ObjectImpl>();
682
+ return obj.emplace(std::forward<K>(k), v).first->second;
683
+ }
684
+
685
+ template <typename V>
686
+ dynamic &dynamic::setDefault(StringPiece k, V &&v) {
687
+ auto &obj = get<ObjectImpl>();
688
+ return obj.emplace(k, std::forward<V>(v)).first->second;
689
+ }
690
+
691
+ inline dynamic &dynamic::setDefault(StringPiece k, dynamic &&v) {
692
+ auto &obj = get<ObjectImpl>();
693
+ return obj.emplace(k, std::move(v)).first->second;
694
+ }
695
+
696
+ inline dynamic &dynamic::setDefault(StringPiece k, const dynamic &v) {
697
+ auto &obj = get<ObjectImpl>();
698
+ return obj.emplace(k, v).first->second;
699
+ }
700
+
701
+ template <typename K>
702
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic const *> dynamic::get_ptr(K &&k) const & {
703
+ return get_ptrImpl(std::forward<K>(k));
704
+ }
705
+
706
+ template <typename K>
707
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic *> dynamic::get_ptr(K &&idx) & {
708
+ return const_cast<dynamic *>(const_cast<dynamic const *>(this)->get_ptr(idx));
709
+ }
710
+
711
+ inline dynamic *dynamic::get_ptr(StringPiece idx) & {
712
+ return const_cast<dynamic *>(const_cast<dynamic const *>(this)->get_ptr(idx));
713
+ }
714
+
715
+ // clang-format off
716
+ inline
717
+ dynamic::resolved_json_pointer<dynamic>
718
+ dynamic::try_get_ptr(json_pointer const& jsonPtr) & {
719
+ auto ret = const_cast<dynamic const*>(this)->try_get_ptr(jsonPtr);
720
+ if (ret.hasValue()) {
721
+ return json_pointer_resolved_value<dynamic>{
722
+ const_cast<dynamic*>(ret.value().parent),
723
+ const_cast<dynamic*>(ret.value().value),
724
+ ret.value().parent_key, ret.value().parent_index};
725
+ } else {
726
+ return makeUnexpected(
727
+ json_pointer_resolution_error<dynamic>{
728
+ ret.error().error_code,
729
+ ret.error().index,
730
+ const_cast<dynamic*>(ret.error().context)}
731
+ );
732
+ }
733
+ }
734
+ // clang-format on
735
+
736
+ inline dynamic *dynamic::get_ptr(json_pointer const &jsonPtr) & {
737
+ return const_cast<dynamic *>(const_cast<dynamic const *>(this)->get_ptr(jsonPtr));
738
+ }
739
+
740
+ template <typename K>
741
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic const &> dynamic::at(K &&k) const & {
742
+ return atImpl(std::forward<K>(k));
743
+ }
744
+
745
+ template <typename K>
746
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic &> dynamic::at(K &&idx) & {
747
+ return const_cast<dynamic &>(const_cast<dynamic const *>(this)->at(idx));
748
+ }
749
+
750
+ template <typename K>
751
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic &&> dynamic::at(K &&idx) && {
752
+ return std::move(at(idx));
753
+ }
754
+
755
+ inline dynamic &dynamic::at(StringPiece idx) & {
756
+ return const_cast<dynamic &>(const_cast<dynamic const *>(this)->at(idx));
757
+ }
758
+
759
+ inline dynamic &&dynamic::at(StringPiece idx) && {
760
+ return std::move(at(idx));
761
+ }
762
+
763
+ inline bool dynamic::empty() const {
764
+ if (isNull()) {
765
+ return true;
766
+ }
767
+ return !size();
768
+ }
769
+
770
+ template <typename K>
771
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic::const_item_iterator> dynamic::find(K &&key) const {
772
+ return get<ObjectImpl>().find(std::forward<K>(key));
773
+ }
774
+
775
+ template <typename K>
776
+ dynamic::IfIsNonStringDynamicConvertible<K, dynamic::item_iterator> dynamic::find(K &&key) {
777
+ return get<ObjectImpl>().find(std::forward<K>(key));
778
+ }
779
+
780
+ inline dynamic::const_item_iterator dynamic::find(StringPiece key) const {
781
+ return get<ObjectImpl>().find(key);
782
+ }
783
+
784
+ inline dynamic::item_iterator dynamic::find(StringPiece key) {
785
+ return get<ObjectImpl>().find(key);
786
+ }
787
+
788
+ template <typename K>
789
+ dynamic::IfIsNonStringDynamicConvertible<K, std::size_t> dynamic::count(K &&key) const {
790
+ return find(std::forward<K>(key)) != items().end() ? 1u : 0u;
791
+ }
792
+
793
+ inline std::size_t dynamic::count(StringPiece key) const {
794
+ return find(key) != items().end() ? 1u : 0u;
795
+ }
796
+
797
+ template <class K, class V>
798
+ inline dynamic::IfNotIterator<K, void> dynamic::insert(K &&key, V &&val) {
799
+ auto &obj = get<ObjectImpl>();
800
+ obj[std::forward<K>(key)] = std::forward<V>(val);
801
+ }
802
+
803
+ template <class T>
804
+ inline dynamic::iterator dynamic::insert(const_iterator pos, T &&value) {
805
+ auto &arr = get<Array>();
806
+ return arr.insert(pos, std::forward<T>(value));
807
+ }
808
+
809
+ inline void dynamic::update(const dynamic &mergeObj) {
810
+ if (!isObject() || !mergeObj.isObject()) {
811
+ throw_exception<TypeError>("object", type(), mergeObj.type());
812
+ }
813
+
814
+ for (const auto &pair : mergeObj.items()) {
815
+ (*this)[pair.first] = pair.second;
816
+ }
817
+ }
818
+
819
+ inline void dynamic::update_missing(const dynamic &mergeObj1) {
820
+ if (!isObject() || !mergeObj1.isObject()) {
821
+ throw_exception<TypeError>("object", type(), mergeObj1.type());
822
+ }
823
+
824
+ // Only add if not already there
825
+ for (const auto &pair : mergeObj1.items()) {
826
+ if ((*this).find(pair.first) == (*this).items().end()) {
827
+ (*this)[pair.first] = pair.second;
828
+ }
829
+ }
830
+ }
831
+
832
+ inline void dynamic::merge_patch(const dynamic &patch) {
833
+ auto &self = *this;
834
+ if (!patch.isObject()) {
835
+ self = patch;
836
+ return;
837
+ }
838
+ // if we are not an object, erase all contents, reset to object
839
+ if (!isObject()) {
840
+ self = object;
841
+ }
842
+ for (const auto &pair : patch.items()) {
843
+ if (pair.second.isNull()) {
844
+ // if name could be found in current object, remove it
845
+ auto it = self.find(pair.first);
846
+ if (it != self.items().end()) {
847
+ self.erase(it);
848
+ }
849
+ } else {
850
+ self[pair.first].merge_patch(pair.second);
851
+ }
852
+ }
853
+ }
854
+
855
+ inline dynamic dynamic::merge(const dynamic &mergeObj1, const dynamic &mergeObj2) {
856
+ // No checks on type needed here because they are done in update_missing
857
+ // Note that we do update_missing here instead of update() because
858
+ // it will prevent the extra writes that would occur with update()
859
+ auto ret = mergeObj2;
860
+ ret.update_missing(mergeObj1);
861
+ return ret;
862
+ }
863
+
864
+ template <typename K>
865
+ dynamic::IfIsNonStringDynamicConvertible<K, std::size_t> dynamic::erase(K &&key) {
866
+ auto &obj = get<ObjectImpl>();
867
+ return obj.erase(std::forward<K>(key));
868
+ }
869
+ inline std::size_t dynamic::erase(StringPiece key) {
870
+ auto &obj = get<ObjectImpl>();
871
+ return obj.erase(key);
872
+ }
873
+
874
+ inline dynamic::iterator dynamic::erase(const_iterator it) {
875
+ auto &arr = get<Array>();
876
+ // std::vector doesn't have an erase method that works on const iterators,
877
+ // even though the standard says it should, so this hack converts to a
878
+ // non-const iterator before calling erase.
879
+ return get<Array>().erase(arr.begin() + (it - arr.begin()));
880
+ }
881
+
882
+ inline dynamic::const_key_iterator dynamic::erase(const_key_iterator it) {
883
+ return const_key_iterator(get<ObjectImpl>().erase(it.base()));
884
+ }
885
+
886
+ inline dynamic::const_key_iterator dynamic::erase(const_key_iterator first, const_key_iterator last) {
887
+ return const_key_iterator(get<ObjectImpl>().erase(first.base(), last.base()));
888
+ }
889
+
890
+ inline dynamic::value_iterator dynamic::erase(const_value_iterator it) {
891
+ return value_iterator(get<ObjectImpl>().erase(it.base()));
892
+ }
893
+
894
+ inline dynamic::value_iterator dynamic::erase(const_value_iterator first, const_value_iterator last) {
895
+ return value_iterator(get<ObjectImpl>().erase(first.base(), last.base()));
896
+ }
897
+
898
+ inline dynamic::item_iterator dynamic::erase(const_item_iterator it) {
899
+ return item_iterator(get<ObjectImpl>().erase(it.base()));
900
+ }
901
+
902
+ inline dynamic::item_iterator dynamic::erase(const_item_iterator first, const_item_iterator last) {
903
+ return item_iterator(get<ObjectImpl>().erase(first.base(), last.base()));
904
+ }
905
+
906
+ inline void dynamic::resize(std::size_t sz, dynamic const &c) {
907
+ auto &arr = get<Array>();
908
+ arr.resize(sz, c);
909
+ }
910
+
911
+ inline void dynamic::push_back(dynamic const &v) {
912
+ auto &arr = get<Array>();
913
+ arr.push_back(v);
914
+ }
915
+
916
+ inline void dynamic::push_back(dynamic &&v) {
917
+ auto &arr = get<Array>();
918
+ arr.push_back(std::move(v));
919
+ }
920
+
921
+ inline void dynamic::pop_back() {
922
+ auto &arr = get<Array>();
923
+ arr.pop_back();
924
+ }
925
+
926
+ inline const dynamic &dynamic::back() const {
927
+ auto &arr = get<Array>();
928
+ return arr.back();
929
+ }
930
+
931
+ //////////////////////////////////////////////////////////////////////
932
+
933
+ inline dynamic::dynamic(Array &&r) : type_(ARRAY) {
934
+ new (&u_.array) Array(std::move(r));
935
+ }
936
+
937
+ #define FOLLY_DYNAMIC_DEC_TYPEINFO(T, val) \
938
+ template <> \
939
+ struct dynamic::TypeInfo<T> { \
940
+ static const char *const name; \
941
+ static constexpr dynamic::Type type = val; \
942
+ };
943
+
944
+ FOLLY_DYNAMIC_DEC_TYPEINFO(std::nullptr_t, dynamic::NULLT)
945
+ FOLLY_DYNAMIC_DEC_TYPEINFO(bool, dynamic::BOOL)
946
+ FOLLY_DYNAMIC_DEC_TYPEINFO(std::string, dynamic::STRING)
947
+ FOLLY_DYNAMIC_DEC_TYPEINFO(dynamic::Array, dynamic::ARRAY)
948
+ FOLLY_DYNAMIC_DEC_TYPEINFO(double, dynamic::DOUBLE)
949
+ FOLLY_DYNAMIC_DEC_TYPEINFO(int64_t, dynamic::INT64)
950
+ FOLLY_DYNAMIC_DEC_TYPEINFO(dynamic::ObjectImpl, dynamic::OBJECT)
951
+
952
+ #undef FOLLY_DYNAMIC_DEC_TYPEINFO
953
+
954
+ template <class T>
955
+ T dynamic::asImpl() const {
956
+ switch (type()) {
957
+ case INT64:
958
+ return to<T>(*get_nothrow<int64_t>());
959
+ case DOUBLE:
960
+ return to<T>(*get_nothrow<double>());
961
+ case BOOL:
962
+ return to<T>(*get_nothrow<bool>());
963
+ case STRING:
964
+ return to<T>(*get_nothrow<std::string>());
965
+ case NULLT:
966
+ case ARRAY:
967
+ case OBJECT:
968
+ default:
969
+ throw_exception<TypeError>("int/double/bool/string", type());
970
+ }
971
+ }
972
+
973
+ // Return a T* to our type, or null if we're not that type.
974
+ // clang-format off
975
+ template <class T>
976
+ T* dynamic::get_nothrow() & noexcept {
977
+ if (type_ != TypeInfo<T>::type) {
978
+ return nullptr;
979
+ }
980
+ return getAddress<T>();
981
+ }
982
+ // clang-format on
983
+
984
+ template <class T>
985
+ T const *dynamic::get_nothrow() const &noexcept {
986
+ return const_cast<dynamic *>(this)->get_nothrow<T>();
987
+ }
988
+
989
+ // Return T* for where we can put a T, without type checking. (Memory
990
+ // might be uninitialized, even.)
991
+ template <class T>
992
+ T *dynamic::getAddress() noexcept {
993
+ return GetAddrImpl<T>::get(u_);
994
+ }
995
+
996
+ template <class T>
997
+ T const *dynamic::getAddress() const noexcept {
998
+ return const_cast<dynamic *>(this)->getAddress<T>();
999
+ }
1000
+
1001
+ template <class T>
1002
+ struct dynamic::GetAddrImpl {};
1003
+ template <>
1004
+ struct dynamic::GetAddrImpl<std::nullptr_t> {
1005
+ static std::nullptr_t *get(Data &d) noexcept {
1006
+ return &d.nul;
1007
+ }
1008
+ };
1009
+ template <>
1010
+ struct dynamic::GetAddrImpl<dynamic::Array> {
1011
+ static Array *get(Data &d) noexcept {
1012
+ return &d.array;
1013
+ }
1014
+ };
1015
+ template <>
1016
+ struct dynamic::GetAddrImpl<bool> {
1017
+ static bool *get(Data &d) noexcept {
1018
+ return &d.boolean;
1019
+ }
1020
+ };
1021
+ template <>
1022
+ struct dynamic::GetAddrImpl<int64_t> {
1023
+ static int64_t *get(Data &d) noexcept {
1024
+ return &d.integer;
1025
+ }
1026
+ };
1027
+ template <>
1028
+ struct dynamic::GetAddrImpl<double> {
1029
+ static double *get(Data &d) noexcept {
1030
+ return &d.doubl;
1031
+ }
1032
+ };
1033
+ template <>
1034
+ struct dynamic::GetAddrImpl<std::string> {
1035
+ static std::string *get(Data &d) noexcept {
1036
+ return &d.string;
1037
+ }
1038
+ };
1039
+ template <>
1040
+ struct dynamic::GetAddrImpl<dynamic::ObjectImpl> {
1041
+ static_assert(
1042
+ sizeof(ObjectImpl) <= sizeof(Data::objectBuffer),
1043
+ "In your implementation, F14NodeMap<> apparently takes different"
1044
+ " amount of space depending on its template parameters. This is "
1045
+ "weird. Make objectBuffer bigger if you want to compile dynamic.");
1046
+
1047
+ static ObjectImpl *get(Data &d) noexcept {
1048
+ void *data = &d.objectBuffer;
1049
+ return static_cast<ObjectImpl *>(data);
1050
+ }
1051
+ };
1052
+
1053
+ // [Win - Forked to avoid using exported data across the dll boundary. Using exported data prevents the ability to
1054
+ // delay load the dll We can remove this, once react-native-win32 stops exporting folly (gets entirely onto the ABI
1055
+ // interface)
1056
+ template <class T>
1057
+ T &dynamic::get() {
1058
+ if (auto *p = get_nothrow<T>()) {
1059
+ return *p;
1060
+ }
1061
+
1062
+ switch (type()) {
1063
+ case dynamic::NULLT:
1064
+ throw_exception<TypeError>("null", dynamic::NULLT);
1065
+ break;
1066
+ case dynamic::BOOL:
1067
+ throw_exception<TypeError>("boolean", dynamic::BOOL);
1068
+ break;
1069
+ case dynamic::STRING:
1070
+ throw_exception<TypeError>("string", dynamic::STRING);
1071
+ break;
1072
+ case dynamic::ARRAY:
1073
+ throw_exception<TypeError>("array", dynamic::ARRAY);
1074
+ break;
1075
+ case dynamic::DOUBLE:
1076
+ throw_exception<TypeError>("double", dynamic::DOUBLE);
1077
+ break;
1078
+ case dynamic::INT64:
1079
+ throw_exception<TypeError>("int64", dynamic::INT64);
1080
+ break;
1081
+ case dynamic::OBJECT:
1082
+ throw_exception<TypeError>("object", dynamic::OBJECT);
1083
+ break;
1084
+ default:
1085
+ throw_exception<TypeError>("never", dynamic::OBJECT);
1086
+ break;
1087
+ }
1088
+ }
1089
+ // Win]
1090
+
1091
+ template <class T>
1092
+ T const &dynamic::get() const {
1093
+ return const_cast<dynamic *>(this)->get<T>();
1094
+ }
1095
+
1096
+ //////////////////////////////////////////////////////////////////////
1097
+
1098
+ /*
1099
+ * Helper for implementing operator<<. Throws if the type shouldn't
1100
+ * support it.
1101
+ */
1102
+ template <class T>
1103
+ struct dynamic::PrintImpl {
1104
+ static void print(dynamic const &, std::ostream &out, T const &t) {
1105
+ out << t;
1106
+ }
1107
+ };
1108
+ // Otherwise, null, being (void*)0, would print as 0.
1109
+ template <>
1110
+ struct dynamic::PrintImpl<std::nullptr_t> {
1111
+ static void print(dynamic const & /* d */, std::ostream &out, std::nullptr_t const &) {
1112
+ out << "null";
1113
+ }
1114
+ };
1115
+ template <>
1116
+ struct dynamic::PrintImpl<dynamic::ObjectImpl> {
1117
+ static void print(dynamic const &d, std::ostream &out, dynamic::ObjectImpl const &) {
1118
+ d.print_as_pseudo_json(out);
1119
+ }
1120
+ };
1121
+ template <>
1122
+ struct dynamic::PrintImpl<dynamic::Array> {
1123
+ static void print(dynamic const &d, std::ostream &out, dynamic::Array const &) {
1124
+ d.print_as_pseudo_json(out);
1125
+ }
1126
+ };
1127
+
1128
+ inline void dynamic::print(std::ostream &out) const {
1129
+ #define FB_X(T) PrintImpl<T>::print(*this, out, *getAddress<T>())
1130
+ FB_DYNAMIC_APPLY(type_, FB_X);
1131
+ #undef FB_X
1132
+ }
1133
+
1134
+ inline std::ostream &operator<<(std::ostream &out, dynamic const &d) {
1135
+ d.print(out);
1136
+ return out;
1137
+ }
1138
+
1139
+ //////////////////////////////////////////////////////////////////////
1140
+
1141
+ // Secialization of FormatValue so dynamic objects can be formatted
1142
+ template <>
1143
+ class FormatValue<dynamic> {
1144
+ public:
1145
+ explicit FormatValue(const dynamic &val) : val_(val) {}
1146
+
1147
+ template <class FormatCallback>
1148
+ void format(FormatArg &arg, FormatCallback &cb) const {
1149
+ switch (val_.type()) {
1150
+ case dynamic::NULLT:
1151
+ FormatValue<std::nullptr_t>(nullptr).format(arg, cb);
1152
+ break;
1153
+ case dynamic::BOOL:
1154
+ FormatValue<bool>(val_.asBool()).format(arg, cb);
1155
+ break;
1156
+ case dynamic::INT64:
1157
+ FormatValue<int64_t>(val_.asInt()).format(arg, cb);
1158
+ break;
1159
+ case dynamic::STRING:
1160
+ FormatValue<std::string>(val_.asString()).format(arg, cb);
1161
+ break;
1162
+ case dynamic::DOUBLE:
1163
+ FormatValue<double>(val_.asDouble()).format(arg, cb);
1164
+ break;
1165
+ case dynamic::ARRAY:
1166
+ FormatValue(val_.at(arg.splitIntKey())).format(arg, cb);
1167
+ break;
1168
+ case dynamic::OBJECT:
1169
+ FormatValue(val_.at(arg.splitKey().toString())).format(arg, cb);
1170
+ break;
1171
+ }
1172
+ }
1173
+
1174
+ private:
1175
+ const dynamic &val_;
1176
+ };
1177
+
1178
+ template <class V>
1179
+ class FormatValue<detail::DefaultValueWrapper<dynamic, V>> {
1180
+ public:
1181
+ explicit FormatValue(const detail::DefaultValueWrapper<dynamic, V> &val) : val_(val) {}
1182
+
1183
+ template <class FormatCallback>
1184
+ void format(FormatArg &arg, FormatCallback &cb) const {
1185
+ auto &c = val_.container;
1186
+ switch (c.type()) {
1187
+ case dynamic::NULLT:
1188
+ case dynamic::BOOL:
1189
+ case dynamic::INT64:
1190
+ case dynamic::STRING:
1191
+ case dynamic::DOUBLE:
1192
+ FormatValue<dynamic>(c).format(arg, cb);
1193
+ break;
1194
+ case dynamic::ARRAY: {
1195
+ int key = arg.splitIntKey();
1196
+ if (key >= 0 && size_t(key) < c.size()) {
1197
+ FormatValue<dynamic>(c.at(key)).format(arg, cb);
1198
+ } else {
1199
+ FormatValue<V>(val_.defaultValue).format(arg, cb);
1200
+ }
1201
+ break;
1202
+ }
1203
+ case dynamic::OBJECT: {
1204
+ auto pos = c.find(arg.splitKey());
1205
+ if (pos != c.items().end()) {
1206
+ FormatValue<dynamic>(pos->second).format(arg, cb);
1207
+ } else {
1208
+ FormatValue<V>(val_.defaultValue).format(arg, cb);
1209
+ }
1210
+ break;
1211
+ }
1212
+ }
1213
+ }
1214
+
1215
+ private:
1216
+ const detail::DefaultValueWrapper<dynamic, V> &val_;
1217
+ };
1218
+
1219
+ } // namespace folly
1220
+
1221
+ #undef FB_DYNAMIC_APPLY
@@ -60,10 +60,16 @@ std::map<std::string, folly::dynamic> PlatformConstantsModule::getConstants() {
60
60
  }
61
61
 
62
62
  /*static*/ int32_t PlatformConstantsModule::OsVersion() noexcept {
63
- for (uint16_t i = 1;; ++i) {
64
- if (!ApiInformation::IsApiContractPresent(L"Windows.Foundation.UniversalApiContract", i)) {
65
- return i - 1;
63
+ try {
64
+ for (uint16_t i = 1;; ++i) {
65
+ if (!ApiInformation::IsApiContractPresent(L"Windows.Foundation.UniversalApiContract", i)) {
66
+ return i - 1;
67
+ }
66
68
  }
69
+ } catch (winrt::hresult_error const &e) {
70
+ // ApiInformation::IsApiContractPresent did not exist before Windows 10240
71
+ // So this indicates a version of windows earlier than this.
72
+ return 0;
67
73
  }
68
74
  }
69
75
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.64.22",
3
+ "version": "0.64.23",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",