From c36ae161e42b768ff3fa11e36c30cf1d9751e020 Mon Sep 17 00:00:00 2001 From: "REDMOND\\agnel" Date: Thu, 13 May 2021 10:00:08 -0500 Subject: [PATCH 1/5] folly bump version --- vnext/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vnext/Directory.Build.props b/vnext/Directory.Build.props index 51b8d2ad916..96ff3e8029d 100644 --- a/vnext/Directory.Build.props +++ b/vnext/Directory.Build.props @@ -18,7 +18,7 @@ The PR (windows-vs-pr.yml) and CI (publish.yml() turn it back on. --> false - 2021.03.29.00 + 2021.05.10.00 7.1.3 From 43b8841f192be1d39ef6ce5d45d36895af66f1e6 Mon Sep 17 00:00:00 2001 From: "REDMOND\\agnel" Date: Thu, 13 May 2021 10:01:11 -0500 Subject: [PATCH 2/5] removing forked files --- vnext/Folly/TEMP_UntilFollyUpdate/dynamic.cpp | 480 ------------------ .../TEMP_UntilFollyUpdate/lang/ToAscii.h | 426 ---------------- 2 files changed, 906 deletions(-) delete mode 100644 vnext/Folly/TEMP_UntilFollyUpdate/dynamic.cpp delete mode 100644 vnext/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h diff --git a/vnext/Folly/TEMP_UntilFollyUpdate/dynamic.cpp b/vnext/Folly/TEMP_UntilFollyUpdate/dynamic.cpp deleted file mode 100644 index f145e2a4600..00000000000 --- a/vnext/Folly/TEMP_UntilFollyUpdate/dynamic.cpp +++ /dev/null @@ -1,480 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include - -#include - -#include -#include -#include -#include -#include - -namespace folly { - -////////////////////////////////////////////////////////////////////// - -#define FOLLY_DYNAMIC_DEF_TYPEINFO(T, str) \ - const char* const dynamic::TypeInfo::name = str; \ - // - -FOLLY_DYNAMIC_DEF_TYPEINFO(std::nullptr_t, "null") -FOLLY_DYNAMIC_DEF_TYPEINFO(bool, "boolean") -FOLLY_DYNAMIC_DEF_TYPEINFO(std::string, "string") -FOLLY_DYNAMIC_DEF_TYPEINFO(dynamic::Array, "array") -FOLLY_DYNAMIC_DEF_TYPEINFO(double, "double") -FOLLY_DYNAMIC_DEF_TYPEINFO(int64_t, "int64") -FOLLY_DYNAMIC_DEF_TYPEINFO(dynamic::ObjectImpl, "object") - -#undef FOLLY_DYNAMIC_DEF_TYPEINFO - -const char* dynamic::typeName() const { - return typeName(type_); -} - -TypeError::TypeError(const std::string& expected, dynamic::Type actual) - : std::runtime_error(sformat( - "TypeError: expected dynamic type `{}', but had type `{}'", - expected, - dynamic::typeName(actual))) {} - -TypeError::TypeError( - const std::string& expected, dynamic::Type actual1, dynamic::Type actual2) - : std::runtime_error(sformat( - "TypeError: expected dynamic types `{}, but had types `{}' and `{}'", - expected, - dynamic::typeName(actual1), - dynamic::typeName(actual2))) {} - -// This is a higher-order preprocessor macro to aid going from runtime -// types to the compile time type system. -#define FB_DYNAMIC_APPLY(type, apply) \ - do { \ - switch ((type)) { \ - case NULLT: \ - apply(std::nullptr_t); \ - break; \ - case ARRAY: \ - apply(Array); \ - break; \ - case BOOL: \ - apply(bool); \ - break; \ - case DOUBLE: \ - apply(double); \ - break; \ - case INT64: \ - apply(int64_t); \ - break; \ - case OBJECT: \ - apply(ObjectImpl); \ - break; \ - case STRING: \ - apply(std::string); \ - break; \ - default: \ - CHECK(0); \ - abort(); \ - } \ - } while (0) - -bool dynamic::operator<(dynamic const& o) const { - if (UNLIKELY(type_ == OBJECT || o.type_ == OBJECT)) { - throw_exception("object", type_); - } - if (type_ != o.type_) { - return type_ < o.type_; - } - -#define FB_X(T) return CompareOp::comp(*getAddress(), *o.getAddress()) - FB_DYNAMIC_APPLY(type_, FB_X); -#undef FB_X -} - -bool dynamic::operator==(dynamic const& o) const { - if (type() != o.type()) { - if (isNumber() && o.isNumber()) { - auto& integ = isInt() ? *this : o; - auto& doubl = isInt() ? o : *this; - return integ.asInt() == doubl.asDouble(); - } - return false; - } - -#define FB_X(T) return *getAddress() == *o.getAddress(); - FB_DYNAMIC_APPLY(type_, FB_X); -#undef FB_X -} - -dynamic& dynamic::operator=(dynamic const& o) { - if (&o != this) { - if (type_ == o.type_) { -#define FB_X(T) *getAddress() = *o.getAddress() - FB_DYNAMIC_APPLY(type_, FB_X); -#undef FB_X - } else { - destroy(); -#define FB_X(T) new (getAddress()) T(*o.getAddress()) - FB_DYNAMIC_APPLY(o.type_, FB_X); -#undef FB_X - type_ = o.type_; - } - } - return *this; -} - -dynamic& dynamic::operator=(dynamic&& o) noexcept { - if (&o != this) { - if (type_ == o.type_) { -#define FB_X(T) *getAddress() = std::move(*o.getAddress()) - FB_DYNAMIC_APPLY(type_, FB_X); -#undef FB_X - } else { - destroy(); -#define FB_X(T) new (getAddress()) T(std::move(*o.getAddress())) - FB_DYNAMIC_APPLY(o.type_, FB_X); -#undef FB_X - type_ = o.type_; - } - } - return *this; -} - -dynamic const& dynamic::atImpl(dynamic const& idx) const& { - if (auto* parray = get_nothrow()) { - if (!idx.isInt()) { - throw_exception("int64", idx.type()); - } - if (idx < 0 || idx >= parray->size()) { - throw_exception("out of range in dynamic array"); - } - return (*parray)[size_t(idx.asInt())]; - } else if (auto* pobject = get_nothrow()) { - auto it = pobject->find(idx); - if (it == pobject->end()) { - throw_exception( - sformat("couldn't find key {} in dynamic object", idx.asString())); - } - return it->second; - } else { - throw_exception("object/array", type()); - } -} - -dynamic const& dynamic::at(StringPiece idx) const& { - auto* pobject = get_nothrow(); - if (!pobject) { - throw_exception("object", type()); - } - auto it = pobject->find(idx); - if (it == pobject->end()) { - throw_exception( - sformat("couldn't find key {} in dynamic object", idx)); - } - return it->second; -} - -dynamic& dynamic::operator[](StringPiece k) & { - auto& obj = get(); - auto ret = obj.emplace(k, nullptr); - return ret.first->second; -} - -dynamic dynamic::getDefault(StringPiece k, const dynamic& v) const& { - auto& obj = get(); - auto it = obj.find(k); - return it == obj.end() ? v : it->second; -} - -dynamic dynamic::getDefault(StringPiece k, dynamic&& v) const& { - auto& obj = get(); - auto it = obj.find(k); - // Avoid clang bug with ternary - if (it == obj.end()) { - return std::move(v); - } else { - return it->second; - } -} - -dynamic dynamic::getDefault(StringPiece k, const dynamic& v) && { - auto& obj = get(); - auto it = obj.find(k); - // Avoid clang bug with ternary - if (it == obj.end()) { - return v; - } else { - return std::move(it->second); - } -} - -dynamic dynamic::getDefault(StringPiece k, dynamic&& v) && { - auto& obj = get(); - auto it = obj.find(k); - return std::move(it == obj.end() ? v : it->second); -} - -const dynamic* dynamic::get_ptrImpl(dynamic const& idx) const& { - if (auto* parray = get_nothrow()) { - if (!idx.isInt()) { - throw_exception("int64", idx.type()); - } - if (idx < 0 || idx >= parray->size()) { - return nullptr; - } - return &(*parray)[size_t(idx.asInt())]; - } else if (auto* pobject = get_nothrow()) { - auto it = pobject->find(idx); - if (it == pobject->end()) { - return nullptr; - } - return &it->second; - } else { - throw_exception("object/array", type()); - } -} - -const dynamic* dynamic::get_ptr(StringPiece idx) const& { - auto* pobject = get_nothrow(); - if (!pobject) { - throw_exception("object", type()); - } - auto it = pobject->find(idx); - if (it == pobject->end()) { - return nullptr; - } - return &it->second; -} - -std::size_t dynamic::size() const { - if (auto* ar = get_nothrow()) { - return ar->size(); - } - if (auto* obj = get_nothrow()) { - return obj->size(); - } - if (auto* str = get_nothrow()) { - return str->size(); - } - throw_exception("array/object/string", type()); -} - -dynamic::iterator dynamic::erase(const_iterator first, const_iterator last) { - auto& arr = get(); - return get().erase( - arr.begin() + (first - arr.begin()), arr.begin() + (last - arr.begin())); -} - -std::size_t dynamic::hash() const { - switch (type()) { - case NULLT: - return 0xBAAAAAAD; - case OBJECT: { - // Accumulate using addition instead of using hash_range (as in the ARRAY - // case), as we need a commutative hash operation since unordered_map's - // iteration order is unspecified. - auto h = std::hash>{}; - return std::accumulate( - items().begin(), - items().end(), - size_t{0x0B1EC7}, - [&](auto acc, auto const& item) { return acc + h(item); }); - } - case ARRAY: - return static_cast(folly::hash::hash_range(begin(), end())); - case INT64: - return std::hash()(getInt()); - case DOUBLE: - return std::hash()(getDouble()); - case BOOL: - return std::hash()(getBool()); - case STRING: - // keep consistent with detail::DynamicHasher - return Hash()(getString()); - } - assume_unreachable(); -} - -char const* dynamic::typeName(Type t) { -#define FB_X(T) return TypeInfo::name - FB_DYNAMIC_APPLY(t, FB_X); -#undef FB_X -} - -void dynamic::destroy() noexcept { - // This short-circuit speeds up some microbenchmarks. - if (type_ == NULLT) { - return; - } - -#define FB_X(T) detail::Destroy::destroy(getAddress()) - FB_DYNAMIC_APPLY(type_, FB_X); -#undef FB_X - type_ = NULLT; - u_.nul = nullptr; -} - -dynamic dynamic::merge_diff(const dynamic& source, const dynamic& target) { - if (!source.isObject() || !target.isObject()) { - return target; - } - - dynamic diff = object; - - // added/modified keys - for (const auto& pair : target.items()) { - auto it = source.find(pair.first); - if (it == source.items().end()) { - diff[pair.first] = pair.second; - } else { - const auto& ssource = it->second; - const auto& starget = pair.second; - if (ssource.isObject() && starget.isObject()) { - auto sdiff = merge_diff(ssource, starget); - if (!sdiff.empty()) { - diff[pair.first] = std::move(sdiff); - } - } else if (ssource != starget) { - diff[pair.first] = merge_diff(ssource, starget); - } - } - } - - // removed keys - for (const auto& pair : source.items()) { - auto it = target.find(pair.first); - if (it == target.items().end()) { - diff[pair.first] = nullptr; - } - } - - return diff; -} - -// clang-format off -dynamic::resolved_json_pointer -// clang-format on -dynamic::try_get_ptr(json_pointer const& jsonPtr) const& { - using err_code = json_pointer_resolution_error_code; - using error = json_pointer_resolution_error; - - auto const& tokens = jsonPtr.tokens(); - if (tokens.empty()) { - return json_pointer_resolved_value{ - nullptr, this, {nullptr, nullptr}, 0}; - } - - dynamic const* curr = this; - dynamic const* prev = nullptr; - - size_t curr_idx{0}; - StringPiece curr_key{}; - - for (auto it : enumerate(tokens)) { - // hit bottom but pointer not exhausted yet - if (!curr) { - return makeUnexpected( - error{err_code::json_pointer_out_of_bounds, it.index, prev}); - } - prev = curr; - // handle lookup in array - if (auto const* parray = curr->get_nothrow()) { - if (it->size() > 1 && it->at(0) == '0') { - return makeUnexpected( - error{err_code::index_has_leading_zero, it.index, prev}); - } - // if last element of pointer is '-', this is an append operation - if (it->size() == 1 && it->at(0) == '-') { - // was '-' the last token in pointer? - if (it.index == tokens.size() - 1) { - return makeUnexpected( - error{err_code::append_requested, it.index, prev}); - } - // Cannot resolve past '-' in an array - curr = nullptr; - continue; - } - auto const idx = tryTo(*it); - if (!idx.hasValue()) { - return makeUnexpected( - error{err_code::index_not_numeric, it.index, prev}); - } - if (idx.value() < parray->size()) { - curr = &(*parray)[idx.value()]; - curr_idx = idx.value(); - } else { - return makeUnexpected( - error{err_code::index_out_of_bounds, it.index, prev}); - } - continue; - } - // handle lookup in object - if (auto const* pobject = curr->get_nothrow()) { - auto const sub_it = pobject->find(*it); - if (sub_it == pobject->end()) { - return makeUnexpected(error{err_code::key_not_found, it.index, prev}); - } - curr = &sub_it->second; - curr_key = *it; - continue; - } - return makeUnexpected( - error{err_code::element_not_object_or_array, it.index, prev}); - } - return json_pointer_resolved_value{ - prev, curr, curr_key, curr_idx}; -} - -const dynamic* dynamic::get_ptr(json_pointer const& jsonPtr) const& { - using err_code = json_pointer_resolution_error_code; - - auto ret = try_get_ptr(jsonPtr); - if (ret.hasValue()) { - return ret.value().value; - } - - auto const ctx = ret.error().context; - auto const objType = ctx ? ctx->type() : Type::NULLT; - - switch (ret.error().error_code) { - case err_code::key_not_found: - return nullptr; - case err_code::index_out_of_bounds: - return nullptr; - case err_code::append_requested: - return nullptr; - case err_code::index_not_numeric: - throw std::invalid_argument("array index is not numeric"); - case err_code::index_has_leading_zero: - throw std::invalid_argument( - "leading zero not allowed when indexing arrays"); - case err_code::element_not_object_or_array: - throw_exception("object/array", objType); - case err_code::json_pointer_out_of_bounds: - return nullptr; - case err_code::other: - default: - return nullptr; - } - assume_unreachable(); -} - -////////////////////////////////////////////////////////////////////// - -} // namespace folly diff --git a/vnext/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h b/vnext/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h deleted file mode 100644 index 1239feb9420..00000000000 --- a/vnext/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include -#include -#include -#include -#include -#include - -#if _MSC_VER -#include -#endif - -namespace folly { - -// to_ascii_alphabet -// -// Used implicity by to_ascii_lower and to_ascii_upper below. -// -// This alphabet translates digits to 0-9,a-z or 0-9,A-Z. The largest supported -// base is 36; operator() presumes an argument less than that. -// -// Alternative alphabets may be used with to_ascii_with provided they match -// the constructibility/destructibility and the interface of this one. -template -struct to_ascii_alphabet { - // operator() - // - // Translates a single digit to 0-9,a-z or 0-9,A-Z. - // - // async-signal-safe - constexpr char operator()(uint8_t b) const { - return b < 10 ? '0' + b : (Upper ? 'A' : 'a') + (b - 10); - } -}; -using to_ascii_alphabet_lower = to_ascii_alphabet; -using to_ascii_alphabet_upper = to_ascii_alphabet; - -namespace detail { - -#if defined(_M_IX86) -FOLLY_ERASE auto to_ascii_port_clzll(uint64_t v) { - return __builtin_clzll(v); -} -#else -FOLLY_ERASE auto to_ascii_port_clzll(uint64_t v) { -#if _MSC_VER -#if FOLLY_X64 - return __lzcnt64(v); -#else - return __assume(0), 0; -#endif -#else - return __builtin_clzll(v); -#endif -} -#endif - -template -struct to_ascii_array { - using data_type_ = c_array; - static constexpr data_type_ data_() { - data_type_ result{}; - Alphabet alpha; - for (size_t i = 0; i < Base; ++i) { - result.data[i] = alpha(static_cast(i)); - } - return result; - } - // @lint-ignore CLANGTIDY - static data_type_ const data; - constexpr char operator()(uint8_t index) const { // also an alphabet - return data.data[index]; - } -}; -template -alignas(hardware_constructive_interference_size) - typename to_ascii_array::data_type_ const - to_ascii_array::data = - to_ascii_array::data_(); - -extern template to_ascii_array<8, to_ascii_alphabet_lower>::data_type_ const - to_ascii_array<8, to_ascii_alphabet_lower>::data; -extern template to_ascii_array<10, to_ascii_alphabet_lower>::data_type_ const - to_ascii_array<10, to_ascii_alphabet_lower>::data; -extern template to_ascii_array<16, to_ascii_alphabet_lower>::data_type_ const - to_ascii_array<16, to_ascii_alphabet_lower>::data; -extern template to_ascii_array<8, to_ascii_alphabet_upper>::data_type_ const - to_ascii_array<8, to_ascii_alphabet_upper>::data; -extern template to_ascii_array<10, to_ascii_alphabet_upper>::data_type_ const - to_ascii_array<10, to_ascii_alphabet_upper>::data; -extern template to_ascii_array<16, to_ascii_alphabet_upper>::data_type_ const - to_ascii_array<16, to_ascii_alphabet_upper>::data; - -template -struct to_ascii_table { - using data_type_ = c_array; - static constexpr data_type_ data_() { - data_type_ result{}; - Alphabet alpha; - for (size_t i = 0; i < Base * Base; ++i) { - result.data[i] = // - (alpha(uint8_t(i / Base)) << (kIsLittleEndian ? 0 : 8)) | - (alpha(uint8_t(i % Base)) << (kIsLittleEndian ? 8 : 0)); - } - return result; - } - // @lint-ignore CLANGTIDY - static data_type_ const data; -}; -template -alignas(hardware_constructive_interference_size) - typename to_ascii_table::data_type_ const - to_ascii_table::data = - to_ascii_table::data_(); - -extern template to_ascii_table<8, to_ascii_alphabet_lower>::data_type_ const - to_ascii_table<8, to_ascii_alphabet_lower>::data; -extern template to_ascii_table<10, to_ascii_alphabet_lower>::data_type_ const - to_ascii_table<10, to_ascii_alphabet_lower>::data; -extern template to_ascii_table<16, to_ascii_alphabet_lower>::data_type_ const - to_ascii_table<16, to_ascii_alphabet_lower>::data; -extern template to_ascii_table<8, to_ascii_alphabet_upper>::data_type_ const - to_ascii_table<8, to_ascii_alphabet_upper>::data; -extern template to_ascii_table<10, to_ascii_alphabet_upper>::data_type_ const - to_ascii_table<10, to_ascii_alphabet_upper>::data; -extern template to_ascii_table<16, to_ascii_alphabet_upper>::data_type_ const - to_ascii_table<16, to_ascii_alphabet_upper>::data; - -template -struct to_ascii_powers { - static constexpr size_t size_(I v) { - return 1 + (v < Base ? 0 : size_(v / Base)); - } - static constexpr size_t const size = size_(~I(0)); - using data_type_ = c_array; - static constexpr data_type_ data_() { - data_type_ result{}; - for (size_t i = 0; i < size; ++i) { - result.data[i] = constexpr_pow(Base, i); - } - return result; - } - // @lint-ignore CLANGTIDY - static data_type_ const data; -}; -template -constexpr size_t const to_ascii_powers::size; -template -alignas(hardware_constructive_interference_size) - typename to_ascii_powers::data_type_ const - to_ascii_powers::data = to_ascii_powers::data_(); - -extern template to_ascii_powers<8, uint64_t>::data_type_ const - to_ascii_powers<8, uint64_t>::data; -extern template to_ascii_powers<10, uint64_t>::data_type_ const - to_ascii_powers<10, uint64_t>::data; -extern template to_ascii_powers<16, uint64_t>::data_type_ const - to_ascii_powers<16, uint64_t>::data; - -template -FOLLY_ALWAYS_INLINE size_t to_ascii_size_imuls(uint64_t v) { - using powers = to_ascii_powers; - uint64_t p = 1; - for (size_t i = 0u; i < powers::size; ++i, p *= Base) { - if (FOLLY_UNLIKELY(v < p)) { - return i + size_t(i == 0); - } - } - return powers::size; -} - -template -FOLLY_ALWAYS_INLINE size_t to_ascii_size_idivs(uint64_t v) { - size_t i = 1; - while (v >= Base) { - i += 1; - v /= Base; - } - return i; -} - -template -FOLLY_ALWAYS_INLINE size_t to_ascii_size_array(uint64_t v) { - using powers = to_ascii_powers; - for (size_t i = 0u; i < powers::size; ++i) { - if (FOLLY_LIKELY(v < powers::data.data[i])) { - return i + size_t(i == 0); - } - } - return powers::size; -} - -// For some architectures, we can get a little help from clzll, the "count -// leading zeros" builtin, which is backed by a single performant instruction. -// -// Note that the compiler implements __builtin_clzll on all architectures, but -// only emits a single clzll instruction when the architecture has one. -// -// This implementation may be faster than the basic ones in the general case -// because the time taken to compute this one is constant for non-zero v, -// whereas the basic ones take time proportional to log<2>(v). Whether this one -// is actually faster depends on the emitted code for this implementation and -// on whether the loops in the basic implementations are unrolled. -template -FOLLY_ALWAYS_INLINE size_t to_ascii_size_clzll(uint64_t v) { - using powers = to_ascii_powers; - - // clzll is undefined for 0; must special case this - if (FOLLY_UNLIKELY(!v)) { - return 1; - } - - // log2 is approx log<2>(v) - size_t const vlog2 = 64 - static_cast(to_ascii_port_clzll(v)); - - // handle directly when Base is power-of-two - if (!(Base & (Base - 1))) { - constexpr auto const blog2 = constexpr_log2(Base); - return vlog2 / blog2 + size_t(vlog2 % blog2 != 0); - } - - // blog2r is approx 1 / log<2>(Base), used in log change-of-base just below - constexpr auto const blog2r = 8. / constexpr_log2(constexpr_pow(Base, 8)); - - // vlogb is approx log(v) = log<2>(v) / log<2>(Base) - auto const vlogb = vlog2 * size_t(blog2r * 256) / 256; - - // return vlogb, adjusted if necessary - return vlogb + size_t(vlogb < powers::size && v >= powers::data.data[vlogb]); -} - -template -FOLLY_ALWAYS_INLINE size_t to_ascii_size(uint64_t v) { - return kIsArchAmd64 && !(Base & (Base - 1)) // - ? to_ascii_size_clzll(v) - : to_ascii_size_array(v); -} - -// The straightforward implementation, assuming the size known in advance. -// -// The straightforward implementation without the size known in advance would -// entail emitting the bytes backward and then reversing them at the end, once -// the size is known. -template -FOLLY_ALWAYS_INLINE void to_ascii_with_basic( - char* out, size_t size, uint64_t v) { - Alphabet const xlate; - for (auto pos = size - 1; pos; --pos) { - // keep /, % together so a peephole optimization computes them together - auto const q = v / Base; - auto const r = v % Base; - out[pos] = xlate(r); - v = q; - } - out[0] = xlate(v); -} -template -FOLLY_ALWAYS_INLINE size_t to_ascii_with_basic(char* out, uint64_t v) { - auto const size = to_ascii_size(v); - to_ascii_with_basic(out, size, v); - return size; -} - -// A variant of the straightforward implementation, but using a lookup table. -template -FOLLY_ALWAYS_INLINE void to_ascii_with_array( - char* out, size_t size, uint64_t v) { - using array = to_ascii_array; // also an alphabet - to_ascii_with_basic(out, size, v); -} -template -FOLLY_ALWAYS_INLINE size_t to_ascii_with_array(char* out, uint64_t v) { - auto const size = to_ascii_size(v); - to_ascii_with_array(out, size, v); - return size; -} - -// A trickier implementation which performs half as many divides as the other, -// more straightforward, implementation. On modern hardware, the divides are -// the bottleneck (even when the compiler emits a complicated sequence of add, -// sub, and mul instructions with special constants to simulate a divide by a -// fixed denominator). -// -// The downside of this implementation is that the emitted code is larger, -// especially when the divide is simulated, which affects inlining decisions. -template -FOLLY_ALWAYS_INLINE void to_ascii_with_table( - char* out, size_t size, uint64_t v) { - using table = to_ascii_table; - auto pos = size - 2; - while (FOLLY_UNLIKELY(v >= Base * Base)) { - // keep /, % together so a peephole optimization computes them together - auto const q = v / (Base * Base); - auto const r = v % (Base * Base); - auto const val = table::data.data[size_t(r)]; - std::memcpy(out + pos, &val, 2); - pos -= 2; - v = q; - } - auto const val = table::data.data[size_t(v)]; - if (FOLLY_UNLIKELY(size % 2 == 0)) { - std::memcpy(out, &val, 2); - } else { - *out = val >> (kIsLittleEndian ? 8 : 0); - } -} -template -FOLLY_ALWAYS_INLINE size_t to_ascii_with_table(char* out, uint64_t v) { - auto const size = to_ascii_size(v); - to_ascii_with_table(out, size, v); - return size; -} - -} // namespace detail - -// to_ascii_size_max -// -// The maximum size buffer that might be required to hold the ascii-encoded -// representation of any value of unsigned type I in base Base. -// -// In base 10, u64 requires at most 20 bytes, u32 at most 10, u16 at most 5, -// and u8 at most 3. -// -// async-signal-safe -template -constexpr size_t to_ascii_size_max() { - return detail::to_ascii_powers::size; -} - -// to_ascii_size_max_decimal -// -// An alias to to_ascii_size_max<10>. -// -// async-signal-safe -template -constexpr size_t to_ascii_size_max_decimal() { - return to_ascii_size_max<10, I>(); -} - -// to_ascii_size -// -// Returns the number of digits in the base Base representation of a uint64_t. -// Useful for preallocating buffers, etc. -// -// async-signal-safe -template -size_t to_ascii_size(uint64_t v) { - return detail::to_ascii_size(v); -} - -// to_ascii_size_decimal -// -// An alias to to_ascii_size<10>. -// -// async-signal-safe -inline size_t to_ascii_size_decimal(uint64_t v) { - return to_ascii_size<10>(v); -} - -// to_ascii_with -// -// Copies the digits of v, in base Base, translated with Alphabet, into buffer -// and returns the number of bytes written. -// -// Does *not* append a null terminator. It is the caller's responsibility to -// append a null terminator if one is required. -// -// Assumes buffer points to at least to_ascii_size(v) bytes of writable -// memory. It is the caller's responsibility to provide a writable buffer with -// the required min size. -// -// async-signal-safe -template -size_t to_ascii_with(char* out, uint64_t v) { - return detail::to_ascii_with_table(out, v); -} - -// to_ascii_lower -// -// Composes to_ascii_with with to_ascii_alphabet_lower. -// -// async-signal-safe -template -size_t to_ascii_lower(char* out, uint64_t v) { - return to_ascii_with(out, v); -} - -// to_ascii_upper -// -// Composes to_ascii_with with to_ascii_alphabet_upper. -// -// async-signal-safe -template -size_t to_ascii_upper(char* out, uint64_t v) { - return to_ascii_with(out, v); -} - -// to_ascii_decimal -// -// An alias to to_ascii<10, false>. -// -// async-signals-afe -inline size_t to_ascii_decimal(char* out, uint64_t v) { - return to_ascii_lower<10>(out, v); -} - -} // namespace folly From 9ed04755adda6e8da247f3002da909e573d412fe Mon Sep 17 00:00:00 2001 From: "REDMOND\\agnel" Date: Thu, 13 May 2021 11:32:55 -0500 Subject: [PATCH 3/5] Change files --- ...ative-windows-0fb7974b-3432-4444-9e4e-74d40818b302.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/react-native-windows-0fb7974b-3432-4444-9e4e-74d40818b302.json diff --git a/change/react-native-windows-0fb7974b-3432-4444-9e4e-74d40818b302.json b/change/react-native-windows-0fb7974b-3432-4444-9e4e-74d40818b302.json new file mode 100644 index 00000000000..f288a1dab87 --- /dev/null +++ b/change/react-native-windows-0fb7974b-3432-4444-9e4e-74d40818b302.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "folly update", + "packageName": "react-native-windows", + "email": "agnel@microsoft.com", + "dependentChangeType": "patch" +} From e67d54ad4543654c3ff69824279822af73ae727e Mon Sep 17 00:00:00 2001 From: "REDMOND\\agnel" Date: Fri, 21 May 2021 11:22:48 -0500 Subject: [PATCH 4/5] additional exports --- vnext/Desktop.DLL/react-native-win32.x64.def | 2 ++ vnext/Desktop.DLL/react-native-win32.x86.def | 2 ++ 2 files changed, 4 insertions(+) diff --git a/vnext/Desktop.DLL/react-native-win32.x64.def b/vnext/Desktop.DLL/react-native-win32.x64.def index 98f64546b56..0ad602317ef 100644 --- a/vnext/Desktop.DLL/react-native-win32.x64.def +++ b/vnext/Desktop.DLL/react-native-win32.x64.def @@ -33,6 +33,8 @@ EXPORTS ?createIUIManager@react@facebook@@YA?AV?$shared_ptr@VIUIManager@react@facebook@@@std@@$$QEAV?$vector@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@V?$allocator@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@@2@@4@PEAUINativeUIManager@12@@Z ?createUIManagerModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@V?$shared_ptr@VIUIManager@react@facebook@@@4@@Z ?createUIManagerModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@$$QEAV?$shared_ptr@VIUIManager@react@facebook@@@4@$$QEAV?$shared_ptr@VMessageQueueThread@react@facebook@@@4@@Z +?data@?$to_ascii_powers@$09_K@detail@folly@@2U?$c_array@_K$0BE@@3@B +?data@?$to_ascii_table@$09U?$to_ascii_alphabet@$0A@@folly@@@detail@folly@@2U?$c_array@G$0GE@@3@B ?destroy@dynamic@folly@@AEAAXXZ ?dispatchCommand@ShadowNode@react@facebook@@UEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBUdynamic@folly@@@Z ?getModuleRegistry@Instance@react@facebook@@QEAAAEAVModuleRegistry@23@XZ diff --git a/vnext/Desktop.DLL/react-native-win32.x86.def b/vnext/Desktop.DLL/react-native-win32.x86.def index 11e76f67153..29efc8b3080 100644 --- a/vnext/Desktop.DLL/react-native-win32.x86.def +++ b/vnext/Desktop.DLL/react-native-win32.x86.def @@ -34,6 +34,8 @@ EXPORTS ?createIUIManager@react@facebook@@YG?AV?$shared_ptr@VIUIManager@react@facebook@@@std@@$$QAV?$vector@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@V?$allocator@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@@2@@4@PAUINativeUIManager@12@@Z ?createUIManagerModule@react@facebook@@YG?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@V?$shared_ptr@VIUIManager@react@facebook@@@4@@Z ?createUIManagerModule@react@facebook@@YG?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@$$QAV?$shared_ptr@VIUIManager@react@facebook@@@4@$$QAV?$shared_ptr@VMessageQueueThread@react@facebook@@@4@@Z +?data@?$to_ascii_powers@$09_K@detail@folly@@2U?$c_array@_K$0BE@@3@B +?data@?$to_ascii_table@$09U?$to_ascii_alphabet@$0A@@folly@@@detail@folly@@2U?$c_array@G$0GE@@3@B ?destroy@dynamic@folly@@AAEXXZ ?dispatchCommand@ShadowNode@react@facebook@@UAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABUdynamic@folly@@@Z ?getModuleRegistry@Instance@react@facebook@@QAEAAVModuleRegistry@23@XZ From 8c7b840df5e1ede95efc5c2b0aefccb62c1d5303 Mon Sep 17 00:00:00 2001 From: "REDMOND\\agnel" Date: Fri, 21 May 2021 12:16:07 -0500 Subject: [PATCH 5/5] compile ThreadId.cpp --- vnext/Folly/Folly.vcxproj | 1 + vnext/Folly/Folly.vcxproj.filters | 3 +++ 2 files changed, 4 insertions(+) diff --git a/vnext/Folly/Folly.vcxproj b/vnext/Folly/Folly.vcxproj index 263a65d5bdd..75c84f1be2b 100644 --- a/vnext/Folly/Folly.vcxproj +++ b/vnext/Folly/Folly.vcxproj @@ -52,6 +52,7 @@ + diff --git a/vnext/Folly/Folly.vcxproj.filters b/vnext/Folly/Folly.vcxproj.filters index 18eabd827d8..0c1f54abdbf 100644 --- a/vnext/Folly/Folly.vcxproj.filters +++ b/vnext/Folly/Folly.vcxproj.filters @@ -30,6 +30,9 @@ + + Source Files\lang + Source Files\lang