diff options
author | ayles <ayles@yandex-team.ru> | 2022-02-10 16:46:11 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:11 +0300 |
commit | d55028e9d9708f94c2d0d35b54ed50d4d7af0456 (patch) | |
tree | d69fdff3b2be7d190a1efa078721d25139d0b030 /contrib/restricted/abseil-cpp | |
parent | baa58daefa91fde4b4769facdbd2903763b9c6a8 (diff) | |
download | ydb-d55028e9d9708f94c2d0d35b54ed50d4d7af0456.tar.gz |
Restoring authorship annotation for <ayles@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/restricted/abseil-cpp')
425 files changed, 22703 insertions, 22703 deletions
diff --git a/contrib/restricted/abseil-cpp/CONTRIBUTING.md b/contrib/restricted/abseil-cpp/CONTRIBUTING.md index 9dadae9376..65b640b126 100644 --- a/contrib/restricted/abseil-cpp/CONTRIBUTING.md +++ b/contrib/restricted/abseil-cpp/CONTRIBUTING.md @@ -123,13 +123,13 @@ will be expected to conform to the style outlined ## Running Tests -If you have [Bazel](https://bazel.build/) installed, use `bazel test ---test_tag_filters="-benchmark" ...` to run the unit tests. +If you have [Bazel](https://bazel.build/) installed, use `bazel test +--test_tag_filters="-benchmark" ...` to run the unit tests. -If you are running the Linux operating system and have -[Docker](https://www.docker.com/) installed, you can also run the `linux_*.sh` -scripts under the `ci/`(https://github.com/abseil/abseil-cpp/tree/master/ci) -directory to test Abseil under a variety of conditions. +If you are running the Linux operating system and have +[Docker](https://www.docker.com/) installed, you can also run the `linux_*.sh` +scripts under the `ci/`(https://github.com/abseil/abseil-cpp/tree/master/ci) +directory to test Abseil under a variety of conditions. ## Abseil Committers diff --git a/contrib/restricted/abseil-cpp/FAQ.md b/contrib/restricted/abseil-cpp/FAQ.md index fbd92ce975..b2032af924 100644 --- a/contrib/restricted/abseil-cpp/FAQ.md +++ b/contrib/restricted/abseil-cpp/FAQ.md @@ -1,167 +1,167 @@ -# Abseil FAQ - -## Is Abseil the right home for my utility library? - -Most often the answer to the question is "no." As both the [About -Abseil](https://abseil.io/about/) page and our [contributing -guidelines](https://github.com/abseil/abseil-cpp/blob/master/CONTRIBUTING.md#contribution-guidelines) -explain, Abseil contains a variety of core C++ library code that is widely used -at [Google](https://www.google.com/). As such, Abseil's primary purpose is to be -used as a dependency by Google's open source C++ projects. While we do hope that -Abseil is also useful to the C++ community at large, this added constraint also -means that we are unlikely to accept a contribution of utility code that isn't -already widely used by Google. - -## How to I set the C++ dialect used to build Abseil? - -The short answer is that whatever mechanism you choose, you need to make sure -that you set this option consistently at the global level for your entire -project. If, for example, you want to set the C++ dialect to C++17, with -[Bazel](https://bazel/build/) as the build system and `gcc` or `clang` as the -compiler, there several ways to do this: -* Pass `--cxxopt=-std=c++17` on the command line (for example, `bazel build - --cxxopt=-std=c++17 ...`) -* Set the environment variable `BAZEL_CXXOPTS` (for example, - `BAZEL_CXXOPTS=-std=c++17`) -* Add `build --cxxopt=-std=c++17` to your [`.bazelrc` - file](https://docs.bazel.build/versions/master/guide.html#bazelrc) - -If you are using CMake as the build system, you'll need to add a line like +# Abseil FAQ + +## Is Abseil the right home for my utility library? + +Most often the answer to the question is "no." As both the [About +Abseil](https://abseil.io/about/) page and our [contributing +guidelines](https://github.com/abseil/abseil-cpp/blob/master/CONTRIBUTING.md#contribution-guidelines) +explain, Abseil contains a variety of core C++ library code that is widely used +at [Google](https://www.google.com/). As such, Abseil's primary purpose is to be +used as a dependency by Google's open source C++ projects. While we do hope that +Abseil is also useful to the C++ community at large, this added constraint also +means that we are unlikely to accept a contribution of utility code that isn't +already widely used by Google. + +## How to I set the C++ dialect used to build Abseil? + +The short answer is that whatever mechanism you choose, you need to make sure +that you set this option consistently at the global level for your entire +project. If, for example, you want to set the C++ dialect to C++17, with +[Bazel](https://bazel/build/) as the build system and `gcc` or `clang` as the +compiler, there several ways to do this: +* Pass `--cxxopt=-std=c++17` on the command line (for example, `bazel build + --cxxopt=-std=c++17 ...`) +* Set the environment variable `BAZEL_CXXOPTS` (for example, + `BAZEL_CXXOPTS=-std=c++17`) +* Add `build --cxxopt=-std=c++17` to your [`.bazelrc` + file](https://docs.bazel.build/versions/master/guide.html#bazelrc) + +If you are using CMake as the build system, you'll need to add a line like `set(CMAKE_CXX_STANDARD 17)` to your top level `CMakeLists.txt` file. If you are developing a library designed to be used by other clients, you should instead leave `CMAKE_CXX_STANDARD` unset and configure the minimum C++ standard required by each of your library targets via `target_compile_features`. See the -[CMake build -instructions](https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md) -for more information. - -For a longer answer to this question and to understand why some other approaches -don't work, see the answer to ["What is ABI and why don't you recommend using a -pre-compiled version of -Abseil?"](#what-is-abi-and-why-dont-you-recommend-using-a-pre-compiled-version-of-abseil) - -## What is ABI and why don't you recommend using a pre-compiled version of Abseil? - -For the purposes of this discussion, you can think of -[ABI](https://en.wikipedia.org/wiki/Application_binary_interface) as the -compiled representation of the interfaces in code. This is in contrast to -[API](https://en.wikipedia.org/wiki/Application_programming_interface), which -you can think of as the interfaces as defined by the code itself. [Abseil has a -strong promise of API compatibility, but does not make any promise of ABI -compatibility](https://abseil.io/about/compatibility). Let's take a look at what -this means in practice. - -You might be tempted to do something like this in a -[Bazel](https://bazel.build/) `BUILD` file: - -``` -# DON'T DO THIS!!! -cc_library( - name = "my_library", - srcs = ["my_library.cc"], - copts = ["-std=c++17"], # May create a mixed-mode compile! - deps = ["@com_google_absl//absl/strings"], -) -``` - -Applying `-std=c++17` to an individual target in your `BUILD` file is going to -compile that specific target in C++17 mode, but it isn't going to ensure the -Abseil library is built in C++17 mode, since the Abseil library itself is a -different build target. If your code includes an Abseil header, then your -program may contain conflicting definitions of the same -class/function/variable/enum, etc. As a rule, all compile options that affect -the ABI of a program need to be applied to the entire build on a global basis. - -C++ has something called the [One Definition -Rule](https://en.wikipedia.org/wiki/One_Definition_Rule) (ODR). C++ doesn't -allow multiple definitions of the same class/function/variable/enum, etc. ODR -violations sometimes result in linker errors, but linkers do not always catch -violations. Uncaught ODR violations can result in strange runtime behaviors or -crashes that can be hard to debug. - -If you build the Abseil library and your code using different compile options -that affect ABI, there is a good chance you will run afoul of the One Definition -Rule. Examples of GCC compile options that affect ABI include (but aren't -limited to) language dialect (e.g. `-std=`), optimization level (e.g. `-O2`), -code generation flags (e.g. `-fexceptions`), and preprocessor defines -(e.g. `-DNDEBUG`). - -If you use a pre-compiled version of Abseil, (for example, from your Linux -distribution package manager or from something like -[vcpkg](https://github.com/microsoft/vcpkg)) you have to be very careful to -ensure ABI compatibility across the components of your program. The only way you -can be sure your program is going to be correct regarding ABI is to ensure -you've used the exact same compile options as were used to build the -pre-compiled library. This does not mean that Abseil cannot work as part of a -Linux distribution since a knowledgeable binary packager will have ensured that -all packages have been built with consistent compile options. This is one of the -reasons we warn against - though do not outright reject - using Abseil as a -pre-compiled library. - -Another possible way that you might afoul of ABI issues is if you accidentally -include two versions of Abseil in your program. Multiple versions of Abseil can -end up within the same binary if your program uses the Abseil library and -another library also transitively depends on Abseil (resulting in what is -sometimes called the diamond dependency problem). In cases such as this you must -structure your build so that all libraries use the same version of Abseil. -[Abseil's strong promise of API compatibility between -releases](https://abseil.io/about/compatibility) means the latest "HEAD" release -of Abseil is almost certainly the right choice if you are doing as we recommend -and building all of your code from source. - -For these reasons we recommend you avoid pre-compiled code and build the Abseil -library yourself in a consistent manner with the rest of your code. - -## What is "live at head" and how do I do it? - -From Abseil's point-of-view, "live at head" means that every Abseil source -release (which happens on an almost daily basis) is either API compatible with -the previous release, or comes with an automated tool that you can run over code -to make it compatible. In practice, the need to use an automated tool is -extremely rare. This means that upgrading from one source release to another -should be a routine practice that can and should be performed often. - -We recommend you update to the [latest commit in the `master` branch of -Abseil](https://github.com/abseil/abseil-cpp/commits/master) as often as -possible. Not only will you pick up bug fixes more quickly, but if you have good -automated testing, you will catch and be able to fix any [Hyrum's -Law](https://www.hyrumslaw.com/) dependency problems on an incremental basis -instead of being overwhelmed by them and having difficulty isolating them if you -wait longer between updates. - -If you are using the [Bazel](https://bazel.build/) build system and its -[external dependencies](https://docs.bazel.build/versions/master/external.html) -feature, updating the -[`http_archive`](https://docs.bazel.build/versions/master/repo/http.html#http_archive) -rule in your -[`WORKSPACE`](https://docs.bazel.build/versions/master/be/workspace.html) for -`com_google_abseil` to point to the [latest commit in the `master` branch of -Abseil](https://github.com/abseil/abseil-cpp/commits/master) is all you need to -do. For example, on February 11, 2020, the latest commit to the master branch -was `98eb410c93ad059f9bba1bf43f5bb916fc92a5ea`. To update to this commit, you -would add the following snippet to your `WORKSPACE` file: - -``` -http_archive( - name = "com_google_absl", - urls = ["https://github.com/abseil/abseil-cpp/archive/98eb410c93ad059f9bba1bf43f5bb916fc92a5ea.zip"], # 2020-02-11T18:50:53Z - strip_prefix = "abseil-cpp-98eb410c93ad059f9bba1bf43f5bb916fc92a5ea", - sha256 = "aabf6c57e3834f8dc3873a927f37eaf69975d4b28117fc7427dfb1c661542a87", -) -``` - -To get the `sha256` of this URL, run `curl -sL --output - -https://github.com/abseil/abseil-cpp/archive/98eb410c93ad059f9bba1bf43f5bb916fc92a5ea.zip -| sha256sum -`. - -You can commit the updated `WORKSPACE` file to your source control every time -you update, and if you have good automated testing, you might even consider -automating this. - -One thing we don't recommend is using GitHub's `master.zip` files (for example -[https://github.com/abseil/abseil-cpp/archive/master.zip](https://github.com/abseil/abseil-cpp/archive/master.zip)), -which are always the latest commit in the `master` branch, to implement live at -head. Since these `master.zip` URLs are not versioned, you will lose build -reproducibility. In addition, some build systems, including Bazel, will simply -cache this file, which means you won't actually be updating to the latest -release until your cache is cleared or invalidated. +[CMake build +instructions](https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md) +for more information. + +For a longer answer to this question and to understand why some other approaches +don't work, see the answer to ["What is ABI and why don't you recommend using a +pre-compiled version of +Abseil?"](#what-is-abi-and-why-dont-you-recommend-using-a-pre-compiled-version-of-abseil) + +## What is ABI and why don't you recommend using a pre-compiled version of Abseil? + +For the purposes of this discussion, you can think of +[ABI](https://en.wikipedia.org/wiki/Application_binary_interface) as the +compiled representation of the interfaces in code. This is in contrast to +[API](https://en.wikipedia.org/wiki/Application_programming_interface), which +you can think of as the interfaces as defined by the code itself. [Abseil has a +strong promise of API compatibility, but does not make any promise of ABI +compatibility](https://abseil.io/about/compatibility). Let's take a look at what +this means in practice. + +You might be tempted to do something like this in a +[Bazel](https://bazel.build/) `BUILD` file: + +``` +# DON'T DO THIS!!! +cc_library( + name = "my_library", + srcs = ["my_library.cc"], + copts = ["-std=c++17"], # May create a mixed-mode compile! + deps = ["@com_google_absl//absl/strings"], +) +``` + +Applying `-std=c++17` to an individual target in your `BUILD` file is going to +compile that specific target in C++17 mode, but it isn't going to ensure the +Abseil library is built in C++17 mode, since the Abseil library itself is a +different build target. If your code includes an Abseil header, then your +program may contain conflicting definitions of the same +class/function/variable/enum, etc. As a rule, all compile options that affect +the ABI of a program need to be applied to the entire build on a global basis. + +C++ has something called the [One Definition +Rule](https://en.wikipedia.org/wiki/One_Definition_Rule) (ODR). C++ doesn't +allow multiple definitions of the same class/function/variable/enum, etc. ODR +violations sometimes result in linker errors, but linkers do not always catch +violations. Uncaught ODR violations can result in strange runtime behaviors or +crashes that can be hard to debug. + +If you build the Abseil library and your code using different compile options +that affect ABI, there is a good chance you will run afoul of the One Definition +Rule. Examples of GCC compile options that affect ABI include (but aren't +limited to) language dialect (e.g. `-std=`), optimization level (e.g. `-O2`), +code generation flags (e.g. `-fexceptions`), and preprocessor defines +(e.g. `-DNDEBUG`). + +If you use a pre-compiled version of Abseil, (for example, from your Linux +distribution package manager or from something like +[vcpkg](https://github.com/microsoft/vcpkg)) you have to be very careful to +ensure ABI compatibility across the components of your program. The only way you +can be sure your program is going to be correct regarding ABI is to ensure +you've used the exact same compile options as were used to build the +pre-compiled library. This does not mean that Abseil cannot work as part of a +Linux distribution since a knowledgeable binary packager will have ensured that +all packages have been built with consistent compile options. This is one of the +reasons we warn against - though do not outright reject - using Abseil as a +pre-compiled library. + +Another possible way that you might afoul of ABI issues is if you accidentally +include two versions of Abseil in your program. Multiple versions of Abseil can +end up within the same binary if your program uses the Abseil library and +another library also transitively depends on Abseil (resulting in what is +sometimes called the diamond dependency problem). In cases such as this you must +structure your build so that all libraries use the same version of Abseil. +[Abseil's strong promise of API compatibility between +releases](https://abseil.io/about/compatibility) means the latest "HEAD" release +of Abseil is almost certainly the right choice if you are doing as we recommend +and building all of your code from source. + +For these reasons we recommend you avoid pre-compiled code and build the Abseil +library yourself in a consistent manner with the rest of your code. + +## What is "live at head" and how do I do it? + +From Abseil's point-of-view, "live at head" means that every Abseil source +release (which happens on an almost daily basis) is either API compatible with +the previous release, or comes with an automated tool that you can run over code +to make it compatible. In practice, the need to use an automated tool is +extremely rare. This means that upgrading from one source release to another +should be a routine practice that can and should be performed often. + +We recommend you update to the [latest commit in the `master` branch of +Abseil](https://github.com/abseil/abseil-cpp/commits/master) as often as +possible. Not only will you pick up bug fixes more quickly, but if you have good +automated testing, you will catch and be able to fix any [Hyrum's +Law](https://www.hyrumslaw.com/) dependency problems on an incremental basis +instead of being overwhelmed by them and having difficulty isolating them if you +wait longer between updates. + +If you are using the [Bazel](https://bazel.build/) build system and its +[external dependencies](https://docs.bazel.build/versions/master/external.html) +feature, updating the +[`http_archive`](https://docs.bazel.build/versions/master/repo/http.html#http_archive) +rule in your +[`WORKSPACE`](https://docs.bazel.build/versions/master/be/workspace.html) for +`com_google_abseil` to point to the [latest commit in the `master` branch of +Abseil](https://github.com/abseil/abseil-cpp/commits/master) is all you need to +do. For example, on February 11, 2020, the latest commit to the master branch +was `98eb410c93ad059f9bba1bf43f5bb916fc92a5ea`. To update to this commit, you +would add the following snippet to your `WORKSPACE` file: + +``` +http_archive( + name = "com_google_absl", + urls = ["https://github.com/abseil/abseil-cpp/archive/98eb410c93ad059f9bba1bf43f5bb916fc92a5ea.zip"], # 2020-02-11T18:50:53Z + strip_prefix = "abseil-cpp-98eb410c93ad059f9bba1bf43f5bb916fc92a5ea", + sha256 = "aabf6c57e3834f8dc3873a927f37eaf69975d4b28117fc7427dfb1c661542a87", +) +``` + +To get the `sha256` of this URL, run `curl -sL --output - +https://github.com/abseil/abseil-cpp/archive/98eb410c93ad059f9bba1bf43f5bb916fc92a5ea.zip +| sha256sum -`. + +You can commit the updated `WORKSPACE` file to your source control every time +you update, and if you have good automated testing, you might even consider +automating this. + +One thing we don't recommend is using GitHub's `master.zip` files (for example +[https://github.com/abseil/abseil-cpp/archive/master.zip](https://github.com/abseil/abseil-cpp/archive/master.zip)), +which are always the latest commit in the `master` branch, to implement live at +head. Since these `master.zip` URLs are not versioned, you will lose build +reproducibility. In addition, some build systems, including Bazel, will simply +cache this file, which means you won't actually be updating to the latest +release until your cache is cleared or invalidated. diff --git a/contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h b/contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h index e9b4733872..2f20719e76 100644 --- a/contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h +++ b/contrib/restricted/abseil-cpp/absl/algorithm/algorithm.h @@ -26,10 +26,10 @@ #include <iterator> #include <type_traits> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace algorithm_internal { @@ -153,7 +153,7 @@ ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator>()); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_ALGORITHM_ALGORITHM_H_ diff --git a/contrib/restricted/abseil-cpp/absl/algorithm/container.h b/contrib/restricted/abseil-cpp/absl/algorithm/container.h index c38a4a63db..1ecf51b26a 100644 --- a/contrib/restricted/abseil-cpp/absl/algorithm/container.h +++ b/contrib/restricted/abseil-cpp/absl/algorithm/container.h @@ -55,7 +55,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_algorithm_internal { // NOTE: it is important to defer to ADL lookup for building with C++ modules, @@ -90,10 +90,10 @@ using ContainerPointerType = // lookup of std::begin and std::end, i.e. // using std::begin; // using std::end; -// std::foo(begin(c), end(c)); +// std::foo(begin(c), end(c)); // becomes // std::foo(container_algorithm_internal::begin(c), -// container_algorithm_internal::end(c)); +// container_algorithm_internal::end(c)); // These are meant for internal use only. template <typename C> @@ -269,8 +269,8 @@ container_algorithm_internal::ContainerIter<Sequence1> c_find_end( // c_find_first_of() // // Container-based version of the <algorithm> `std::find_first_of()` function to -// find the first element within the container that is also within the options -// container. +// find the first element within the container that is also within the options +// container. template <typename C1, typename C2> container_algorithm_internal::ContainerIter<C1> c_find_first_of(C1& container, C2& options) { @@ -340,45 +340,45 @@ container_algorithm_internal::ContainerDifferenceType<const C> c_count_if( // c_mismatch() // // Container-based version of the <algorithm> `std::mismatch()` function to -// return the first element where two ordered containers differ. Applies `==` to -// the first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)). +// return the first element where two ordered containers differ. Applies `==` to +// the first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)). template <typename C1, typename C2> container_algorithm_internal::ContainerIterPairType<C1, C2> c_mismatch(C1& c1, C2& c2) { - auto first1 = container_algorithm_internal::c_begin(c1); - auto last1 = container_algorithm_internal::c_end(c1); - auto first2 = container_algorithm_internal::c_begin(c2); - auto last2 = container_algorithm_internal::c_end(c2); - - for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) { - // Negates equality because Cpp17EqualityComparable doesn't require clients - // to overload both `operator==` and `operator!=`. - if (!(*first1 == *first2)) { - break; - } - } - - return std::make_pair(first1, first2); + auto first1 = container_algorithm_internal::c_begin(c1); + auto last1 = container_algorithm_internal::c_end(c1); + auto first2 = container_algorithm_internal::c_begin(c2); + auto last2 = container_algorithm_internal::c_end(c2); + + for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) { + // Negates equality because Cpp17EqualityComparable doesn't require clients + // to overload both `operator==` and `operator!=`. + if (!(*first1 == *first2)) { + break; + } + } + + return std::make_pair(first1, first2); } // Overload of c_mismatch() for using a predicate evaluation other than `==` as -// the function's test condition. Applies `pred`to the first N elements of `c1` -// and `c2`, where N = min(size(c1), size(c2)). +// the function's test condition. Applies `pred`to the first N elements of `c1` +// and `c2`, where N = min(size(c1), size(c2)). template <typename C1, typename C2, typename BinaryPredicate> container_algorithm_internal::ContainerIterPairType<C1, C2> -c_mismatch(C1& c1, C2& c2, BinaryPredicate pred) { - auto first1 = container_algorithm_internal::c_begin(c1); - auto last1 = container_algorithm_internal::c_end(c1); - auto first2 = container_algorithm_internal::c_begin(c2); - auto last2 = container_algorithm_internal::c_end(c2); - - for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) { - if (!pred(*first1, *first2)) { - break; - } - } - - return std::make_pair(first1, first2); +c_mismatch(C1& c1, C2& c2, BinaryPredicate pred) { + auto first1 = container_algorithm_internal::c_begin(c1); + auto last1 = container_algorithm_internal::c_end(c1); + auto first2 = container_algorithm_internal::c_begin(c2); + auto last2 = container_algorithm_internal::c_end(c2); + + for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) { + if (!pred(*first1, *first2)) { + break; + } + } + + return std::make_pair(first1, first2); } // c_equal() @@ -560,20 +560,20 @@ BidirectionalIterator c_move_backward(C&& src, BidirectionalIterator dest) { // c_swap_ranges() // // Container-based version of the <algorithm> `std::swap_ranges()` function to -// swap a container's elements with another container's elements. Swaps the -// first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)). +// swap a container's elements with another container's elements. Swaps the +// first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)). template <typename C1, typename C2> container_algorithm_internal::ContainerIter<C2> c_swap_ranges(C1& c1, C2& c2) { - auto first1 = container_algorithm_internal::c_begin(c1); - auto last1 = container_algorithm_internal::c_end(c1); - auto first2 = container_algorithm_internal::c_begin(c2); - auto last2 = container_algorithm_internal::c_end(c2); - - using std::swap; - for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) { - swap(*first1, *first2); - } - return first2; + auto first1 = container_algorithm_internal::c_begin(c1); + auto last1 = container_algorithm_internal::c_end(c1); + auto first2 = container_algorithm_internal::c_begin(c2); + auto last2 = container_algorithm_internal::c_end(c2); + + using std::swap; + for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) { + swap(*first1, *first2); + } + return first2; } // c_transform() @@ -591,23 +591,23 @@ OutputIterator c_transform(const InputSequence& input, OutputIterator output, } // Overload of c_transform() for performing a transformation using a binary -// predicate. Applies `binary_op` to the first N elements of `c1` and `c2`, -// where N = min(size(c1), size(c2)). +// predicate. Applies `binary_op` to the first N elements of `c1` and `c2`, +// where N = min(size(c1), size(c2)). template <typename InputSequence1, typename InputSequence2, typename OutputIterator, typename BinaryOp> OutputIterator c_transform(const InputSequence1& input1, const InputSequence2& input2, OutputIterator output, BinaryOp&& binary_op) { - auto first1 = container_algorithm_internal::c_begin(input1); - auto last1 = container_algorithm_internal::c_end(input1); - auto first2 = container_algorithm_internal::c_begin(input2); - auto last2 = container_algorithm_internal::c_end(input2); - for (; first1 != last1 && first2 != last2; - ++first1, (void)++first2, ++output) { - *output = binary_op(*first1, *first2); - } - - return output; + auto first1 = container_algorithm_internal::c_begin(input1); + auto last1 = container_algorithm_internal::c_end(input1); + auto first2 = container_algorithm_internal::c_begin(input2); + auto last2 = container_algorithm_internal::c_end(input2); + for (; first1 != last1 && first2 != last2; + ++first1, (void)++first2, ++output) { + *output = binary_op(*first1, *first2); + } + + return output; } // c_replace() @@ -979,10 +979,10 @@ void c_partial_sort( // c_partial_sort_copy() // // Container-based version of the <algorithm> `std::partial_sort_copy()` -// function to sort the elements in the given range `result` within the larger -// `sequence` in ascending order (and using `result` as the output parameter). -// At most min(result.last - result.first, sequence.last - sequence.first) -// elements from the sequence will be stored in the result. +// function to sort the elements in the given range `result` within the larger +// `sequence` in ascending order (and using `result` as the output parameter). +// At most min(result.last - result.first, sequence.last - sequence.first) +// elements from the sequence will be stored in the result. template <typename C, typename RandomAccessContainer> container_algorithm_internal::ContainerIter<RandomAccessContainer> c_partial_sort_copy(const C& sequence, RandomAccessContainer& result) { @@ -1768,7 +1768,7 @@ OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first, output_first, std::forward<BinaryOp>(op)); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_ALGORITHM_CONTAINER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/attributes.h b/contrib/restricted/abseil-cpp/absl/base/attributes.h index e3907827d6..b0889cf712 100644 --- a/contrib/restricted/abseil-cpp/absl/base/attributes.h +++ b/contrib/restricted/abseil-cpp/absl/base/attributes.h @@ -30,12 +30,12 @@ // of them are not supported in older version of Clang. Thus, we check // `__has_attribute()` first. If the check fails, we check if we are on GCC and // assume the attribute exists on GCC (which is verified on GCC 4.7). - + #ifndef ABSL_BASE_ATTRIBUTES_H_ #define ABSL_BASE_ATTRIBUTES_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + // ABSL_HAVE_ATTRIBUTE // // A function-like feature checking macro that is a wrapper around @@ -210,7 +210,7 @@ // out of bounds or does other scary things with memory. // NOTE: GCC supports AddressSanitizer(asan) since 4.8. // https://gcc.gnu.org/gcc-4.8/changes.html -#if ABSL_HAVE_ATTRIBUTE(no_sanitize_address) +#if ABSL_HAVE_ATTRIBUTE(no_sanitize_address) #define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) #else #define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS @@ -218,13 +218,13 @@ // ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // -// Tells the MemorySanitizer to relax the handling of a given function. All "Use -// of uninitialized value" warnings from such functions will be suppressed, and -// all values loaded from memory will be considered fully initialized. This -// attribute is similar to the ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS attribute -// above, but deals with initialized-ness rather than addressability issues. +// Tells the MemorySanitizer to relax the handling of a given function. All "Use +// of uninitialized value" warnings from such functions will be suppressed, and +// all values loaded from memory will be considered fully initialized. This +// attribute is similar to the ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS attribute +// above, but deals with initialized-ness rather than addressability issues. // NOTE: MemorySanitizer(msan) is supported by Clang but not GCC. -#if ABSL_HAVE_ATTRIBUTE(no_sanitize_memory) +#if ABSL_HAVE_ATTRIBUTE(no_sanitize_memory) #define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) #else #define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY @@ -235,7 +235,7 @@ // Tells the ThreadSanitizer to not instrument a given function. // NOTE: GCC supports ThreadSanitizer(tsan) since 4.8. // https://gcc.gnu.org/gcc-4.8/changes.html -#if ABSL_HAVE_ATTRIBUTE(no_sanitize_thread) +#if ABSL_HAVE_ATTRIBUTE(no_sanitize_thread) #define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) #else #define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD @@ -247,11 +247,11 @@ // where certain behavior (eg. division by zero) is being used intentionally. // NOTE: GCC supports UndefinedBehaviorSanitizer(ubsan) since 4.9. // https://gcc.gnu.org/gcc-4.9/changes.html -#if ABSL_HAVE_ATTRIBUTE(no_sanitize_undefined) -#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \ - __attribute__((no_sanitize_undefined)) -#elif ABSL_HAVE_ATTRIBUTE(no_sanitize) +#if ABSL_HAVE_ATTRIBUTE(no_sanitize_undefined) #define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \ + __attribute__((no_sanitize_undefined)) +#elif ABSL_HAVE_ATTRIBUTE(no_sanitize) +#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \ __attribute__((no_sanitize("undefined"))) #else #define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED @@ -261,7 +261,7 @@ // // Tells the ControlFlowIntegrity sanitizer to not instrument a given function. // See https://clang.llvm.org/docs/ControlFlowIntegrity.html for details. -#if ABSL_HAVE_ATTRIBUTE(no_sanitize) +#if ABSL_HAVE_ATTRIBUTE(no_sanitize) #define ABSL_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi"))) #else #define ABSL_ATTRIBUTE_NO_SANITIZE_CFI @@ -271,7 +271,7 @@ // // Tells the SafeStack to not instrument a given function. // See https://clang.llvm.org/docs/SafeStack.html for details. -#if ABSL_HAVE_ATTRIBUTE(no_sanitize) +#if ABSL_HAVE_ATTRIBUTE(no_sanitize) #define ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK \ __attribute__((no_sanitize("safe-stack"))) #else @@ -490,10 +490,10 @@ // packages/targets, as this may lead to conflicting definitions of functions at // link-time. // -// XRay isn't currently supported on Android: -// https://github.com/android/ndk/issues/368 +// XRay isn't currently supported on Android: +// https://github.com/android/ndk/issues/368 #if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_always_instrument) && \ - !defined(ABSL_NO_XRAY_ATTRIBUTES) && !defined(__ANDROID__) + !defined(ABSL_NO_XRAY_ATTRIBUTES) && !defined(__ANDROID__) #define ABSL_XRAY_ALWAYS_INSTRUMENT [[clang::xray_always_instrument]] #define ABSL_XRAY_NEVER_INSTRUMENT [[clang::xray_never_instrument]] #if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_log_args) @@ -555,9 +555,9 @@ // ABSL_ATTRIBUTE_PACKED // -// Instructs the compiler not to use natural alignment for a tagged data +// Instructs the compiler not to use natural alignment for a tagged data // structure, but instead to reduce its alignment to 1. -// +// // Therefore, DO NOT APPLY THIS ATTRIBUTE TO STRUCTS CONTAINING ATOMICS. Doing // so can cause atomic variables to be mis-aligned and silently violate // atomicity on x86. @@ -570,10 +570,10 @@ // structure. Instead, apply this attribute only to structure members that need // it. // -// When applying ABSL_ATTRIBUTE_PACKED only to specific structure members the -// natural alignment of structure members not annotated is preserved. Aligned -// member accesses are faster than non-aligned member accesses even if the -// targeted microprocessor supports non-aligned accesses. +// When applying ABSL_ATTRIBUTE_PACKED only to specific structure members the +// natural alignment of structure members not annotated is preserved. Aligned +// member accesses are faster than non-aligned member accesses even if the +// targeted microprocessor supports non-aligned accesses. #if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__)) #define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__)) #else @@ -590,79 +590,79 @@ #define ABSL_ATTRIBUTE_FUNC_ALIGN(bytes) #endif -// ABSL_FALLTHROUGH_INTENDED -// -// Annotates implicit fall-through between switch labels, allowing a case to -// indicate intentional fallthrough and turn off warnings about any lack of a -// `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by -// a semicolon and can be used in most places where `break` can, provided that -// no statements exist between it and the next switch label. -// -// Example: -// -// switch (x) { -// case 40: -// case 41: -// if (truth_is_out_there) { -// ++x; -// ABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations -// // in comments -// } else { -// return x; -// } -// case 42: -// ... -// +// ABSL_FALLTHROUGH_INTENDED +// +// Annotates implicit fall-through between switch labels, allowing a case to +// indicate intentional fallthrough and turn off warnings about any lack of a +// `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by +// a semicolon and can be used in most places where `break` can, provided that +// no statements exist between it and the next switch label. +// +// Example: +// +// switch (x) { +// case 40: +// case 41: +// if (truth_is_out_there) { +// ++x; +// ABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations +// // in comments +// } else { +// return x; +// } +// case 42: +// ... +// // Notes: When supported, GCC and Clang can issue a warning on switch labels // with unannotated fallthrough using the warning `-Wimplicit-fallthrough`. See // clang documentation on language extensions for details: -// https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough -// +// https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough +// // When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro has // no effect on diagnostics. In any case this macro has no effect on runtime -// behavior and performance of code. +// behavior and performance of code. -#ifdef ABSL_FALLTHROUGH_INTENDED -#error "ABSL_FALLTHROUGH_INTENDED should not be defined." +#ifdef ABSL_FALLTHROUGH_INTENDED +#error "ABSL_FALLTHROUGH_INTENDED should not be defined." #elif ABSL_HAVE_CPP_ATTRIBUTE(fallthrough) #define ABSL_FALLTHROUGH_INTENDED [[fallthrough]] #elif ABSL_HAVE_CPP_ATTRIBUTE(clang::fallthrough) -#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] +#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] #elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::fallthrough) -#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] -#else -#define ABSL_FALLTHROUGH_INTENDED \ - do { \ - } while (0) -#endif - -// ABSL_DEPRECATED() -// -// Marks a deprecated class, struct, enum, function, method and variable -// declarations. The macro argument is used as a custom diagnostic message (e.g. -// suggestion of a better alternative). -// -// Examples: -// -// class ABSL_DEPRECATED("Use Bar instead") Foo {...}; -// -// ABSL_DEPRECATED("Use Baz() instead") void Bar() {...} -// -// template <typename T> -// ABSL_DEPRECATED("Use DoThat() instead") -// void DoThis(); -// -// Every usage of a deprecated entity will trigger a warning when compiled with -// clang's `-Wdeprecated-declarations` option. This option is turned off by -// default, but the warnings will be reported by clang-tidy. +#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] +#else +#define ABSL_FALLTHROUGH_INTENDED \ + do { \ + } while (0) +#endif + +// ABSL_DEPRECATED() +// +// Marks a deprecated class, struct, enum, function, method and variable +// declarations. The macro argument is used as a custom diagnostic message (e.g. +// suggestion of a better alternative). +// +// Examples: +// +// class ABSL_DEPRECATED("Use Bar instead") Foo {...}; +// +// ABSL_DEPRECATED("Use Baz() instead") void Bar() {...} +// +// template <typename T> +// ABSL_DEPRECATED("Use DoThat() instead") +// void DoThis(); +// +// Every usage of a deprecated entity will trigger a warning when compiled with +// clang's `-Wdeprecated-declarations` option. This option is turned off by +// default, but the warnings will be reported by clang-tidy. #if defined(__clang__) && defined(__cplusplus) && __cplusplus >= 201103L -#define ABSL_DEPRECATED(message) __attribute__((deprecated(message))) -#endif - -#ifndef ABSL_DEPRECATED -#define ABSL_DEPRECATED(message) -#endif - +#define ABSL_DEPRECATED(message) __attribute__((deprecated(message))) +#endif + +#ifndef ABSL_DEPRECATED +#define ABSL_DEPRECATED(message) +#endif + // ABSL_CONST_INIT // // A variable declaration annotated with the `ABSL_CONST_INIT` attribute will diff --git a/contrib/restricted/abseil-cpp/absl/base/call_once.h b/contrib/restricted/abseil-cpp/absl/base/call_once.h index 96109f537c..8382cb2d1f 100644 --- a/contrib/restricted/abseil-cpp/absl/base/call_once.h +++ b/contrib/restricted/abseil-cpp/absl/base/call_once.h @@ -41,7 +41,7 @@ #include "absl/base/port.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN class once_flag; @@ -175,7 +175,7 @@ void CallOnceImpl(std::atomic<uint32_t>* control, std::memory_order_relaxed) || base_internal::SpinLockWait(control, ABSL_ARRAYSIZE(trans), trans, scheduling_mode) == kOnceInit) { - base_internal::invoke(std::forward<Callable>(fn), + base_internal::invoke(std::forward<Callable>(fn), std::forward<Args>(args)...); old_control = control->exchange(base_internal::kOnceDone, std::memory_order_release); @@ -213,7 +213,7 @@ void call_once(absl::once_flag& flag, Callable&& fn, Args&&... args) { } } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_CALL_ONCE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/casts.h b/contrib/restricted/abseil-cpp/absl/base/casts.h index 83c691265f..eec2f32c5e 100644 --- a/contrib/restricted/abseil-cpp/absl/base/casts.h +++ b/contrib/restricted/abseil-cpp/absl/base/casts.h @@ -34,7 +34,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace internal_casts { @@ -159,19 +159,19 @@ inline Dest bit_cast(const Source& source) { return dest; } -// NOTE: This overload is only picked if the requirements of bit_cast are -// not met. It is therefore UB, but is provided temporarily as previous -// versions of this function template were unchecked. Do not use this in -// new code. +// NOTE: This overload is only picked if the requirements of bit_cast are +// not met. It is therefore UB, but is provided temporarily as previous +// versions of this function template were unchecked. Do not use this in +// new code. template < typename Dest, typename Source, typename std::enable_if< - !internal_casts::is_bitcastable<Dest, Source>::value, - int>::type = 0> + !internal_casts::is_bitcastable<Dest, Source>::value, + int>::type = 0> ABSL_DEPRECATED( - "absl::bit_cast type requirements were violated. Update the types " - "being used such that they are the same size and are both " - "TriviallyCopyable.") + "absl::bit_cast type requirements were violated. Update the types " + "being used such that they are the same size and are both " + "TriviallyCopyable.") inline Dest bit_cast(const Source& source) { static_assert(sizeof(Dest) == sizeof(Source), "Source and destination types should have equal sizes."); @@ -181,7 +181,7 @@ inline Dest bit_cast(const Source& source) { return dest; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_CASTS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/config.h b/contrib/restricted/abseil-cpp/absl/base/config.h index 450d00bc4c..2b3bee4a55 100644 --- a/contrib/restricted/abseil-cpp/absl/base/config.h +++ b/contrib/restricted/abseil-cpp/absl/base/config.h @@ -95,76 +95,76 @@ #define ABSL_LTS_RELEASE_VERSION 20211102 #define ABSL_LTS_RELEASE_PATCH_LEVEL 0 -// Helper macro to convert a CPP variable to a string literal. -#define ABSL_INTERNAL_DO_TOKEN_STR(x) #x -#define ABSL_INTERNAL_TOKEN_STR(x) ABSL_INTERNAL_DO_TOKEN_STR(x) - -// ----------------------------------------------------------------------------- -// Abseil namespace annotations +// Helper macro to convert a CPP variable to a string literal. +#define ABSL_INTERNAL_DO_TOKEN_STR(x) #x +#define ABSL_INTERNAL_TOKEN_STR(x) ABSL_INTERNAL_DO_TOKEN_STR(x) + // ----------------------------------------------------------------------------- - -// ABSL_NAMESPACE_BEGIN/ABSL_NAMESPACE_END -// -// An annotation placed at the beginning/end of each `namespace absl` scope. -// This is used to inject an inline namespace. -// -// The proper way to write Abseil code in the `absl` namespace is: -// -// namespace absl { -// ABSL_NAMESPACE_BEGIN -// -// void Foo(); // absl::Foo(). -// -// ABSL_NAMESPACE_END -// } // namespace absl -// -// Users of Abseil should not use these macros, because users of Abseil should -// not write `namespace absl {` in their own code for any reason. (Abseil does -// not support forward declarations of its own types, nor does it support -// user-provided specialization of Abseil templates. Code that violates these -// rules may be broken without warning.) -#if !defined(ABSL_OPTION_USE_INLINE_NAMESPACE) || \ - !defined(ABSL_OPTION_INLINE_NAMESPACE_NAME) -#error options.h is misconfigured. -#endif - -// Check that ABSL_OPTION_INLINE_NAMESPACE_NAME is neither "head" nor "" -#if defined(__cplusplus) && ABSL_OPTION_USE_INLINE_NAMESPACE == 1 - -#define ABSL_INTERNAL_INLINE_NAMESPACE_STR \ - ABSL_INTERNAL_TOKEN_STR(ABSL_OPTION_INLINE_NAMESPACE_NAME) - -static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != '\0', - "options.h misconfigured: ABSL_OPTION_INLINE_NAMESPACE_NAME must " - "not be empty."); -static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || - ABSL_INTERNAL_INLINE_NAMESPACE_STR[1] != 'e' || - ABSL_INTERNAL_INLINE_NAMESPACE_STR[2] != 'a' || - ABSL_INTERNAL_INLINE_NAMESPACE_STR[3] != 'd' || - ABSL_INTERNAL_INLINE_NAMESPACE_STR[4] != '\0', - "options.h misconfigured: ABSL_OPTION_INLINE_NAMESPACE_NAME must " - "be changed to a new, unique identifier name."); - -#endif - -#if ABSL_OPTION_USE_INLINE_NAMESPACE == 0 -#define ABSL_NAMESPACE_BEGIN -#define ABSL_NAMESPACE_END +// Abseil namespace annotations +// ----------------------------------------------------------------------------- + +// ABSL_NAMESPACE_BEGIN/ABSL_NAMESPACE_END +// +// An annotation placed at the beginning/end of each `namespace absl` scope. +// This is used to inject an inline namespace. +// +// The proper way to write Abseil code in the `absl` namespace is: +// +// namespace absl { +// ABSL_NAMESPACE_BEGIN +// +// void Foo(); // absl::Foo(). +// +// ABSL_NAMESPACE_END +// } // namespace absl +// +// Users of Abseil should not use these macros, because users of Abseil should +// not write `namespace absl {` in their own code for any reason. (Abseil does +// not support forward declarations of its own types, nor does it support +// user-provided specialization of Abseil templates. Code that violates these +// rules may be broken without warning.) +#if !defined(ABSL_OPTION_USE_INLINE_NAMESPACE) || \ + !defined(ABSL_OPTION_INLINE_NAMESPACE_NAME) +#error options.h is misconfigured. +#endif + +// Check that ABSL_OPTION_INLINE_NAMESPACE_NAME is neither "head" nor "" +#if defined(__cplusplus) && ABSL_OPTION_USE_INLINE_NAMESPACE == 1 + +#define ABSL_INTERNAL_INLINE_NAMESPACE_STR \ + ABSL_INTERNAL_TOKEN_STR(ABSL_OPTION_INLINE_NAMESPACE_NAME) + +static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != '\0', + "options.h misconfigured: ABSL_OPTION_INLINE_NAMESPACE_NAME must " + "not be empty."); +static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || + ABSL_INTERNAL_INLINE_NAMESPACE_STR[1] != 'e' || + ABSL_INTERNAL_INLINE_NAMESPACE_STR[2] != 'a' || + ABSL_INTERNAL_INLINE_NAMESPACE_STR[3] != 'd' || + ABSL_INTERNAL_INLINE_NAMESPACE_STR[4] != '\0', + "options.h misconfigured: ABSL_OPTION_INLINE_NAMESPACE_NAME must " + "be changed to a new, unique identifier name."); + +#endif + +#if ABSL_OPTION_USE_INLINE_NAMESPACE == 0 +#define ABSL_NAMESPACE_BEGIN +#define ABSL_NAMESPACE_END #define ABSL_INTERNAL_C_SYMBOL(x) x -#elif ABSL_OPTION_USE_INLINE_NAMESPACE == 1 -#define ABSL_NAMESPACE_BEGIN \ - inline namespace ABSL_OPTION_INLINE_NAMESPACE_NAME { -#define ABSL_NAMESPACE_END } +#elif ABSL_OPTION_USE_INLINE_NAMESPACE == 1 +#define ABSL_NAMESPACE_BEGIN \ + inline namespace ABSL_OPTION_INLINE_NAMESPACE_NAME { +#define ABSL_NAMESPACE_END } #define ABSL_INTERNAL_C_SYMBOL_HELPER_2(x, v) x##_##v #define ABSL_INTERNAL_C_SYMBOL_HELPER_1(x, v) \ ABSL_INTERNAL_C_SYMBOL_HELPER_2(x, v) #define ABSL_INTERNAL_C_SYMBOL(x) \ ABSL_INTERNAL_C_SYMBOL_HELPER_1(x, ABSL_OPTION_INLINE_NAMESPACE_NAME) -#else -#error options.h is misconfigured. -#endif - -// ----------------------------------------------------------------------------- +#else +#error options.h is misconfigured. +#endif + +// ----------------------------------------------------------------------------- // Compiler Feature Checks // ----------------------------------------------------------------------------- @@ -189,12 +189,12 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define ABSL_INTERNAL_HAS_KEYWORD(x) 0 #endif -#ifdef __has_feature -#define ABSL_HAVE_FEATURE(f) __has_feature(f) -#else -#define ABSL_HAVE_FEATURE(f) 0 -#endif - +#ifdef __has_feature +#define ABSL_HAVE_FEATURE(f) __has_feature(f) +#else +#define ABSL_HAVE_FEATURE(f) 0 +#endif + // Portable check for GCC minimum version: // https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html #if defined(__GNUC__) && defined(__GNUC_MINOR__) @@ -285,9 +285,9 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || // * Xcode 9.3 started disallowing `thread_local` for 32-bit iOS simulator // targeting iOS 9.x. // * Xcode 10 moves the deployment target check for iOS < 9.0 to link time -// making ABSL_HAVE_FEATURE unreliable there. +// making ABSL_HAVE_FEATURE unreliable there. // -#if ABSL_HAVE_FEATURE(cxx_thread_local) && \ +#if ABSL_HAVE_FEATURE(cxx_thread_local) && \ !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0) #define ABSL_HAVE_THREAD_LOCAL 1 #endif @@ -365,16 +365,16 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #ifdef ABSL_HAVE_EXCEPTIONS #error ABSL_HAVE_EXCEPTIONS cannot be directly set. #elif ABSL_INTERNAL_HAVE_MIN_CLANG_VERSION(3, 6) -// Clang >= 3.6 -#if ABSL_HAVE_FEATURE(cxx_exceptions) +// Clang >= 3.6 +#if ABSL_HAVE_FEATURE(cxx_exceptions) #define ABSL_HAVE_EXCEPTIONS 1 -#endif // ABSL_HAVE_FEATURE(cxx_exceptions) +#endif // ABSL_HAVE_FEATURE(cxx_exceptions) #elif defined(__clang__) -// Clang < 3.6 -// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro -#if defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions) -#define ABSL_HAVE_EXCEPTIONS 1 -#endif // defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions) +// Clang < 3.6 +// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro +#if defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions) +#define ABSL_HAVE_EXCEPTIONS 1 +#endif // defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions) // Handle remaining special cases and default to exceptions being supported. #elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \ !(ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(5, 0) && \ @@ -533,9 +533,9 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \ (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 50000) || \ + __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 50000) || \ (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 120000)) + __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 120000)) #define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 1 #else #define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 0 @@ -678,83 +678,83 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define ABSL_INTERNAL_MSVC_2017_DBG_MODE #endif -// ABSL_INTERNAL_MANGLED_NS -// ABSL_INTERNAL_MANGLED_BACKREFERENCE -// -// Internal macros for building up mangled names in our internal fork of CCTZ. -// This implementation detail is only needed and provided for the MSVC build. -// -// These macros both expand to string literals. ABSL_INTERNAL_MANGLED_NS is -// the mangled spelling of the `absl` namespace, and -// ABSL_INTERNAL_MANGLED_BACKREFERENCE is a back-reference integer representing -// the proper count to skip past the CCTZ fork namespace names. (This number -// is one larger when there is an inline namespace name to skip.) -#if defined(_MSC_VER) -#if ABSL_OPTION_USE_INLINE_NAMESPACE == 0 -#define ABSL_INTERNAL_MANGLED_NS "absl" -#define ABSL_INTERNAL_MANGLED_BACKREFERENCE "5" -#else -#define ABSL_INTERNAL_MANGLED_NS \ - ABSL_INTERNAL_TOKEN_STR(ABSL_OPTION_INLINE_NAMESPACE_NAME) "@absl" -#define ABSL_INTERNAL_MANGLED_BACKREFERENCE "6" -#endif -#endif - +// ABSL_INTERNAL_MANGLED_NS +// ABSL_INTERNAL_MANGLED_BACKREFERENCE +// +// Internal macros for building up mangled names in our internal fork of CCTZ. +// This implementation detail is only needed and provided for the MSVC build. +// +// These macros both expand to string literals. ABSL_INTERNAL_MANGLED_NS is +// the mangled spelling of the `absl` namespace, and +// ABSL_INTERNAL_MANGLED_BACKREFERENCE is a back-reference integer representing +// the proper count to skip past the CCTZ fork namespace names. (This number +// is one larger when there is an inline namespace name to skip.) +#if defined(_MSC_VER) +#if ABSL_OPTION_USE_INLINE_NAMESPACE == 0 +#define ABSL_INTERNAL_MANGLED_NS "absl" +#define ABSL_INTERNAL_MANGLED_BACKREFERENCE "5" +#else +#define ABSL_INTERNAL_MANGLED_NS \ + ABSL_INTERNAL_TOKEN_STR(ABSL_OPTION_INLINE_NAMESPACE_NAME) "@absl" +#define ABSL_INTERNAL_MANGLED_BACKREFERENCE "6" +#endif +#endif + #undef ABSL_INTERNAL_HAS_KEYWORD -// ABSL_DLL -// -// When building Abseil as a DLL, this macro expands to `__declspec(dllexport)` -// so we can annotate symbols appropriately as being exported. When used in -// headers consuming a DLL, this macro expands to `__declspec(dllimport)` so -// that consumers know the symbol is defined inside the DLL. In all other cases, -// the macro expands to nothing. -#if defined(_MSC_VER) -#if defined(ABSL_BUILD_DLL) -#define ABSL_DLL __declspec(dllexport) -#elif defined(ABSL_CONSUME_DLL) -#define ABSL_DLL __declspec(dllimport) -#else -#define ABSL_DLL -#endif -#else -#define ABSL_DLL -#endif // defined(_MSC_VER) - -// ABSL_HAVE_MEMORY_SANITIZER -// -// MemorySanitizer (MSan) is a detector of uninitialized reads. It consists of -// a compiler instrumentation module and a run-time library. -#ifdef ABSL_HAVE_MEMORY_SANITIZER -#error "ABSL_HAVE_MEMORY_SANITIZER cannot be directly set." -#elif defined(__SANITIZE_MEMORY__) -#define ABSL_HAVE_MEMORY_SANITIZER 1 -#elif !defined(__native_client__) && ABSL_HAVE_FEATURE(memory_sanitizer) -#define ABSL_HAVE_MEMORY_SANITIZER 1 -#endif - -// ABSL_HAVE_THREAD_SANITIZER -// -// ThreadSanitizer (TSan) is a fast data race detector. -#ifdef ABSL_HAVE_THREAD_SANITIZER -#error "ABSL_HAVE_THREAD_SANITIZER cannot be directly set." -#elif defined(__SANITIZE_THREAD__) -#define ABSL_HAVE_THREAD_SANITIZER 1 -#elif ABSL_HAVE_FEATURE(thread_sanitizer) -#define ABSL_HAVE_THREAD_SANITIZER 1 -#endif - -// ABSL_HAVE_ADDRESS_SANITIZER -// -// AddressSanitizer (ASan) is a fast memory error detector. -#ifdef ABSL_HAVE_ADDRESS_SANITIZER -#error "ABSL_HAVE_ADDRESS_SANITIZER cannot be directly set." -#elif defined(__SANITIZE_ADDRESS__) -#define ABSL_HAVE_ADDRESS_SANITIZER 1 -#elif ABSL_HAVE_FEATURE(address_sanitizer) -#define ABSL_HAVE_ADDRESS_SANITIZER 1 -#endif - +// ABSL_DLL +// +// When building Abseil as a DLL, this macro expands to `__declspec(dllexport)` +// so we can annotate symbols appropriately as being exported. When used in +// headers consuming a DLL, this macro expands to `__declspec(dllimport)` so +// that consumers know the symbol is defined inside the DLL. In all other cases, +// the macro expands to nothing. +#if defined(_MSC_VER) +#if defined(ABSL_BUILD_DLL) +#define ABSL_DLL __declspec(dllexport) +#elif defined(ABSL_CONSUME_DLL) +#define ABSL_DLL __declspec(dllimport) +#else +#define ABSL_DLL +#endif +#else +#define ABSL_DLL +#endif // defined(_MSC_VER) + +// ABSL_HAVE_MEMORY_SANITIZER +// +// MemorySanitizer (MSan) is a detector of uninitialized reads. It consists of +// a compiler instrumentation module and a run-time library. +#ifdef ABSL_HAVE_MEMORY_SANITIZER +#error "ABSL_HAVE_MEMORY_SANITIZER cannot be directly set." +#elif defined(__SANITIZE_MEMORY__) +#define ABSL_HAVE_MEMORY_SANITIZER 1 +#elif !defined(__native_client__) && ABSL_HAVE_FEATURE(memory_sanitizer) +#define ABSL_HAVE_MEMORY_SANITIZER 1 +#endif + +// ABSL_HAVE_THREAD_SANITIZER +// +// ThreadSanitizer (TSan) is a fast data race detector. +#ifdef ABSL_HAVE_THREAD_SANITIZER +#error "ABSL_HAVE_THREAD_SANITIZER cannot be directly set." +#elif defined(__SANITIZE_THREAD__) +#define ABSL_HAVE_THREAD_SANITIZER 1 +#elif ABSL_HAVE_FEATURE(thread_sanitizer) +#define ABSL_HAVE_THREAD_SANITIZER 1 +#endif + +// ABSL_HAVE_ADDRESS_SANITIZER +// +// AddressSanitizer (ASan) is a fast memory error detector. +#ifdef ABSL_HAVE_ADDRESS_SANITIZER +#error "ABSL_HAVE_ADDRESS_SANITIZER cannot be directly set." +#elif defined(__SANITIZE_ADDRESS__) +#define ABSL_HAVE_ADDRESS_SANITIZER 1 +#elif ABSL_HAVE_FEATURE(address_sanitizer) +#define ABSL_HAVE_ADDRESS_SANITIZER 1 +#endif + // ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION // // Class template argument deduction is a language feature added in C++17. diff --git a/contrib/restricted/abseil-cpp/absl/base/const_init.h b/contrib/restricted/abseil-cpp/absl/base/const_init.h index 16520b61d9..946b6f5339 100644 --- a/contrib/restricted/abseil-cpp/absl/base/const_init.h +++ b/contrib/restricted/abseil-cpp/absl/base/const_init.h @@ -22,8 +22,8 @@ #ifndef ABSL_BASE_CONST_INIT_H_ #define ABSL_BASE_CONST_INIT_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + // In general, objects with static storage duration (such as global variables) // can trigger tricky object lifetime situations. Attempting to access them // from the constructors or destructors of other global objects can result in @@ -64,13 +64,13 @@ // or thread_local storage duration. namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN enum ConstInitType { kConstInit, }; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_CONST_INIT_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/dynamic_annotations.h b/contrib/restricted/abseil-cpp/absl/base/dynamic_annotations.h index 3ea7c1568c..fe8b087b51 100644 --- a/contrib/restricted/abseil-cpp/absl/base/dynamic_annotations.h +++ b/contrib/restricted/abseil-cpp/absl/base/dynamic_annotations.h @@ -1,471 +1,471 @@ -// Copyright 2017 The Abseil Authors. -// -// 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 -// -// https://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. - -// This file defines dynamic annotations for use with dynamic analysis tool -// such as valgrind, PIN, etc. -// -// Dynamic annotation is a source code annotation that affects the generated -// code (that is, the annotation is not a comment). Each such annotation is -// attached to a particular instruction and/or to a particular object (address) -// in the program. -// -// The annotations that should be used by users are macros in all upper-case -// (e.g., ABSL_ANNOTATE_THREAD_NAME). -// -// Actual implementation of these macros may differ depending on the dynamic -// analysis tool being used. -// -// This file supports the following configurations: -// - Dynamic Annotations enabled (with static thread-safety warnings disabled). -// In this case, macros expand to functions implemented by Thread Sanitizer, -// when building with TSan. When not provided an external implementation, -// dynamic_annotations.cc provides no-op implementations. -// -// - Static Clang thread-safety warnings enabled. -// When building with a Clang compiler that supports thread-safety warnings, -// a subset of annotations can be statically-checked at compile-time. We -// expand these macros to static-inline functions that can be analyzed for -// thread-safety, but afterwards elided when building the final binary. -// -// - All annotations are disabled. -// If neither Dynamic Annotations nor Clang thread-safety warnings are -// enabled, then all annotation-macros expand to empty. - -#ifndef ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ -#define ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ - -#include <stddef.h> - -#include "absl/base/attributes.h" -#include "absl/base/config.h" -#ifdef __cplusplus -#include "absl/base/macros.h" -#endif - -// TODO(rogeeff): Remove after the backward compatibility period. -#include "absl/base/internal/dynamic_annotations.h" // IWYU pragma: export - -// ------------------------------------------------------------------------- -// Decide which features are enabled. - -#ifdef ABSL_HAVE_THREAD_SANITIZER - -#define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 1 -#define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 1 -#define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 1 -#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0 -#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED 1 - -#else - -#define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 0 -#define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 0 -#define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 0 - -// Clang provides limited support for static thread-safety analysis through a -// feature called Annotalysis. We configure macro-definitions according to -// whether Annotalysis support is available. When running in opt-mode, GCC -// will issue a warning, if these attributes are compiled. Only include them -// when compiling using Clang. - -#if defined(__clang__) -#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 1 -#if !defined(SWIG) -#define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 1 -#endif -#else -#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0 -#endif - -// Read/write annotations are enabled in Annotalysis mode; disabled otherwise. -#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED \ - ABSL_INTERNAL_ANNOTALYSIS_ENABLED - -#endif // ABSL_HAVE_THREAD_SANITIZER - -#ifdef __cplusplus -#define ABSL_INTERNAL_BEGIN_EXTERN_C extern "C" { -#define ABSL_INTERNAL_END_EXTERN_C } // extern "C" -#define ABSL_INTERNAL_GLOBAL_SCOPED(F) ::F -#define ABSL_INTERNAL_STATIC_INLINE inline -#else -#define ABSL_INTERNAL_BEGIN_EXTERN_C // empty -#define ABSL_INTERNAL_END_EXTERN_C // empty -#define ABSL_INTERNAL_GLOBAL_SCOPED(F) F -#define ABSL_INTERNAL_STATIC_INLINE static inline +// Copyright 2017 The Abseil Authors. +// +// 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 +// +// https://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. + +// This file defines dynamic annotations for use with dynamic analysis tool +// such as valgrind, PIN, etc. +// +// Dynamic annotation is a source code annotation that affects the generated +// code (that is, the annotation is not a comment). Each such annotation is +// attached to a particular instruction and/or to a particular object (address) +// in the program. +// +// The annotations that should be used by users are macros in all upper-case +// (e.g., ABSL_ANNOTATE_THREAD_NAME). +// +// Actual implementation of these macros may differ depending on the dynamic +// analysis tool being used. +// +// This file supports the following configurations: +// - Dynamic Annotations enabled (with static thread-safety warnings disabled). +// In this case, macros expand to functions implemented by Thread Sanitizer, +// when building with TSan. When not provided an external implementation, +// dynamic_annotations.cc provides no-op implementations. +// +// - Static Clang thread-safety warnings enabled. +// When building with a Clang compiler that supports thread-safety warnings, +// a subset of annotations can be statically-checked at compile-time. We +// expand these macros to static-inline functions that can be analyzed for +// thread-safety, but afterwards elided when building the final binary. +// +// - All annotations are disabled. +// If neither Dynamic Annotations nor Clang thread-safety warnings are +// enabled, then all annotation-macros expand to empty. + +#ifndef ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ +#define ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ + +#include <stddef.h> + +#include "absl/base/attributes.h" +#include "absl/base/config.h" +#ifdef __cplusplus +#include "absl/base/macros.h" +#endif + +// TODO(rogeeff): Remove after the backward compatibility period. +#include "absl/base/internal/dynamic_annotations.h" // IWYU pragma: export + +// ------------------------------------------------------------------------- +// Decide which features are enabled. + +#ifdef ABSL_HAVE_THREAD_SANITIZER + +#define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 1 +#define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 1 +#define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 1 +#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0 +#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED 1 + +#else + +#define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 0 +#define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 0 +#define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 0 + +// Clang provides limited support for static thread-safety analysis through a +// feature called Annotalysis. We configure macro-definitions according to +// whether Annotalysis support is available. When running in opt-mode, GCC +// will issue a warning, if these attributes are compiled. Only include them +// when compiling using Clang. + +#if defined(__clang__) +#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 1 +#if !defined(SWIG) +#define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 1 #endif - -// ------------------------------------------------------------------------- -// Define race annotations. - -#if ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 1 +#else +#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0 +#endif + +// Read/write annotations are enabled in Annotalysis mode; disabled otherwise. +#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED \ + ABSL_INTERNAL_ANNOTALYSIS_ENABLED + +#endif // ABSL_HAVE_THREAD_SANITIZER + +#ifdef __cplusplus +#define ABSL_INTERNAL_BEGIN_EXTERN_C extern "C" { +#define ABSL_INTERNAL_END_EXTERN_C } // extern "C" +#define ABSL_INTERNAL_GLOBAL_SCOPED(F) ::F +#define ABSL_INTERNAL_STATIC_INLINE inline +#else +#define ABSL_INTERNAL_BEGIN_EXTERN_C // empty +#define ABSL_INTERNAL_END_EXTERN_C // empty +#define ABSL_INTERNAL_GLOBAL_SCOPED(F) F +#define ABSL_INTERNAL_STATIC_INLINE static inline +#endif + +// ------------------------------------------------------------------------- +// Define race annotations. + +#if ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 1 // Some of the symbols used in this section (e.g. AnnotateBenignRaceSized) are // defined by the compiler-based santizer implementation, not by the Abseil // library. Therefore they do not use ABSL_INTERNAL_C_SYMBOL. -// ------------------------------------------------------------- -// Annotations that suppress errors. It is usually better to express the -// program's synchronization using the other annotations, but these can be used -// when all else fails. - -// Report that we may have a benign race at `pointer`, with size -// "sizeof(*(pointer))". `pointer` must be a non-void* pointer. Insert at the -// point where `pointer` has been allocated, preferably close to the point -// where the race happens. See also ABSL_ANNOTATE_BENIGN_RACE_STATIC. -#define ABSL_ANNOTATE_BENIGN_RACE(pointer, description) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \ - (__FILE__, __LINE__, pointer, sizeof(*(pointer)), description) - -// Same as ABSL_ANNOTATE_BENIGN_RACE(`address`, `description`), but applies to -// the memory range [`address`, `address`+`size`). -#define ABSL_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \ - (__FILE__, __LINE__, address, size, description) - -// Enable (`enable`!=0) or disable (`enable`==0) race detection for all threads. -// This annotation could be useful if you want to skip expensive race analysis -// during some period of program execution, e.g. during initialization. -#define ABSL_ANNOTATE_ENABLE_RACE_DETECTION(enable) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateEnableRaceDetection) \ - (__FILE__, __LINE__, enable) - -// ------------------------------------------------------------- -// Annotations useful for debugging. - -// Report the current thread `name` to a race detector. -#define ABSL_ANNOTATE_THREAD_NAME(name) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateThreadName)(__FILE__, __LINE__, name) - -// ------------------------------------------------------------- -// Annotations useful when implementing locks. They are not normally needed by -// modules that merely use locks. The `lock` argument is a pointer to the lock -// object. - -// Report that a lock has been created at address `lock`. -#define ABSL_ANNOTATE_RWLOCK_CREATE(lock) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreate)(__FILE__, __LINE__, lock) - -// Report that a linker initialized lock has been created at address `lock`. -#ifdef ABSL_HAVE_THREAD_SANITIZER -#define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreateStatic) \ - (__FILE__, __LINE__, lock) +// ------------------------------------------------------------- +// Annotations that suppress errors. It is usually better to express the +// program's synchronization using the other annotations, but these can be used +// when all else fails. + +// Report that we may have a benign race at `pointer`, with size +// "sizeof(*(pointer))". `pointer` must be a non-void* pointer. Insert at the +// point where `pointer` has been allocated, preferably close to the point +// where the race happens. See also ABSL_ANNOTATE_BENIGN_RACE_STATIC. +#define ABSL_ANNOTATE_BENIGN_RACE(pointer, description) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \ + (__FILE__, __LINE__, pointer, sizeof(*(pointer)), description) + +// Same as ABSL_ANNOTATE_BENIGN_RACE(`address`, `description`), but applies to +// the memory range [`address`, `address`+`size`). +#define ABSL_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \ + (__FILE__, __LINE__, address, size, description) + +// Enable (`enable`!=0) or disable (`enable`==0) race detection for all threads. +// This annotation could be useful if you want to skip expensive race analysis +// during some period of program execution, e.g. during initialization. +#define ABSL_ANNOTATE_ENABLE_RACE_DETECTION(enable) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateEnableRaceDetection) \ + (__FILE__, __LINE__, enable) + +// ------------------------------------------------------------- +// Annotations useful for debugging. + +// Report the current thread `name` to a race detector. +#define ABSL_ANNOTATE_THREAD_NAME(name) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateThreadName)(__FILE__, __LINE__, name) + +// ------------------------------------------------------------- +// Annotations useful when implementing locks. They are not normally needed by +// modules that merely use locks. The `lock` argument is a pointer to the lock +// object. + +// Report that a lock has been created at address `lock`. +#define ABSL_ANNOTATE_RWLOCK_CREATE(lock) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreate)(__FILE__, __LINE__, lock) + +// Report that a linker initialized lock has been created at address `lock`. +#ifdef ABSL_HAVE_THREAD_SANITIZER +#define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreateStatic) \ + (__FILE__, __LINE__, lock) #else -#define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ - ABSL_ANNOTATE_RWLOCK_CREATE(lock) +#define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ + ABSL_ANNOTATE_RWLOCK_CREATE(lock) #endif -// Report that the lock at address `lock` is about to be destroyed. -#define ABSL_ANNOTATE_RWLOCK_DESTROY(lock) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockDestroy)(__FILE__, __LINE__, lock) - -// Report that the lock at address `lock` has been acquired. -// `is_w`=1 for writer lock, `is_w`=0 for reader lock. -#define ABSL_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockAcquired) \ - (__FILE__, __LINE__, lock, is_w) - -// Report that the lock at address `lock` is about to be released. -// `is_w`=1 for writer lock, `is_w`=0 for reader lock. -#define ABSL_ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockReleased) \ - (__FILE__, __LINE__, lock, is_w) - -// Apply ABSL_ANNOTATE_BENIGN_RACE_SIZED to a static variable `static_var`. -#define ABSL_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ - namespace { \ - class static_var##_annotator { \ - public: \ - static_var##_annotator() { \ - ABSL_ANNOTATE_BENIGN_RACE_SIZED(&static_var, sizeof(static_var), \ - #static_var ": " description); \ - } \ - }; \ - static static_var##_annotator the##static_var##_annotator; \ - } // namespace - -// Function prototypes of annotations provided by the compiler-based sanitizer -// implementation. -ABSL_INTERNAL_BEGIN_EXTERN_C -void AnnotateRWLockCreate(const char* file, int line, - const volatile void* lock); -void AnnotateRWLockCreateStatic(const char* file, int line, - const volatile void* lock); -void AnnotateRWLockDestroy(const char* file, int line, - const volatile void* lock); -void AnnotateRWLockAcquired(const char* file, int line, - const volatile void* lock, long is_w); // NOLINT -void AnnotateRWLockReleased(const char* file, int line, - const volatile void* lock, long is_w); // NOLINT -void AnnotateBenignRace(const char* file, int line, - const volatile void* address, const char* description); -void AnnotateBenignRaceSized(const char* file, int line, - const volatile void* address, size_t size, - const char* description); -void AnnotateThreadName(const char* file, int line, const char* name); -void AnnotateEnableRaceDetection(const char* file, int line, int enable); -ABSL_INTERNAL_END_EXTERN_C - -#else // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 0 - -#define ABSL_ANNOTATE_RWLOCK_CREATE(lock) // empty -#define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) // empty -#define ABSL_ANNOTATE_RWLOCK_DESTROY(lock) // empty -#define ABSL_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) // empty -#define ABSL_ANNOTATE_RWLOCK_RELEASED(lock, is_w) // empty -#define ABSL_ANNOTATE_BENIGN_RACE(address, description) // empty -#define ABSL_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) // empty -#define ABSL_ANNOTATE_THREAD_NAME(name) // empty -#define ABSL_ANNOTATE_ENABLE_RACE_DETECTION(enable) // empty -#define ABSL_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) // empty - -#endif // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED - -// ------------------------------------------------------------------------- -// Define memory annotations. - -#ifdef ABSL_HAVE_MEMORY_SANITIZER - -#include <sanitizer/msan_interface.h> - -#define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ - __msan_unpoison(address, size) - -#define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ - __msan_allocated_memory(address, size) - -#else // !defined(ABSL_HAVE_MEMORY_SANITIZER) - -// TODO(rogeeff): remove this branch -#ifdef ABSL_HAVE_THREAD_SANITIZER -#define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ - do { \ - (void)(address); \ - (void)(size); \ - } while (0) -#define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ - do { \ - (void)(address); \ - (void)(size); \ - } while (0) +// Report that the lock at address `lock` is about to be destroyed. +#define ABSL_ANNOTATE_RWLOCK_DESTROY(lock) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockDestroy)(__FILE__, __LINE__, lock) + +// Report that the lock at address `lock` has been acquired. +// `is_w`=1 for writer lock, `is_w`=0 for reader lock. +#define ABSL_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockAcquired) \ + (__FILE__, __LINE__, lock, is_w) + +// Report that the lock at address `lock` is about to be released. +// `is_w`=1 for writer lock, `is_w`=0 for reader lock. +#define ABSL_ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockReleased) \ + (__FILE__, __LINE__, lock, is_w) + +// Apply ABSL_ANNOTATE_BENIGN_RACE_SIZED to a static variable `static_var`. +#define ABSL_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ + namespace { \ + class static_var##_annotator { \ + public: \ + static_var##_annotator() { \ + ABSL_ANNOTATE_BENIGN_RACE_SIZED(&static_var, sizeof(static_var), \ + #static_var ": " description); \ + } \ + }; \ + static static_var##_annotator the##static_var##_annotator; \ + } // namespace + +// Function prototypes of annotations provided by the compiler-based sanitizer +// implementation. +ABSL_INTERNAL_BEGIN_EXTERN_C +void AnnotateRWLockCreate(const char* file, int line, + const volatile void* lock); +void AnnotateRWLockCreateStatic(const char* file, int line, + const volatile void* lock); +void AnnotateRWLockDestroy(const char* file, int line, + const volatile void* lock); +void AnnotateRWLockAcquired(const char* file, int line, + const volatile void* lock, long is_w); // NOLINT +void AnnotateRWLockReleased(const char* file, int line, + const volatile void* lock, long is_w); // NOLINT +void AnnotateBenignRace(const char* file, int line, + const volatile void* address, const char* description); +void AnnotateBenignRaceSized(const char* file, int line, + const volatile void* address, size_t size, + const char* description); +void AnnotateThreadName(const char* file, int line, const char* name); +void AnnotateEnableRaceDetection(const char* file, int line, int enable); +ABSL_INTERNAL_END_EXTERN_C + +#else // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 0 + +#define ABSL_ANNOTATE_RWLOCK_CREATE(lock) // empty +#define ABSL_ANNOTATE_RWLOCK_CREATE_STATIC(lock) // empty +#define ABSL_ANNOTATE_RWLOCK_DESTROY(lock) // empty +#define ABSL_ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) // empty +#define ABSL_ANNOTATE_RWLOCK_RELEASED(lock, is_w) // empty +#define ABSL_ANNOTATE_BENIGN_RACE(address, description) // empty +#define ABSL_ANNOTATE_BENIGN_RACE_SIZED(address, size, description) // empty +#define ABSL_ANNOTATE_THREAD_NAME(name) // empty +#define ABSL_ANNOTATE_ENABLE_RACE_DETECTION(enable) // empty +#define ABSL_ANNOTATE_BENIGN_RACE_STATIC(static_var, description) // empty + +#endif // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED + +// ------------------------------------------------------------------------- +// Define memory annotations. + +#ifdef ABSL_HAVE_MEMORY_SANITIZER + +#include <sanitizer/msan_interface.h> + +#define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ + __msan_unpoison(address, size) + +#define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ + __msan_allocated_memory(address, size) + +#else // !defined(ABSL_HAVE_MEMORY_SANITIZER) + +// TODO(rogeeff): remove this branch +#ifdef ABSL_HAVE_THREAD_SANITIZER +#define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ + do { \ + (void)(address); \ + (void)(size); \ + } while (0) +#define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ + do { \ + (void)(address); \ + (void)(size); \ + } while (0) #else -#define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) // empty -#define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) // empty - +#define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) // empty +#define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) // empty + #endif -#endif // ABSL_HAVE_MEMORY_SANITIZER +#endif // ABSL_HAVE_MEMORY_SANITIZER -// ------------------------------------------------------------------------- -// Define IGNORE_READS_BEGIN/_END attributes. +// ------------------------------------------------------------------------- +// Define IGNORE_READS_BEGIN/_END attributes. -#if defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) +#if defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) -#define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE \ - __attribute((exclusive_lock_function("*"))) -#define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE \ - __attribute((unlock_function("*"))) +#define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE \ + __attribute((exclusive_lock_function("*"))) +#define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE \ + __attribute((unlock_function("*"))) -#else // !defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) +#else // !defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) -#define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE // empty -#define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE // empty +#define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE // empty +#define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE // empty -#endif // defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) +#endif // defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) -// ------------------------------------------------------------------------- -// Define IGNORE_READS_BEGIN/_END annotations. +// ------------------------------------------------------------------------- +// Define IGNORE_READS_BEGIN/_END annotations. -#if ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED == 1 +#if ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED == 1 // Some of the symbols used in this section (e.g. AnnotateIgnoreReadsBegin) are // defined by the compiler-based implementation, not by the Abseil // library. Therefore they do not use ABSL_INTERNAL_C_SYMBOL. -// Request the analysis tool to ignore all reads in the current thread until -// ABSL_ANNOTATE_IGNORE_READS_END is called. Useful to ignore intentional racey -// reads, while still checking other reads and all writes. -// See also ABSL_ANNOTATE_UNPROTECTED_READ. +// Request the analysis tool to ignore all reads in the current thread until +// ABSL_ANNOTATE_IGNORE_READS_END is called. Useful to ignore intentional racey +// reads, while still checking other reads and all writes. +// See also ABSL_ANNOTATE_UNPROTECTED_READ. #define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsBegin) \ (__FILE__, __LINE__) -// Stop ignoring reads. +// Stop ignoring reads. #define ABSL_ANNOTATE_IGNORE_READS_END() \ ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsEnd) \ (__FILE__, __LINE__) -// Function prototypes of annotations provided by the compiler-based sanitizer -// implementation. -ABSL_INTERNAL_BEGIN_EXTERN_C -void AnnotateIgnoreReadsBegin(const char* file, int line) - ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE; -void AnnotateIgnoreReadsEnd(const char* file, - int line) ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE; -ABSL_INTERNAL_END_EXTERN_C +// Function prototypes of annotations provided by the compiler-based sanitizer +// implementation. +ABSL_INTERNAL_BEGIN_EXTERN_C +void AnnotateIgnoreReadsBegin(const char* file, int line) + ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE; +void AnnotateIgnoreReadsEnd(const char* file, + int line) ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE; +ABSL_INTERNAL_END_EXTERN_C -#elif defined(ABSL_INTERNAL_ANNOTALYSIS_ENABLED) +#elif defined(ABSL_INTERNAL_ANNOTALYSIS_ENABLED) -// When Annotalysis is enabled without Dynamic Annotations, the use of -// static-inline functions allows the annotations to be read at compile-time, -// while still letting the compiler elide the functions from the final build. -// -// TODO(delesley) -- The exclusive lock here ignores writes as well, but -// allows IGNORE_READS_AND_WRITES to work properly. +// When Annotalysis is enabled without Dynamic Annotations, the use of +// static-inline functions allows the annotations to be read at compile-time, +// while still letting the compiler elide the functions from the final build. +// +// TODO(delesley) -- The exclusive lock here ignores writes as well, but +// allows IGNORE_READS_AND_WRITES to work properly. #define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ ABSL_INTERNAL_GLOBAL_SCOPED( \ ABSL_INTERNAL_C_SYMBOL(AbslInternalAnnotateIgnoreReadsBegin)) \ () - + #define ABSL_ANNOTATE_IGNORE_READS_END() \ ABSL_INTERNAL_GLOBAL_SCOPED( \ ABSL_INTERNAL_C_SYMBOL(AbslInternalAnnotateIgnoreReadsEnd)) \ () - + ABSL_INTERNAL_STATIC_INLINE void ABSL_INTERNAL_C_SYMBOL( AbslInternalAnnotateIgnoreReadsBegin)() - ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE {} - + ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE {} + ABSL_INTERNAL_STATIC_INLINE void ABSL_INTERNAL_C_SYMBOL( AbslInternalAnnotateIgnoreReadsEnd)() - ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE {} - + ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE {} + #else -#define ABSL_ANNOTATE_IGNORE_READS_BEGIN() // empty -#define ABSL_ANNOTATE_IGNORE_READS_END() // empty - +#define ABSL_ANNOTATE_IGNORE_READS_BEGIN() // empty +#define ABSL_ANNOTATE_IGNORE_READS_END() // empty + #endif -// ------------------------------------------------------------------------- -// Define IGNORE_WRITES_BEGIN/_END annotations. - -#if ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED == 1 - -// Similar to ABSL_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead. -#define ABSL_ANNOTATE_IGNORE_WRITES_BEGIN() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesBegin)(__FILE__, __LINE__) - -// Stop ignoring writes. -#define ABSL_ANNOTATE_IGNORE_WRITES_END() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesEnd)(__FILE__, __LINE__) - -// Function prototypes of annotations provided by the compiler-based sanitizer -// implementation. -ABSL_INTERNAL_BEGIN_EXTERN_C -void AnnotateIgnoreWritesBegin(const char* file, int line); -void AnnotateIgnoreWritesEnd(const char* file, int line); -ABSL_INTERNAL_END_EXTERN_C - -#else - -#define ABSL_ANNOTATE_IGNORE_WRITES_BEGIN() // empty -#define ABSL_ANNOTATE_IGNORE_WRITES_END() // empty - +// ------------------------------------------------------------------------- +// Define IGNORE_WRITES_BEGIN/_END annotations. + +#if ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED == 1 + +// Similar to ABSL_ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead. +#define ABSL_ANNOTATE_IGNORE_WRITES_BEGIN() \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesBegin)(__FILE__, __LINE__) + +// Stop ignoring writes. +#define ABSL_ANNOTATE_IGNORE_WRITES_END() \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesEnd)(__FILE__, __LINE__) + +// Function prototypes of annotations provided by the compiler-based sanitizer +// implementation. +ABSL_INTERNAL_BEGIN_EXTERN_C +void AnnotateIgnoreWritesBegin(const char* file, int line); +void AnnotateIgnoreWritesEnd(const char* file, int line); +ABSL_INTERNAL_END_EXTERN_C + +#else + +#define ABSL_ANNOTATE_IGNORE_WRITES_BEGIN() // empty +#define ABSL_ANNOTATE_IGNORE_WRITES_END() // empty + #endif -// ------------------------------------------------------------------------- -// Define the ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more -// primitive annotations defined above. -// -// Instead of doing -// ABSL_ANNOTATE_IGNORE_READS_BEGIN(); -// ... = x; -// ABSL_ANNOTATE_IGNORE_READS_END(); -// one can use -// ... = ABSL_ANNOTATE_UNPROTECTED_READ(x); - -#if defined(ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED) - -// Start ignoring all memory accesses (both reads and writes). -#define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ - do { \ - ABSL_ANNOTATE_IGNORE_READS_BEGIN(); \ - ABSL_ANNOTATE_IGNORE_WRITES_BEGIN(); \ - } while (0) - -// Stop ignoring both reads and writes. -#define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END() \ - do { \ - ABSL_ANNOTATE_IGNORE_WRITES_END(); \ - ABSL_ANNOTATE_IGNORE_READS_END(); \ - } while (0) +// ------------------------------------------------------------------------- +// Define the ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more +// primitive annotations defined above. +// +// Instead of doing +// ABSL_ANNOTATE_IGNORE_READS_BEGIN(); +// ... = x; +// ABSL_ANNOTATE_IGNORE_READS_END(); +// one can use +// ... = ABSL_ANNOTATE_UNPROTECTED_READ(x); + +#if defined(ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED) + +// Start ignoring all memory accesses (both reads and writes). +#define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ + do { \ + ABSL_ANNOTATE_IGNORE_READS_BEGIN(); \ + ABSL_ANNOTATE_IGNORE_WRITES_BEGIN(); \ + } while (0) + +// Stop ignoring both reads and writes. +#define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END() \ + do { \ + ABSL_ANNOTATE_IGNORE_WRITES_END(); \ + ABSL_ANNOTATE_IGNORE_READS_END(); \ + } while (0) #ifdef __cplusplus -// ABSL_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. -#define ABSL_ANNOTATE_UNPROTECTED_READ(x) \ - absl::base_internal::AnnotateUnprotectedRead(x) +// ABSL_ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. +#define ABSL_ANNOTATE_UNPROTECTED_READ(x) \ + absl::base_internal::AnnotateUnprotectedRead(x) -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace base_internal { +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace base_internal { template <typename T> -inline T AnnotateUnprotectedRead(const volatile T& x) { // NOLINT - ABSL_ANNOTATE_IGNORE_READS_BEGIN(); +inline T AnnotateUnprotectedRead(const volatile T& x) { // NOLINT + ABSL_ANNOTATE_IGNORE_READS_BEGIN(); T res = x; - ABSL_ANNOTATE_IGNORE_READS_END(); + ABSL_ANNOTATE_IGNORE_READS_END(); return res; -} - -} // namespace base_internal -ABSL_NAMESPACE_END -} // namespace absl -#endif - +} + +} // namespace base_internal +ABSL_NAMESPACE_END +} // namespace absl +#endif + #else - -#define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() // empty -#define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END() // empty -#define ABSL_ANNOTATE_UNPROTECTED_READ(x) (x) - + +#define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() // empty +#define ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END() // empty +#define ABSL_ANNOTATE_UNPROTECTED_READ(x) (x) + #endif -// ------------------------------------------------------------------------- -// Address sanitizer annotations - -#ifdef ABSL_HAVE_ADDRESS_SANITIZER -// Describe the current state of a contiguous container such as e.g. -// std::vector or std::string. For more details see -// sanitizer/common_interface_defs.h, which is provided by the compiler. +// ------------------------------------------------------------------------- +// Address sanitizer annotations + +#ifdef ABSL_HAVE_ADDRESS_SANITIZER +// Describe the current state of a contiguous container such as e.g. +// std::vector or std::string. For more details see +// sanitizer/common_interface_defs.h, which is provided by the compiler. #include <sanitizer/common_interface_defs.h> - -#define ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \ + +#define ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \ __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid) -#define ABSL_ADDRESS_SANITIZER_REDZONE(name) \ - struct { \ +#define ABSL_ADDRESS_SANITIZER_REDZONE(name) \ + struct { \ alignas(8) char x[8]; \ - } name - + } name + #else -#define ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) // empty -#define ABSL_ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "") - -#endif // ABSL_HAVE_ADDRESS_SANITIZER - -// ------------------------------------------------------------------------- -// Undefine the macros intended only for this file. - -#undef ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED -#undef ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED -#undef ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED -#undef ABSL_INTERNAL_ANNOTALYSIS_ENABLED -#undef ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED -#undef ABSL_INTERNAL_BEGIN_EXTERN_C -#undef ABSL_INTERNAL_END_EXTERN_C -#undef ABSL_INTERNAL_STATIC_INLINE - -#endif // ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ +#define ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) // empty +#define ABSL_ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "") + +#endif // ABSL_HAVE_ADDRESS_SANITIZER + +// ------------------------------------------------------------------------- +// Undefine the macros intended only for this file. + +#undef ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED +#undef ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED +#undef ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED +#undef ABSL_INTERNAL_ANNOTALYSIS_ENABLED +#undef ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED +#undef ABSL_INTERNAL_BEGIN_EXTERN_C +#undef ABSL_INTERNAL_END_EXTERN_C +#undef ABSL_INTERNAL_STATIC_INLINE + +#endif // ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/atomic_hook.h b/contrib/restricted/abseil-cpp/absl/base/internal/atomic_hook.h index ae21cd7fe5..7e5021b189 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/atomic_hook.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/atomic_hook.h @@ -20,37 +20,37 @@ #include <cstdint> #include <utility> -#include "absl/base/attributes.h" -#include "absl/base/config.h" - -#if defined(_MSC_VER) && !defined(__clang__) +#include "absl/base/attributes.h" +#include "absl/base/config.h" + +#if defined(_MSC_VER) && !defined(__clang__) #define ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT 0 #else #define ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT 1 #endif -#if defined(_MSC_VER) -#define ABSL_HAVE_WORKING_ATOMIC_POINTER 0 -#else -#define ABSL_HAVE_WORKING_ATOMIC_POINTER 1 -#endif - +#if defined(_MSC_VER) +#define ABSL_HAVE_WORKING_ATOMIC_POINTER 0 +#else +#define ABSL_HAVE_WORKING_ATOMIC_POINTER 1 +#endif + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { template <typename T> class AtomicHook; -// To workaround AtomicHook not being constant-initializable on some platforms, -// prefer to annotate instances with `ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES` -// instead of `ABSL_CONST_INIT`. -#if ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT -#define ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES ABSL_CONST_INIT -#else -#define ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES -#endif - +// To workaround AtomicHook not being constant-initializable on some platforms, +// prefer to annotate instances with `ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES` +// instead of `ABSL_CONST_INIT`. +#if ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT +#define ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES ABSL_CONST_INIT +#else +#define ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES +#endif + // `AtomicHook` is a helper class, templatized on a raw function pointer type, // for implementing Abseil customization hooks. It is a callable object that // dispatches to the registered hook. Objects of type `AtomicHook` must have @@ -59,11 +59,11 @@ class AtomicHook; // A default constructed object performs a no-op (and returns a default // constructed object) if no hook has been registered. // -// Hooks can be pre-registered via constant initialization, for example: -// -// ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES static AtomicHook<void(*)()> -// my_hook(DefaultAction); -// +// Hooks can be pre-registered via constant initialization, for example: +// +// ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES static AtomicHook<void(*)()> +// my_hook(DefaultAction); +// // and then changed at runtime via a call to `Store()`. // // Reads and writes guarantee memory_order_acquire/memory_order_release @@ -82,15 +82,15 @@ class AtomicHook<ReturnType (*)(Args...)> { #if ABSL_HAVE_WORKING_ATOMIC_POINTER && ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT explicit constexpr AtomicHook(FnPtr default_fn) : hook_(default_fn), default_fn_(default_fn) {} -#elif ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT - explicit constexpr AtomicHook(FnPtr default_fn) - : hook_(kUninitialized), default_fn_(default_fn) {} +#elif ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT + explicit constexpr AtomicHook(FnPtr default_fn) + : hook_(kUninitialized), default_fn_(default_fn) {} #else - // As of January 2020, on all known versions of MSVC this constructor runs in - // the global constructor sequence. If `Store()` is called by a dynamic - // initializer, we want to preserve the value, even if this constructor runs - // after the call to `Store()`. If not, `hook_` will be - // zero-initialized by the linker and we have no need to set it. + // As of January 2020, on all known versions of MSVC this constructor runs in + // the global constructor sequence. If `Store()` is called by a dynamic + // initializer, we want to preserve the value, even if this constructor runs + // after the call to `Store()`. If not, `hook_` will be + // zero-initialized by the linker and we have no need to set it. // https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html explicit constexpr AtomicHook(FnPtr default_fn) : /* hook_(deliberately omitted), */ default_fn_(default_fn) { @@ -194,7 +194,7 @@ class AtomicHook<ReturnType (*)(Args...)> { #undef ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/atomic_hook_test_helper.h b/contrib/restricted/abseil-cpp/absl/base/internal/atomic_hook_test_helper.h index 3e72b4977d..d6be76efb9 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/atomic_hook_test_helper.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/atomic_hook_test_helper.h @@ -18,7 +18,7 @@ #include "absl/base/internal/atomic_hook.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace atomic_hook_internal { using VoidF = void (*)(); @@ -28,7 +28,7 @@ void DefaultFunc(); void RegisterFunc(VoidF func); } // namespace atomic_hook_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_ATOMIC_HOOK_TEST_HELPER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/cycleclock.cc b/contrib/restricted/abseil-cpp/absl/base/internal/cycleclock.cc index 0e65005b89..e211c7494f 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/cycleclock.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/cycleclock.cc @@ -28,7 +28,7 @@ #include "absl/base/internal/unscaledcycleclock.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { #if ABSL_USE_UNSCALED_CYCLECLOCK @@ -103,5 +103,5 @@ double CycleClock::Frequency() { #endif } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/cycleclock.h b/contrib/restricted/abseil-cpp/absl/base/internal/cycleclock.h index a18b584445..c5912b50ec 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/cycleclock.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/cycleclock.h @@ -44,10 +44,10 @@ #include <cstdint> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { // ----------------------------------------------------------------------------- @@ -88,7 +88,7 @@ class CycleClockSource { }; } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_CYCLECLOCK_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/direct_mmap.h b/contrib/restricted/abseil-cpp/absl/base/internal/direct_mmap.h index 274054cd5a..d7d9ad49de 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/direct_mmap.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/direct_mmap.h @@ -61,12 +61,12 @@ extern "C" void* __mmap2(void*, size_t, int, int, int, size_t); #endif #endif // __BIONIC__ -#if defined(__NR_mmap2) && !defined(SYS_mmap2) -#define SYS_mmap2 __NR_mmap2 -#endif - +#if defined(__NR_mmap2) && !defined(SYS_mmap2) +#define SYS_mmap2 __NR_mmap2 +#endif + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { // Platform specific logic extracted from @@ -78,7 +78,7 @@ inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd, (defined(__hppa__) && !defined(__LP64__)) || \ (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ (defined(__PPC__) && !defined(__PPC64__)) || \ - (defined(__riscv) && __riscv_xlen == 32) || \ + (defined(__riscv) && __riscv_xlen == 32) || \ (defined(__s390__) && !defined(__s390x__)) || \ (defined(__sparc__) && !defined(__arch64__)) // On these architectures, implement mmap with mmap2. @@ -137,7 +137,7 @@ inline int DirectMunmap(void* start, size_t length) { } } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #else // !__linux__ @@ -146,7 +146,7 @@ ABSL_NAMESPACE_END // actual mmap()/munmap() methods. namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd, @@ -159,7 +159,7 @@ inline int DirectMunmap(void* start, size_t length) { } } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // __linux__ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/dynamic_annotations.h b/contrib/restricted/abseil-cpp/absl/base/internal/dynamic_annotations.h index b23c5ec1c4..cf394c6c14 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/dynamic_annotations.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/dynamic_annotations.h @@ -1,398 +1,398 @@ -// Copyright 2017 The Abseil Authors. -// -// 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 -// -// https://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. - -// This file defines dynamic annotations for use with dynamic analysis tool -// such as valgrind, PIN, etc. -// -// Dynamic annotation is a source code annotation that affects the generated -// code (that is, the annotation is not a comment). Each such annotation is -// attached to a particular instruction and/or to a particular object (address) -// in the program. -// -// The annotations that should be used by users are macros in all upper-case -// (e.g., ANNOTATE_THREAD_NAME). -// -// Actual implementation of these macros may differ depending on the dynamic -// analysis tool being used. -// -// This file supports the following configurations: -// - Dynamic Annotations enabled (with static thread-safety warnings disabled). -// In this case, macros expand to functions implemented by Thread Sanitizer, -// when building with TSan. When not provided an external implementation, -// dynamic_annotations.cc provides no-op implementations. -// -// - Static Clang thread-safety warnings enabled. -// When building with a Clang compiler that supports thread-safety warnings, -// a subset of annotations can be statically-checked at compile-time. We -// expand these macros to static-inline functions that can be analyzed for -// thread-safety, but afterwards elided when building the final binary. -// -// - All annotations are disabled. -// If neither Dynamic Annotations nor Clang thread-safety warnings are -// enabled, then all annotation-macros expand to empty. - -#ifndef ABSL_BASE_INTERNAL_DYNAMIC_ANNOTATIONS_H_ -#define ABSL_BASE_INTERNAL_DYNAMIC_ANNOTATIONS_H_ - -#include <stddef.h> - -#include "absl/base/config.h" - -// ------------------------------------------------------------------------- -// Decide which features are enabled - -#ifndef DYNAMIC_ANNOTATIONS_ENABLED -#define DYNAMIC_ANNOTATIONS_ENABLED 0 -#endif - -#if defined(__clang__) && !defined(SWIG) -#define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 1 -#endif - -#if DYNAMIC_ANNOTATIONS_ENABLED != 0 - -#define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 1 -#define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 1 -#define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 1 -#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0 -#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED 1 - -#else - -#define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 0 -#define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 0 -#define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 0 - -// Clang provides limited support for static thread-safety analysis through a -// feature called Annotalysis. We configure macro-definitions according to -// whether Annotalysis support is available. When running in opt-mode, GCC -// will issue a warning, if these attributes are compiled. Only include them -// when compiling using Clang. - -// ANNOTALYSIS_ENABLED == 1 when IGNORE_READ_ATTRIBUTE_ENABLED == 1 -#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED \ - defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) -// Read/write annotations are enabled in Annotalysis mode; disabled otherwise. -#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED \ - ABSL_INTERNAL_ANNOTALYSIS_ENABLED -#endif - -// Memory annotations are also made available to LLVM's Memory Sanitizer -#if defined(ABSL_HAVE_MEMORY_SANITIZER) && !defined(__native_client__) -#define ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED 1 -#endif - -#ifndef ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED -#define ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED 0 -#endif - -#ifdef __cplusplus -#define ABSL_INTERNAL_BEGIN_EXTERN_C extern "C" { -#define ABSL_INTERNAL_END_EXTERN_C } // extern "C" -#define ABSL_INTERNAL_GLOBAL_SCOPED(F) ::F -#define ABSL_INTERNAL_STATIC_INLINE inline -#else -#define ABSL_INTERNAL_BEGIN_EXTERN_C // empty -#define ABSL_INTERNAL_END_EXTERN_C // empty -#define ABSL_INTERNAL_GLOBAL_SCOPED(F) F -#define ABSL_INTERNAL_STATIC_INLINE static inline -#endif - -// ------------------------------------------------------------------------- -// Define race annotations. - -#if ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 1 - -// ------------------------------------------------------------- -// Annotations that suppress errors. It is usually better to express the -// program's synchronization using the other annotations, but these can be used -// when all else fails. - -// Report that we may have a benign race at `pointer`, with size -// "sizeof(*(pointer))". `pointer` must be a non-void* pointer. Insert at the -// point where `pointer` has been allocated, preferably close to the point -// where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC. -#define ANNOTATE_BENIGN_RACE(pointer, description) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \ - (__FILE__, __LINE__, pointer, sizeof(*(pointer)), description) - -// Same as ANNOTATE_BENIGN_RACE(`address`, `description`), but applies to -// the memory range [`address`, `address`+`size`). -#define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \ - (__FILE__, __LINE__, address, size, description) - -// Enable (`enable`!=0) or disable (`enable`==0) race detection for all threads. -// This annotation could be useful if you want to skip expensive race analysis -// during some period of program execution, e.g. during initialization. -#define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateEnableRaceDetection) \ - (__FILE__, __LINE__, enable) - -// ------------------------------------------------------------- -// Annotations useful for debugging. - -// Report the current thread `name` to a race detector. -#define ANNOTATE_THREAD_NAME(name) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateThreadName)(__FILE__, __LINE__, name) - -// ------------------------------------------------------------- -// Annotations useful when implementing locks. They are not normally needed by -// modules that merely use locks. The `lock` argument is a pointer to the lock -// object. - -// Report that a lock has been created at address `lock`. -#define ANNOTATE_RWLOCK_CREATE(lock) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreate)(__FILE__, __LINE__, lock) - -// Report that a linker initialized lock has been created at address `lock`. -#ifdef ABSL_HAVE_THREAD_SANITIZER -#define ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreateStatic) \ - (__FILE__, __LINE__, lock) -#else -#define ANNOTATE_RWLOCK_CREATE_STATIC(lock) ANNOTATE_RWLOCK_CREATE(lock) -#endif - -// Report that the lock at address `lock` is about to be destroyed. -#define ANNOTATE_RWLOCK_DESTROY(lock) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockDestroy)(__FILE__, __LINE__, lock) - -// Report that the lock at address `lock` has been acquired. -// `is_w`=1 for writer lock, `is_w`=0 for reader lock. -#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockAcquired) \ - (__FILE__, __LINE__, lock, is_w) - -// Report that the lock at address `lock` is about to be released. -// `is_w`=1 for writer lock, `is_w`=0 for reader lock. -#define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockReleased) \ - (__FILE__, __LINE__, lock, is_w) - -// Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable `static_var`. -#define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ - namespace { \ - class static_var##_annotator { \ - public: \ - static_var##_annotator() { \ - ANNOTATE_BENIGN_RACE_SIZED(&static_var, sizeof(static_var), \ - #static_var ": " description); \ - } \ - }; \ - static static_var##_annotator the##static_var##_annotator; \ - } // namespace - -#else // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 0 - -#define ANNOTATE_RWLOCK_CREATE(lock) // empty -#define ANNOTATE_RWLOCK_CREATE_STATIC(lock) // empty -#define ANNOTATE_RWLOCK_DESTROY(lock) // empty -#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) // empty -#define ANNOTATE_RWLOCK_RELEASED(lock, is_w) // empty -#define ANNOTATE_BENIGN_RACE(address, description) // empty -#define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) // empty -#define ANNOTATE_THREAD_NAME(name) // empty -#define ANNOTATE_ENABLE_RACE_DETECTION(enable) // empty -#define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) // empty - -#endif // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED - -// ------------------------------------------------------------------------- -// Define memory annotations. - -#if ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED == 1 - -#include <sanitizer/msan_interface.h> - -#define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ - __msan_unpoison(address, size) - -#define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ - __msan_allocated_memory(address, size) - -#else // ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED == 0 - -#if DYNAMIC_ANNOTATIONS_ENABLED == 1 -#define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ - do { \ - (void)(address); \ - (void)(size); \ - } while (0) -#define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ - do { \ - (void)(address); \ - (void)(size); \ - } while (0) -#else -#define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) // empty -#define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) // empty -#endif - -#endif // ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED - -// ------------------------------------------------------------------------- -// Define IGNORE_READS_BEGIN/_END attributes. - -#if defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) - -#define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE \ - __attribute((exclusive_lock_function("*"))) -#define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE \ - __attribute((unlock_function("*"))) - -#else // !defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) - -#define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE // empty -#define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE // empty - -#endif // defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) - -// ------------------------------------------------------------------------- -// Define IGNORE_READS_BEGIN/_END annotations. - -#if ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED == 1 - -// Request the analysis tool to ignore all reads in the current thread until -// ANNOTATE_IGNORE_READS_END is called. Useful to ignore intentional racey -// reads, while still checking other reads and all writes. -// See also ANNOTATE_UNPROTECTED_READ. -#define ANNOTATE_IGNORE_READS_BEGIN() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsBegin)(__FILE__, __LINE__) - -// Stop ignoring reads. -#define ANNOTATE_IGNORE_READS_END() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsEnd)(__FILE__, __LINE__) - -#elif defined(ABSL_INTERNAL_ANNOTALYSIS_ENABLED) - -// When Annotalysis is enabled without Dynamic Annotations, the use of -// static-inline functions allows the annotations to be read at compile-time, -// while still letting the compiler elide the functions from the final build. -// -// TODO(delesley) -- The exclusive lock here ignores writes as well, but -// allows IGNORE_READS_AND_WRITES to work properly. - -#define ANNOTATE_IGNORE_READS_BEGIN() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsBegin)() - -#define ANNOTATE_IGNORE_READS_END() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsEnd)() - -#else - -#define ANNOTATE_IGNORE_READS_BEGIN() // empty -#define ANNOTATE_IGNORE_READS_END() // empty - -#endif - -// ------------------------------------------------------------------------- -// Define IGNORE_WRITES_BEGIN/_END annotations. - -#if ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED == 1 - -// Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead. -#define ANNOTATE_IGNORE_WRITES_BEGIN() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesBegin)(__FILE__, __LINE__) - -// Stop ignoring writes. -#define ANNOTATE_IGNORE_WRITES_END() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesEnd)(__FILE__, __LINE__) - -#else - -#define ANNOTATE_IGNORE_WRITES_BEGIN() // empty -#define ANNOTATE_IGNORE_WRITES_END() // empty - -#endif - -// ------------------------------------------------------------------------- -// Define the ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more -// primitive annotations defined above. -// -// Instead of doing -// ANNOTATE_IGNORE_READS_BEGIN(); -// ... = x; -// ANNOTATE_IGNORE_READS_END(); -// one can use -// ... = ANNOTATE_UNPROTECTED_READ(x); - -#if defined(ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED) - -// Start ignoring all memory accesses (both reads and writes). -#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ - do { \ - ANNOTATE_IGNORE_READS_BEGIN(); \ - ANNOTATE_IGNORE_WRITES_BEGIN(); \ - } while (0) - -// Stop ignoring both reads and writes. -#define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ - do { \ - ANNOTATE_IGNORE_WRITES_END(); \ - ANNOTATE_IGNORE_READS_END(); \ - } while (0) - -#ifdef __cplusplus -// ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. -#define ANNOTATE_UNPROTECTED_READ(x) \ - absl::base_internal::AnnotateUnprotectedRead(x) - -#endif - -#else - -#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() // empty -#define ANNOTATE_IGNORE_READS_AND_WRITES_END() // empty -#define ANNOTATE_UNPROTECTED_READ(x) (x) - -#endif - -// ------------------------------------------------------------------------- -// Address sanitizer annotations - -#ifdef ABSL_HAVE_ADDRESS_SANITIZER -// Describe the current state of a contiguous container such as e.g. -// std::vector or std::string. For more details see -// sanitizer/common_interface_defs.h, which is provided by the compiler. -#include <sanitizer/common_interface_defs.h> - -#define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \ - __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid) -#define ADDRESS_SANITIZER_REDZONE(name) \ - struct { \ - char x[8] __attribute__((aligned(8))); \ - } name - -#else - -#define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) -#define ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "") - -#endif // ABSL_HAVE_ADDRESS_SANITIZER - -// ------------------------------------------------------------------------- -// Undefine the macros intended only for this file. - -#undef ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED -#undef ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED -#undef ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED -#undef ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED -#undef ABSL_INTERNAL_ANNOTALYSIS_ENABLED -#undef ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED -#undef ABSL_INTERNAL_BEGIN_EXTERN_C -#undef ABSL_INTERNAL_END_EXTERN_C -#undef ABSL_INTERNAL_STATIC_INLINE - -#endif // ABSL_BASE_INTERNAL_DYNAMIC_ANNOTATIONS_H_ +// Copyright 2017 The Abseil Authors. +// +// 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 +// +// https://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. + +// This file defines dynamic annotations for use with dynamic analysis tool +// such as valgrind, PIN, etc. +// +// Dynamic annotation is a source code annotation that affects the generated +// code (that is, the annotation is not a comment). Each such annotation is +// attached to a particular instruction and/or to a particular object (address) +// in the program. +// +// The annotations that should be used by users are macros in all upper-case +// (e.g., ANNOTATE_THREAD_NAME). +// +// Actual implementation of these macros may differ depending on the dynamic +// analysis tool being used. +// +// This file supports the following configurations: +// - Dynamic Annotations enabled (with static thread-safety warnings disabled). +// In this case, macros expand to functions implemented by Thread Sanitizer, +// when building with TSan. When not provided an external implementation, +// dynamic_annotations.cc provides no-op implementations. +// +// - Static Clang thread-safety warnings enabled. +// When building with a Clang compiler that supports thread-safety warnings, +// a subset of annotations can be statically-checked at compile-time. We +// expand these macros to static-inline functions that can be analyzed for +// thread-safety, but afterwards elided when building the final binary. +// +// - All annotations are disabled. +// If neither Dynamic Annotations nor Clang thread-safety warnings are +// enabled, then all annotation-macros expand to empty. + +#ifndef ABSL_BASE_INTERNAL_DYNAMIC_ANNOTATIONS_H_ +#define ABSL_BASE_INTERNAL_DYNAMIC_ANNOTATIONS_H_ + +#include <stddef.h> + +#include "absl/base/config.h" + +// ------------------------------------------------------------------------- +// Decide which features are enabled + +#ifndef DYNAMIC_ANNOTATIONS_ENABLED +#define DYNAMIC_ANNOTATIONS_ENABLED 0 +#endif + +#if defined(__clang__) && !defined(SWIG) +#define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 1 +#endif + +#if DYNAMIC_ANNOTATIONS_ENABLED != 0 + +#define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 1 +#define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 1 +#define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 1 +#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0 +#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED 1 + +#else + +#define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 0 +#define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 0 +#define ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED 0 + +// Clang provides limited support for static thread-safety analysis through a +// feature called Annotalysis. We configure macro-definitions according to +// whether Annotalysis support is available. When running in opt-mode, GCC +// will issue a warning, if these attributes are compiled. Only include them +// when compiling using Clang. + +// ANNOTALYSIS_ENABLED == 1 when IGNORE_READ_ATTRIBUTE_ENABLED == 1 +#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED \ + defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) +// Read/write annotations are enabled in Annotalysis mode; disabled otherwise. +#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED \ + ABSL_INTERNAL_ANNOTALYSIS_ENABLED +#endif + +// Memory annotations are also made available to LLVM's Memory Sanitizer +#if defined(ABSL_HAVE_MEMORY_SANITIZER) && !defined(__native_client__) +#define ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED 1 +#endif + +#ifndef ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED +#define ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED 0 +#endif + +#ifdef __cplusplus +#define ABSL_INTERNAL_BEGIN_EXTERN_C extern "C" { +#define ABSL_INTERNAL_END_EXTERN_C } // extern "C" +#define ABSL_INTERNAL_GLOBAL_SCOPED(F) ::F +#define ABSL_INTERNAL_STATIC_INLINE inline +#else +#define ABSL_INTERNAL_BEGIN_EXTERN_C // empty +#define ABSL_INTERNAL_END_EXTERN_C // empty +#define ABSL_INTERNAL_GLOBAL_SCOPED(F) F +#define ABSL_INTERNAL_STATIC_INLINE static inline +#endif + +// ------------------------------------------------------------------------- +// Define race annotations. + +#if ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 1 + +// ------------------------------------------------------------- +// Annotations that suppress errors. It is usually better to express the +// program's synchronization using the other annotations, but these can be used +// when all else fails. + +// Report that we may have a benign race at `pointer`, with size +// "sizeof(*(pointer))". `pointer` must be a non-void* pointer. Insert at the +// point where `pointer` has been allocated, preferably close to the point +// where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC. +#define ANNOTATE_BENIGN_RACE(pointer, description) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \ + (__FILE__, __LINE__, pointer, sizeof(*(pointer)), description) + +// Same as ANNOTATE_BENIGN_RACE(`address`, `description`), but applies to +// the memory range [`address`, `address`+`size`). +#define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateBenignRaceSized) \ + (__FILE__, __LINE__, address, size, description) + +// Enable (`enable`!=0) or disable (`enable`==0) race detection for all threads. +// This annotation could be useful if you want to skip expensive race analysis +// during some period of program execution, e.g. during initialization. +#define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateEnableRaceDetection) \ + (__FILE__, __LINE__, enable) + +// ------------------------------------------------------------- +// Annotations useful for debugging. + +// Report the current thread `name` to a race detector. +#define ANNOTATE_THREAD_NAME(name) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateThreadName)(__FILE__, __LINE__, name) + +// ------------------------------------------------------------- +// Annotations useful when implementing locks. They are not normally needed by +// modules that merely use locks. The `lock` argument is a pointer to the lock +// object. + +// Report that a lock has been created at address `lock`. +#define ANNOTATE_RWLOCK_CREATE(lock) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreate)(__FILE__, __LINE__, lock) + +// Report that a linker initialized lock has been created at address `lock`. +#ifdef ABSL_HAVE_THREAD_SANITIZER +#define ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockCreateStatic) \ + (__FILE__, __LINE__, lock) +#else +#define ANNOTATE_RWLOCK_CREATE_STATIC(lock) ANNOTATE_RWLOCK_CREATE(lock) +#endif + +// Report that the lock at address `lock` is about to be destroyed. +#define ANNOTATE_RWLOCK_DESTROY(lock) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockDestroy)(__FILE__, __LINE__, lock) + +// Report that the lock at address `lock` has been acquired. +// `is_w`=1 for writer lock, `is_w`=0 for reader lock. +#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockAcquired) \ + (__FILE__, __LINE__, lock, is_w) + +// Report that the lock at address `lock` is about to be released. +// `is_w`=1 for writer lock, `is_w`=0 for reader lock. +#define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateRWLockReleased) \ + (__FILE__, __LINE__, lock, is_w) + +// Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable `static_var`. +#define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ + namespace { \ + class static_var##_annotator { \ + public: \ + static_var##_annotator() { \ + ANNOTATE_BENIGN_RACE_SIZED(&static_var, sizeof(static_var), \ + #static_var ": " description); \ + } \ + }; \ + static static_var##_annotator the##static_var##_annotator; \ + } // namespace + +#else // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 0 + +#define ANNOTATE_RWLOCK_CREATE(lock) // empty +#define ANNOTATE_RWLOCK_CREATE_STATIC(lock) // empty +#define ANNOTATE_RWLOCK_DESTROY(lock) // empty +#define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) // empty +#define ANNOTATE_RWLOCK_RELEASED(lock, is_w) // empty +#define ANNOTATE_BENIGN_RACE(address, description) // empty +#define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) // empty +#define ANNOTATE_THREAD_NAME(name) // empty +#define ANNOTATE_ENABLE_RACE_DETECTION(enable) // empty +#define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) // empty + +#endif // ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED + +// ------------------------------------------------------------------------- +// Define memory annotations. + +#if ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED == 1 + +#include <sanitizer/msan_interface.h> + +#define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ + __msan_unpoison(address, size) + +#define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ + __msan_allocated_memory(address, size) + +#else // ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED == 0 + +#if DYNAMIC_ANNOTATIONS_ENABLED == 1 +#define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ + do { \ + (void)(address); \ + (void)(size); \ + } while (0) +#define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ + do { \ + (void)(address); \ + (void)(size); \ + } while (0) +#else +#define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) // empty +#define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) // empty +#endif + +#endif // ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED + +// ------------------------------------------------------------------------- +// Define IGNORE_READS_BEGIN/_END attributes. + +#if defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) + +#define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE \ + __attribute((exclusive_lock_function("*"))) +#define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE \ + __attribute((unlock_function("*"))) + +#else // !defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) + +#define ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE // empty +#define ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE // empty + +#endif // defined(ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED) + +// ------------------------------------------------------------------------- +// Define IGNORE_READS_BEGIN/_END annotations. + +#if ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED == 1 + +// Request the analysis tool to ignore all reads in the current thread until +// ANNOTATE_IGNORE_READS_END is called. Useful to ignore intentional racey +// reads, while still checking other reads and all writes. +// See also ANNOTATE_UNPROTECTED_READ. +#define ANNOTATE_IGNORE_READS_BEGIN() \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsBegin)(__FILE__, __LINE__) + +// Stop ignoring reads. +#define ANNOTATE_IGNORE_READS_END() \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsEnd)(__FILE__, __LINE__) + +#elif defined(ABSL_INTERNAL_ANNOTALYSIS_ENABLED) + +// When Annotalysis is enabled without Dynamic Annotations, the use of +// static-inline functions allows the annotations to be read at compile-time, +// while still letting the compiler elide the functions from the final build. +// +// TODO(delesley) -- The exclusive lock here ignores writes as well, but +// allows IGNORE_READS_AND_WRITES to work properly. + +#define ANNOTATE_IGNORE_READS_BEGIN() \ + ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsBegin)() + +#define ANNOTATE_IGNORE_READS_END() \ + ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsEnd)() + +#else + +#define ANNOTATE_IGNORE_READS_BEGIN() // empty +#define ANNOTATE_IGNORE_READS_END() // empty + +#endif + +// ------------------------------------------------------------------------- +// Define IGNORE_WRITES_BEGIN/_END annotations. + +#if ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED == 1 + +// Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead. +#define ANNOTATE_IGNORE_WRITES_BEGIN() \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesBegin)(__FILE__, __LINE__) + +// Stop ignoring writes. +#define ANNOTATE_IGNORE_WRITES_END() \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreWritesEnd)(__FILE__, __LINE__) + +#else + +#define ANNOTATE_IGNORE_WRITES_BEGIN() // empty +#define ANNOTATE_IGNORE_WRITES_END() // empty + +#endif + +// ------------------------------------------------------------------------- +// Define the ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more +// primitive annotations defined above. +// +// Instead of doing +// ANNOTATE_IGNORE_READS_BEGIN(); +// ... = x; +// ANNOTATE_IGNORE_READS_END(); +// one can use +// ... = ANNOTATE_UNPROTECTED_READ(x); + +#if defined(ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED) + +// Start ignoring all memory accesses (both reads and writes). +#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ + do { \ + ANNOTATE_IGNORE_READS_BEGIN(); \ + ANNOTATE_IGNORE_WRITES_BEGIN(); \ + } while (0) + +// Stop ignoring both reads and writes. +#define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ + do { \ + ANNOTATE_IGNORE_WRITES_END(); \ + ANNOTATE_IGNORE_READS_END(); \ + } while (0) + +#ifdef __cplusplus +// ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. +#define ANNOTATE_UNPROTECTED_READ(x) \ + absl::base_internal::AnnotateUnprotectedRead(x) + +#endif + +#else + +#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() // empty +#define ANNOTATE_IGNORE_READS_AND_WRITES_END() // empty +#define ANNOTATE_UNPROTECTED_READ(x) (x) + +#endif + +// ------------------------------------------------------------------------- +// Address sanitizer annotations + +#ifdef ABSL_HAVE_ADDRESS_SANITIZER +// Describe the current state of a contiguous container such as e.g. +// std::vector or std::string. For more details see +// sanitizer/common_interface_defs.h, which is provided by the compiler. +#include <sanitizer/common_interface_defs.h> + +#define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \ + __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid) +#define ADDRESS_SANITIZER_REDZONE(name) \ + struct { \ + char x[8] __attribute__((aligned(8))); \ + } name + +#else + +#define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) +#define ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "") + +#endif // ABSL_HAVE_ADDRESS_SANITIZER + +// ------------------------------------------------------------------------- +// Undefine the macros intended only for this file. + +#undef ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED +#undef ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED +#undef ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED +#undef ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED +#undef ABSL_INTERNAL_ANNOTALYSIS_ENABLED +#undef ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED +#undef ABSL_INTERNAL_BEGIN_EXTERN_C +#undef ABSL_INTERNAL_END_EXTERN_C +#undef ABSL_INTERNAL_STATIC_INLINE + +#endif // ABSL_BASE_INTERNAL_DYNAMIC_ANNOTATIONS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/endian.h b/contrib/restricted/abseil-cpp/absl/base/internal/endian.h index dad0e9aeb0..5c11b5f651 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/endian.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/endian.h @@ -32,7 +32,7 @@ #include "absl/base/port.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // Use compiler byte-swapping intrinsics if they are available. 32-bit // and 64-bit versions are available in Clang and GCC as of GCC 4.3.0. @@ -321,7 +321,7 @@ inline void Store64(void *p, uint64_t v) { } // namespace big_endian -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_ENDIAN_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/errno_saver.h b/contrib/restricted/abseil-cpp/absl/base/internal/errno_saver.h index 251de510fc..5b2af9af97 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/errno_saver.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/errno_saver.h @@ -1,43 +1,43 @@ -// Copyright 2017 The Abseil Authors. -// -// 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 -// -// https://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. - -#ifndef ABSL_BASE_INTERNAL_ERRNO_SAVER_H_ -#define ABSL_BASE_INTERNAL_ERRNO_SAVER_H_ - -#include <cerrno> - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace base_internal { - -// `ErrnoSaver` captures the value of `errno` upon construction and restores it -// upon deletion. It is used in low-level code and must be super fast. Do not -// add instrumentation, even in debug modes. -class ErrnoSaver { - public: - ErrnoSaver() : saved_errno_(errno) {} - ~ErrnoSaver() { errno = saved_errno_; } - int operator()() const { return saved_errno_; } - - private: - const int saved_errno_; -}; - -} // namespace base_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_BASE_INTERNAL_ERRNO_SAVER_H_ +// Copyright 2017 The Abseil Authors. +// +// 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 +// +// https://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. + +#ifndef ABSL_BASE_INTERNAL_ERRNO_SAVER_H_ +#define ABSL_BASE_INTERNAL_ERRNO_SAVER_H_ + +#include <cerrno> + +#include "absl/base/config.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace base_internal { + +// `ErrnoSaver` captures the value of `errno` upon construction and restores it +// upon deletion. It is used in low-level code and must be super fast. Do not +// add instrumentation, even in debug modes. +class ErrnoSaver { + public: + ErrnoSaver() : saved_errno_(errno) {} + ~ErrnoSaver() { errno = saved_errno_; } + int operator()() const { return saved_errno_; } + + private: + const int saved_errno_; +}; + +} // namespace base_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_ERRNO_SAVER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/fast_type_id.h b/contrib/restricted/abseil-cpp/absl/base/internal/fast_type_id.h index 3db59e8374..976f505531 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/fast_type_id.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/fast_type_id.h @@ -1,48 +1,48 @@ -// -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. -// - -#ifndef ABSL_BASE_INTERNAL_FAST_TYPE_ID_H_ -#define ABSL_BASE_INTERNAL_FAST_TYPE_ID_H_ - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace base_internal { - -template <typename Type> -struct FastTypeTag { - constexpr static char dummy_var = 0; -}; - -template <typename Type> -constexpr char FastTypeTag<Type>::dummy_var; - -// FastTypeId<Type>() evaluates at compile/link-time to a unique pointer for the -// passed-in type. These are meant to be good match for keys into maps or -// straight up comparisons. -using FastTypeIdType = const void*; - -template <typename Type> -constexpr inline FastTypeIdType FastTypeId() { - return &FastTypeTag<Type>::dummy_var; -} - -} // namespace base_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_BASE_INTERNAL_FAST_TYPE_ID_H_ +// +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. +// + +#ifndef ABSL_BASE_INTERNAL_FAST_TYPE_ID_H_ +#define ABSL_BASE_INTERNAL_FAST_TYPE_ID_H_ + +#include "absl/base/config.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace base_internal { + +template <typename Type> +struct FastTypeTag { + constexpr static char dummy_var = 0; +}; + +template <typename Type> +constexpr char FastTypeTag<Type>::dummy_var; + +// FastTypeId<Type>() evaluates at compile/link-time to a unique pointer for the +// passed-in type. These are meant to be good match for keys into maps or +// straight up comparisons. +using FastTypeIdType = const void*; + +template <typename Type> +constexpr inline FastTypeIdType FastTypeId() { + return &FastTypeTag<Type>::dummy_var; +} + +} // namespace base_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_FAST_TYPE_ID_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/hide_ptr.h b/contrib/restricted/abseil-cpp/absl/base/internal/hide_ptr.h index 1dba80909a..a258331c0e 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/hide_ptr.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/hide_ptr.h @@ -17,10 +17,10 @@ #include <cstdint> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { // Arbitrary value with high bits set. Xor'ing with it is unlikely @@ -45,7 +45,7 @@ inline T* UnhidePtr(uintptr_t hidden) { } } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_HIDE_PTR_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/identity.h b/contrib/restricted/abseil-cpp/absl/base/internal/identity.h index a3154ed7bc..e0444550d5 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/identity.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/identity.h @@ -16,10 +16,10 @@ #ifndef ABSL_BASE_INTERNAL_IDENTITY_H_ #define ABSL_BASE_INTERNAL_IDENTITY_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace internal { template <typename T> @@ -31,7 +31,7 @@ template <typename T> using identity_t = typename identity<T>::type; } // namespace internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_IDENTITY_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/inline_variable_testing.h b/contrib/restricted/abseil-cpp/absl/base/internal/inline_variable_testing.h index 3856b9f80f..43814d2b6c 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/inline_variable_testing.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/inline_variable_testing.h @@ -18,7 +18,7 @@ #include "absl/base/internal/inline_variable.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace inline_variable_testing_internal { struct Foo { @@ -40,7 +40,7 @@ const int& get_int_a(); const int& get_int_b(); } // namespace inline_variable_testing_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INLINE_VARIABLE_TESTING_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/invoke.h b/contrib/restricted/abseil-cpp/absl/base/internal/invoke.h index 5c71f32823..c6805672b2 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/invoke.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/invoke.h @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// absl::base_internal::invoke(f, args...) is an implementation of +// absl::base_internal::invoke(f, args...) is an implementation of // INVOKE(f, args...) from section [func.require] of the C++ standard. // // [func.require] @@ -29,7 +29,7 @@ // is not one of the types described in the previous item; // 5. f(t1, t2, ..., tN) in all other cases. // -// The implementation is SFINAE-friendly: substitution failure within invoke() +// The implementation is SFINAE-friendly: substitution failure within invoke() // isn't an error. #ifndef ABSL_BASE_INTERNAL_INVOKE_H_ @@ -45,7 +45,7 @@ // top of this file for the API documentation. namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { // The five classes below each implement one of the clauses from the definition @@ -170,18 +170,18 @@ struct Invoker { // The result type of Invoke<F, Args...>. template <typename F, typename... Args> -using invoke_result_t = decltype(Invoker<F, Args...>::type::Invoke( +using invoke_result_t = decltype(Invoker<F, Args...>::type::Invoke( std::declval<F>(), std::declval<Args>()...)); // Invoke(f, args...) is an implementation of INVOKE(f, args...) from section // [func.require] of the C++ standard. template <typename F, typename... Args> -invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) { +invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) { return Invoker<F, Args...>::type::Invoke(std::forward<F>(f), std::forward<Args>(args)...); } } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_INVOKE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.cc b/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.cc index 229ab9162d..7a6f7c38b6 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.cc @@ -63,7 +63,7 @@ #endif // __APPLE__ namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { // A first-fit allocator with amortized logarithmic free() time. @@ -223,14 +223,14 @@ namespace { // Static storage space for the lazily-constructed, default global arena // instances. We require this space because the whole point of LowLevelAlloc // is to avoid relying on malloc/new. -alignas(LowLevelAlloc::Arena) unsigned char default_arena_storage[sizeof( - LowLevelAlloc::Arena)]; -alignas(LowLevelAlloc::Arena) unsigned char unhooked_arena_storage[sizeof( - LowLevelAlloc::Arena)]; +alignas(LowLevelAlloc::Arena) unsigned char default_arena_storage[sizeof( + LowLevelAlloc::Arena)]; +alignas(LowLevelAlloc::Arena) unsigned char unhooked_arena_storage[sizeof( + LowLevelAlloc::Arena)]; #ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING -alignas( - LowLevelAlloc::Arena) unsigned char unhooked_async_sig_safe_arena_storage - [sizeof(LowLevelAlloc::Arena)]; +alignas( + LowLevelAlloc::Arena) unsigned char unhooked_async_sig_safe_arena_storage + [sizeof(LowLevelAlloc::Arena)]; #endif // We must use LowLevelCallOnce here to construct the global arenas, rather than @@ -598,7 +598,7 @@ static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) { section.Leave(); result = &s->levels; } - ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(result, request); + ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(result, request); return result; } @@ -614,7 +614,7 @@ void *LowLevelAlloc::AllocWithArena(size_t request, Arena *arena) { } } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_LOW_LEVEL_ALLOC_MISSING diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.h b/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.h index db91951c82..df29081b2a 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc.h @@ -55,7 +55,7 @@ #include "absl/base/port.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { class LowLevelAlloc { @@ -120,7 +120,7 @@ class LowLevelAlloc { }; } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc/ya.make b/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc/ya.make index df53191043..b771bb5bf7 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc/ya.make +++ b/contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc/ya.make @@ -23,10 +23,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/base/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/low_level_scheduling.h b/contrib/restricted/abseil-cpp/absl/base/internal/low_level_scheduling.h index 9baccc0659..d24882817c 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/low_level_scheduling.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/low_level_scheduling.h @@ -18,7 +18,7 @@ #ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ #define ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ -#include "absl/base/internal/raw_logging.h" +#include "absl/base/internal/raw_logging.h" #include "absl/base/internal/scheduling_mode.h" #include "absl/base/macros.h" @@ -29,14 +29,14 @@ extern "C" bool __google_disable_rescheduling(void); extern "C" void __google_enable_rescheduling(bool disable_result); namespace absl { -ABSL_NAMESPACE_BEGIN -class CondVar; -class Mutex; - -namespace synchronization_internal { -int MutexDelay(int32_t c, int mode); -} // namespace synchronization_internal - +ABSL_NAMESPACE_BEGIN +class CondVar; +class Mutex; + +namespace synchronization_internal { +int MutexDelay(int32_t c, int mode); +} // namespace synchronization_internal + namespace base_internal { class SchedulingHelper; // To allow use of SchedulingGuard. @@ -86,23 +86,23 @@ class SchedulingGuard { bool disabled; }; - // A scoped helper to enable rescheduling temporarily. - // REQUIRES: destructor must run in same thread as constructor. - class ScopedEnable { - public: - ScopedEnable(); - ~ScopedEnable(); - - private: - int scheduling_disabled_depth_; - }; - - // Access to SchedulingGuard is explicitly permitted. - friend class absl::CondVar; - friend class absl::Mutex; + // A scoped helper to enable rescheduling temporarily. + // REQUIRES: destructor must run in same thread as constructor. + class ScopedEnable { + public: + ScopedEnable(); + ~ScopedEnable(); + + private: + int scheduling_disabled_depth_; + }; + + // Access to SchedulingGuard is explicitly permitted. + friend class absl::CondVar; + friend class absl::Mutex; friend class SchedulingHelper; friend class SpinLock; - friend int absl::synchronization_internal::MutexDelay(int32_t c, int mode); + friend int absl::synchronization_internal::MutexDelay(int32_t c, int mode); }; //------------------------------------------------------------------------------ @@ -121,14 +121,14 @@ inline void SchedulingGuard::EnableRescheduling(bool /* disable_result */) { return; } -inline SchedulingGuard::ScopedEnable::ScopedEnable() - : scheduling_disabled_depth_(0) {} -inline SchedulingGuard::ScopedEnable::~ScopedEnable() { - ABSL_RAW_CHECK(scheduling_disabled_depth_ == 0, "disable unused warning"); -} - +inline SchedulingGuard::ScopedEnable::ScopedEnable() + : scheduling_disabled_depth_(0) {} +inline SchedulingGuard::ScopedEnable::~ScopedEnable() { + ABSL_RAW_CHECK(scheduling_disabled_depth_ == 0, "disable unused warning"); +} + } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.cc b/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.cc index 074e026adb..73d8c71ca7 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.cc @@ -37,8 +37,8 @@ // this, consider moving both to config.h instead. #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ defined(__Fuchsia__) || defined(__native_client__) || \ - defined(__EMSCRIPTEN__) || defined(__ASYLO__) - + defined(__EMSCRIPTEN__) || defined(__ASYLO__) + #include <unistd.h> #define ABSL_HAVE_POSIX_WRITE 1 @@ -225,9 +225,9 @@ bool RawLoggingFullySupported() { #endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED } -ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES ABSL_DLL - absl::base_internal::AtomicHook<InternalLogFunction> - internal_log_function(DefaultInternalLog); +ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES ABSL_DLL + absl::base_internal::AtomicHook<InternalLogFunction> + internal_log_function(DefaultInternalLog); void RegisterLogPrefixHook(LogPrefixHook func) { log_prefix_hook.Store(func); } @@ -238,5 +238,5 @@ void RegisterInternalLogFunction(InternalLogFunction func) { } } // namespace raw_logging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.h b/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.h index 2bf7aabac1..8d1d5c537f 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging.h @@ -22,11 +22,11 @@ #include <string> #include "absl/base/attributes.h" -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/base/internal/atomic_hook.h" #include "absl/base/log_severity.h" #include "absl/base/macros.h" -#include "absl/base/optimization.h" +#include "absl/base/optimization.h" #include "absl/base/port.h" // This is similar to LOG(severity) << format..., but @@ -99,7 +99,7 @@ ::absl::NormalizeLogSeverity(severity) namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace raw_logging_internal { // Helper function to implement ABSL_RAW_LOG @@ -160,7 +160,7 @@ using LogPrefixHook = bool (*)(absl::LogSeverity severity, const char* file, // // 'file' and 'line' are the file and line number where the ABSL_RAW_LOG macro // was located. -// The NUL-terminated logged message lives in the buffer between 'buf_start' +// The NUL-terminated logged message lives in the buffer between 'buf_start' // and 'buf_end'. 'prefix_end' points to the first non-prefix character of the // buffer (as written by the LogPrefixHook.) using AbortHook = void (*)(const char* file, int line, const char* buf_start, @@ -174,9 +174,9 @@ using InternalLogFunction = void (*)(absl::LogSeverity severity, const char* file, int line, const std::string& message); -ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES ABSL_DLL extern base_internal::AtomicHook< - InternalLogFunction> - internal_log_function; +ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES ABSL_DLL extern base_internal::AtomicHook< + InternalLogFunction> + internal_log_function; // Registers hooks of the above types. Only a single hook of each type may be // registered. It is an error to call these functions multiple times with @@ -189,7 +189,7 @@ void RegisterAbortHook(AbortHook func); void RegisterInternalLogFunction(InternalLogFunction func); } // namespace raw_logging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_RAW_LOGGING_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging/ya.make b/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging/ya.make index 7d51c953ee..98463a8dc0 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging/ya.make +++ b/contrib/restricted/abseil-cpp/absl/base/internal/raw_logging/ya.make @@ -20,10 +20,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/base/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/scheduling_mode.h b/contrib/restricted/abseil-cpp/absl/base/internal/scheduling_mode.h index 8be5ab6dd3..571f5addc1 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/scheduling_mode.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/scheduling_mode.h @@ -18,10 +18,10 @@ #ifndef ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_ #define ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { // Used to describe how a thread may be scheduled. Typically associated with @@ -52,7 +52,7 @@ enum SchedulingMode { }; } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env.cc b/contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env.cc index 8a934cb511..503b6d0a7c 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env.cc @@ -23,7 +23,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { namespace { @@ -77,5 +77,5 @@ ScopedSetEnv::~ScopedSetEnv() { } } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env.h b/contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env.h index 19ec7b5d8a..a74d34c5e3 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env.h @@ -19,10 +19,10 @@ #include <string> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { class ScopedSetEnv { @@ -39,7 +39,7 @@ class ScopedSetEnv { }; } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_SCOPED_SET_ENV_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env/ya.make b/contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env/ya.make index d858ec9351..06eed94cc4 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env/ya.make +++ b/contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env/ya.make @@ -21,10 +21,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/base/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.cc b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.cc index 35c0696a34..63e070b673 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.cc @@ -54,11 +54,11 @@ // holder to acquire the lock. There may be outstanding waiter(s). namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { -ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES static base_internal::AtomicHook<void (*)( - const void *lock, int64_t wait_cycles)> +ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES static base_internal::AtomicHook<void (*)( + const void *lock, int64_t wait_cycles)> submit_profile_data; void RegisterSpinLockProfiler(void (*fn)(const void *contendedlock, @@ -66,13 +66,13 @@ void RegisterSpinLockProfiler(void (*fn)(const void *contendedlock, submit_profile_data.Store(fn); } -// Static member variable definitions. -constexpr uint32_t SpinLock::kSpinLockHeld; -constexpr uint32_t SpinLock::kSpinLockCooperative; -constexpr uint32_t SpinLock::kSpinLockDisabledScheduling; -constexpr uint32_t SpinLock::kSpinLockSleeper; -constexpr uint32_t SpinLock::kWaitTimeMask; - +// Static member variable definitions. +constexpr uint32_t SpinLock::kSpinLockHeld; +constexpr uint32_t SpinLock::kSpinLockCooperative; +constexpr uint32_t SpinLock::kSpinLockDisabledScheduling; +constexpr uint32_t SpinLock::kSpinLockSleeper; +constexpr uint32_t SpinLock::kWaitTimeMask; + // Uncommon constructors. SpinLock::SpinLock(base_internal::SchedulingMode mode) : lockword_(IsCooperative(mode) ? kSpinLockCooperative : 0) { @@ -105,14 +105,14 @@ void SpinLock::SlowLock() { if ((lock_value & kSpinLockHeld) == 0) { return; } - - base_internal::SchedulingMode scheduling_mode; - if ((lock_value & kSpinLockCooperative) != 0) { - scheduling_mode = base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL; - } else { - scheduling_mode = base_internal::SCHEDULE_KERNEL_ONLY; - } - + + base_internal::SchedulingMode scheduling_mode; + if ((lock_value & kSpinLockCooperative) != 0) { + scheduling_mode = base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL; + } else { + scheduling_mode = base_internal::SCHEDULE_KERNEL_ONLY; + } + // The lock was not obtained initially, so this thread needs to wait for // it. Record the current timestamp in the local variable wait_start_time // so the total wait time can be stored in the lockword once this thread @@ -185,32 +185,32 @@ void SpinLock::SlowUnlock(uint32_t lock_value) { // We use the upper 29 bits of the lock word to store the time spent waiting to // acquire this lock. This is reported by contentionz profiling. Since the // lower bits of the cycle counter wrap very quickly on high-frequency -// processors we divide to reduce the granularity to 2^kProfileTimestampShift +// processors we divide to reduce the granularity to 2^kProfileTimestampShift // sized units. On a 4Ghz machine this will lose track of wait times greater // than (2^29/4 Ghz)*128 =~ 17.2 seconds. Such waits should be extremely rare. -static constexpr int kProfileTimestampShift = 7; - -// We currently reserve the lower 3 bits. -static constexpr int kLockwordReservedShift = 3; +static constexpr int kProfileTimestampShift = 7; +// We currently reserve the lower 3 bits. +static constexpr int kLockwordReservedShift = 3; + uint32_t SpinLock::EncodeWaitCycles(int64_t wait_start_time, int64_t wait_end_time) { static const int64_t kMaxWaitTime = - std::numeric_limits<uint32_t>::max() >> kLockwordReservedShift; + std::numeric_limits<uint32_t>::max() >> kLockwordReservedShift; int64_t scaled_wait_time = - (wait_end_time - wait_start_time) >> kProfileTimestampShift; + (wait_end_time - wait_start_time) >> kProfileTimestampShift; // Return a representation of the time spent waiting that can be stored in // the lock word's upper bits. uint32_t clamped = static_cast<uint32_t>( - std::min(scaled_wait_time, kMaxWaitTime) << kLockwordReservedShift); + std::min(scaled_wait_time, kMaxWaitTime) << kLockwordReservedShift); if (clamped == 0) { return kSpinLockSleeper; // Just wake waiters, but don't record contention. } // Bump up value if necessary to avoid returning kSpinLockSleeper. const uint32_t kMinWaitTime = - kSpinLockSleeper + (1 << kLockwordReservedShift); + kSpinLockSleeper + (1 << kLockwordReservedShift); if (clamped == kSpinLockSleeper) { return kMinWaitTime; } @@ -221,9 +221,9 @@ uint64_t SpinLock::DecodeWaitCycles(uint32_t lock_value) { // Cast to uint32_t first to ensure bits [63:32] are cleared. const uint64_t scaled_wait_time = static_cast<uint32_t>(lock_value & kWaitTimeMask); - return scaled_wait_time << (kProfileTimestampShift - kLockwordReservedShift); + return scaled_wait_time << (kProfileTimestampShift - kLockwordReservedShift); } } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h index ac40daff12..80bbc4bff5 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock.h @@ -35,7 +35,7 @@ #include <atomic> #include "absl/base/attributes.h" -#include "absl/base/const_init.h" +#include "absl/base/const_init.h" #include "absl/base/dynamic_annotations.h" #include "absl/base/internal/low_level_scheduling.h" #include "absl/base/internal/raw_logging.h" @@ -46,7 +46,7 @@ #include "absl/base/thread_annotations.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { class ABSL_LOCKABLE SpinLock { @@ -59,18 +59,18 @@ class ABSL_LOCKABLE SpinLock { // inside thread schedulers. Normal clients should not use these. explicit SpinLock(base_internal::SchedulingMode mode); - // Constructor for global SpinLock instances. See absl/base/const_init.h. - constexpr SpinLock(absl::ConstInitType, base_internal::SchedulingMode mode) - : lockword_(IsCooperative(mode) ? kSpinLockCooperative : 0) {} - - // For global SpinLock instances prefer trivial destructor when possible. - // Default but non-trivial destructor in some build configurations causes an - // extra static initializer. -#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE + // Constructor for global SpinLock instances. See absl/base/const_init.h. + constexpr SpinLock(absl::ConstInitType, base_internal::SchedulingMode mode) + : lockword_(IsCooperative(mode) ? kSpinLockCooperative : 0) {} + + // For global SpinLock instances prefer trivial destructor when possible. + // Default but non-trivial destructor in some build configurations causes an + // extra static initializer. +#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE ~SpinLock() { ABSL_TSAN_MUTEX_DESTROY(this, __tsan_mutex_not_static); } -#else - ~SpinLock() = default; -#endif +#else + ~SpinLock() = default; +#endif // Acquire this SpinLock. inline void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION() { @@ -153,13 +153,13 @@ class ABSL_LOCKABLE SpinLock { // // Invariant: if the lock is not held, the value is either 0 or // kSpinLockCooperative. - static constexpr uint32_t kSpinLockHeld = 1; - static constexpr uint32_t kSpinLockCooperative = 2; - static constexpr uint32_t kSpinLockDisabledScheduling = 4; - static constexpr uint32_t kSpinLockSleeper = 8; - // Includes kSpinLockSleeper. - static constexpr uint32_t kWaitTimeMask = - ~(kSpinLockHeld | kSpinLockCooperative | kSpinLockDisabledScheduling); + static constexpr uint32_t kSpinLockHeld = 1; + static constexpr uint32_t kSpinLockCooperative = 2; + static constexpr uint32_t kSpinLockDisabledScheduling = 4; + static constexpr uint32_t kSpinLockSleeper = 8; + // Includes kSpinLockSleeper. + static constexpr uint32_t kWaitTimeMask = + ~(kSpinLockHeld | kSpinLockCooperative | kSpinLockDisabledScheduling); // Returns true if the provided scheduling mode is cooperative. static constexpr bool IsCooperative( @@ -242,7 +242,7 @@ inline uint32_t SpinLock::TryLockInternal(uint32_t lock_value, } } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_SPINLOCK_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_linux.inc b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_linux.inc index 202f7cdfc8..53226e5686 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_linux.inc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_linux.inc @@ -24,7 +24,7 @@ #include <ctime> #include "absl/base/attributes.h" -#include "absl/base/internal/errno_saver.h" +#include "absl/base/internal/errno_saver.h" // The SpinLock lockword is `std::atomic<uint32_t>`. Here we assert that // `std::atomic<uint32_t>` is bitwise equivalent of the `int` expected @@ -46,20 +46,20 @@ static_assert(sizeof(std::atomic<uint32_t>) == sizeof(int), #endif #endif -#if defined(__NR_futex_time64) && !defined(SYS_futex_time64) -#define SYS_futex_time64 __NR_futex_time64 -#endif - -#if defined(SYS_futex_time64) && !defined(SYS_futex) -#define SYS_futex SYS_futex_time64 -#endif - +#if defined(__NR_futex_time64) && !defined(SYS_futex_time64) +#define SYS_futex_time64 __NR_futex_time64 +#endif + +#if defined(SYS_futex_time64) && !defined(SYS_futex) +#define SYS_futex SYS_futex_time64 +#endif + extern "C" { ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( std::atomic<uint32_t> *w, uint32_t value, int loop, absl::base_internal::SchedulingMode) { - absl::base_internal::ErrnoSaver errno_saver; + absl::base_internal::ErrnoSaver errno_saver; struct timespec tm; tm.tv_sec = 0; tm.tv_nsec = absl::base_internal::SpinLockSuggestedDelayNS(loop); diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_posix.inc b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_posix.inc index 4f6f887d99..596dacef88 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_posix.inc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_posix.inc @@ -15,11 +15,11 @@ // This file is a Posix-specific part of spinlock_wait.cc #include <sched.h> - + #include <atomic> #include <ctime> -#include "absl/base/internal/errno_saver.h" +#include "absl/base/internal/errno_saver.h" #include "absl/base/internal/scheduling_mode.h" #include "absl/base/port.h" @@ -28,7 +28,7 @@ extern "C" { ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( std::atomic<uint32_t>* /* lock_word */, uint32_t /* value */, int loop, absl::base_internal::SchedulingMode /* mode */) { - absl::base_internal::ErrnoSaver errno_saver; + absl::base_internal::ErrnoSaver errno_saver; if (loop == 0) { } else if (loop == 1) { sched_yield(); diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait.cc b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait.cc index fa824be1c0..1570b6a7e2 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait.cc @@ -32,7 +32,7 @@ #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { // See spinlock_wait.h for spec. @@ -77,5 +77,5 @@ int SpinLockSuggestedDelayNS(int loop) { } } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait.h b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait.h index 9a1adcda5e..f806844419 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait.h @@ -24,7 +24,7 @@ #include "absl/base/internal/scheduling_mode.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { // SpinLockWait() waits until it can perform one of several transitions from @@ -63,7 +63,7 @@ void SpinLockDelay(std::atomic<uint32_t> *w, uint32_t value, int loop, int SpinLockSuggestedDelayNS(int loop); } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl // In some build configurations we pass --detect-odr-violations to the diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait/ya.make b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait/ya.make index 8eae89d717..c5e99fa179 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait/ya.make +++ b/contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait/ya.make @@ -16,10 +16,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/base/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/strerror.cc b/contrib/restricted/abseil-cpp/absl/base/internal/strerror.cc index 0d6226fd0a..dd00f1cd70 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/strerror.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/strerror.cc @@ -1,88 +1,88 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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 "absl/base/internal/strerror.h" - -#include <array> -#include <cerrno> -#include <cstddef> -#include <cstdio> -#include <cstring> -#include <string> -#include <type_traits> - -#include "absl/base/internal/errno_saver.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace base_internal { -namespace { - -const char* StrErrorAdaptor(int errnum, char* buf, size_t buflen) { -#if defined(_WIN32) - int rc = strerror_s(buf, buflen, errnum); - buf[buflen - 1] = '\0'; // guarantee NUL termination - if (rc == 0 && strncmp(buf, "Unknown error", buflen) == 0) *buf = '\0'; - return buf; -#else - // The type of `ret` is platform-specific; both of these branches must compile - // either way but only one will execute on any given platform: - auto ret = strerror_r(errnum, buf, buflen); - if (std::is_same<decltype(ret), int>::value) { - // XSI `strerror_r`; `ret` is `int`: - if (ret) *buf = '\0'; - return buf; - } else { - // GNU `strerror_r`; `ret` is `char *`: - return reinterpret_cast<const char*>(ret); - } -#endif -} - -std::string StrErrorInternal(int errnum) { - char buf[100]; - const char* str = StrErrorAdaptor(errnum, buf, sizeof buf); - if (*str == '\0') { - snprintf(buf, sizeof buf, "Unknown error %d", errnum); - str = buf; - } - return str; -} - -// kSysNerr is the number of errors from a recent glibc. `StrError()` falls back -// to `StrErrorAdaptor()` if the value is larger than this. -constexpr int kSysNerr = 135; - -std::array<std::string, kSysNerr>* NewStrErrorTable() { - auto* table = new std::array<std::string, kSysNerr>; - for (int i = 0; i < static_cast<int>(table->size()); ++i) { - (*table)[i] = StrErrorInternal(i); - } - return table; -} - -} // namespace - -std::string StrError(int errnum) { +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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 "absl/base/internal/strerror.h" + +#include <array> +#include <cerrno> +#include <cstddef> +#include <cstdio> +#include <cstring> +#include <string> +#include <type_traits> + +#include "absl/base/internal/errno_saver.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace base_internal { +namespace { + +const char* StrErrorAdaptor(int errnum, char* buf, size_t buflen) { +#if defined(_WIN32) + int rc = strerror_s(buf, buflen, errnum); + buf[buflen - 1] = '\0'; // guarantee NUL termination + if (rc == 0 && strncmp(buf, "Unknown error", buflen) == 0) *buf = '\0'; + return buf; +#else + // The type of `ret` is platform-specific; both of these branches must compile + // either way but only one will execute on any given platform: + auto ret = strerror_r(errnum, buf, buflen); + if (std::is_same<decltype(ret), int>::value) { + // XSI `strerror_r`; `ret` is `int`: + if (ret) *buf = '\0'; + return buf; + } else { + // GNU `strerror_r`; `ret` is `char *`: + return reinterpret_cast<const char*>(ret); + } +#endif +} + +std::string StrErrorInternal(int errnum) { + char buf[100]; + const char* str = StrErrorAdaptor(errnum, buf, sizeof buf); + if (*str == '\0') { + snprintf(buf, sizeof buf, "Unknown error %d", errnum); + str = buf; + } + return str; +} + +// kSysNerr is the number of errors from a recent glibc. `StrError()` falls back +// to `StrErrorAdaptor()` if the value is larger than this. +constexpr int kSysNerr = 135; + +std::array<std::string, kSysNerr>* NewStrErrorTable() { + auto* table = new std::array<std::string, kSysNerr>; + for (int i = 0; i < static_cast<int>(table->size()); ++i) { + (*table)[i] = StrErrorInternal(i); + } + return table; +} + +} // namespace + +std::string StrError(int errnum) { absl::base_internal::ErrnoSaver errno_saver; - static const auto* table = NewStrErrorTable(); - if (errnum >= 0 && errnum < static_cast<int>(table->size())) { - return (*table)[errnum]; - } - return StrErrorInternal(errnum); -} - -} // namespace base_internal -ABSL_NAMESPACE_END -} // namespace absl + static const auto* table = NewStrErrorTable(); + if (errnum >= 0 && errnum < static_cast<int>(table->size())) { + return (*table)[errnum]; + } + return StrErrorInternal(errnum); +} + +} // namespace base_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/strerror.h b/contrib/restricted/abseil-cpp/absl/base/internal/strerror.h index 350097366e..4d44a0f9b4 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/strerror.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/strerror.h @@ -1,39 +1,39 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. - -#ifndef ABSL_BASE_INTERNAL_STRERROR_H_ -#define ABSL_BASE_INTERNAL_STRERROR_H_ - -#include <string> - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace base_internal { - -// A portable and thread-safe alternative to C89's `strerror`. -// -// The C89 specification of `strerror` is not suitable for use in a -// multi-threaded application as the returned string may be changed by calls to -// `strerror` from another thread. The many non-stdlib alternatives differ -// enough in their names, availability, and semantics to justify this wrapper -// around them. `errno` will not be modified by a call to `absl::StrError`. -std::string StrError(int errnum); - -} // namespace base_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_BASE_INTERNAL_STRERROR_H_ +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. + +#ifndef ABSL_BASE_INTERNAL_STRERROR_H_ +#define ABSL_BASE_INTERNAL_STRERROR_H_ + +#include <string> + +#include "absl/base/config.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace base_internal { + +// A portable and thread-safe alternative to C89's `strerror`. +// +// The C89 specification of `strerror` is not suitable for use in a +// multi-threaded application as the returned string may be changed by calls to +// `strerror` from another thread. The many non-stdlib alternatives differ +// enough in their names, availability, and semantics to justify this wrapper +// around them. `errno` will not be modified by a call to `absl::StrError`. +std::string StrError(int errnum); + +} // namespace base_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_STRERROR_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/strerror/ya.make b/contrib/restricted/abseil-cpp/absl/base/internal/strerror/ya.make index deedba52eb..346a5e7172 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/strerror/ya.make +++ b/contrib/restricted/abseil-cpp/absl/base/internal/strerror/ya.make @@ -1,29 +1,29 @@ -# Generated by devtools/yamaker. - -LIBRARY() - +# Generated by devtools/yamaker. + +LIBRARY() + WITHOUT_LICENSE_TEXTS() -OWNER(g:cpp-contrib) - -LICENSE(Apache-2.0) - -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DNOMINMAX -) - -SRCDIR(contrib/restricted/abseil-cpp/absl/base/internal) - -SRCS( - strerror.cc -) - -END() +OWNER(g:cpp-contrib) + +LICENSE(Apache-2.0) + +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DNOMINMAX +) + +SRCDIR(contrib/restricted/abseil-cpp/absl/base/internal) + +SRCS( + strerror.cc +) + +END() diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc b/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc index 8c2e6c87fa..2f9d93b9e0 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.cc @@ -39,7 +39,7 @@ #endif #include <string.h> - + #include <cassert> #include <cstdint> #include <cstdio> @@ -51,14 +51,14 @@ #include <vector> #include "absl/base/call_once.h" -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/base/internal/raw_logging.h" #include "absl/base/internal/spinlock.h" #include "absl/base/internal/unscaledcycleclock.h" -#include "absl/base/thread_annotations.h" +#include "absl/base/thread_annotations.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { namespace { @@ -144,32 +144,32 @@ static int GetNumCPUs() { #if defined(_WIN32) static double GetNominalCPUFrequency() { -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ - !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) - // UWP apps don't have access to the registry and currently don't provide an - // API informing about CPU nominal frequency. - return 1.0; -#else -#pragma comment(lib, "advapi32.lib") // For Reg* functions. - HKEY key; - // Use the Reg* functions rather than the SH functions because shlwapi.dll - // pulls in gdi32.dll which makes process destruction much more costly. - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, - "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, - KEY_READ, &key) == ERROR_SUCCESS) { - DWORD type = 0; - DWORD data = 0; - DWORD data_size = sizeof(data); - auto result = RegQueryValueExA(key, "~MHz", 0, &type, - reinterpret_cast<LPBYTE>(&data), &data_size); - RegCloseKey(key); - if (result == ERROR_SUCCESS && type == REG_DWORD && - data_size == sizeof(data)) { - return data * 1e6; // Value is MHz. - } +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ + !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + // UWP apps don't have access to the registry and currently don't provide an + // API informing about CPU nominal frequency. + return 1.0; +#else +#pragma comment(lib, "advapi32.lib") // For Reg* functions. + HKEY key; + // Use the Reg* functions rather than the SH functions because shlwapi.dll + // pulls in gdi32.dll which makes process destruction much more costly. + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, + "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, + KEY_READ, &key) == ERROR_SUCCESS) { + DWORD type = 0; + DWORD data = 0; + DWORD data_size = sizeof(data); + auto result = RegQueryValueExA(key, "~MHz", 0, &type, + reinterpret_cast<LPBYTE>(&data), &data_size); + RegCloseKey(key); + if (result == ERROR_SUCCESS && type == REG_DWORD && + data_size == sizeof(data)) { + return data * 1e6; // Value is MHz. + } } return 1.0; -#endif // WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP +#endif // WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP } #elif defined(CTL_HW) && defined(HW_CPU_FREQ) @@ -340,34 +340,34 @@ static double GetNominalCPUFrequency() { #endif -ABSL_CONST_INIT static once_flag init_num_cpus_once; -ABSL_CONST_INIT static int num_cpus = 0; +ABSL_CONST_INIT static once_flag init_num_cpus_once; +ABSL_CONST_INIT static int num_cpus = 0; -// NumCPUs() may be called before main() and before malloc is properly -// initialized, therefore this must not allocate memory. +// NumCPUs() may be called before main() and before malloc is properly +// initialized, therefore this must not allocate memory. int NumCPUs() { - base_internal::LowLevelCallOnce( - &init_num_cpus_once, []() { num_cpus = GetNumCPUs(); }); + base_internal::LowLevelCallOnce( + &init_num_cpus_once, []() { num_cpus = GetNumCPUs(); }); return num_cpus; } -// A default frequency of 0.0 might be dangerous if it is used in division. -ABSL_CONST_INIT static once_flag init_nominal_cpu_frequency_once; -ABSL_CONST_INIT static double nominal_cpu_frequency = 1.0; - -// NominalCPUFrequency() may be called before main() and before malloc is -// properly initialized, therefore this must not allocate memory. +// A default frequency of 0.0 might be dangerous if it is used in division. +ABSL_CONST_INIT static once_flag init_nominal_cpu_frequency_once; +ABSL_CONST_INIT static double nominal_cpu_frequency = 1.0; + +// NominalCPUFrequency() may be called before main() and before malloc is +// properly initialized, therefore this must not allocate memory. double NominalCPUFrequency() { - base_internal::LowLevelCallOnce( - &init_nominal_cpu_frequency_once, - []() { nominal_cpu_frequency = GetNominalCPUFrequency(); }); + base_internal::LowLevelCallOnce( + &init_nominal_cpu_frequency_once, + []() { nominal_cpu_frequency = GetNominalCPUFrequency(); }); return nominal_cpu_frequency; } #if defined(_WIN32) pid_t GetTID() { - return pid_t{GetCurrentThreadId()}; + return pid_t{GetCurrentThreadId()}; } #elif defined(__linux__) @@ -415,16 +415,16 @@ pid_t GetTID() { #else // Fallback implementation of GetTID using pthread_getspecific. -ABSL_CONST_INIT static once_flag tid_once; -ABSL_CONST_INIT static pthread_key_t tid_key; -ABSL_CONST_INIT static absl::base_internal::SpinLock tid_lock( - absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY); +ABSL_CONST_INIT static once_flag tid_once; +ABSL_CONST_INIT static pthread_key_t tid_key; +ABSL_CONST_INIT static absl::base_internal::SpinLock tid_lock( + absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY); // We set a bit per thread in this array to indicate that an ID is in // use. ID 0 is unused because it is the default value returned by // pthread_getspecific(). -ABSL_CONST_INIT static std::vector<uint32_t> *tid_array - ABSL_GUARDED_BY(tid_lock) = nullptr; +ABSL_CONST_INIT static std::vector<uint32_t> *tid_array + ABSL_GUARDED_BY(tid_lock) = nullptr; static constexpr int kBitsPerWord = 32; // tid_array is uint32_t. // Returns the TID to tid_array. @@ -491,18 +491,18 @@ pid_t GetTID() { #endif -// GetCachedTID() caches the thread ID in thread-local storage (which is a -// userspace construct) to avoid unnecessary system calls. Without this caching, -// it can take roughly 98ns, while it takes roughly 1ns with this caching. -pid_t GetCachedTID() { +// GetCachedTID() caches the thread ID in thread-local storage (which is a +// userspace construct) to avoid unnecessary system calls. Without this caching, +// it can take roughly 98ns, while it takes roughly 1ns with this caching. +pid_t GetCachedTID() { #ifdef ABSL_HAVE_THREAD_LOCAL - static thread_local pid_t thread_id = GetTID(); - return thread_id; -#else - return GetTID(); -#endif // ABSL_HAVE_THREAD_LOCAL -} - + static thread_local pid_t thread_id = GetTID(); + return thread_id; +#else + return GetTID(); +#endif // ABSL_HAVE_THREAD_LOCAL +} + } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.h b/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.h index 119cf1f0e8..77317f352c 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/sysinfo.h @@ -28,13 +28,13 @@ #include <sys/types.h> #endif -#include <cstdint> - -#include "absl/base/config.h" +#include <cstdint> + +#include "absl/base/config.h" #include "absl/base/port.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { // Nominal core processor cycles per second of each processor. This is _not_ @@ -53,22 +53,22 @@ int NumCPUs(); // On Linux, you may send a signal to the resulting ID with kill(). However, // it is recommended for portability that you use pthread_kill() instead. #ifdef _WIN32 -// On Windows, process id and thread id are of the same type according to the -// return types of GetProcessId() and GetThreadId() are both DWORD, an unsigned -// 32-bit type. -using pid_t = uint32_t; +// On Windows, process id and thread id are of the same type according to the +// return types of GetProcessId() and GetThreadId() are both DWORD, an unsigned +// 32-bit type. +using pid_t = uint32_t; #endif pid_t GetTID(); -// Like GetTID(), but caches the result in thread-local storage in order -// to avoid unnecessary system calls. Note that there are some cases where -// one must call through to GetTID directly, which is why this exists as a -// separate function. For example, GetCachedTID() is not safe to call in -// an asynchronous signal-handling context nor right after a call to fork(). -pid_t GetCachedTID(); - +// Like GetTID(), but caches the result in thread-local storage in order +// to avoid unnecessary system calls. Note that there are some cases where +// one must call through to GetTID directly, which is why this exists as a +// separate function. For example, GetCachedTID() is not safe to call in +// an asynchronous signal-handling context nor right after a call to fork(). +pid_t GetCachedTID(); + } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_SYSINFO_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.cc b/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.cc index 9950e63a79..8b7b938524 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.cc @@ -29,7 +29,7 @@ #include "absl/base/internal/spinlock.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { #if ABSL_THREAD_IDENTITY_MODE != ABSL_THREAD_IDENTITY_MODE_USE_CPP11 @@ -59,12 +59,12 @@ void AllocateThreadIdentityKey(ThreadIdentityReclaimerFunction reclaimer) { #if ABSL_HAVE_ATTRIBUTE(visibility) && !defined(__APPLE__) __attribute__((visibility("protected"))) #endif // ABSL_HAVE_ATTRIBUTE(visibility) && !defined(__APPLE__) -#if ABSL_PER_THREAD_TLS -// Prefer __thread to thread_local as benchmarks indicate it is a bit faster. -ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity* thread_identity_ptr = nullptr; -#elif defined(ABSL_HAVE_THREAD_LOCAL) -thread_local ThreadIdentity* thread_identity_ptr = nullptr; -#endif // ABSL_PER_THREAD_TLS +#if ABSL_PER_THREAD_TLS +// Prefer __thread to thread_local as benchmarks indicate it is a bit faster. +ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity* thread_identity_ptr = nullptr; +#elif defined(ABSL_HAVE_THREAD_LOCAL) +thread_local ThreadIdentity* thread_identity_ptr = nullptr; +#endif // ABSL_PER_THREAD_TLS #endif // TLS or CPP11 void SetCurrentThreadIdentity( @@ -78,8 +78,8 @@ void SetCurrentThreadIdentity( absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey, reclaimer); -#if defined(__EMSCRIPTEN__) || defined(__MINGW32__) - // Emscripten and MinGW pthread implementations does not support signals. +#if defined(__EMSCRIPTEN__) || defined(__MINGW32__) + // Emscripten and MinGW pthread implementations does not support signals. // See https://kripken.github.io/emscripten-site/docs/porting/pthreads.html // for more information. pthread_setspecific(thread_identity_pthread_key, @@ -98,7 +98,7 @@ void SetCurrentThreadIdentity( pthread_setspecific(thread_identity_pthread_key, reinterpret_cast<void*>(identity)); pthread_sigmask(SIG_SETMASK, &curr_signals, nullptr); -#endif // !__EMSCRIPTEN__ && !__MINGW32__ +#endif // !__EMSCRIPTEN__ && !__MINGW32__ #elif ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS // NOTE: Not async-safe. But can be open-coded. @@ -116,18 +116,18 @@ void SetCurrentThreadIdentity( #endif } -#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ - ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 - -// Please see the comment on `CurrentThreadIdentityIfPresent` in +#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ + ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 + +// Please see the comment on `CurrentThreadIdentityIfPresent` in // thread_identity.h. When we cannot expose thread_local variables in // headers, we opt for the correct-but-slower option of not inlining this // function. #ifndef ABSL_INTERNAL_INLINE_CURRENT_THREAD_IDENTITY_IF_PRESENT -ThreadIdentity* CurrentThreadIdentityIfPresent() { return thread_identity_ptr; } -#endif -#endif - +ThreadIdentity* CurrentThreadIdentityIfPresent() { return thread_identity_ptr; } +#endif +#endif + void ClearCurrentThreadIdentity() { #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 @@ -151,5 +151,5 @@ ThreadIdentity* CurrentThreadIdentityIfPresent() { #endif } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.h b/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.h index 659694b326..348ac0d7a2 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/thread_identity.h @@ -30,12 +30,12 @@ #include <atomic> #include <cstdint> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/base/internal/per_thread_tls.h" #include "absl/base/optimization.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN struct SynchLocksHeld; struct SynchWaitParams; @@ -209,7 +209,7 @@ void ClearCurrentThreadIdentity(); #error ABSL_THREAD_IDENTITY_MODE cannot be directly set #elif defined(ABSL_FORCE_THREAD_IDENTITY_MODE) #define ABSL_THREAD_IDENTITY_MODE ABSL_FORCE_THREAD_IDENTITY_MODE -#elif defined(_WIN32) && !defined(__MINGW32__) +#elif defined(_WIN32) && !defined(__MINGW32__) #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11 #elif defined(__APPLE__) && defined(ABSL_HAVE_THREAD_LOCAL) #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11 @@ -227,20 +227,20 @@ void ClearCurrentThreadIdentity(); #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 -#if ABSL_PER_THREAD_TLS -ABSL_CONST_INIT extern ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity* - thread_identity_ptr; -#elif defined(ABSL_HAVE_THREAD_LOCAL) -ABSL_CONST_INIT extern thread_local ThreadIdentity* thread_identity_ptr; -#else -#error Thread-local storage not detected on this platform -#endif +#if ABSL_PER_THREAD_TLS +ABSL_CONST_INIT extern ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity* + thread_identity_ptr; +#elif defined(ABSL_HAVE_THREAD_LOCAL) +ABSL_CONST_INIT extern thread_local ThreadIdentity* thread_identity_ptr; +#else +#error Thread-local storage not detected on this platform +#endif // thread_local variables cannot be in headers exposed by DLLs or in certain // build configurations on Apple platforms. However, it is important for // performance reasons in general that `CurrentThreadIdentityIfPresent` be // inlined. In the other cases we opt to have the function not be inlined. Note -// that `CurrentThreadIdentityIfPresent` is declared above so we can exclude +// that `CurrentThreadIdentityIfPresent` is declared above so we can exclude // this entire inline definition. #if !defined(__APPLE__) && !defined(ABSL_BUILD_DLL) && \ !defined(ABSL_CONSUME_DLL) @@ -251,7 +251,7 @@ ABSL_CONST_INIT extern thread_local ThreadIdentity* thread_identity_ptr; inline ThreadIdentity* CurrentThreadIdentityIfPresent() { return thread_identity_ptr; } -#endif +#endif #elif ABSL_THREAD_IDENTITY_MODE != \ ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC @@ -259,7 +259,7 @@ inline ThreadIdentity* CurrentThreadIdentityIfPresent() { #endif } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate.cc b/contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate.cc index c260ff1eed..0535f55265 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate.cc @@ -23,7 +23,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { // NOTE: The various STL exception throwing functions are placed within the @@ -208,5 +208,5 @@ void ThrowStdBadAlloc() { } } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate.h b/contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate.h index 075f527254..93e9b9ae73 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate.h @@ -19,10 +19,10 @@ #include <string> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { // Helper functions that allow throwing exceptions consistently from anywhere. @@ -69,7 +69,7 @@ namespace base_internal { // [[noreturn]] void ThrowStdBadArrayNewLength(); } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate/ya.make b/contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate/ya.make index 3df680adf0..2c4ad47ce4 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate/ya.make +++ b/contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate/ya.make @@ -21,10 +21,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/base/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/tsan_mutex_interface.h b/contrib/restricted/abseil-cpp/absl/base/internal/tsan_mutex_interface.h index 39207d8a5c..18bd39b615 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/tsan_mutex_interface.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/tsan_mutex_interface.h @@ -19,8 +19,8 @@ #ifndef ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_ #define ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + // ABSL_INTERNAL_HAVE_TSAN_INTERFACE // Macro intended only for internal use. // @@ -30,7 +30,7 @@ #error "ABSL_INTERNAL_HAVE_TSAN_INTERFACE cannot be directly set." #endif -#if defined(ABSL_HAVE_THREAD_SANITIZER) && defined(__has_include) +#if defined(ABSL_HAVE_THREAD_SANITIZER) && defined(__has_include) #if __has_include(<sanitizer/tsan_interface.h>) #define ABSL_INTERNAL_HAVE_TSAN_INTERFACE 1 #endif diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/unaligned_access.h b/contrib/restricted/abseil-cpp/absl/base/internal/unaligned_access.h index 093dd9b499..a07e342351 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/unaligned_access.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/unaligned_access.h @@ -18,11 +18,11 @@ #define ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_ #include <string.h> - + #include <cstdint> #include "absl/base/attributes.h" -#include "absl/base/config.h" +#include "absl/base/config.h" // unaligned APIs @@ -32,7 +32,7 @@ // (namespaces, inline) which are absent or incompatible in C. #if defined(__cplusplus) namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { inline uint16_t UnalignedLoad16(const void *p) { @@ -60,7 +60,7 @@ inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); } inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc b/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc index 4d352bd110..f4f1990ae1 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +++ b/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.cc @@ -21,18 +21,18 @@ #endif #if defined(__powerpc__) || defined(__ppc__) -#ifdef __GLIBC__ +#ifdef __GLIBC__ #include <sys/platform/ppc.h> -#elif defined(__FreeBSD__) -#include <sys/sysctl.h> -#include <sys/types.h> -#endif +#elif defined(__FreeBSD__) +#include <sys/sysctl.h> +#include <sys/types.h> #endif +#endif #include "absl/base/internal/sysinfo.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { #if defined(__i386__) @@ -62,47 +62,47 @@ double UnscaledCycleClock::Frequency() { #elif defined(__powerpc__) || defined(__ppc__) int64_t UnscaledCycleClock::Now() { -#ifdef __GLIBC__ +#ifdef __GLIBC__ return __ppc_get_timebase(); -#else -#ifdef __powerpc64__ - int64_t tbr; - asm volatile("mfspr %0, 268" : "=r"(tbr)); - return tbr; -#else - int32_t tbu, tbl, tmp; - asm volatile( - "0:\n" - "mftbu %[hi32]\n" - "mftb %[lo32]\n" - "mftbu %[tmp]\n" - "cmpw %[tmp],%[hi32]\n" - "bne 0b\n" - : [ hi32 ] "=r"(tbu), [ lo32 ] "=r"(tbl), [ tmp ] "=r"(tmp)); - return (static_cast<int64_t>(tbu) << 32) | tbl; -#endif -#endif +#else +#ifdef __powerpc64__ + int64_t tbr; + asm volatile("mfspr %0, 268" : "=r"(tbr)); + return tbr; +#else + int32_t tbu, tbl, tmp; + asm volatile( + "0:\n" + "mftbu %[hi32]\n" + "mftb %[lo32]\n" + "mftbu %[tmp]\n" + "cmpw %[tmp],%[hi32]\n" + "bne 0b\n" + : [ hi32 ] "=r"(tbu), [ lo32 ] "=r"(tbl), [ tmp ] "=r"(tmp)); + return (static_cast<int64_t>(tbu) << 32) | tbl; +#endif +#endif } double UnscaledCycleClock::Frequency() { -#ifdef __GLIBC__ +#ifdef __GLIBC__ return __ppc_get_timebase_freq(); #elif defined(_AIX) // This is the same constant value as returned by // __ppc_get_timebase_freq(). return static_cast<double>(512000000); -#elif defined(__FreeBSD__) - static once_flag init_timebase_frequency_once; - static double timebase_frequency = 0.0; - base_internal::LowLevelCallOnce(&init_timebase_frequency_once, [&]() { - size_t length = sizeof(timebase_frequency); - sysctlbyname("kern.timecounter.tc.timebase.frequency", &timebase_frequency, - &length, nullptr, 0); - }); - return timebase_frequency; -#else -#error Must implement UnscaledCycleClock::Frequency() -#endif +#elif defined(__FreeBSD__) + static once_flag init_timebase_frequency_once; + static double timebase_frequency = 0.0; + base_internal::LowLevelCallOnce(&init_timebase_frequency_once, [&]() { + size_t length = sizeof(timebase_frequency); + sysctlbyname("kern.timecounter.tc.timebase.frequency", &timebase_frequency, + &length, nullptr, 0); + }); + return timebase_frequency; +#else +#error Must implement UnscaledCycleClock::Frequency() +#endif } #elif defined(__aarch64__) @@ -139,7 +139,7 @@ double UnscaledCycleClock::Frequency() { #pragma intrinsic(__rdtsc) -int64_t UnscaledCycleClock::Now() { return __rdtsc(); } +int64_t UnscaledCycleClock::Now() { return __rdtsc(); } double UnscaledCycleClock::Frequency() { return base_internal::NominalCPUFrequency(); @@ -148,7 +148,7 @@ double UnscaledCycleClock::Frequency() { #endif } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USE_UNSCALED_CYCLECLOCK diff --git a/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h b/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h index 681ff8f996..f409de29ac 100644 --- a/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h +++ b/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h @@ -15,8 +15,8 @@ // UnscaledCycleClock // An UnscaledCycleClock yields the value and frequency of a cycle counter // that increments at a rate that is approximately constant. -// This class is for internal use only, you should consider using CycleClock -// instead. +// This class is for internal use only, you should consider using CycleClock +// instead. // // Notes: // The cycle counter frequency is not necessarily the core clock frequency. @@ -86,7 +86,7 @@ #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { class UnscaledCycleClockWrapperForGetCurrentTime; } // namespace time_internal @@ -109,14 +109,14 @@ class UnscaledCycleClock { // value. static double Frequency(); - // Allowed users + // Allowed users friend class base_internal::CycleClock; friend class time_internal::UnscaledCycleClockWrapperForGetCurrentTime; friend class base_internal::UnscaledCycleClockWrapperForInitializeFrequency; }; } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USE_UNSCALED_CYCLECLOCK diff --git a/contrib/restricted/abseil-cpp/absl/base/log_severity.cc b/contrib/restricted/abseil-cpp/absl/base/log_severity.cc index 72312afd36..a8f1507f41 100644 --- a/contrib/restricted/abseil-cpp/absl/base/log_severity.cc +++ b/contrib/restricted/abseil-cpp/absl/base/log_severity.cc @@ -17,11 +17,11 @@ #include <ostream> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN std::ostream& operator<<(std::ostream& os, absl::LogSeverity s) { if (s == absl::NormalizeLogSeverity(s)) return os << absl::LogSeverityName(s); return os << "absl::LogSeverity(" << static_cast<int>(s) << ")"; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/base/log_severity.h b/contrib/restricted/abseil-cpp/absl/base/log_severity.h index 2236422462..858813ed38 100644 --- a/contrib/restricted/abseil-cpp/absl/base/log_severity.h +++ b/contrib/restricted/abseil-cpp/absl/base/log_severity.h @@ -12,58 +12,58 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef ABSL_BASE_LOG_SEVERITY_H_ -#define ABSL_BASE_LOG_SEVERITY_H_ +#ifndef ABSL_BASE_LOG_SEVERITY_H_ +#define ABSL_BASE_LOG_SEVERITY_H_ #include <array> #include <ostream> #include "absl/base/attributes.h" -#include "absl/base/config.h" +#include "absl/base/config.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN -// absl::LogSeverity -// -// Four severity levels are defined. Logging APIs should terminate the program +// absl::LogSeverity +// +// Four severity levels are defined. Logging APIs should terminate the program // when a message is logged at severity `kFatal`; the other levels have no // special semantics. // -// Values other than the four defined levels (e.g. produced by `static_cast`) -// are valid, but their semantics when passed to a function, macro, or flag -// depend on the function, macro, or flag. The usual behavior is to normalize -// such values to a defined severity level, however in some cases values other -// than the defined levels are useful for comparison. +// Values other than the four defined levels (e.g. produced by `static_cast`) +// are valid, but their semantics when passed to a function, macro, or flag +// depend on the function, macro, or flag. The usual behavior is to normalize +// such values to a defined severity level, however in some cases values other +// than the defined levels are useful for comparison. // // Example: // -// // Effectively disables all logging: -// SetMinLogLevel(static_cast<absl::LogSeverity>(100)); -// -// Abseil flags may be defined with type `LogSeverity`. Dependency layering -// constraints require that the `AbslParseFlag()` overload be declared and -// defined in the flags library itself rather than here. The `AbslUnparseFlag()` -// overload is defined there as well for consistency. -// -// absl::LogSeverity Flag String Representation -// -// An `absl::LogSeverity` has a string representation used for parsing -// command-line flags based on the enumerator name (e.g. `kFatal`) or -// its unprefixed name (without the `k`) in any case-insensitive form. (E.g. -// "FATAL", "fatal" or "Fatal" are all valid.) Unparsing such flags produces an -// unprefixed string representation in all caps (e.g. "FATAL") or an integer. -// -// Additionally, the parser accepts arbitrary integers (as if the type were -// `int`). -// -// Examples: -// -// --my_log_level=kInfo -// --my_log_level=INFO -// --my_log_level=info -// --my_log_level=0 -// +// // Effectively disables all logging: +// SetMinLogLevel(static_cast<absl::LogSeverity>(100)); +// +// Abseil flags may be defined with type `LogSeverity`. Dependency layering +// constraints require that the `AbslParseFlag()` overload be declared and +// defined in the flags library itself rather than here. The `AbslUnparseFlag()` +// overload is defined there as well for consistency. +// +// absl::LogSeverity Flag String Representation +// +// An `absl::LogSeverity` has a string representation used for parsing +// command-line flags based on the enumerator name (e.g. `kFatal`) or +// its unprefixed name (without the `k`) in any case-insensitive form. (E.g. +// "FATAL", "fatal" or "Fatal" are all valid.) Unparsing such flags produces an +// unprefixed string representation in all caps (e.g. "FATAL") or an integer. +// +// Additionally, the parser accepts arbitrary integers (as if the type were +// `int`). +// +// Examples: +// +// --my_log_level=kInfo +// --my_log_level=INFO +// --my_log_level=info +// --my_log_level=0 +// // Unparsing a flag produces the same result as `absl::LogSeverityName()` for // the standard levels and a base-ten integer otherwise. enum class LogSeverity : int { @@ -73,8 +73,8 @@ enum class LogSeverity : int { kFatal = 3, }; -// LogSeverities() -// +// LogSeverities() +// // Returns an iterable of all standard `absl::LogSeverity` values, ordered from // least to most severe. constexpr std::array<absl::LogSeverity, 4> LogSeverities() { @@ -82,8 +82,8 @@ constexpr std::array<absl::LogSeverity, 4> LogSeverities() { absl::LogSeverity::kError, absl::LogSeverity::kFatal}}; } -// LogSeverityName() -// +// LogSeverityName() +// // Returns the all-caps string representation (e.g. "INFO") of the specified // severity level if it is one of the standard levels and "UNKNOWN" otherwise. constexpr const char* LogSeverityName(absl::LogSeverity s) { @@ -96,8 +96,8 @@ constexpr const char* LogSeverityName(absl::LogSeverity s) { : s == absl::LogSeverity::kFatal ? "FATAL" : "UNKNOWN"; } -// NormalizeLogSeverity() -// +// NormalizeLogSeverity() +// // Values less than `kInfo` normalize to `kInfo`; values greater than `kFatal` // normalize to `kError` (**NOT** `kFatal`). constexpr absl::LogSeverity NormalizeLogSeverity(absl::LogSeverity s) { @@ -109,13 +109,13 @@ constexpr absl::LogSeverity NormalizeLogSeverity(int s) { return absl::NormalizeLogSeverity(static_cast<absl::LogSeverity>(s)); } -// operator<< -// +// operator<< +// // The exact representation of a streamed `absl::LogSeverity` is deliberately // unspecified; do not rely on it. std::ostream& operator<<(std::ostream& os, absl::LogSeverity s); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl -#endif // ABSL_BASE_LOG_SEVERITY_H_ +#endif // ABSL_BASE_LOG_SEVERITY_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/log_severity/ya.make b/contrib/restricted/abseil-cpp/absl/base/log_severity/ya.make index f249279d8e..a238af4a2c 100644 --- a/contrib/restricted/abseil-cpp/absl/base/log_severity/ya.make +++ b/contrib/restricted/abseil-cpp/absl/base/log_severity/ya.make @@ -16,10 +16,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/base) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/base/macros.h b/contrib/restricted/abseil-cpp/absl/base/macros.h index 3e085a916b..6b63fecef3 100644 --- a/contrib/restricted/abseil-cpp/absl/base/macros.h +++ b/contrib/restricted/abseil-cpp/absl/base/macros.h @@ -31,8 +31,8 @@ #include <cassert> #include <cstddef> -#include "absl/base/attributes.h" -#include "absl/base/config.h" +#include "absl/base/attributes.h" +#include "absl/base/config.h" #include "absl/base/optimization.h" #include "absl/base/port.h" @@ -45,14 +45,14 @@ (sizeof(::absl::macros_internal::ArraySizeHelper(array))) namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace macros_internal { // Note: this internal template function declaration is used by ABSL_ARRAYSIZE. // The function doesn't need a definition, as we only use its type. template <typename T, size_t N> auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N]; } // namespace macros_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl // ABSL_BAD_CALL_IF() @@ -60,7 +60,7 @@ ABSL_NAMESPACE_END // Used on a function overload to trap bad calls: any call that matches the // overload will cause a compile-time error. This macro uses a clang-specific // "enable_if" attribute, as described at -// https://clang.llvm.org/docs/AttributeReference.html#enable-if +// https://clang.llvm.org/docs/AttributeReference.html#enable-if // // Overloads which use this macro should be bracketed by // `#ifdef ABSL_BAD_CALL_IF`. @@ -73,9 +73,9 @@ ABSL_NAMESPACE_END // ABSL_BAD_CALL_IF(c <= -1 || c > 255, // "'c' must have the value of an unsigned char or EOF"); // #endif // ABSL_BAD_CALL_IF -#if ABSL_HAVE_ATTRIBUTE(enable_if) -#define ABSL_BAD_CALL_IF(expr, msg) \ - __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg))) +#if ABSL_HAVE_ATTRIBUTE(enable_if) +#define ABSL_BAD_CALL_IF(expr, msg) \ + __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg))) #endif // ABSL_ASSERT() @@ -99,41 +99,41 @@ ABSL_NAMESPACE_END : [] { assert(false && #expr); }()) // NOLINT #endif -// `ABSL_INTERNAL_HARDENING_ABORT()` controls how `ABSL_HARDENING_ASSERT()` -// aborts the program in release mode (when NDEBUG is defined). The -// implementation should abort the program as quickly as possible and ideally it -// should not be possible to ignore the abort request. -#if (ABSL_HAVE_BUILTIN(__builtin_trap) && \ - ABSL_HAVE_BUILTIN(__builtin_unreachable)) || \ - (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_INTERNAL_HARDENING_ABORT() \ - do { \ - __builtin_trap(); \ - __builtin_unreachable(); \ - } while (false) -#else -#define ABSL_INTERNAL_HARDENING_ABORT() abort() -#endif - -// ABSL_HARDENING_ASSERT() -// -// `ABSL_HARDENING_ASSERT()` is like `ABSL_ASSERT()`, but used to implement -// runtime assertions that should be enabled in hardened builds even when -// `NDEBUG` is defined. -// -// When `NDEBUG` is not defined, `ABSL_HARDENING_ASSERT()` is identical to -// `ABSL_ASSERT()`. -// -// See `ABSL_OPTION_HARDENED` in `absl/base/options.h` for more information on -// hardened mode. -#if ABSL_OPTION_HARDENED == 1 && defined(NDEBUG) -#define ABSL_HARDENING_ASSERT(expr) \ - (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \ - : [] { ABSL_INTERNAL_HARDENING_ABORT(); }()) -#else -#define ABSL_HARDENING_ASSERT(expr) ABSL_ASSERT(expr) -#endif - +// `ABSL_INTERNAL_HARDENING_ABORT()` controls how `ABSL_HARDENING_ASSERT()` +// aborts the program in release mode (when NDEBUG is defined). The +// implementation should abort the program as quickly as possible and ideally it +// should not be possible to ignore the abort request. +#if (ABSL_HAVE_BUILTIN(__builtin_trap) && \ + ABSL_HAVE_BUILTIN(__builtin_unreachable)) || \ + (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_INTERNAL_HARDENING_ABORT() \ + do { \ + __builtin_trap(); \ + __builtin_unreachable(); \ + } while (false) +#else +#define ABSL_INTERNAL_HARDENING_ABORT() abort() +#endif + +// ABSL_HARDENING_ASSERT() +// +// `ABSL_HARDENING_ASSERT()` is like `ABSL_ASSERT()`, but used to implement +// runtime assertions that should be enabled in hardened builds even when +// `NDEBUG` is defined. +// +// When `NDEBUG` is not defined, `ABSL_HARDENING_ASSERT()` is identical to +// `ABSL_ASSERT()`. +// +// See `ABSL_OPTION_HARDENED` in `absl/base/options.h` for more information on +// hardened mode. +#if ABSL_OPTION_HARDENED == 1 && defined(NDEBUG) +#define ABSL_HARDENING_ASSERT(expr) \ + (ABSL_PREDICT_TRUE((expr)) ? static_cast<void>(0) \ + : [] { ABSL_INTERNAL_HARDENING_ABORT(); }()) +#else +#define ABSL_HARDENING_ASSERT(expr) ABSL_ASSERT(expr) +#endif + #ifdef ABSL_HAVE_EXCEPTIONS #define ABSL_INTERNAL_TRY try #define ABSL_INTERNAL_CATCH_ANY catch (...) diff --git a/contrib/restricted/abseil-cpp/absl/base/optimization.h b/contrib/restricted/abseil-cpp/absl/base/optimization.h index d090be1286..5eab831ca3 100644 --- a/contrib/restricted/abseil-cpp/absl/base/optimization.h +++ b/contrib/restricted/abseil-cpp/absl/base/optimization.h @@ -174,71 +174,71 @@ // to yield performance improvements. #if ABSL_HAVE_BUILTIN(__builtin_expect) || \ (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_PREDICT_FALSE(x) (__builtin_expect(false || (x), false)) +#define ABSL_PREDICT_FALSE(x) (__builtin_expect(false || (x), false)) #define ABSL_PREDICT_TRUE(x) (__builtin_expect(false || (x), true)) #else #define ABSL_PREDICT_FALSE(x) (x) #define ABSL_PREDICT_TRUE(x) (x) #endif -// ABSL_INTERNAL_ASSUME(cond) +// ABSL_INTERNAL_ASSUME(cond) // Informs the compiler that a condition is always true and that it can assume -// it to be true for optimization purposes. The call has undefined behavior if -// the condition is false. -// In !NDEBUG mode, the condition is checked with an assert(). -// NOTE: The expression must not have side effects, as it will only be evaluated -// in some compilation modes and not others. -// -// Example: -// -// int x = ...; -// ABSL_INTERNAL_ASSUME(x >= 0); -// // The compiler can optimize the division to a simple right shift using the -// // assumption specified above. -// int y = x / 16; -// -#if !defined(NDEBUG) -#define ABSL_INTERNAL_ASSUME(cond) assert(cond) -#elif ABSL_HAVE_BUILTIN(__builtin_assume) -#define ABSL_INTERNAL_ASSUME(cond) __builtin_assume(cond) -#elif defined(__GNUC__) || ABSL_HAVE_BUILTIN(__builtin_unreachable) -#define ABSL_INTERNAL_ASSUME(cond) \ - do { \ - if (!(cond)) __builtin_unreachable(); \ - } while (0) -#elif defined(_MSC_VER) -#define ABSL_INTERNAL_ASSUME(cond) __assume(cond) -#else -#define ABSL_INTERNAL_ASSUME(cond) \ - do { \ - static_cast<void>(false && (cond)); \ - } while (0) -#endif - -// ABSL_INTERNAL_UNIQUE_SMALL_NAME(cond) -// This macro forces small unique name on a static file level symbols like -// static local variables or static functions. This is intended to be used in -// macro definitions to optimize the cost of generated code. Do NOT use it on +// it to be true for optimization purposes. The call has undefined behavior if +// the condition is false. +// In !NDEBUG mode, the condition is checked with an assert(). +// NOTE: The expression must not have side effects, as it will only be evaluated +// in some compilation modes and not others. +// +// Example: +// +// int x = ...; +// ABSL_INTERNAL_ASSUME(x >= 0); +// // The compiler can optimize the division to a simple right shift using the +// // assumption specified above. +// int y = x / 16; +// +#if !defined(NDEBUG) +#define ABSL_INTERNAL_ASSUME(cond) assert(cond) +#elif ABSL_HAVE_BUILTIN(__builtin_assume) +#define ABSL_INTERNAL_ASSUME(cond) __builtin_assume(cond) +#elif defined(__GNUC__) || ABSL_HAVE_BUILTIN(__builtin_unreachable) +#define ABSL_INTERNAL_ASSUME(cond) \ + do { \ + if (!(cond)) __builtin_unreachable(); \ + } while (0) +#elif defined(_MSC_VER) +#define ABSL_INTERNAL_ASSUME(cond) __assume(cond) +#else +#define ABSL_INTERNAL_ASSUME(cond) \ + do { \ + static_cast<void>(false && (cond)); \ + } while (0) +#endif + +// ABSL_INTERNAL_UNIQUE_SMALL_NAME(cond) +// This macro forces small unique name on a static file level symbols like +// static local variables or static functions. This is intended to be used in +// macro definitions to optimize the cost of generated code. Do NOT use it on // symbols exported from translation unit since it may cause a link time -// conflict. -// -// Example: -// -// #define MY_MACRO(txt) -// namespace { -// char VeryVeryLongVarName[] ABSL_INTERNAL_UNIQUE_SMALL_NAME() = txt; -// const char* VeryVeryLongFuncName() ABSL_INTERNAL_UNIQUE_SMALL_NAME(); -// const char* VeryVeryLongFuncName() { return txt; } -// } -// - -#if defined(__GNUC__) -#define ABSL_INTERNAL_UNIQUE_SMALL_NAME2(x) #x -#define ABSL_INTERNAL_UNIQUE_SMALL_NAME1(x) ABSL_INTERNAL_UNIQUE_SMALL_NAME2(x) -#define ABSL_INTERNAL_UNIQUE_SMALL_NAME() \ - asm(ABSL_INTERNAL_UNIQUE_SMALL_NAME1(.absl.__COUNTER__)) -#else -#define ABSL_INTERNAL_UNIQUE_SMALL_NAME() -#endif - +// conflict. +// +// Example: +// +// #define MY_MACRO(txt) +// namespace { +// char VeryVeryLongVarName[] ABSL_INTERNAL_UNIQUE_SMALL_NAME() = txt; +// const char* VeryVeryLongFuncName() ABSL_INTERNAL_UNIQUE_SMALL_NAME(); +// const char* VeryVeryLongFuncName() { return txt; } +// } +// + +#if defined(__GNUC__) +#define ABSL_INTERNAL_UNIQUE_SMALL_NAME2(x) #x +#define ABSL_INTERNAL_UNIQUE_SMALL_NAME1(x) ABSL_INTERNAL_UNIQUE_SMALL_NAME2(x) +#define ABSL_INTERNAL_UNIQUE_SMALL_NAME() \ + asm(ABSL_INTERNAL_UNIQUE_SMALL_NAME1(.absl.__COUNTER__)) +#else +#define ABSL_INTERNAL_UNIQUE_SMALL_NAME() +#endif + #endif // ABSL_BASE_OPTIMIZATION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/options.h b/contrib/restricted/abseil-cpp/absl/base/options.h index 56b4e36ee0..0f25c1dee0 100644 --- a/contrib/restricted/abseil-cpp/absl/base/options.h +++ b/contrib/restricted/abseil-cpp/absl/base/options.h @@ -63,16 +63,16 @@ // NOTE: the defaults within this file all assume that Abseil can select the // proper Abseil implementation at compile-time, which will not be sufficient // to guarantee ABI stability to package managers. - -#ifndef ABSL_BASE_OPTIONS_H_ -#define ABSL_BASE_OPTIONS_H_ - -// Include a standard library header to allow configuration based on the -// standard library in use. -#ifdef __cplusplus -#include <ciso646> -#endif - + +#ifndef ABSL_BASE_OPTIONS_H_ +#define ABSL_BASE_OPTIONS_H_ + +// Include a standard library header to allow configuration based on the +// standard library in use. +#ifdef __cplusplus +#include <ciso646> +#endif + // ----------------------------------------------------------------------------- // Type Compatibility Options // ----------------------------------------------------------------------------- @@ -182,57 +182,57 @@ #define ABSL_OPTION_USE_STD_VARIANT 2 - -// ABSL_OPTION_USE_INLINE_NAMESPACE -// ABSL_OPTION_INLINE_NAMESPACE_NAME -// -// These options controls whether all entities in the absl namespace are -// contained within an inner inline namespace. This does not affect the -// user-visible API of Abseil, but it changes the mangled names of all symbols. -// -// This can be useful as a version tag if you are distributing Abseil in -// precompiled form. This will prevent a binary library build of Abseil with -// one inline namespace being used with headers configured with a different -// inline namespace name. Binary packagers are reminded that Abseil does not -// guarantee any ABI stability in Abseil, so any update of Abseil or -// configuration change in such a binary package should be combined with a -// new, unique value for the inline namespace name. -// -// A value of 0 means not to use inline namespaces. -// -// A value of 1 means to use an inline namespace with the given name inside -// namespace absl. If this is set, ABSL_OPTION_INLINE_NAMESPACE_NAME must also -// be changed to a new, unique identifier name. In particular "head" is not -// allowed. - + +// ABSL_OPTION_USE_INLINE_NAMESPACE +// ABSL_OPTION_INLINE_NAMESPACE_NAME +// +// These options controls whether all entities in the absl namespace are +// contained within an inner inline namespace. This does not affect the +// user-visible API of Abseil, but it changes the mangled names of all symbols. +// +// This can be useful as a version tag if you are distributing Abseil in +// precompiled form. This will prevent a binary library build of Abseil with +// one inline namespace being used with headers configured with a different +// inline namespace name. Binary packagers are reminded that Abseil does not +// guarantee any ABI stability in Abseil, so any update of Abseil or +// configuration change in such a binary package should be combined with a +// new, unique value for the inline namespace name. +// +// A value of 0 means not to use inline namespaces. +// +// A value of 1 means to use an inline namespace with the given name inside +// namespace absl. If this is set, ABSL_OPTION_INLINE_NAMESPACE_NAME must also +// be changed to a new, unique identifier name. In particular "head" is not +// allowed. + #define ABSL_OPTION_USE_INLINE_NAMESPACE 1 #define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_20211102 - -// ABSL_OPTION_HARDENED -// -// This option enables a "hardened" build in release mode (in this context, -// release mode is defined as a build where the `NDEBUG` macro is defined). -// -// A value of 0 means that "hardened" mode is not enabled. -// -// A value of 1 means that "hardened" mode is enabled. -// -// Hardened builds have additional security checks enabled when `NDEBUG` is -// defined. Defining `NDEBUG` is normally used to turn `assert()` macro into a -// no-op, as well as disabling other bespoke program consistency checks. By -// defining ABSL_OPTION_HARDENED to 1, a select set of checks remain enabled in -// release mode. These checks guard against programming errors that may lead to -// security vulnerabilities. In release mode, when one of these programming -// errors is encountered, the program will immediately abort, possibly without -// any attempt at logging. -// -// The checks enabled by this option are not free; they do incur runtime cost. -// -// The checks enabled by this option are always active when `NDEBUG` is not -// defined, even in the case when ABSL_OPTION_HARDENED is defined to 0. The -// checks enabled by this option may abort the program in a different way and -// log additional information when `NDEBUG` is not defined. - -#define ABSL_OPTION_HARDENED 0 - + +// ABSL_OPTION_HARDENED +// +// This option enables a "hardened" build in release mode (in this context, +// release mode is defined as a build where the `NDEBUG` macro is defined). +// +// A value of 0 means that "hardened" mode is not enabled. +// +// A value of 1 means that "hardened" mode is enabled. +// +// Hardened builds have additional security checks enabled when `NDEBUG` is +// defined. Defining `NDEBUG` is normally used to turn `assert()` macro into a +// no-op, as well as disabling other bespoke program consistency checks. By +// defining ABSL_OPTION_HARDENED to 1, a select set of checks remain enabled in +// release mode. These checks guard against programming errors that may lead to +// security vulnerabilities. In release mode, when one of these programming +// errors is encountered, the program will immediately abort, possibly without +// any attempt at logging. +// +// The checks enabled by this option are not free; they do incur runtime cost. +// +// The checks enabled by this option are always active when `NDEBUG` is not +// defined, even in the case when ABSL_OPTION_HARDENED is defined to 0. The +// checks enabled by this option may abort the program in a different way and +// log additional information when `NDEBUG` is not defined. + +#define ABSL_OPTION_HARDENED 0 + #endif // ABSL_BASE_OPTIONS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/policy_checks.h b/contrib/restricted/abseil-cpp/absl/base/policy_checks.h index 06b3243916..c1cdca12f5 100644 --- a/contrib/restricted/abseil-cpp/absl/base/policy_checks.h +++ b/contrib/restricted/abseil-cpp/absl/base/policy_checks.h @@ -41,7 +41,7 @@ #endif // ----------------------------------------------------------------------------- -// Toolchain Check +// Toolchain Check // ----------------------------------------------------------------------------- // We support MSVC++ 14.0 update 2 and later. diff --git a/contrib/restricted/abseil-cpp/absl/base/thread_annotations.h b/contrib/restricted/abseil-cpp/absl/base/thread_annotations.h index 9695f6de67..e0243042f5 100644 --- a/contrib/restricted/abseil-cpp/absl/base/thread_annotations.h +++ b/contrib/restricted/abseil-cpp/absl/base/thread_annotations.h @@ -34,8 +34,8 @@ #ifndef ABSL_BASE_THREAD_ANNOTATIONS_H_ #define ABSL_BASE_THREAD_ANNOTATIONS_H_ -#include "absl/base/attributes.h" -#include "absl/base/config.h" +#include "absl/base/attributes.h" +#include "absl/base/config.h" // TODO(mbonadei): Remove after the backward compatibility period. #include "absl/base/internal/thread_annotations.h" // IWYU pragma: export @@ -56,11 +56,11 @@ // int p1_ ABSL_GUARDED_BY(mu_); // ... // }; -#if ABSL_HAVE_ATTRIBUTE(guarded_by) -#define ABSL_GUARDED_BY(x) __attribute__((guarded_by(x))) -#else -#define ABSL_GUARDED_BY(x) -#endif +#if ABSL_HAVE_ATTRIBUTE(guarded_by) +#define ABSL_GUARDED_BY(x) __attribute__((guarded_by(x))) +#else +#define ABSL_GUARDED_BY(x) +#endif // ABSL_PT_GUARDED_BY() // @@ -82,11 +82,11 @@ // // `q_`, guarded by `mu1_`, points to a shared memory location that is // // guarded by `mu2_`: // int *q_ ABSL_GUARDED_BY(mu1_) ABSL_PT_GUARDED_BY(mu2_); -#if ABSL_HAVE_ATTRIBUTE(pt_guarded_by) -#define ABSL_PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x))) -#else -#define ABSL_PT_GUARDED_BY(x) -#endif +#if ABSL_HAVE_ATTRIBUTE(pt_guarded_by) +#define ABSL_PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x))) +#else +#define ABSL_PT_GUARDED_BY(x) +#endif // ABSL_ACQUIRED_AFTER() / ABSL_ACQUIRED_BEFORE() // @@ -103,17 +103,17 @@ // // Mutex m1_; // Mutex m2_ ABSL_ACQUIRED_AFTER(m1_); -#if ABSL_HAVE_ATTRIBUTE(acquired_after) -#define ABSL_ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__))) -#else -#define ABSL_ACQUIRED_AFTER(...) -#endif +#if ABSL_HAVE_ATTRIBUTE(acquired_after) +#define ABSL_ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__))) +#else +#define ABSL_ACQUIRED_AFTER(...) +#endif -#if ABSL_HAVE_ATTRIBUTE(acquired_before) -#define ABSL_ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__))) -#else -#define ABSL_ACQUIRED_BEFORE(...) -#endif +#if ABSL_HAVE_ATTRIBUTE(acquired_before) +#define ABSL_ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__))) +#else +#define ABSL_ACQUIRED_BEFORE(...) +#endif // ABSL_EXCLUSIVE_LOCKS_REQUIRED() / ABSL_SHARED_LOCKS_REQUIRED() // @@ -138,50 +138,50 @@ // // void foo() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... } // void bar() const ABSL_SHARED_LOCKS_REQUIRED(mu1, mu2) { ... } -#if ABSL_HAVE_ATTRIBUTE(exclusive_locks_required) -#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...) \ - __attribute__((exclusive_locks_required(__VA_ARGS__))) -#else -#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...) -#endif +#if ABSL_HAVE_ATTRIBUTE(exclusive_locks_required) +#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...) \ + __attribute__((exclusive_locks_required(__VA_ARGS__))) +#else +#define ABSL_EXCLUSIVE_LOCKS_REQUIRED(...) +#endif -#if ABSL_HAVE_ATTRIBUTE(shared_locks_required) +#if ABSL_HAVE_ATTRIBUTE(shared_locks_required) #define ABSL_SHARED_LOCKS_REQUIRED(...) \ - __attribute__((shared_locks_required(__VA_ARGS__))) -#else -#define ABSL_SHARED_LOCKS_REQUIRED(...) -#endif + __attribute__((shared_locks_required(__VA_ARGS__))) +#else +#define ABSL_SHARED_LOCKS_REQUIRED(...) +#endif // ABSL_LOCKS_EXCLUDED() // // Documents the locks acquired in the body of the function. These locks // cannot be held when calling this function (as Abseil's `Mutex` locks are // non-reentrant). -#if ABSL_HAVE_ATTRIBUTE(locks_excluded) -#define ABSL_LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__))) -#else -#define ABSL_LOCKS_EXCLUDED(...) -#endif +#if ABSL_HAVE_ATTRIBUTE(locks_excluded) +#define ABSL_LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__))) +#else +#define ABSL_LOCKS_EXCLUDED(...) +#endif // ABSL_LOCK_RETURNED() // // Documents a function that returns a mutex without acquiring it. For example, // a public getter method that returns a pointer to a private mutex should // be annotated with ABSL_LOCK_RETURNED. -#if ABSL_HAVE_ATTRIBUTE(lock_returned) -#define ABSL_LOCK_RETURNED(x) __attribute__((lock_returned(x))) -#else -#define ABSL_LOCK_RETURNED(x) -#endif +#if ABSL_HAVE_ATTRIBUTE(lock_returned) +#define ABSL_LOCK_RETURNED(x) __attribute__((lock_returned(x))) +#else +#define ABSL_LOCK_RETURNED(x) +#endif // ABSL_LOCKABLE // // Documents if a class/type is a lockable type (such as the `Mutex` class). -#if ABSL_HAVE_ATTRIBUTE(lockable) -#define ABSL_LOCKABLE __attribute__((lockable)) -#else -#define ABSL_LOCKABLE -#endif +#if ABSL_HAVE_ATTRIBUTE(lockable) +#define ABSL_LOCKABLE __attribute__((lockable)) +#else +#define ABSL_LOCKABLE +#endif // ABSL_SCOPED_LOCKABLE // @@ -190,43 +190,43 @@ // acquired, and the destructor should use `UNLOCK_FUNCTION()` with no // arguments; the analysis will assume that the destructor unlocks whatever the // constructor locked. -#if ABSL_HAVE_ATTRIBUTE(scoped_lockable) -#define ABSL_SCOPED_LOCKABLE __attribute__((scoped_lockable)) -#else -#define ABSL_SCOPED_LOCKABLE -#endif +#if ABSL_HAVE_ATTRIBUTE(scoped_lockable) +#define ABSL_SCOPED_LOCKABLE __attribute__((scoped_lockable)) +#else +#define ABSL_SCOPED_LOCKABLE +#endif // ABSL_EXCLUSIVE_LOCK_FUNCTION() // // Documents functions that acquire a lock in the body of a function, and do // not release it. -#if ABSL_HAVE_ATTRIBUTE(exclusive_lock_function) -#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...) \ - __attribute__((exclusive_lock_function(__VA_ARGS__))) -#else -#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...) -#endif +#if ABSL_HAVE_ATTRIBUTE(exclusive_lock_function) +#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...) \ + __attribute__((exclusive_lock_function(__VA_ARGS__))) +#else +#define ABSL_EXCLUSIVE_LOCK_FUNCTION(...) +#endif // ABSL_SHARED_LOCK_FUNCTION() // // Documents functions that acquire a shared (reader) lock in the body of a // function, and do not release it. -#if ABSL_HAVE_ATTRIBUTE(shared_lock_function) +#if ABSL_HAVE_ATTRIBUTE(shared_lock_function) #define ABSL_SHARED_LOCK_FUNCTION(...) \ - __attribute__((shared_lock_function(__VA_ARGS__))) -#else -#define ABSL_SHARED_LOCK_FUNCTION(...) -#endif + __attribute__((shared_lock_function(__VA_ARGS__))) +#else +#define ABSL_SHARED_LOCK_FUNCTION(...) +#endif // ABSL_UNLOCK_FUNCTION() // // Documents functions that expect a lock to be held on entry to the function, // and release it in the body of the function. -#if ABSL_HAVE_ATTRIBUTE(unlock_function) -#define ABSL_UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) -#else -#define ABSL_UNLOCK_FUNCTION(...) -#endif +#if ABSL_HAVE_ATTRIBUTE(unlock_function) +#define ABSL_UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) +#else +#define ABSL_UNLOCK_FUNCTION(...) +#endif // ABSL_EXCLUSIVE_TRYLOCK_FUNCTION() / ABSL_SHARED_TRYLOCK_FUNCTION() // @@ -236,49 +236,49 @@ // success, or `false` for functions that return `false` on success. The second // argument specifies the mutex that is locked on success. If unspecified, this // mutex is assumed to be `this`. -#if ABSL_HAVE_ATTRIBUTE(exclusive_trylock_function) +#if ABSL_HAVE_ATTRIBUTE(exclusive_trylock_function) #define ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(...) \ - __attribute__((exclusive_trylock_function(__VA_ARGS__))) -#else -#define ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(...) -#endif + __attribute__((exclusive_trylock_function(__VA_ARGS__))) +#else +#define ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(...) +#endif -#if ABSL_HAVE_ATTRIBUTE(shared_trylock_function) -#define ABSL_SHARED_TRYLOCK_FUNCTION(...) \ - __attribute__((shared_trylock_function(__VA_ARGS__))) -#else -#define ABSL_SHARED_TRYLOCK_FUNCTION(...) -#endif +#if ABSL_HAVE_ATTRIBUTE(shared_trylock_function) +#define ABSL_SHARED_TRYLOCK_FUNCTION(...) \ + __attribute__((shared_trylock_function(__VA_ARGS__))) +#else +#define ABSL_SHARED_TRYLOCK_FUNCTION(...) +#endif // ABSL_ASSERT_EXCLUSIVE_LOCK() / ABSL_ASSERT_SHARED_LOCK() // // Documents functions that dynamically check to see if a lock is held, and fail // if it is not held. -#if ABSL_HAVE_ATTRIBUTE(assert_exclusive_lock) +#if ABSL_HAVE_ATTRIBUTE(assert_exclusive_lock) #define ABSL_ASSERT_EXCLUSIVE_LOCK(...) \ - __attribute__((assert_exclusive_lock(__VA_ARGS__))) -#else -#define ABSL_ASSERT_EXCLUSIVE_LOCK(...) -#endif + __attribute__((assert_exclusive_lock(__VA_ARGS__))) +#else +#define ABSL_ASSERT_EXCLUSIVE_LOCK(...) +#endif -#if ABSL_HAVE_ATTRIBUTE(assert_shared_lock) +#if ABSL_HAVE_ATTRIBUTE(assert_shared_lock) #define ABSL_ASSERT_SHARED_LOCK(...) \ - __attribute__((assert_shared_lock(__VA_ARGS__))) -#else -#define ABSL_ASSERT_SHARED_LOCK(...) -#endif + __attribute__((assert_shared_lock(__VA_ARGS__))) +#else +#define ABSL_ASSERT_SHARED_LOCK(...) +#endif // ABSL_NO_THREAD_SAFETY_ANALYSIS // // Turns off thread safety checking within the body of a particular function. // This annotation is used to mark functions that are known to be correct, but // the locking behavior is more complicated than the analyzer can handle. -#if ABSL_HAVE_ATTRIBUTE(no_thread_safety_analysis) +#if ABSL_HAVE_ATTRIBUTE(no_thread_safety_analysis) #define ABSL_NO_THREAD_SAFETY_ANALYSIS \ - __attribute__((no_thread_safety_analysis)) -#else -#define ABSL_NO_THREAD_SAFETY_ANALYSIS -#endif + __attribute__((no_thread_safety_analysis)) +#else +#define ABSL_NO_THREAD_SAFETY_ANALYSIS +#endif //------------------------------------------------------------------------------ // Tool-Supplied Annotations @@ -312,7 +312,7 @@ #define ABSL_TS_UNCHECKED_READ(x) absl::base_internal::ts_unchecked_read(x) namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace base_internal { // Takes a reference to a guarded data member, and returns an unguarded @@ -329,7 +329,7 @@ inline T& ts_unchecked_read(T& v) ABSL_NO_THREAD_SAFETY_ANALYSIS { } } // namespace base_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_THREAD_ANNOTATIONS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/base/ya.make b/contrib/restricted/abseil-cpp/absl/base/ya.make index dadb4a5c81..182ddcf33e 100644 --- a/contrib/restricted/abseil-cpp/absl/base/ya.make +++ b/contrib/restricted/abseil-cpp/absl/base/ya.make @@ -22,10 +22,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCS( internal/cycleclock.cc internal/spinlock.cc diff --git a/contrib/restricted/abseil-cpp/absl/city/ya.make b/contrib/restricted/abseil-cpp/absl/city/ya.make index dffd2d3a70..b01c89dddd 100644 --- a/contrib/restricted/abseil-cpp/absl/city/ya.make +++ b/contrib/restricted/abseil-cpp/absl/city/ya.make @@ -23,10 +23,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/hash/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/container/btree_map.h b/contrib/restricted/abseil-cpp/absl/container/btree_map.h index f0a8d4a6a4..9e25d2e740 100644 --- a/contrib/restricted/abseil-cpp/absl/container/btree_map.h +++ b/contrib/restricted/abseil-cpp/absl/container/btree_map.h @@ -51,7 +51,7 @@ #include "absl/container/internal/btree_container.h" // IWYU pragma: export namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // absl::btree_map<> // @@ -185,7 +185,7 @@ class btree_map // template <typename K> size_type erase(const K& key): // // Erases the element with the matching key, if it exists, returning the - // number of elements erased (0 or 1). + // number of elements erased (0 or 1). using Base::erase; // btree_map::insert() @@ -226,30 +226,30 @@ class btree_map // Inserts the elements within the initializer list `ilist`. using Base::insert; - // btree_map::insert_or_assign() - // - // Inserts an element of the specified value into the `btree_map` provided - // that a value with the given key does not already exist, or replaces the - // corresponding mapped type with the forwarded `obj` argument if a key for - // that value already exists, returning an iterator pointing to the newly - // inserted element. Overloads are listed below. - // - // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj): - // pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj): - // - // Inserts/Assigns (or moves) the element of the specified key into the - // `btree_map`. If the returned bool is true, insertion took place, and if - // it's false, assignment took place. - // - // iterator insert_or_assign(const_iterator hint, - // const key_type& k, M&& obj): - // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj): - // - // Inserts/Assigns (or moves) the element of the specified key into the - // `btree_map` using the position of `hint` as a non-binding suggestion - // for where to begin the insertion search. - using Base::insert_or_assign; - + // btree_map::insert_or_assign() + // + // Inserts an element of the specified value into the `btree_map` provided + // that a value with the given key does not already exist, or replaces the + // corresponding mapped type with the forwarded `obj` argument if a key for + // that value already exists, returning an iterator pointing to the newly + // inserted element. Overloads are listed below. + // + // pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj): + // pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj): + // + // Inserts/Assigns (or moves) the element of the specified key into the + // `btree_map`. If the returned bool is true, insertion took place, and if + // it's false, assignment took place. + // + // iterator insert_or_assign(const_iterator hint, + // const key_type& k, M&& obj): + // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj): + // + // Inserts/Assigns (or moves) the element of the specified key into the + // `btree_map` using the position of `hint` as a non-binding suggestion + // for where to begin the insertion search. + using Base::insert_or_assign; + // btree_map::emplace() // // Inserts an element of the specified value by constructing it in-place @@ -318,18 +318,18 @@ class btree_map // Extracts the element at the indicated position and returns a node handle // owning that extracted data. // - // template <typename K> node_type extract(const K& k): + // template <typename K> node_type extract(const K& k): // // Extracts the element with the key matching the passed key value and // returns a node handle owning that extracted data. If the `btree_map` // does not contain an element with a matching key, this function returns an // empty node handle. // - // NOTE: when compiled in an earlier version of C++ than C++17, - // `node_type::key()` returns a const reference to the key instead of a - // mutable reference. We cannot safely return a mutable reference without - // std::launder (which is not available before C++17). - // + // NOTE: when compiled in an earlier version of C++ than C++17, + // `node_type::key()` returns a const reference to the key instead of a + // mutable reference. We cannot safely return a mutable reference without + // std::launder (which is not available before C++17). + // // NOTE: In this context, `node_type` refers to the C++17 concept of a // move-only type that owns and provides access to the elements in associative // containers (https://en.cppreference.com/w/cpp/container/node_handle). @@ -464,20 +464,20 @@ void swap(btree_map<K, V, C, A> &x, btree_map<K, V, C, A> &y) { return x.swap(y); } -// absl::erase_if(absl::btree_map<>, Pred) -// -// Erases all elements that satisfy the predicate pred from the container. -template <typename K, typename V, typename C, typename A, typename Pred> -void erase_if(btree_map<K, V, C, A> &map, Pred pred) { - for (auto it = map.begin(); it != map.end();) { - if (pred(*it)) { - it = map.erase(it); - } else { - ++it; - } - } -} - +// absl::erase_if(absl::btree_map<>, Pred) +// +// Erases all elements that satisfy the predicate pred from the container. +template <typename K, typename V, typename C, typename A, typename Pred> +void erase_if(btree_map<K, V, C, A> &map, Pred pred) { + for (auto it = map.begin(); it != map.end();) { + if (pred(*it)) { + it = map.erase(it); + } else { + ++it; + } + } +} + // absl::btree_multimap // // An `absl::btree_multimap<K, V>` is an ordered associative container of @@ -673,18 +673,18 @@ class btree_multimap // Extracts the element at the indicated position and returns a node handle // owning that extracted data. // - // template <typename K> node_type extract(const K& k): + // template <typename K> node_type extract(const K& k): // // Extracts the element with the key matching the passed key value and // returns a node handle owning that extracted data. If the `btree_multimap` // does not contain an element with a matching key, this function returns an // empty node handle. // - // NOTE: when compiled in an earlier version of C++ than C++17, - // `node_type::key()` returns a const reference to the key instead of a - // mutable reference. We cannot safely return a mutable reference without - // std::launder (which is not available before C++17). - // + // NOTE: when compiled in an earlier version of C++ than C++17, + // `node_type::key()` returns a const reference to the key instead of a + // mutable reference. We cannot safely return a mutable reference without + // std::launder (which is not available before C++17). + // // NOTE: In this context, `node_type` refers to the C++17 concept of a // move-only type that owns and provides access to the elements in associative // containers (https://en.cppreference.com/w/cpp/container/node_handle). @@ -795,21 +795,21 @@ void swap(btree_multimap<K, V, C, A> &x, btree_multimap<K, V, C, A> &y) { return x.swap(y); } -// absl::erase_if(absl::btree_multimap<>, Pred) -// -// Erases all elements that satisfy the predicate pred from the container. -template <typename K, typename V, typename C, typename A, typename Pred> -void erase_if(btree_multimap<K, V, C, A> &map, Pred pred) { - for (auto it = map.begin(); it != map.end();) { - if (pred(*it)) { - it = map.erase(it); - } else { - ++it; - } - } -} - -ABSL_NAMESPACE_END +// absl::erase_if(absl::btree_multimap<>, Pred) +// +// Erases all elements that satisfy the predicate pred from the container. +template <typename K, typename V, typename C, typename A, typename Pred> +void erase_if(btree_multimap<K, V, C, A> &map, Pred pred) { + for (auto it = map.begin(); it != map.end();) { + if (pred(*it)) { + it = map.erase(it); + } else { + ++it; + } + } +} + +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_BTREE_MAP_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/btree_set.h b/contrib/restricted/abseil-cpp/absl/container/btree_set.h index 8973900693..dcd87cc3ef 100644 --- a/contrib/restricted/abseil-cpp/absl/container/btree_set.h +++ b/contrib/restricted/abseil-cpp/absl/container/btree_set.h @@ -51,7 +51,7 @@ #include "absl/container/internal/btree_container.h" // IWYU pragma: export namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // absl::btree_set<> // @@ -183,7 +183,7 @@ class btree_set // template <typename K> size_type erase(const K& key): // // Erases the element with the matching key, if it exists, returning the - // number of elements erased (0 or 1). + // number of elements erased (0 or 1). using Base::erase; // btree_set::insert() @@ -263,7 +263,7 @@ class btree_set // Extracts the element at the indicated position and returns a node handle // owning that extracted data. // - // template <typename K> node_type extract(const K& k): + // template <typename K> node_type extract(const K& k): // // Extracts the element with the key matching the passed key value and // returns a node handle owning that extracted data. If the `btree_set` @@ -382,20 +382,20 @@ void swap(btree_set<K, C, A> &x, btree_set<K, C, A> &y) { return x.swap(y); } -// absl::erase_if(absl::btree_set<>, Pred) -// -// Erases all elements that satisfy the predicate pred from the container. -template <typename K, typename C, typename A, typename Pred> -void erase_if(btree_set<K, C, A> &set, Pred pred) { - for (auto it = set.begin(); it != set.end();) { - if (pred(*it)) { - it = set.erase(it); - } else { - ++it; - } - } -} - +// absl::erase_if(absl::btree_set<>, Pred) +// +// Erases all elements that satisfy the predicate pred from the container. +template <typename K, typename C, typename A, typename Pred> +void erase_if(btree_set<K, C, A> &set, Pred pred) { + for (auto it = set.begin(); it != set.end();) { + if (pred(*it)) { + it = set.erase(it); + } else { + ++it; + } + } +} + // absl::btree_multiset<> // // An `absl::btree_multiset<K>` is an ordered associative container of @@ -589,7 +589,7 @@ class btree_multiset // Extracts the element at the indicated position and returns a node handle // owning that extracted data. // - // template <typename K> node_type extract(const K& k): + // template <typename K> node_type extract(const K& k): // // Extracts the element with the key matching the passed key value and // returns a node handle owning that extracted data. If the `btree_multiset` @@ -708,21 +708,21 @@ void swap(btree_multiset<K, C, A> &x, btree_multiset<K, C, A> &y) { return x.swap(y); } -// absl::erase_if(absl::btree_multiset<>, Pred) -// -// Erases all elements that satisfy the predicate pred from the container. -template <typename K, typename C, typename A, typename Pred> -void erase_if(btree_multiset<K, C, A> &set, Pred pred) { - for (auto it = set.begin(); it != set.end();) { - if (pred(*it)) { - it = set.erase(it); - } else { - ++it; - } - } -} - -ABSL_NAMESPACE_END +// absl::erase_if(absl::btree_multiset<>, Pred) +// +// Erases all elements that satisfy the predicate pred from the container. +template <typename K, typename C, typename A, typename Pred> +void erase_if(btree_multiset<K, C, A> &set, Pred pred) { + for (auto it = set.begin(); it != set.end();) { + if (pred(*it)) { + it = set.erase(it); + } else { + ++it; + } + } +} + +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_BTREE_SET_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/btree_test.h b/contrib/restricted/abseil-cpp/absl/container/btree_test.h index 624908072d..484e06e551 100644 --- a/contrib/restricted/abseil-cpp/absl/container/btree_test.h +++ b/contrib/restricted/abseil-cpp/absl/container/btree_test.h @@ -25,11 +25,11 @@ #include "absl/container/btree_map.h" #include "absl/container/btree_set.h" #include "absl/container/flat_hash_set.h" -#include "absl/strings/cord.h" +#include "absl/strings/cord.h" #include "absl/time/time.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { // Like remove_const but propagates the removal through std::pair. @@ -101,16 +101,16 @@ struct Generator<std::string> { } }; -template <> -struct Generator<Cord> { - int maxval; - explicit Generator(int m) : maxval(m) {} - Cord operator()(int i) const { - char buf[16]; - return Cord(GenerateDigits(buf, i, maxval)); - } -}; - +template <> +struct Generator<Cord> { + int maxval; + explicit Generator(int m) : maxval(m) {} + Cord operator()(int i) const { + char buf[16]; + return Cord(GenerateDigits(buf, i, maxval)); + } +}; + template <typename T, typename U> struct Generator<std::pair<T, U> > { Generator<typename remove_pair_const<T>::type> tgen; @@ -160,7 +160,7 @@ std::vector<V> GenerateValuesWithSeed(int n, int maxval, int seed) { } } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_BTREE_TEST_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/fixed_array.h b/contrib/restricted/abseil-cpp/absl/container/fixed_array.h index 839ba0bc16..996c96c6ab 100644 --- a/contrib/restricted/abseil-cpp/absl/container/fixed_array.h +++ b/contrib/restricted/abseil-cpp/absl/container/fixed_array.h @@ -41,7 +41,7 @@ #include <type_traits> #include "absl/algorithm/algorithm.h" -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/base/dynamic_annotations.h" #include "absl/base/internal/throw_delegate.h" #include "absl/base/macros.h" @@ -51,7 +51,7 @@ #include "absl/memory/memory.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN constexpr static auto kFixedArrayUseDefault = static_cast<size_t>(-1); @@ -102,13 +102,13 @@ class FixedArray { public: using allocator_type = typename AllocatorTraits::allocator_type; - using value_type = typename AllocatorTraits::value_type; - using pointer = typename AllocatorTraits::pointer; - using const_pointer = typename AllocatorTraits::const_pointer; - using reference = value_type&; - using const_reference = const value_type&; - using size_type = typename AllocatorTraits::size_type; - using difference_type = typename AllocatorTraits::difference_type; + using value_type = typename AllocatorTraits::value_type; + using pointer = typename AllocatorTraits::pointer; + using const_pointer = typename AllocatorTraits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = typename AllocatorTraits::size_type; + using difference_type = typename AllocatorTraits::difference_type; using iterator = pointer; using const_iterator = const_pointer; using reverse_iterator = std::reverse_iterator<iterator>; @@ -213,7 +213,7 @@ class FixedArray { // Returns a reference the ith element of the fixed array. // REQUIRES: 0 <= i < size() reference operator[](size_type i) { - ABSL_HARDENING_ASSERT(i < size()); + ABSL_HARDENING_ASSERT(i < size()); return data()[i]; } @@ -221,7 +221,7 @@ class FixedArray { // ith element of the fixed array. // REQUIRES: 0 <= i < size() const_reference operator[](size_type i) const { - ABSL_HARDENING_ASSERT(i < size()); + ABSL_HARDENING_ASSERT(i < size()); return data()[i]; } @@ -248,32 +248,32 @@ class FixedArray { // FixedArray::front() // // Returns a reference to the first element of the fixed array. - reference front() { - ABSL_HARDENING_ASSERT(!empty()); - return data()[0]; - } + reference front() { + ABSL_HARDENING_ASSERT(!empty()); + return data()[0]; + } // Overload of FixedArray::front() to return a reference to the first element // of a fixed array of const values. - const_reference front() const { - ABSL_HARDENING_ASSERT(!empty()); - return data()[0]; - } + const_reference front() const { + ABSL_HARDENING_ASSERT(!empty()); + return data()[0]; + } // FixedArray::back() // // Returns a reference to the last element of the fixed array. - reference back() { - ABSL_HARDENING_ASSERT(!empty()); - return data()[size() - 1]; - } + reference back() { + ABSL_HARDENING_ASSERT(!empty()); + return data()[size() - 1]; + } // Overload of FixedArray::back() to return a reference to the last element // of a fixed array of const values. - const_reference back() const { - ABSL_HARDENING_ASSERT(!empty()); - return data()[size() - 1]; - } + const_reference back() const { + ABSL_HARDENING_ASSERT(!empty()); + return data()[size() - 1]; + } // FixedArray::begin() // @@ -418,15 +418,15 @@ class FixedArray { void AnnotateConstruct(size_type n); void AnnotateDestruct(size_type n); -#ifdef ABSL_HAVE_ADDRESS_SANITIZER +#ifdef ABSL_HAVE_ADDRESS_SANITIZER void* RedzoneBegin() { return &redzone_begin_; } void* RedzoneEnd() { return &redzone_end_ + 1; } -#endif // ABSL_HAVE_ADDRESS_SANITIZER +#endif // ABSL_HAVE_ADDRESS_SANITIZER private: - ABSL_ADDRESS_SANITIZER_REDZONE(redzone_begin_); + ABSL_ADDRESS_SANITIZER_REDZONE(redzone_begin_); alignas(StorageElement) char buff_[sizeof(StorageElement[inline_elements])]; - ABSL_ADDRESS_SANITIZER_REDZONE(redzone_end_); + ABSL_ADDRESS_SANITIZER_REDZONE(redzone_end_); }; class EmptyInlinedStorage { @@ -499,29 +499,29 @@ constexpr typename FixedArray<T, N, A>::size_type template <typename T, size_t N, typename A> void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateConstruct( typename FixedArray<T, N, A>::size_type n) { -#ifdef ABSL_HAVE_ADDRESS_SANITIZER +#ifdef ABSL_HAVE_ADDRESS_SANITIZER if (!n) return; - ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), RedzoneEnd(), - data() + n); - ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), data(), - RedzoneBegin()); -#endif // ABSL_HAVE_ADDRESS_SANITIZER + ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), RedzoneEnd(), + data() + n); + ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), data(), + RedzoneBegin()); +#endif // ABSL_HAVE_ADDRESS_SANITIZER static_cast<void>(n); // Mark used when not in asan mode } template <typename T, size_t N, typename A> void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateDestruct( typename FixedArray<T, N, A>::size_type n) { -#ifdef ABSL_HAVE_ADDRESS_SANITIZER +#ifdef ABSL_HAVE_ADDRESS_SANITIZER if (!n) return; - ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), data() + n, - RedzoneEnd()); - ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), RedzoneBegin(), - data()); -#endif // ABSL_HAVE_ADDRESS_SANITIZER + ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), data() + n, + RedzoneEnd()); + ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), RedzoneBegin(), + data()); +#endif // ABSL_HAVE_ADDRESS_SANITIZER static_cast<void>(n); // Mark used when not in asan mode } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_FIXED_ARRAY_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/flat_hash_map.h b/contrib/restricted/abseil-cpp/absl/container/flat_hash_map.h index 74def0df0e..a811d3f25f 100644 --- a/contrib/restricted/abseil-cpp/absl/container/flat_hash_map.h +++ b/contrib/restricted/abseil-cpp/absl/container/flat_hash_map.h @@ -42,7 +42,7 @@ #include "absl/memory/memory.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class K, class V> struct FlatHashMapPolicy; @@ -234,8 +234,8 @@ class flat_hash_map : public absl::container_internal::raw_hash_map< // // size_type erase(const key_type& key): // - // Erases the element with the matching key, if it exists, returning the - // number of elements erased (0 or 1). + // Erases the element with the matching key, if it exists, returning the + // number of elements erased (0 or 1). using Base::erase; // flat_hash_map::insert() @@ -384,11 +384,11 @@ class flat_hash_map : public absl::container_internal::raw_hash_map< // key value and returns a node handle owning that extracted data. If the // `flat_hash_map` does not contain an element with a matching key, this // function returns an empty node handle. - // - // NOTE: when compiled in an earlier version of C++ than C++17, - // `node_type::key()` returns a const reference to the key instead of a - // mutable reference. We cannot safely return a mutable reference without - // std::launder (which is not available before C++17). + // + // NOTE: when compiled in an earlier version of C++ than C++17, + // `node_type::key()` returns a const reference to the key instead of a + // mutable reference. We cannot safely return a mutable reference without + // std::launder (which is not available before C++17). using Base::extract; // flat_hash_map::merge() @@ -538,15 +538,15 @@ class flat_hash_map : public absl::container_internal::raw_hash_map< using Base::key_eq; }; -// erase_if(flat_hash_map<>, Pred) -// -// Erases all elements that satisfy the predicate `pred` from the container `c`. -template <typename K, typename V, typename H, typename E, typename A, - typename Predicate> -void erase_if(flat_hash_map<K, V, H, E, A>& c, Predicate pred) { - container_internal::EraseIf(pred, &c); -} - +// erase_if(flat_hash_map<>, Pred) +// +// Erases all elements that satisfy the predicate `pred` from the container `c`. +template <typename K, typename V, typename H, typename E, typename A, + typename Predicate> +void erase_if(flat_hash_map<K, V, H, E, A>& c, Predicate pred) { + container_internal::EraseIf(pred, &c); +} + namespace container_internal { template <class K, class V> @@ -600,7 +600,7 @@ struct IsUnorderedContainer< } // namespace container_algorithm_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_FLAT_HASH_MAP_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/flat_hash_set.h b/contrib/restricted/abseil-cpp/absl/container/flat_hash_set.h index 6b89da6571..fa8d87e145 100644 --- a/contrib/restricted/abseil-cpp/absl/container/flat_hash_set.h +++ b/contrib/restricted/abseil-cpp/absl/container/flat_hash_set.h @@ -40,7 +40,7 @@ #include "absl/memory/memory.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <typename T> struct FlatHashSetPolicy; @@ -227,8 +227,8 @@ class flat_hash_set // // size_type erase(const key_type& key): // - // Erases the element with the matching key, if it exists, returning the - // number of elements erased (0 or 1). + // Erases the element with the matching key, if it exists, returning the + // number of elements erased (0 or 1). using Base::erase; // flat_hash_set::insert() @@ -440,14 +440,14 @@ class flat_hash_set using Base::key_eq; }; -// erase_if(flat_hash_set<>, Pred) -// -// Erases all elements that satisfy the predicate `pred` from the container `c`. -template <typename T, typename H, typename E, typename A, typename Predicate> -void erase_if(flat_hash_set<T, H, E, A>& c, Predicate pred) { - container_internal::EraseIf(pred, &c); -} - +// erase_if(flat_hash_set<>, Pred) +// +// Erases all elements that satisfy the predicate `pred` from the container `c`. +template <typename T, typename H, typename E, typename A, typename Predicate> +void erase_if(flat_hash_set<T, H, E, A>& c, Predicate pred) { + container_internal::EraseIf(pred, &c); +} + namespace container_internal { template <class T> @@ -498,7 +498,7 @@ struct IsUnorderedContainer<absl::flat_hash_set<Key, Hash, KeyEqual, Allocator>> } // namespace container_algorithm_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_FLAT_HASH_SET_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/inlined_vector.h b/contrib/restricted/abseil-cpp/absl/container/inlined_vector.h index df9e09917d..5ed1d6a748 100644 --- a/contrib/restricted/abseil-cpp/absl/container/inlined_vector.h +++ b/contrib/restricted/abseil-cpp/absl/container/inlined_vector.h @@ -48,14 +48,14 @@ #include "absl/algorithm/algorithm.h" #include "absl/base/internal/throw_delegate.h" -#include "absl/base/macros.h" +#include "absl/base/macros.h" #include "absl/base/optimization.h" #include "absl/base/port.h" #include "absl/container/internal/inlined_vector.h" #include "absl/memory/memory.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // InlinedVector // ----------------------------------------------------------------------------- @@ -64,7 +64,7 @@ ABSL_NAMESPACE_BEGIN // `std::vector` for use cases where the vector's size is sufficiently small // that it can be inlined. If the inlined vector does grow beyond its estimated // capacity, it will trigger an initial allocation on the heap, and will behave -// as a `std::vector`. The API of the `absl::InlinedVector` within this file is +// as a `std::vector`. The API of the `absl::InlinedVector` within this file is // designed to cover the same API footprint as covered by `std::vector`. template <typename T, size_t N, typename A = std::allocator<T>> class InlinedVector { @@ -319,14 +319,14 @@ class InlinedVector { // // Returns a `reference` to the `i`th element of the inlined vector. reference operator[](size_type i) { - ABSL_HARDENING_ASSERT(i < size()); + ABSL_HARDENING_ASSERT(i < size()); return data()[i]; } // Overload of `InlinedVector::operator[](...)` that returns a // `const_reference` to the `i`th element of the inlined vector. const_reference operator[](size_type i) const { - ABSL_HARDENING_ASSERT(i < size()); + ABSL_HARDENING_ASSERT(i < size()); return data()[i]; } @@ -361,30 +361,30 @@ class InlinedVector { // // Returns a `reference` to the first element of the inlined vector. reference front() { - ABSL_HARDENING_ASSERT(!empty()); - return data()[0]; + ABSL_HARDENING_ASSERT(!empty()); + return data()[0]; } // Overload of `InlinedVector::front()` that returns a `const_reference` to // the first element of the inlined vector. const_reference front() const { - ABSL_HARDENING_ASSERT(!empty()); - return data()[0]; + ABSL_HARDENING_ASSERT(!empty()); + return data()[0]; } // `InlinedVector::back()` // // Returns a `reference` to the last element of the inlined vector. reference back() { - ABSL_HARDENING_ASSERT(!empty()); - return data()[size() - 1]; + ABSL_HARDENING_ASSERT(!empty()); + return data()[size() - 1]; } // Overload of `InlinedVector::back()` that returns a `const_reference` to the // last element of the inlined vector. const_reference back() const { - ABSL_HARDENING_ASSERT(!empty()); - return data()[size() - 1]; + ABSL_HARDENING_ASSERT(!empty()); + return data()[size() - 1]; } // `InlinedVector::begin()` @@ -535,7 +535,7 @@ class InlinedVector { void assign(InputIterator first, InputIterator last) { size_type i = 0; for (; i < size() && first != last; ++i, static_cast<void>(++first)) { - data()[i] = *first; + data()[i] = *first; } erase(data() + i, data() + size()); @@ -546,12 +546,12 @@ class InlinedVector { // // Resizes the inlined vector to contain `n` elements. // - // NOTE: If `n` is smaller than `size()`, extra elements are destroyed. If `n` + // NOTE: If `n` is smaller than `size()`, extra elements are destroyed. If `n` // is larger than `size()`, new elements are value-initialized. - void resize(size_type n) { - ABSL_HARDENING_ASSERT(n <= max_size()); + void resize(size_type n) { + ABSL_HARDENING_ASSERT(n <= max_size()); storage_.Resize(DefaultValueAdapter<A>(), n); - } + } // Overload of `InlinedVector::resize(...)` that resizes the inlined vector to // contain `n` elements. @@ -559,7 +559,7 @@ class InlinedVector { // NOTE: if `n` is smaller than `size()`, extra elements are destroyed. If `n` // is larger than `size()`, new elements are copied-constructed from `v`. void resize(size_type n, const_reference v) { - ABSL_HARDENING_ASSERT(n <= max_size()); + ABSL_HARDENING_ASSERT(n <= max_size()); storage_.Resize(CopyValueAdapter<A>(std::addressof(v)), n); } @@ -581,8 +581,8 @@ class InlinedVector { // of `v` starting at `pos`, returning an `iterator` pointing to the first of // the newly inserted elements. iterator insert(const_iterator pos, size_type n, const_reference v) { - ABSL_HARDENING_ASSERT(pos >= begin()); - ABSL_HARDENING_ASSERT(pos <= end()); + ABSL_HARDENING_ASSERT(pos >= begin()); + ABSL_HARDENING_ASSERT(pos <= end()); if (ABSL_PREDICT_TRUE(n != 0)) { value_type dealias = v; @@ -609,8 +609,8 @@ class InlinedVector { EnableIfAtLeastForwardIterator<ForwardIterator> = 0> iterator insert(const_iterator pos, ForwardIterator first, ForwardIterator last) { - ABSL_HARDENING_ASSERT(pos >= begin()); - ABSL_HARDENING_ASSERT(pos <= end()); + ABSL_HARDENING_ASSERT(pos >= begin()); + ABSL_HARDENING_ASSERT(pos <= end()); if (ABSL_PREDICT_TRUE(first != last)) { return storage_.Insert(pos, @@ -629,8 +629,8 @@ class InlinedVector { template <typename InputIterator, DisableIfAtLeastForwardIterator<InputIterator> = 0> iterator insert(const_iterator pos, InputIterator first, InputIterator last) { - ABSL_HARDENING_ASSERT(pos >= begin()); - ABSL_HARDENING_ASSERT(pos <= end()); + ABSL_HARDENING_ASSERT(pos >= begin()); + ABSL_HARDENING_ASSERT(pos <= end()); size_type index = std::distance(cbegin(), pos); for (size_type i = index; first != last; ++i, static_cast<void>(++first)) { @@ -646,8 +646,8 @@ class InlinedVector { // `pos`, returning an `iterator` pointing to the newly emplaced element. template <typename... Args> iterator emplace(const_iterator pos, Args&&... args) { - ABSL_HARDENING_ASSERT(pos >= begin()); - ABSL_HARDENING_ASSERT(pos <= end()); + ABSL_HARDENING_ASSERT(pos >= begin()); + ABSL_HARDENING_ASSERT(pos <= end()); value_type dealias(std::forward<Args>(args)...); return storage_.Insert(pos, @@ -680,7 +680,7 @@ class InlinedVector { // // Destroys the element at `back()`, reducing the size by `1`. void pop_back() noexcept { - ABSL_HARDENING_ASSERT(!empty()); + ABSL_HARDENING_ASSERT(!empty()); AllocatorTraits<A>::destroy(storage_.GetAllocator(), data() + (size() - 1)); storage_.SubtractSize(1); @@ -693,8 +693,8 @@ class InlinedVector { // // NOTE: may return `end()`, which is not dereferencable. iterator erase(const_iterator pos) { - ABSL_HARDENING_ASSERT(pos >= begin()); - ABSL_HARDENING_ASSERT(pos < end()); + ABSL_HARDENING_ASSERT(pos >= begin()); + ABSL_HARDENING_ASSERT(pos < end()); return storage_.Erase(pos, pos + 1); } @@ -705,9 +705,9 @@ class InlinedVector { // // NOTE: may return `end()`, which is not dereferencable. iterator erase(const_iterator from, const_iterator to) { - ABSL_HARDENING_ASSERT(from >= begin()); - ABSL_HARDENING_ASSERT(from <= to); - ABSL_HARDENING_ASSERT(to <= end()); + ABSL_HARDENING_ASSERT(from >= begin()); + ABSL_HARDENING_ASSERT(from <= to); + ABSL_HARDENING_ASSERT(to <= end()); if (ABSL_PREDICT_TRUE(from != to)) { return storage_.Erase(from, to); @@ -849,7 +849,7 @@ H AbslHashValue(H h, const absl::InlinedVector<T, N, A>& a) { return H::combine(H::combine_contiguous(std::move(h), a.data(), size), size); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INLINED_VECTOR_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/btree.h b/contrib/restricted/abseil-cpp/absl/container/internal/btree.h index f636c5fc73..c3c06d2527 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/btree.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/btree.h @@ -65,13 +65,13 @@ #include "absl/container/internal/layout.h" #include "absl/memory/memory.h" #include "absl/meta/type_traits.h" -#include "absl/strings/cord.h" +#include "absl/strings/cord.h" #include "absl/strings/string_view.h" #include "absl/types/compare.h" #include "absl/utility/utility.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { // A helper class that indicates if the Compare parameter is a key-compare-to @@ -99,19 +99,19 @@ struct StringBtreeDefaultLess { absl::string_view rhs) const { return compare_internal::compare_result_as_ordering(lhs.compare(rhs)); } - StringBtreeDefaultLess(std::less<absl::Cord>) {} // NOLINT - absl::weak_ordering operator()(const absl::Cord &lhs, - const absl::Cord &rhs) const { - return compare_internal::compare_result_as_ordering(lhs.Compare(rhs)); - } - absl::weak_ordering operator()(const absl::Cord &lhs, - absl::string_view rhs) const { - return compare_internal::compare_result_as_ordering(lhs.Compare(rhs)); - } - absl::weak_ordering operator()(absl::string_view lhs, - const absl::Cord &rhs) const { - return compare_internal::compare_result_as_ordering(-rhs.Compare(lhs)); - } + StringBtreeDefaultLess(std::less<absl::Cord>) {} // NOLINT + absl::weak_ordering operator()(const absl::Cord &lhs, + const absl::Cord &rhs) const { + return compare_internal::compare_result_as_ordering(lhs.Compare(rhs)); + } + absl::weak_ordering operator()(const absl::Cord &lhs, + absl::string_view rhs) const { + return compare_internal::compare_result_as_ordering(lhs.Compare(rhs)); + } + absl::weak_ordering operator()(absl::string_view lhs, + const absl::Cord &rhs) const { + return compare_internal::compare_result_as_ordering(-rhs.Compare(lhs)); + } }; struct StringBtreeDefaultGreater { @@ -131,30 +131,30 @@ struct StringBtreeDefaultGreater { absl::string_view rhs) const { return compare_internal::compare_result_as_ordering(rhs.compare(lhs)); } - StringBtreeDefaultGreater(std::greater<absl::Cord>) {} // NOLINT - absl::weak_ordering operator()(const absl::Cord &lhs, - const absl::Cord &rhs) const { - return compare_internal::compare_result_as_ordering(rhs.Compare(lhs)); - } - absl::weak_ordering operator()(const absl::Cord &lhs, - absl::string_view rhs) const { - return compare_internal::compare_result_as_ordering(-lhs.Compare(rhs)); - } - absl::weak_ordering operator()(absl::string_view lhs, - const absl::Cord &rhs) const { - return compare_internal::compare_result_as_ordering(rhs.Compare(lhs)); - } + StringBtreeDefaultGreater(std::greater<absl::Cord>) {} // NOLINT + absl::weak_ordering operator()(const absl::Cord &lhs, + const absl::Cord &rhs) const { + return compare_internal::compare_result_as_ordering(rhs.Compare(lhs)); + } + absl::weak_ordering operator()(const absl::Cord &lhs, + absl::string_view rhs) const { + return compare_internal::compare_result_as_ordering(-lhs.Compare(rhs)); + } + absl::weak_ordering operator()(absl::string_view lhs, + const absl::Cord &rhs) const { + return compare_internal::compare_result_as_ordering(rhs.Compare(lhs)); + } }; // A helper class to convert a boolean comparison into a three-way "compare-to" -// comparison that returns an `absl::weak_ordering`. This helper +// comparison that returns an `absl::weak_ordering`. This helper // class is specialized for less<std::string>, greater<std::string>, -// less<string_view>, greater<string_view>, less<absl::Cord>, and -// greater<absl::Cord>. +// less<string_view>, greater<string_view>, less<absl::Cord>, and +// greater<absl::Cord>. // // key_compare_to_adapter is provided so that btree users // automatically get the more efficient compare-to code when using common -// Abseil string types with common comparison functors. +// Abseil string types with common comparison functors. // These string-like specializations also turn on heterogeneous lookup by // default. template <typename Compare> @@ -182,16 +182,16 @@ struct key_compare_to_adapter<std::greater<absl::string_view>> { using type = StringBtreeDefaultGreater; }; -template <> -struct key_compare_to_adapter<std::less<absl::Cord>> { - using type = StringBtreeDefaultLess; -}; - -template <> -struct key_compare_to_adapter<std::greater<absl::Cord>> { - using type = StringBtreeDefaultGreater; -}; - +template <> +struct key_compare_to_adapter<std::less<absl::Cord>> { + using type = StringBtreeDefaultLess; +}; + +template <> +struct key_compare_to_adapter<std::greater<absl::Cord>> { + using type = StringBtreeDefaultGreater; +}; + // Detects an 'absl_btree_prefer_linear_node_search' member. This is // a protocol used as an opt-in or opt-out of linear search. // @@ -229,7 +229,7 @@ template <typename Key, typename Compare, typename Alloc, int TargetNodeSize, struct common_params { using original_key_compare = Compare; - // If Compare is a common comparator for a string-like type, then we adapt it + // If Compare is a common comparator for a string-like type, then we adapt it // to use heterogeneous lookup and to be a key-compare-to comparator. using key_compare = typename key_compare_to_adapter<Compare>::type; // A type which indicates if we have a key-compare-to functor or a plain old @@ -348,17 +348,17 @@ struct map_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi, }; using is_map_container = std::true_type; - template <typename V> - static auto key(const V &value) -> decltype(value.first) { - return value.first; - } - static const Key &key(const slot_type *s) { return slot_policy::key(s); } - static const Key &key(slot_type *s) { return slot_policy::key(s); } - // For use in node handle. - static auto mutable_key(slot_type *s) - -> decltype(slot_policy::mutable_key(s)) { - return slot_policy::mutable_key(s); - } + template <typename V> + static auto key(const V &value) -> decltype(value.first) { + return value.first; + } + static const Key &key(const slot_type *s) { return slot_policy::key(s); } + static const Key &key(slot_type *s) { return slot_policy::key(s); } + // For use in node handle. + static auto mutable_key(slot_type *s) + -> decltype(slot_policy::mutable_key(s)) { + return slot_policy::mutable_key(s); + } static mapped_type &value(value_type *value) { return value->second; } }; @@ -413,10 +413,10 @@ struct set_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi, typename set_params::common_params::original_key_compare; using is_map_container = std::false_type; - template <typename V> - static const V &key(const V &value) { return value; } - static const Key &key(const slot_type *slot) { return *slot; } - static const Key &key(slot_type *slot) { return *slot; } + template <typename V> + static const V &key(const V &value) { return value; } + static const Key &key(const slot_type *slot) { return *slot; } + static const Key &key(slot_type *slot) { return *slot; } }; // An adapter class that converts a lower-bound compare into an upper-bound @@ -426,8 +426,8 @@ struct set_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi, template <typename Compare> struct upper_bound_adapter { explicit upper_bound_adapter(const Compare &c) : comp(c) {} - template <typename K1, typename K2> - bool operator()(const K1 &a, const K2 &b) const { + template <typename K1, typename K2> + bool operator()(const K1 &a, const K2 &b) const { // Returns true when a is not greater than b. return !compare_internal::compare_result_as_less_than(comp(b, a)); } @@ -453,9 +453,9 @@ struct SearchResult { template <typename V> struct SearchResult<V, false> { SearchResult() {} - explicit SearchResult(V value) : value(value) {} - SearchResult(V value, MatchKind /*match*/) : value(value) {} - + explicit SearchResult(V value) : value(value) {} + SearchResult(V value, MatchKind /*match*/) : value(value) {} + V value; static constexpr bool HasMatch() { return false; } @@ -513,9 +513,9 @@ class btree_node { // // TODO(ezb): right now, `start` is always 0. Update insertion/merge // // logic to allow for floating storage within nodes. // field_type start; - // // The index after the last populated value in `values`. Currently, this - // // is the same as the count of values. - // field_type finish; + // // The index after the last populated value in `values`. Currently, this + // // is the same as the count of values. + // field_type finish; // // The maximum number of values the node can hold. This is an integer in // // [1, kNodeSlots] for root leaf nodes, kNodeSlots for non-root leaf // // nodes, and kInternalNodeMaxCount (as a sentinel value) for internal @@ -526,7 +526,7 @@ class btree_node { // // // The array of values. The capacity is `max_count` for leaf nodes and // // kNodeSlots for internal nodes. Only the values in - // // [start, finish) have been initialized and are valid. + // // [start, finish) have been initialized and are valid. // slot_type values[max_count]; // // // The array of child pointers. The keys in children[i] are all less @@ -557,7 +557,7 @@ class btree_node { slot_type, btree_node *>; constexpr static size_type SizeWithNSlots(size_type n) { return layout_type(/*parent*/ 1, - /*position, start, finish, max_count*/ 4, + /*position, start, finish, max_count*/ 4, /*slots*/ n, /*children*/ 0) .AllocSize(); @@ -599,13 +599,13 @@ class btree_node { // Leaves can have less than kNodeSlots values. constexpr static layout_type LeafLayout(const int slot_count = kNodeSlots) { return layout_type(/*parent*/ 1, - /*position, start, finish, max_count*/ 4, + /*position, start, finish, max_count*/ 4, /*slots*/ slot_count, /*children*/ 0); } constexpr static layout_type InternalLayout() { return layout_type(/*parent*/ 1, - /*position, start, finish, max_count*/ 4, + /*position, start, finish, max_count*/ 4, /*slots*/ kNodeSlots, /*children*/ kNodeSlots + 1); } @@ -631,14 +631,14 @@ class btree_node { reinterpret_cast<const char *>(this)); } void set_parent(btree_node *p) { *GetField<0>() = p; } - field_type &mutable_finish() { return GetField<1>()[2]; } + field_type &mutable_finish() { return GetField<1>()[2]; } slot_type *slot(int i) { return &GetField<2>()[i]; } - slot_type *start_slot() { return slot(start()); } - slot_type *finish_slot() { return slot(finish()); } + slot_type *start_slot() { return slot(start()); } + slot_type *finish_slot() { return slot(finish()); } const slot_type *slot(int i) const { return &GetField<2>()[i]; } void set_position(field_type v) { GetField<1>()[0] = v; } void set_start(field_type v) { GetField<1>()[1] = v; } - void set_finish(field_type v) { GetField<1>()[2] = v; } + void set_finish(field_type v) { GetField<1>()[2] = v; } // This method is only called by the node init methods. void set_max_count(field_type v) { GetField<1>()[3] = v; } @@ -651,20 +651,20 @@ class btree_node { field_type position() const { return GetField<1>()[0]; } // Getter for the offset of the first value in the `values` array. - field_type start() const { - // TODO(ezb): when floating storage is implemented, return GetField<1>()[1]; - assert(GetField<1>()[1] == 0); - return 0; - } - - // Getter for the offset after the last value in the `values` array. - field_type finish() const { return GetField<1>()[2]; } - + field_type start() const { + // TODO(ezb): when floating storage is implemented, return GetField<1>()[1]; + assert(GetField<1>()[1] == 0); + return 0; + } + + // Getter for the offset after the last value in the `values` array. + field_type finish() const { return GetField<1>()[2]; } + // Getters for the number of values stored in this node. - field_type count() const { - assert(finish() >= start()); - return finish() - start(); - } + field_type count() const { + assert(finish() >= start()); + return finish() - start(); + } field_type max_count() const { // Internal nodes have max_count==kInternalNodeMaxCount. // Leaf nodes have max_count in [1, kNodeSlots]. @@ -692,7 +692,7 @@ class btree_node { // Getters/setter for the child at position i in the node. btree_node *child(int i) const { return GetField<3>()[i]; } - btree_node *start_child() const { return child(start()); } + btree_node *start_child() const { return child(start()); } btree_node *&mutable_child(int i) { return GetField<3>()[i]; } void clear_child(int i) { absl::container_internal::SanitizerPoisonObject(&mutable_child(i)); @@ -725,14 +725,14 @@ class btree_node { template <typename K, typename Compare> SearchResult<int, btree_is_key_compare_to<Compare, key_type>::value> linear_search(const K &k, const Compare &comp) const { - return linear_search_impl(k, start(), finish(), comp, + return linear_search_impl(k, start(), finish(), comp, btree_is_key_compare_to<Compare, key_type>()); } template <typename K, typename Compare> SearchResult<int, btree_is_key_compare_to<Compare, key_type>::value> binary_search(const K &k, const Compare &comp) const { - return binary_search_impl(k, start(), finish(), comp, + return binary_search_impl(k, start(), finish(), comp, btree_is_key_compare_to<Compare, key_type>()); } @@ -748,7 +748,7 @@ class btree_node { } ++s; } - return SearchResult<int, false>{s}; + return SearchResult<int, false>{s}; } // Returns the position of the first value whose key is not less than k using @@ -783,7 +783,7 @@ class btree_node { e = mid; } } - return SearchResult<int, false>{s}; + return SearchResult<int, false>{s}; } // Returns the position of the first value whose key is not less than k using @@ -831,10 +831,10 @@ class btree_node { template <typename... Args> void emplace_value(size_type i, allocator_type *alloc, Args &&... args); - // Removes the values at positions [i, i + to_erase), shifting all existing - // values and children after that range to the left by to_erase. Clears all - // children between [i, i + to_erase). - void remove_values(field_type i, field_type to_erase, allocator_type *alloc); + // Removes the values at positions [i, i + to_erase), shifting all existing + // values and children after that range to the left by to_erase. Clears all + // children between [i, i + to_erase). + void remove_values(field_type i, field_type to_erase, allocator_type *alloc); // Rebalances a node with its right sibling. void rebalance_right_to_left(int to_move, btree_node *right, @@ -846,87 +846,87 @@ class btree_node { void split(int insert_position, btree_node *dest, allocator_type *alloc); // Merges a node with its right sibling, moving all of the values and the - // delimiting key in the parent node onto itself, and deleting the src node. - void merge(btree_node *src, allocator_type *alloc); + // delimiting key in the parent node onto itself, and deleting the src node. + void merge(btree_node *src, allocator_type *alloc); // Node allocation/deletion routines. - void init_leaf(btree_node *parent, int max_count) { - set_parent(parent); - set_position(0); - set_start(0); - set_finish(0); - set_max_count(max_count); + void init_leaf(btree_node *parent, int max_count) { + set_parent(parent); + set_position(0); + set_start(0); + set_finish(0); + set_max_count(max_count); absl::container_internal::SanitizerPoisonMemoryRegion( - start_slot(), max_count * sizeof(slot_type)); + start_slot(), max_count * sizeof(slot_type)); } - void init_internal(btree_node *parent) { + void init_internal(btree_node *parent) { init_leaf(parent, kNodeSlots); // Set `max_count` to a sentinel value to indicate that this node is // internal. - set_max_count(kInternalNodeMaxCount); + set_max_count(kInternalNodeMaxCount); absl::container_internal::SanitizerPoisonMemoryRegion( &mutable_child(start()), (kNodeSlots + 1) * sizeof(btree_node *)); } - - static void deallocate(const size_type size, btree_node *node, - allocator_type *alloc) { - absl::container_internal::Deallocate<Alignment()>(alloc, node, size); + + static void deallocate(const size_type size, btree_node *node, + allocator_type *alloc) { + absl::container_internal::Deallocate<Alignment()>(alloc, node, size); } - // Deletes a node and all of its children. - static void clear_and_delete(btree_node *node, allocator_type *alloc); - + // Deletes a node and all of its children. + static void clear_and_delete(btree_node *node, allocator_type *alloc); + private: template <typename... Args> - void value_init(const field_type i, allocator_type *alloc, Args &&... args) { + void value_init(const field_type i, allocator_type *alloc, Args &&... args) { absl::container_internal::SanitizerUnpoisonObject(slot(i)); params_type::construct(alloc, slot(i), std::forward<Args>(args)...); } - void value_destroy(const field_type i, allocator_type *alloc) { + void value_destroy(const field_type i, allocator_type *alloc) { params_type::destroy(alloc, slot(i)); absl::container_internal::SanitizerPoisonObject(slot(i)); } - void value_destroy_n(const field_type i, const field_type n, - allocator_type *alloc) { - for (slot_type *s = slot(i), *end = slot(i + n); s != end; ++s) { - params_type::destroy(alloc, s); - absl::container_internal::SanitizerPoisonObject(s); - } - } - - static void transfer(slot_type *dest, slot_type *src, allocator_type *alloc) { - absl::container_internal::SanitizerUnpoisonObject(dest); - params_type::transfer(alloc, dest, src); - absl::container_internal::SanitizerPoisonObject(src); - } - - // Transfers value from slot `src_i` in `src_node` to slot `dest_i` in `this`. - void transfer(const size_type dest_i, const size_type src_i, - btree_node *src_node, allocator_type *alloc) { - transfer(slot(dest_i), src_node->slot(src_i), alloc); - } - - // Transfers `n` values starting at value `src_i` in `src_node` into the - // values starting at value `dest_i` in `this`. - void transfer_n(const size_type n, const size_type dest_i, - const size_type src_i, btree_node *src_node, - allocator_type *alloc) { - for (slot_type *src = src_node->slot(src_i), *end = src + n, - *dest = slot(dest_i); + void value_destroy_n(const field_type i, const field_type n, + allocator_type *alloc) { + for (slot_type *s = slot(i), *end = slot(i + n); s != end; ++s) { + params_type::destroy(alloc, s); + absl::container_internal::SanitizerPoisonObject(s); + } + } + + static void transfer(slot_type *dest, slot_type *src, allocator_type *alloc) { + absl::container_internal::SanitizerUnpoisonObject(dest); + params_type::transfer(alloc, dest, src); + absl::container_internal::SanitizerPoisonObject(src); + } + + // Transfers value from slot `src_i` in `src_node` to slot `dest_i` in `this`. + void transfer(const size_type dest_i, const size_type src_i, + btree_node *src_node, allocator_type *alloc) { + transfer(slot(dest_i), src_node->slot(src_i), alloc); + } + + // Transfers `n` values starting at value `src_i` in `src_node` into the + // values starting at value `dest_i` in `this`. + void transfer_n(const size_type n, const size_type dest_i, + const size_type src_i, btree_node *src_node, + allocator_type *alloc) { + for (slot_type *src = src_node->slot(src_i), *end = src + n, + *dest = slot(dest_i); src != end; ++src, ++dest) { - transfer(dest, src, alloc); + transfer(dest, src, alloc); } } - // Same as above, except that we start at the end and work our way to the - // beginning. - void transfer_n_backward(const size_type n, const size_type dest_i, - const size_type src_i, btree_node *src_node, - allocator_type *alloc) { - for (slot_type *src = src_node->slot(src_i + n - 1), *end = src - n, - *dest = slot(dest_i + n - 1); - src != end; --src, --dest) { - transfer(dest, src, alloc); + // Same as above, except that we start at the end and work our way to the + // beginning. + void transfer_n_backward(const size_type n, const size_type dest_i, + const size_type src_i, btree_node *src_node, + allocator_type *alloc) { + for (slot_type *src = src_node->slot(src_i + n - 1), *end = src - n, + *dest = slot(dest_i + n - 1); + src != end; --src, --dest) { + transfer(dest, src, alloc); } } @@ -968,7 +968,7 @@ struct btree_iterator { using iterator_category = std::bidirectional_iterator_tag; btree_iterator() : node(nullptr), position(-1) {} - explicit btree_iterator(Node *n) : node(n), position(n->start()) {} + explicit btree_iterator(Node *n) : node(n), position(n->start()) {} btree_iterator(Node *n, int p) : node(n), position(p) {} // NOTE: this SFINAE allows for implicit conversions from iterator to @@ -980,7 +980,7 @@ struct btree_iterator { std::is_same<btree_iterator, const_iterator>::value, int> = 0> btree_iterator(const btree_iterator<N, R, P> other) // NOLINT - : node(other.node), position(other.position) {} + : node(other.node), position(other.position) {} private: // This SFINAE allows explicit conversions from const_iterator to @@ -993,11 +993,11 @@ struct btree_iterator { std::is_same<btree_iterator, iterator>::value, int> = 0> explicit btree_iterator(const btree_iterator<N, R, P> other) - : node(const_cast<node_type *>(other.node)), position(other.position) {} + : node(const_cast<node_type *>(other.node)), position(other.position) {} // Increment/decrement the iterator. void increment() { - if (node->leaf() && ++position < node->finish()) { + if (node->leaf() && ++position < node->finish()) { return; } increment_slow(); @@ -1005,7 +1005,7 @@ struct btree_iterator { void increment_slow(); void decrement() { - if (node->leaf() && --position >= node->start()) { + if (node->leaf() && --position >= node->start()) { return; } decrement_slow(); @@ -1013,33 +1013,33 @@ struct btree_iterator { void decrement_slow(); public: - bool operator==(const iterator &other) const { - return node == other.node && position == other.position; + bool operator==(const iterator &other) const { + return node == other.node && position == other.position; } - bool operator==(const const_iterator &other) const { - return node == other.node && position == other.position; - } - bool operator!=(const iterator &other) const { - return node != other.node || position != other.position; - } - bool operator!=(const const_iterator &other) const { - return node != other.node || position != other.position; + bool operator==(const const_iterator &other) const { + return node == other.node && position == other.position; } + bool operator!=(const iterator &other) const { + return node != other.node || position != other.position; + } + bool operator!=(const const_iterator &other) const { + return node != other.node || position != other.position; + } // Accessors for the key/value the iterator is pointing at. reference operator*() const { - ABSL_HARDENING_ASSERT(node != nullptr); - ABSL_HARDENING_ASSERT(node->start() <= position); - ABSL_HARDENING_ASSERT(node->finish() > position); + ABSL_HARDENING_ASSERT(node != nullptr); + ABSL_HARDENING_ASSERT(node->start() <= position); + ABSL_HARDENING_ASSERT(node->finish() > position); return node->value(position); } - pointer operator->() const { return &operator*(); } + pointer operator->() const { return &operator*(); } - btree_iterator &operator++() { + btree_iterator &operator++() { increment(); return *this; } - btree_iterator &operator--() { + btree_iterator &operator--() { decrement(); return *this; } @@ -1076,8 +1076,8 @@ struct btree_iterator { // The node in the tree the iterator is pointing at. Node *node; // The position within the node of the tree the iterator is pointing at. - // NOTE: this is an int rather than a field_type because iterators can point - // to invalid positions (such as -1) in certain circumstances. + // NOTE: this is an int rather than a field_type because iterators can point + // to invalid positions (such as -1) in certain circumstances. int position; }; @@ -1085,8 +1085,8 @@ template <typename Params> class btree { using node_type = btree_node<Params>; using is_key_compare_to = typename Params::is_key_compare_to; - using init_type = typename Params::init_type; - using field_type = typename node_type::field_type; + using init_type = typename Params::init_type; + using field_type = typename node_type::field_type; // We use a static empty node for the root/leftmost/rightmost of empty btrees // in order to avoid branching in begin()/end(). @@ -1095,7 +1095,7 @@ class btree { node_type *parent; field_type position = 0; field_type start = 0; - field_type finish = 0; + field_type finish = 0; // max_count must be != kInternalNodeMaxCount (so that this node is regarded // as a leaf node). max_count() is never called when the tree is empty. field_type max_count = node_type::kInternalNodeMaxCount + 1; @@ -1110,7 +1110,7 @@ class btree { static node_type *EmptyNode() { #ifdef _MSC_VER - static EmptyNodeType *empty_node = new EmptyNodeType; + static EmptyNodeType *empty_node = new EmptyNodeType; // This assert fails on some other construction methods. assert(empty_node->parent == empty_node); return empty_node; @@ -1121,7 +1121,7 @@ class btree { #endif } - enum : uint32_t { + enum : uint32_t { kNodeSlots = node_type::kNodeSlots, kMinNodeValues = kNodeSlots / 2, }; @@ -1129,11 +1129,11 @@ class btree { struct node_stats { using size_type = typename Params::size_type; - node_stats(size_type l, size_type i) : leaf_nodes(l), internal_nodes(i) {} + node_stats(size_type l, size_type i) : leaf_nodes(l), internal_nodes(i) {} - node_stats &operator+=(const node_stats &other) { - leaf_nodes += other.leaf_nodes; - internal_nodes += other.internal_nodes; + node_stats &operator+=(const node_stats &other) { + leaf_nodes += other.leaf_nodes; + internal_nodes += other.internal_nodes; return *this; } @@ -1167,7 +1167,7 @@ class btree { private: // For use in copy_or_move_values_in_order. - const value_type &maybe_move_from_iterator(const_iterator it) { return *it; } + const value_type &maybe_move_from_iterator(const_iterator it) { return *it; } value_type &&maybe_move_from_iterator(iterator it) { // This is a destructive operation on the other container so it's safe for // us to const_cast and move from the keys here even if it's a set. @@ -1175,9 +1175,9 @@ class btree { } // Copies or moves (depending on the template parameter) the values in - // other into this btree in their order in other. This btree must be empty - // before this method is called. This method is used in copy construction, - // copy assignment, and move assignment. + // other into this btree in their order in other. This btree must be empty + // before this method is called. This method is used in copy construction, + // copy assignment, and move assignment. template <typename Btree> void copy_or_move_values_in_order(Btree &other); @@ -1193,11 +1193,11 @@ class btree { : btree(other.key_comp(), alloc) { copy_or_move_values_in_order(other); } - btree(btree &&other) noexcept - : root_(std::move(other.root_)), - rightmost_(absl::exchange(other.rightmost_, EmptyNode())), - size_(absl::exchange(other.size_, 0)) { - other.mutable_root() = EmptyNode(); + btree(btree &&other) noexcept + : root_(std::move(other.root_)), + rightmost_(absl::exchange(other.rightmost_, EmptyNode())), + size_(absl::exchange(other.size_, 0)) { + other.mutable_root() = EmptyNode(); } btree(btree &&other, const allocator_type &alloc) : btree(other.key_comp(), alloc) { @@ -1216,21 +1216,21 @@ class btree { clear(); } - // Assign the contents of other to *this. - btree &operator=(const btree &other); - btree &operator=(btree &&other) noexcept; + // Assign the contents of other to *this. + btree &operator=(const btree &other); + btree &operator=(btree &&other) noexcept; - iterator begin() { return iterator(leftmost()); } - const_iterator begin() const { return const_iterator(leftmost()); } - iterator end() { return iterator(rightmost_, rightmost_->finish()); } + iterator begin() { return iterator(leftmost()); } + const_iterator begin() const { return const_iterator(leftmost()); } + iterator end() { return iterator(rightmost_, rightmost_->finish()); } const_iterator end() const { - return const_iterator(rightmost_, rightmost_->finish()); + return const_iterator(rightmost_, rightmost_->finish()); } - reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } - reverse_iterator rend() { return reverse_iterator(begin()); } + reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } @@ -1261,21 +1261,21 @@ class btree { } // Finds the range of values which compare equal to key. The first member of - // the returned pair is equal to lower_bound(key). The second member of the - // pair is equal to upper_bound(key). + // the returned pair is equal to lower_bound(key). The second member of the + // pair is equal to upper_bound(key). template <typename K> - std::pair<iterator, iterator> equal_range(const K &key); + std::pair<iterator, iterator> equal_range(const K &key); template <typename K> std::pair<const_iterator, const_iterator> equal_range(const K &key) const { - return const_cast<btree *>(this)->equal_range(key); + return const_cast<btree *>(this)->equal_range(key); } // Inserts a value into the btree only if it does not already exist. The // boolean return value indicates whether insertion succeeded or failed. // Requirement: if `key` already exists in the btree, does not consume `args`. // Requirement: `key` is never referenced after consuming `args`. - template <typename K, typename... Args> - std::pair<iterator, bool> insert_unique(const K &key, Args &&... args); + template <typename K, typename... Args> + std::pair<iterator, bool> insert_unique(const K &key, Args &&... args); // Inserts with hint. Checks to see if the value should be placed immediately // before `position` in the tree. If so, then the insertion will take @@ -1283,23 +1283,23 @@ class btree { // logarithmic time as if a call to insert_unique() were made. // Requirement: if `key` already exists in the btree, does not consume `args`. // Requirement: `key` is never referenced after consuming `args`. - template <typename K, typename... Args> + template <typename K, typename... Args> std::pair<iterator, bool> insert_hint_unique(iterator position, - const K &key, + const K &key, Args &&... args); // Insert a range of values into the btree. - // Note: the first overload avoids constructing a value_type if the key - // already exists in the btree. - template <typename InputIterator, - typename = decltype(std::declval<const key_compare &>()( - params_type::key(*std::declval<InputIterator>()), - std::declval<const key_type &>()))> - void insert_iterator_unique(InputIterator b, InputIterator e, int); - // We need the second overload for cases in which we need to construct a - // value_type in order to compare it with the keys already in the btree. + // Note: the first overload avoids constructing a value_type if the key + // already exists in the btree. + template <typename InputIterator, + typename = decltype(std::declval<const key_compare &>()( + params_type::key(*std::declval<InputIterator>()), + std::declval<const key_type &>()))> + void insert_iterator_unique(InputIterator b, InputIterator e, int); + // We need the second overload for cases in which we need to construct a + // value_type in order to compare it with the keys already in the btree. template <typename InputIterator> - void insert_iterator_unique(InputIterator b, InputIterator e, char); + void insert_iterator_unique(InputIterator b, InputIterator e, char); // Inserts a value into the btree. template <typename ValueType> @@ -1330,7 +1330,7 @@ class btree { // Erases range. Returns the number of keys erased and an iterator pointing // to the element after the last erased element. - std::pair<size_type, iterator> erase_range(iterator begin, iterator end); + std::pair<size_type, iterator> erase_range(iterator begin, iterator end); // Finds an element with key equivalent to `key` or returns `end()` if `key` // is not present. @@ -1346,15 +1346,15 @@ class btree { // Clear the btree, deleting all of the values it contains. void clear(); - // Swaps the contents of `this` and `other`. - void swap(btree &other); + // Swaps the contents of `this` and `other`. + void swap(btree &other); const key_compare &key_comp() const noexcept { return root_.template get<0>(); } - template <typename K1, typename K2> - bool compare_keys(const K1 &a, const K2 &b) const { - return compare_internal::compare_result_as_less_than(key_comp()(a, b)); + template <typename K1, typename K2> + bool compare_keys(const K1 &a, const K2 &b) const { + return compare_internal::compare_result_as_less_than(key_comp()(a, b)); } value_compare value_comp() const { @@ -1387,7 +1387,7 @@ class btree { } // The number of internal, leaf and total nodes used by the btree. - size_type leaf_nodes() const { return internal_stats(root()).leaf_nodes; } + size_type leaf_nodes() const { return internal_stats(root()).leaf_nodes; } size_type internal_nodes() const { return internal_stats(root()).internal_nodes; } @@ -1400,9 +1400,9 @@ class btree { size_type bytes_used() const { node_stats stats = internal_stats(root()); if (stats.leaf_nodes == 1 && stats.internal_nodes == 0) { - return sizeof(*this) + node_type::LeafSize(root()->max_count()); + return sizeof(*this) + node_type::LeafSize(root()->max_count()); } else { - return sizeof(*this) + stats.leaf_nodes * node_type::LeafSize() + + return sizeof(*this) + stats.leaf_nodes * node_type::LeafSize() + stats.internal_nodes * node_type::InternalSize(); } } @@ -1437,7 +1437,7 @@ class btree { } // The allocator used by the btree. - allocator_type get_allocator() const { return allocator(); } + allocator_type get_allocator() const { return allocator(); } private: // Internal accessor routines. @@ -1467,20 +1467,20 @@ class btree { } // Node creation/deletion routines. - node_type *new_internal_node(node_type *parent) { - node_type *n = allocate(node_type::InternalSize()); - n->init_internal(parent); - return n; + node_type *new_internal_node(node_type *parent) { + node_type *n = allocate(node_type::InternalSize()); + n->init_internal(parent); + return n; } - node_type *new_leaf_node(node_type *parent) { - node_type *n = allocate(node_type::LeafSize()); + node_type *new_leaf_node(node_type *parent) { + node_type *n = allocate(node_type::LeafSize()); n->init_leaf(parent, kNodeSlots); - return n; + return n; } node_type *new_leaf_root_node(const int max_count) { - node_type *n = allocate(node_type::LeafSize(max_count)); - n->init_leaf(/*parent=*/n, max_count); - return n; + node_type *n = allocate(node_type::LeafSize(max_count)); + n->init_leaf(/*parent=*/n, max_count); + return n; } // Deletion helper routines. @@ -1515,19 +1515,19 @@ class btree { iterator internal_emplace(iterator iter, Args &&... args); // Returns an iterator pointing to the first value >= the value "iter" is - // pointing at. Note that "iter" might be pointing to an invalid location such - // as iter.position == iter.node->finish(). This routine simply moves iter up - // in the tree to a valid location. + // pointing at. Note that "iter" might be pointing to an invalid location such + // as iter.position == iter.node->finish(). This routine simply moves iter up + // in the tree to a valid location. // Requires: iter.node is non-null. template <typename IterType> static IterType internal_last(IterType iter); // Returns an iterator pointing to the leaf position at which key would - // reside in the tree, unless there is an exact match - in which case, the - // result may not be on a leaf. When there's a three-way comparator, we can - // return whether there was an exact match. This allows the caller to avoid a - // subsequent comparison to determine if an exact match was made, which is - // important for keys with expensive comparison, such as strings. + // reside in the tree, unless there is an exact match - in which case, the + // result may not be on a leaf. When there's a three-way comparator, we can + // return whether there was an exact match. This allows the caller to avoid a + // subsequent comparison to determine if an exact match was made, which is + // important for keys with expensive comparison, such as strings. template <typename K> SearchResult<iterator, is_key_compare_to::value> internal_locate( const K &key) const; @@ -1546,8 +1546,8 @@ class btree { iterator internal_find(const K &key) const; // Verifies the tree structure of node. - int internal_verify(const node_type *node, const key_type *lo, - const key_type *hi) const; + int internal_verify(const node_type *node, const key_type *lo, + const key_type *hi) const; node_stats internal_stats(const node_type *node) const { // The root can be a static empty node. @@ -1558,7 +1558,7 @@ class btree { return node_stats(1, 0); } node_stats res(0, 1); - for (int i = node->start(); i <= node->finish(); ++i) { + for (int i = node->start(); i <= node->finish(); ++i) { res += internal_stats(node->child(i)); } return res; @@ -1585,19 +1585,19 @@ template <typename... Args> inline void btree_node<P>::emplace_value(const size_type i, allocator_type *alloc, Args &&... args) { - assert(i >= start()); - assert(i <= finish()); + assert(i >= start()); + assert(i <= finish()); // Shift old values to create space for new value and then construct it in // place. - if (i < finish()) { - transfer_n_backward(finish() - i, /*dest_i=*/i + 1, /*src_i=*/i, this, - alloc); + if (i < finish()) { + transfer_n_backward(finish() - i, /*dest_i=*/i + 1, /*src_i=*/i, this, + alloc); } value_init(i, alloc, std::forward<Args>(args)...); - set_finish(finish() + 1); + set_finish(finish() + 1); - if (!leaf() && finish() > i + 1) { - for (int j = finish(); j > i + 1; --j) { + if (!leaf() && finish() > i + 1) { + for (int j = finish(); j > i + 1; --j) { set_child(j, child(j - 1)); } clear_child(i + 1); @@ -1605,27 +1605,27 @@ inline void btree_node<P>::emplace_value(const size_type i, } template <typename P> -inline void btree_node<P>::remove_values(const field_type i, - const field_type to_erase, - allocator_type *alloc) { - // Transfer values after the removed range into their new places. - value_destroy_n(i, to_erase, alloc); - const field_type orig_finish = finish(); - const field_type src_i = i + to_erase; - transfer_n(orig_finish - src_i, i, src_i, this, alloc); - - if (!leaf()) { - // Delete all children between begin and end. - for (int j = 0; j < to_erase; ++j) { - clear_and_delete(child(i + j + 1), alloc); - } - // Rotate children after end into new positions. - for (int j = i + to_erase + 1; j <= orig_finish; ++j) { - set_child(j - to_erase, child(j)); - clear_child(j); +inline void btree_node<P>::remove_values(const field_type i, + const field_type to_erase, + allocator_type *alloc) { + // Transfer values after the removed range into their new places. + value_destroy_n(i, to_erase, alloc); + const field_type orig_finish = finish(); + const field_type src_i = i + to_erase; + transfer_n(orig_finish - src_i, i, src_i, this, alloc); + + if (!leaf()) { + // Delete all children between begin and end. + for (int j = 0; j < to_erase; ++j) { + clear_and_delete(child(i + j + 1), alloc); } + // Rotate children after end into new positions. + for (int j = i + to_erase + 1; j <= orig_finish; ++j) { + set_child(j - to_erase, child(j)); + clear_child(j); + } } - set_finish(orig_finish - to_erase); + set_finish(orig_finish - to_erase); } template <typename P> @@ -1639,33 +1639,33 @@ void btree_node<P>::rebalance_right_to_left(const int to_move, assert(to_move <= right->count()); // 1) Move the delimiting value in the parent to the left node. - transfer(finish(), position(), parent(), alloc); + transfer(finish(), position(), parent(), alloc); // 2) Move the (to_move - 1) values from the right node to the left node. - transfer_n(to_move - 1, finish() + 1, right->start(), right, alloc); + transfer_n(to_move - 1, finish() + 1, right->start(), right, alloc); // 3) Move the new delimiting value to the parent from the right node. - parent()->transfer(position(), right->start() + to_move - 1, right, alloc); + parent()->transfer(position(), right->start() + to_move - 1, right, alloc); - // 4) Shift the values in the right node to their correct positions. - right->transfer_n(right->count() - to_move, right->start(), - right->start() + to_move, right, alloc); + // 4) Shift the values in the right node to their correct positions. + right->transfer_n(right->count() - to_move, right->start(), + right->start() + to_move, right, alloc); if (!leaf()) { // Move the child pointers from the right to the left node. for (int i = 0; i < to_move; ++i) { - init_child(finish() + i + 1, right->child(i)); + init_child(finish() + i + 1, right->child(i)); } - for (int i = right->start(); i <= right->finish() - to_move; ++i) { + for (int i = right->start(); i <= right->finish() - to_move; ++i) { assert(i + to_move <= right->max_count()); right->init_child(i, right->child(i + to_move)); right->clear_child(i + to_move); } } - // Fixup `finish` on the left and right nodes. - set_finish(finish() + to_move); - right->set_finish(right->finish() - to_move); + // Fixup `finish` on the left and right nodes. + set_finish(finish() + to_move); + right->set_finish(right->finish() - to_move); } template <typename P> @@ -1684,35 +1684,35 @@ void btree_node<P>::rebalance_left_to_right(const int to_move, // Lastly, a new delimiting value is moved from the left node into the // parent, and the remaining empty left node entries are destroyed. - // 1) Shift existing values in the right node to their correct positions. - right->transfer_n_backward(right->count(), right->start() + to_move, - right->start(), right, alloc); + // 1) Shift existing values in the right node to their correct positions. + right->transfer_n_backward(right->count(), right->start() + to_move, + right->start(), right, alloc); - // 2) Move the delimiting value in the parent to the right node. - right->transfer(right->start() + to_move - 1, position(), parent(), alloc); + // 2) Move the delimiting value in the parent to the right node. + right->transfer(right->start() + to_move - 1, position(), parent(), alloc); - // 3) Move the (to_move - 1) values from the left node to the right node. - right->transfer_n(to_move - 1, right->start(), finish() - (to_move - 1), this, - alloc); + // 3) Move the (to_move - 1) values from the left node to the right node. + right->transfer_n(to_move - 1, right->start(), finish() - (to_move - 1), this, + alloc); // 4) Move the new delimiting value to the parent from the left node. - parent()->transfer(position(), finish() - to_move, this, alloc); + parent()->transfer(position(), finish() - to_move, this, alloc); if (!leaf()) { // Move the child pointers from the left to the right node. - for (int i = right->finish(); i >= right->start(); --i) { + for (int i = right->finish(); i >= right->start(); --i) { right->init_child(i + to_move, right->child(i)); right->clear_child(i); } for (int i = 1; i <= to_move; ++i) { - right->init_child(i - 1, child(finish() - to_move + i)); - clear_child(finish() - to_move + i); + right->init_child(i - 1, child(finish() - to_move + i)); + clear_child(finish() - to_move + i); } } // Fixup the counts on the left and right nodes. - set_finish(finish() - to_move); - right->set_finish(right->finish() + to_move); + set_finish(finish() - to_move); + right->set_finish(right->finish() + to_move); } template <typename P> @@ -1725,31 +1725,31 @@ void btree_node<P>::split(const int insert_position, btree_node *dest, // inserting at the beginning of the left node then bias the split to put // more values on the right node. If we're inserting at the end of the // right node then bias the split to put more values on the left node. - if (insert_position == start()) { - dest->set_finish(dest->start() + finish() - 1); + if (insert_position == start()) { + dest->set_finish(dest->start() + finish() - 1); } else if (insert_position == kNodeSlots) { - dest->set_finish(dest->start()); + dest->set_finish(dest->start()); } else { - dest->set_finish(dest->start() + count() / 2); + dest->set_finish(dest->start() + count() / 2); } - set_finish(finish() - dest->count()); + set_finish(finish() - dest->count()); assert(count() >= 1); // Move values from the left sibling to the right sibling. - dest->transfer_n(dest->count(), dest->start(), finish(), this, alloc); + dest->transfer_n(dest->count(), dest->start(), finish(), this, alloc); // The split key is the largest value in the left sibling. - --mutable_finish(); - parent()->emplace_value(position(), alloc, finish_slot()); - value_destroy(finish(), alloc); + --mutable_finish(); + parent()->emplace_value(position(), alloc, finish_slot()); + value_destroy(finish(), alloc); parent()->init_child(position() + 1, dest); if (!leaf()) { - for (int i = dest->start(), j = finish() + 1; i <= dest->finish(); - ++i, ++j) { - assert(child(j) != nullptr); - dest->init_child(i, child(j)); - clear_child(j); + for (int i = dest->start(), j = finish() + 1; i <= dest->finish(); + ++i, ++j) { + assert(child(j) != nullptr); + dest->init_child(i, child(j)); + clear_child(j); } } } @@ -1760,75 +1760,75 @@ void btree_node<P>::merge(btree_node *src, allocator_type *alloc) { assert(position() + 1 == src->position()); // Move the delimiting value to the left node. - value_init(finish(), alloc, parent()->slot(position())); + value_init(finish(), alloc, parent()->slot(position())); // Move the values from the right to the left node. - transfer_n(src->count(), finish() + 1, src->start(), src, alloc); + transfer_n(src->count(), finish() + 1, src->start(), src, alloc); if (!leaf()) { // Move the child pointers from the right to the left node. - for (int i = src->start(), j = finish() + 1; i <= src->finish(); ++i, ++j) { - init_child(j, src->child(i)); + for (int i = src->start(), j = finish() + 1; i <= src->finish(); ++i, ++j) { + init_child(j, src->child(i)); src->clear_child(i); } } - // Fixup `finish` on the src and dest nodes. - set_finish(start() + 1 + count() + src->count()); - src->set_finish(src->start()); + // Fixup `finish` on the src and dest nodes. + set_finish(start() + 1 + count() + src->count()); + src->set_finish(src->start()); - // Remove the value on the parent node and delete the src node. - parent()->remove_values(position(), /*to_erase=*/1, alloc); + // Remove the value on the parent node and delete the src node. + parent()->remove_values(position(), /*to_erase=*/1, alloc); } template <typename P> -void btree_node<P>::clear_and_delete(btree_node *node, allocator_type *alloc) { - if (node->leaf()) { - node->value_destroy_n(node->start(), node->count(), alloc); - deallocate(LeafSize(node->max_count()), node, alloc); - return; +void btree_node<P>::clear_and_delete(btree_node *node, allocator_type *alloc) { + if (node->leaf()) { + node->value_destroy_n(node->start(), node->count(), alloc); + deallocate(LeafSize(node->max_count()), node, alloc); + return; } - if (node->count() == 0) { - deallocate(InternalSize(), node, alloc); - return; + if (node->count() == 0) { + deallocate(InternalSize(), node, alloc); + return; } - // The parent of the root of the subtree we are deleting. - btree_node *delete_root_parent = node->parent(); + // The parent of the root of the subtree we are deleting. + btree_node *delete_root_parent = node->parent(); - // Navigate to the leftmost leaf under node, and then delete upwards. - while (!node->leaf()) node = node->start_child(); + // Navigate to the leftmost leaf under node, and then delete upwards. + while (!node->leaf()) node = node->start_child(); // Use `int` because `pos` needs to be able to hold `kNodeSlots+1`, which - // isn't guaranteed to be a valid `field_type`. - int pos = node->position(); - btree_node *parent = node->parent(); - for (;;) { - // In each iteration of the next loop, we delete one leaf node and go right. - assert(pos <= parent->finish()); - do { - node = parent->child(pos); - if (!node->leaf()) { - // Navigate to the leftmost leaf under node. - while (!node->leaf()) node = node->start_child(); - pos = node->position(); - parent = node->parent(); - } - node->value_destroy_n(node->start(), node->count(), alloc); - deallocate(LeafSize(node->max_count()), node, alloc); - ++pos; - } while (pos <= parent->finish()); - - // Once we've deleted all children of parent, delete parent and go up/right. - assert(pos > parent->finish()); - do { - node = parent; - pos = node->position(); - parent = node->parent(); - node->value_destroy_n(node->start(), node->count(), alloc); - deallocate(InternalSize(), node, alloc); - if (parent == delete_root_parent) return; - ++pos; - } while (pos > parent->finish()); + // isn't guaranteed to be a valid `field_type`. + int pos = node->position(); + btree_node *parent = node->parent(); + for (;;) { + // In each iteration of the next loop, we delete one leaf node and go right. + assert(pos <= parent->finish()); + do { + node = parent->child(pos); + if (!node->leaf()) { + // Navigate to the leftmost leaf under node. + while (!node->leaf()) node = node->start_child(); + pos = node->position(); + parent = node->parent(); + } + node->value_destroy_n(node->start(), node->count(), alloc); + deallocate(LeafSize(node->max_count()), node, alloc); + ++pos; + } while (pos <= parent->finish()); + + // Once we've deleted all children of parent, delete parent and go up/right. + assert(pos > parent->finish()); + do { + node = parent; + pos = node->position(); + parent = node->parent(); + node->value_destroy_n(node->start(), node->count(), alloc); + deallocate(InternalSize(), node, alloc); + if (parent == delete_root_parent) return; + ++pos; + } while (pos > parent->finish()); } } @@ -1837,24 +1837,24 @@ void btree_node<P>::clear_and_delete(btree_node *node, allocator_type *alloc) { template <typename N, typename R, typename P> void btree_iterator<N, R, P>::increment_slow() { if (node->leaf()) { - assert(position >= node->finish()); + assert(position >= node->finish()); btree_iterator save(*this); - while (position == node->finish() && !node->is_root()) { + while (position == node->finish() && !node->is_root()) { assert(node->parent()->child(node->position()) == node); position = node->position(); node = node->parent(); } - // TODO(ezb): assert we aren't incrementing end() instead of handling. - if (position == node->finish()) { + // TODO(ezb): assert we aren't incrementing end() instead of handling. + if (position == node->finish()) { *this = save; } } else { - assert(position < node->finish()); + assert(position < node->finish()); node = node->child(position + 1); while (!node->leaf()) { - node = node->start_child(); + node = node->start_child(); } - position = node->start(); + position = node->start(); } } @@ -1863,22 +1863,22 @@ void btree_iterator<N, R, P>::decrement_slow() { if (node->leaf()) { assert(position <= -1); btree_iterator save(*this); - while (position < node->start() && !node->is_root()) { + while (position < node->start() && !node->is_root()) { assert(node->parent()->child(node->position()) == node); position = node->position() - 1; node = node->parent(); } - // TODO(ezb): assert we aren't decrementing begin() instead of handling. - if (position < node->start()) { + // TODO(ezb): assert we aren't decrementing begin() instead of handling. + if (position < node->start()) { *this = save; } } else { - assert(position >= node->start()); + assert(position >= node->start()); node = node->child(position); while (!node->leaf()) { - node = node->child(node->finish()); + node = node->child(node->finish()); } - position = node->finish() - 1; + position = node->finish() - 1; } } @@ -1950,44 +1950,44 @@ auto btree<P>::lower_bound_equal(const K &key) const } template <typename P> -template <typename K> -auto btree<P>::equal_range(const K &key) -> std::pair<iterator, iterator> { +template <typename K> +auto btree<P>::equal_range(const K &key) -> std::pair<iterator, iterator> { const std::pair<iterator, bool> lower_and_equal = lower_bound_equal(key); const iterator lower = lower_and_equal.first; if (!lower_and_equal.second) { return {lower, lower}; } - - const iterator next = std::next(lower); + + const iterator next = std::next(lower); if (!params_type::template can_have_multiple_equivalent_keys<K>()) { - // The next iterator after lower must point to a key greater than `key`. - // Note: if this assert fails, then it may indicate that the comparator does - // not meet the equivalence requirements for Compare - // (see https://en.cppreference.com/w/cpp/named_req/Compare). - assert(next == end() || compare_keys(key, next.key())); - return {lower, next}; - } - // Try once more to avoid the call to upper_bound() if there's only one - // equivalent key. This should prevent all calls to upper_bound() in cases of - // unique-containers with heterogeneous comparators in which all comparison + // The next iterator after lower must point to a key greater than `key`. + // Note: if this assert fails, then it may indicate that the comparator does + // not meet the equivalence requirements for Compare + // (see https://en.cppreference.com/w/cpp/named_req/Compare). + assert(next == end() || compare_keys(key, next.key())); + return {lower, next}; + } + // Try once more to avoid the call to upper_bound() if there's only one + // equivalent key. This should prevent all calls to upper_bound() in cases of + // unique-containers with heterogeneous comparators in which all comparison // operators have the same equivalence classes. - if (next == end() || compare_keys(key, next.key())) return {lower, next}; - - // In this case, we need to call upper_bound() to avoid worst case O(N) - // behavior if we were to iterate over equal keys. - return {lower, upper_bound(key)}; -} - -template <typename P> -template <typename K, typename... Args> -auto btree<P>::insert_unique(const K &key, Args &&... args) + if (next == end() || compare_keys(key, next.key())) return {lower, next}; + + // In this case, we need to call upper_bound() to avoid worst case O(N) + // behavior if we were to iterate over equal keys. + return {lower, upper_bound(key)}; +} + +template <typename P> +template <typename K, typename... Args> +auto btree<P>::insert_unique(const K &key, Args &&... args) -> std::pair<iterator, bool> { if (empty()) { mutable_root() = rightmost_ = new_leaf_root_node(1); } - SearchResult<iterator, is_key_compare_to::value> res = internal_locate(key); - iterator iter = res.value; + SearchResult<iterator, is_key_compare_to::value> res = internal_locate(key); + iterator iter = res.value; if (res.HasMatch()) { if (res.IsEq()) { @@ -2005,13 +2005,13 @@ auto btree<P>::insert_unique(const K &key, Args &&... args) } template <typename P> -template <typename K, typename... Args> -inline auto btree<P>::insert_hint_unique(iterator position, const K &key, +template <typename K, typename... Args> +inline auto btree<P>::insert_hint_unique(iterator position, const K &key, Args &&... args) -> std::pair<iterator, bool> { if (!empty()) { if (position == end() || compare_keys(key, position.key())) { - if (position == begin() || compare_keys(std::prev(position).key(), key)) { + if (position == begin() || compare_keys(std::prev(position).key(), key)) { // prev.key() < key < position.key() return {internal_emplace(position, std::forward<Args>(args)...), true}; } @@ -2030,23 +2030,23 @@ inline auto btree<P>::insert_hint_unique(iterator position, const K &key, } template <typename P> -template <typename InputIterator, typename> -void btree<P>::insert_iterator_unique(InputIterator b, InputIterator e, int) { +template <typename InputIterator, typename> +void btree<P>::insert_iterator_unique(InputIterator b, InputIterator e, int) { for (; b != e; ++b) { insert_hint_unique(end(), params_type::key(*b), *b); } } template <typename P> -template <typename InputIterator> -void btree<P>::insert_iterator_unique(InputIterator b, InputIterator e, char) { - for (; b != e; ++b) { - init_type value(*b); - insert_hint_unique(end(), params_type::key(value), std::move(value)); - } -} - -template <typename P> +template <typename InputIterator> +void btree<P>::insert_iterator_unique(InputIterator b, InputIterator e, char) { + for (; b != e; ++b) { + init_type value(*b); + insert_hint_unique(end(), params_type::key(value), std::move(value)); + } +} + +template <typename P> template <typename ValueType> auto btree<P>::insert_multi(const key_type &key, ValueType &&v) -> iterator { if (empty()) { @@ -2066,16 +2066,16 @@ auto btree<P>::insert_hint_multi(iterator position, ValueType &&v) -> iterator { if (!empty()) { const key_type &key = params_type::key(v); if (position == end() || !compare_keys(position.key(), key)) { - if (position == begin() || - !compare_keys(key, std::prev(position).key())) { + if (position == begin() || + !compare_keys(key, std::prev(position).key())) { // prev.key() <= key <= position.key() return internal_emplace(position, std::forward<ValueType>(v)); } } else { - ++position; - if (position == end() || !compare_keys(position.key(), key)) { - // {original `position`}.key() < key < {current `position`}.key() - return internal_emplace(position, std::forward<ValueType>(v)); + ++position; + if (position == end() || !compare_keys(position.key(), key)) { + // {original `position`}.key() < key < {current `position`}.key() + return internal_emplace(position, std::forward<ValueType>(v)); } } } @@ -2091,14 +2091,14 @@ void btree<P>::insert_iterator_multi(InputIterator b, InputIterator e) { } template <typename P> -auto btree<P>::operator=(const btree &other) -> btree & { - if (this != &other) { +auto btree<P>::operator=(const btree &other) -> btree & { + if (this != &other) { clear(); - *mutable_key_comp() = other.key_comp(); + *mutable_key_comp() = other.key_comp(); if (absl::allocator_traits< allocator_type>::propagate_on_container_copy_assignment::value) { - *mutable_allocator() = other.allocator(); + *mutable_allocator() = other.allocator(); } copy_or_move_values_in_order(other); @@ -2107,30 +2107,30 @@ auto btree<P>::operator=(const btree &other) -> btree & { } template <typename P> -auto btree<P>::operator=(btree &&other) noexcept -> btree & { - if (this != &other) { +auto btree<P>::operator=(btree &&other) noexcept -> btree & { + if (this != &other) { clear(); using std::swap; if (absl::allocator_traits< allocator_type>::propagate_on_container_copy_assignment::value) { // Note: `root_` also contains the allocator and the key comparator. - swap(root_, other.root_); - swap(rightmost_, other.rightmost_); - swap(size_, other.size_); + swap(root_, other.root_); + swap(rightmost_, other.rightmost_); + swap(size_, other.size_); } else { - if (allocator() == other.allocator()) { - swap(mutable_root(), other.mutable_root()); - swap(*mutable_key_comp(), *other.mutable_key_comp()); - swap(rightmost_, other.rightmost_); - swap(size_, other.size_); + if (allocator() == other.allocator()) { + swap(mutable_root(), other.mutable_root()); + swap(*mutable_key_comp(), *other.mutable_key_comp()); + swap(rightmost_, other.rightmost_); + swap(size_, other.size_); } else { // We aren't allowed to propagate the allocator and the allocator is // different so we can't take over its memory. We must move each element - // individually. We need both `other` and `this` to have `other`s key - // comparator while moving the values so we can't swap the key - // comparators. - *mutable_key_comp() = other.key_comp(); + // individually. We need both `other` and `this` to have `other`s key + // comparator while moving the values so we can't swap the key + // comparators. + *mutable_key_comp() = other.key_comp(); copy_or_move_values_in_order(other); } } @@ -2143,7 +2143,7 @@ auto btree<P>::erase(iterator iter) -> iterator { bool internal_delete = false; if (!iter.node->leaf()) { // Deletion of a value on an internal node. First, move the largest value - // from our left child here, then delete that position (in remove_values() + // from our left child here, then delete that position (in remove_values() // below). We can get to the largest value from our left child by // decrementing iter. iterator internal_iter(iter); @@ -2155,7 +2155,7 @@ auto btree<P>::erase(iterator iter) -> iterator { } // Delete the key from the leaf. - iter.node->remove_values(iter.position, /*to_erase=*/1, mutable_allocator()); + iter.node->remove_values(iter.position, /*to_erase=*/1, mutable_allocator()); --size_; // We want to return the next value after the one we just erased. If we @@ -2206,8 +2206,8 @@ auto btree<P>::rebalance_after_delete(iterator iter) -> iterator { // Adjust our return value. If we're pointing at the end of a node, advance // the iterator. - if (res.position == res.node->finish()) { - res.position = res.node->finish() - 1; + if (res.position == res.node->finish()) { + res.position = res.node->finish() - 1; ++res; } @@ -2215,7 +2215,7 @@ auto btree<P>::rebalance_after_delete(iterator iter) -> iterator { } template <typename P> -auto btree<P>::erase_range(iterator begin, iterator end) +auto btree<P>::erase_range(iterator begin, iterator end) -> std::pair<size_type, iterator> { difference_type count = std::distance(begin, end); assert(count >= 0); @@ -2230,9 +2230,9 @@ auto btree<P>::erase_range(iterator begin, iterator end) } if (begin.node == end.node) { - assert(end.position > begin.position); - begin.node->remove_values(begin.position, end.position - begin.position, - mutable_allocator()); + assert(end.position > begin.position); + begin.node->remove_values(begin.position, end.position - begin.position, + mutable_allocator()); size_ -= count; return {count, rebalance_after_delete(begin)}; } @@ -2241,12 +2241,12 @@ auto btree<P>::erase_range(iterator begin, iterator end) while (size_ > target_size) { if (begin.node->leaf()) { const size_type remaining_to_erase = size_ - target_size; - const size_type remaining_in_node = begin.node->finish() - begin.position; - const size_type to_erase = - (std::min)(remaining_to_erase, remaining_in_node); - begin.node->remove_values(begin.position, to_erase, mutable_allocator()); - size_ -= to_erase; - begin = rebalance_after_delete(begin); + const size_type remaining_in_node = begin.node->finish() - begin.position; + const size_type to_erase = + (std::min)(remaining_to_erase, remaining_in_node); + begin.node->remove_values(begin.position, to_erase, mutable_allocator()); + size_ -= to_erase; + begin = rebalance_after_delete(begin); } else { begin = erase(begin); } @@ -2257,7 +2257,7 @@ auto btree<P>::erase_range(iterator begin, iterator end) template <typename P> void btree<P>::clear() { if (!empty()) { - node_type::clear_and_delete(root(), mutable_allocator()); + node_type::clear_and_delete(root(), mutable_allocator()); } mutable_root() = EmptyNode(); rightmost_ = EmptyNode(); @@ -2265,20 +2265,20 @@ void btree<P>::clear() { } template <typename P> -void btree<P>::swap(btree &other) { +void btree<P>::swap(btree &other) { using std::swap; if (absl::allocator_traits< allocator_type>::propagate_on_container_swap::value) { // Note: `root_` also contains the allocator and the key comparator. - swap(root_, other.root_); + swap(root_, other.root_); } else { // It's undefined behavior if the allocators are unequal here. - assert(allocator() == other.allocator()); - swap(mutable_root(), other.mutable_root()); - swap(*mutable_key_comp(), *other.mutable_key_comp()); + assert(allocator() == other.allocator()); + swap(mutable_root(), other.mutable_root()); + swap(*mutable_key_comp(), *other.mutable_key_comp()); } - swap(rightmost_, other.rightmost_); - swap(size_, other.size_); + swap(rightmost_, other.rightmost_); + swap(size_, other.size_); } template <typename P> @@ -2288,7 +2288,7 @@ void btree<P>::verify() const { assert(rightmost_ != nullptr); assert(empty() || size() == internal_verify(root(), nullptr, nullptr)); assert(leftmost() == (++const_iterator(root(), -1)).node); - assert(rightmost_ == (--const_iterator(root(), root()->finish())).node); + assert(rightmost_ == (--const_iterator(root(), root()->finish())).node); assert(leftmost()->leaf()); assert(rightmost_->leaf()); } @@ -2303,7 +2303,7 @@ void btree<P>::rebalance_or_split(iterator *iter) { // First try to make room on the node by rebalancing. node_type *parent = node->parent(); if (node != root()) { - if (node->position() > parent->start()) { + if (node->position() > parent->start()) { // Try rebalancing with our left sibling. node_type *left = parent->child(node->position() - 1); assert(left->max_count() == kNodeSlots); @@ -2315,13 +2315,13 @@ void btree<P>::rebalance_or_split(iterator *iter) { (1 + (insert_position < static_cast<int>(kNodeSlots))); to_move = (std::max)(1, to_move); - if (insert_position - to_move >= node->start() || + if (insert_position - to_move >= node->start() || left->count() + to_move < static_cast<int>(kNodeSlots)) { left->rebalance_right_to_left(to_move, node, mutable_allocator()); assert(node->max_count() - node->count() == to_move); insert_position = insert_position - to_move; - if (insert_position < node->start()) { + if (insert_position < node->start()) { insert_position = insert_position + left->count() + 1; node = left; } @@ -2332,7 +2332,7 @@ void btree<P>::rebalance_or_split(iterator *iter) { } } - if (node->position() < parent->finish()) { + if (node->position() < parent->finish()) { // Try rebalancing with our right sibling. node_type *right = parent->child(node->position() + 1); assert(right->max_count() == kNodeSlots); @@ -2341,14 +2341,14 @@ void btree<P>::rebalance_or_split(iterator *iter) { // inserting at the beginning of the left node then we bias rebalancing // to fill up the right node. int to_move = (static_cast<int>(kNodeSlots) - right->count()) / - (1 + (insert_position > node->start())); + (1 + (insert_position > node->start())); to_move = (std::max)(1, to_move); - if (insert_position <= node->finish() - to_move || + if (insert_position <= node->finish() - to_move || right->count() + to_move < static_cast<int>(kNodeSlots)) { node->rebalance_left_to_right(to_move, right, mutable_allocator()); - if (insert_position > node->finish()) { + if (insert_position > node->finish()) { insert_position = insert_position - node->count() - 1; node = right; } @@ -2371,11 +2371,11 @@ void btree<P>::rebalance_or_split(iterator *iter) { // Create a new root node and set the current root node as the child of the // new root. parent = new_internal_node(parent); - parent->init_child(parent->start(), root()); + parent->init_child(parent->start(), root()); mutable_root() = parent; // If the former root was a leaf node, then it's now the rightmost node. - assert(!parent->start_child()->leaf() || - parent->start_child() == rightmost_); + assert(!parent->start_child()->leaf() || + parent->start_child() == rightmost_); } // Split the node. @@ -2389,7 +2389,7 @@ void btree<P>::rebalance_or_split(iterator *iter) { node->split(insert_position, split_node, mutable_allocator()); } - if (insert_position > node->finish()) { + if (insert_position > node->finish()) { insert_position = insert_position - node->count() - 1; node = split_node; } @@ -2398,13 +2398,13 @@ void btree<P>::rebalance_or_split(iterator *iter) { template <typename P> void btree<P>::merge_nodes(node_type *left, node_type *right) { left->merge(right, mutable_allocator()); - if (rightmost_ == right) rightmost_ = left; + if (rightmost_ == right) rightmost_ = left; } template <typename P> bool btree<P>::try_merge_or_rebalance(iterator *iter) { node_type *parent = iter->node->parent(); - if (iter->node->position() > parent->start()) { + if (iter->node->position() > parent->start()) { // Try merging with our left sibling. node_type *left = parent->child(iter->node->position() - 1); assert(left->max_count() == kNodeSlots); @@ -2415,7 +2415,7 @@ bool btree<P>::try_merge_or_rebalance(iterator *iter) { return true; } } - if (iter->node->position() < parent->finish()) { + if (iter->node->position() < parent->finish()) { // Try merging with our right sibling. node_type *right = parent->child(iter->node->position() + 1); assert(right->max_count() == kNodeSlots); @@ -2427,22 +2427,22 @@ bool btree<P>::try_merge_or_rebalance(iterator *iter) { // we deleted the first element from iter->node and the node is not // empty. This is a small optimization for the common pattern of deleting // from the front of the tree. - if (right->count() > kMinNodeValues && - (iter->node->count() == 0 || iter->position > iter->node->start())) { + if (right->count() > kMinNodeValues && + (iter->node->count() == 0 || iter->position > iter->node->start())) { int to_move = (right->count() - iter->node->count()) / 2; to_move = (std::min)(to_move, right->count() - 1); iter->node->rebalance_right_to_left(to_move, right, mutable_allocator()); return false; } } - if (iter->node->position() > parent->start()) { + if (iter->node->position() > parent->start()) { // Try rebalancing with our left sibling. We don't perform rebalancing if // we deleted the last element from iter->node and the node is not // empty. This is a small optimization for the common pattern of deleting // from the back of the tree. node_type *left = parent->child(iter->node->position() - 1); - if (left->count() > kMinNodeValues && - (iter->node->count() == 0 || iter->position < iter->node->finish())) { + if (left->count() > kMinNodeValues && + (iter->node->count() == 0 || iter->position < iter->node->finish())) { int to_move = (left->count() - iter->node->count()) / 2; to_move = (std::min)(to_move, left->count() - 1); left->rebalance_left_to_right(to_move, iter->node, mutable_allocator()); @@ -2455,27 +2455,27 @@ bool btree<P>::try_merge_or_rebalance(iterator *iter) { template <typename P> void btree<P>::try_shrink() { - node_type *orig_root = root(); - if (orig_root->count() > 0) { + node_type *orig_root = root(); + if (orig_root->count() > 0) { return; } // Deleted the last item on the root node, shrink the height of the tree. - if (orig_root->leaf()) { + if (orig_root->leaf()) { assert(size() == 0); - mutable_root() = rightmost_ = EmptyNode(); + mutable_root() = rightmost_ = EmptyNode(); } else { - node_type *child = orig_root->start_child(); + node_type *child = orig_root->start_child(); child->make_root(); mutable_root() = child; } - node_type::clear_and_delete(orig_root, mutable_allocator()); + node_type::clear_and_delete(orig_root, mutable_allocator()); } template <typename P> template <typename IterType> inline IterType btree<P>::internal_last(IterType iter) { assert(iter.node != nullptr); - while (iter.position == iter.node->finish()) { + while (iter.position == iter.node->finish()) { iter.position = iter.node->position(); iter.node = iter.node->parent(); if (iter.node->leaf()) { @@ -2496,8 +2496,8 @@ inline auto btree<P>::internal_emplace(iterator iter, Args &&... args) --iter; ++iter.position; } - const field_type max_count = iter.node->max_count(); - allocator_type *alloc = mutable_allocator(); + const field_type max_count = iter.node->max_count(); + allocator_type *alloc = mutable_allocator(); if (iter.node->count() == max_count) { // Make room in the leaf for the new item. if (max_count < kNodeSlots) { @@ -2506,20 +2506,20 @@ inline auto btree<P>::internal_emplace(iterator iter, Args &&... args) assert(iter.node == root()); iter.node = new_leaf_root_node((std::min<int>)(kNodeSlots, 2 * max_count)); - // Transfer the values from the old root to the new root. - node_type *old_root = root(); - node_type *new_root = iter.node; - new_root->transfer_n(old_root->count(), new_root->start(), - old_root->start(), old_root, alloc); - new_root->set_finish(old_root->finish()); - old_root->set_finish(old_root->start()); - node_type::clear_and_delete(old_root, alloc); - mutable_root() = rightmost_ = new_root; + // Transfer the values from the old root to the new root. + node_type *old_root = root(); + node_type *new_root = iter.node; + new_root->transfer_n(old_root->count(), new_root->start(), + old_root->start(), old_root, alloc); + new_root->set_finish(old_root->finish()); + old_root->set_finish(old_root->start()); + node_type::clear_and_delete(old_root, alloc); + mutable_root() = rightmost_ = new_root; } else { rebalance_or_split(&iter); } } - iter.node->emplace_value(iter.position, alloc, std::forward<Args>(args)...); + iter.node->emplace_value(iter.position, alloc, std::forward<Args>(args)...); ++size_; return iter; } @@ -2528,25 +2528,25 @@ template <typename P> template <typename K> inline auto btree<P>::internal_locate(const K &key) const -> SearchResult<iterator, is_key_compare_to::value> { - iterator iter(const_cast<node_type *>(root())); + iterator iter(const_cast<node_type *>(root())); for (;;) { - SearchResult<int, is_key_compare_to::value> res = - iter.node->lower_bound(key, key_comp()); + SearchResult<int, is_key_compare_to::value> res = + iter.node->lower_bound(key, key_comp()); iter.position = res.value; - if (res.IsEq()) { + if (res.IsEq()) { return {iter, MatchKind::kEq}; } - // Note: in the non-key-compare-to case, we don't need to walk all the way - // down the tree if the keys are equal, but determining equality would - // require doing an extra comparison on each node on the way down, and we - // will need to go all the way to the leaf node in the expected case. + // Note: in the non-key-compare-to case, we don't need to walk all the way + // down the tree if the keys are equal, but determining equality would + // require doing an extra comparison on each node on the way down, and we + // will need to go all the way to the leaf node in the expected case. if (iter.node->leaf()) { break; } iter.node = iter.node->child(iter.position); } - // Note: in the non-key-compare-to case, the key may actually be equivalent - // here (and the MatchKind::kNe is ignored). + // Note: in the non-key-compare-to case, the key may actually be equivalent + // here (and the MatchKind::kNe is ignored). return {iter, MatchKind::kNe}; } @@ -2559,7 +2559,7 @@ auto btree<P>::internal_lower_bound(const K &key) const ret.value = internal_last(ret.value); return ret; } - iterator iter(const_cast<node_type *>(root())); + iterator iter(const_cast<node_type *>(root())); SearchResult<int, is_key_compare_to::value> res; bool seen_eq = false; for (;;) { @@ -2578,7 +2578,7 @@ auto btree<P>::internal_lower_bound(const K &key) const template <typename P> template <typename K> auto btree<P>::internal_upper_bound(const K &key) const -> iterator { - iterator iter(const_cast<node_type *>(root())); + iterator iter(const_cast<node_type *>(root())); for (;;) { iter.position = iter.node->upper_bound(key, key_comp()); if (iter.node->leaf()) { @@ -2592,7 +2592,7 @@ auto btree<P>::internal_upper_bound(const K &key) const -> iterator { template <typename P> template <typename K> auto btree<P>::internal_find(const K &key) const -> iterator { - SearchResult<iterator, is_key_compare_to::value> res = internal_locate(key); + SearchResult<iterator, is_key_compare_to::value> res = internal_locate(key); if (res.HasMatch()) { if (res.IsEq()) { return res.value; @@ -2607,35 +2607,35 @@ auto btree<P>::internal_find(const K &key) const -> iterator { } template <typename P> -int btree<P>::internal_verify(const node_type *node, const key_type *lo, - const key_type *hi) const { +int btree<P>::internal_verify(const node_type *node, const key_type *lo, + const key_type *hi) const { assert(node->count() > 0); assert(node->count() <= node->max_count()); if (lo) { - assert(!compare_keys(node->key(node->start()), *lo)); + assert(!compare_keys(node->key(node->start()), *lo)); } if (hi) { - assert(!compare_keys(*hi, node->key(node->finish() - 1))); + assert(!compare_keys(*hi, node->key(node->finish() - 1))); } - for (int i = node->start() + 1; i < node->finish(); ++i) { + for (int i = node->start() + 1; i < node->finish(); ++i) { assert(!compare_keys(node->key(i), node->key(i - 1))); } int count = node->count(); if (!node->leaf()) { - for (int i = node->start(); i <= node->finish(); ++i) { + for (int i = node->start(); i <= node->finish(); ++i) { assert(node->child(i) != nullptr); assert(node->child(i)->parent() == node); assert(node->child(i)->position() == i); - count += internal_verify(node->child(i), - i == node->start() ? lo : &node->key(i - 1), - i == node->finish() ? hi : &node->key(i)); + count += internal_verify(node->child(i), + i == node->start() ? lo : &node->key(i - 1), + i == node->finish() ? hi : &node->key(i)); } } return count; } } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_BTREE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/btree_container.h b/contrib/restricted/abseil-cpp/absl/container/internal/btree_container.h index a99668c713..f78a637798 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/btree_container.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/btree_container.h @@ -28,7 +28,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { // A common base class for btree_set, btree_map, btree_multiset, and @@ -85,8 +85,8 @@ class btree_container { btree_container(btree_container &&other, const allocator_type &alloc) : tree_(std::move(other.tree_), alloc) {} - btree_container &operator=(const btree_container &other) = default; - btree_container &operator=(btree_container &&other) noexcept( + btree_container &operator=(const btree_container &other) = default; + btree_container &operator=(btree_container &&other) noexcept( std::is_nothrow_move_assignable<Tree>::value) = default; // Iterator routines. @@ -156,7 +156,7 @@ class btree_container { iterator erase(const_iterator iter) { return tree_.erase(iterator(iter)); } iterator erase(iterator iter) { return tree_.erase(iter); } iterator erase(const_iterator first, const_iterator last) { - return tree_.erase_range(iterator(first), iterator(last)).second; + return tree_.erase_range(iterator(first), iterator(last)).second; } template <typename K = key_type> size_type erase(const key_arg<K> &key) { @@ -178,7 +178,7 @@ class btree_container { // Utility routines. ABSL_ATTRIBUTE_REINITIALIZES void clear() { tree_.clear(); } - void swap(btree_container &other) { tree_.swap(other.tree_); } + void swap(btree_container &other) { tree_.swap(other.tree_); } void verify() const { tree_.verify(); } // Size routines. @@ -282,48 +282,48 @@ class btree_set_container : public btree_container<Tree> { : btree_set_container(init.begin(), init.end(), alloc) {} // Insertion routines. - std::pair<iterator, bool> insert(const value_type &v) { - return this->tree_.insert_unique(params_type::key(v), v); + std::pair<iterator, bool> insert(const value_type &v) { + return this->tree_.insert_unique(params_type::key(v), v); } - std::pair<iterator, bool> insert(value_type &&v) { - return this->tree_.insert_unique(params_type::key(v), std::move(v)); + std::pair<iterator, bool> insert(value_type &&v) { + return this->tree_.insert_unique(params_type::key(v), std::move(v)); } template <typename... Args> std::pair<iterator, bool> emplace(Args &&... args) { init_type v(std::forward<Args>(args)...); return this->tree_.insert_unique(params_type::key(v), std::move(v)); } - iterator insert(const_iterator hint, const value_type &v) { + iterator insert(const_iterator hint, const value_type &v) { return this->tree_ - .insert_hint_unique(iterator(hint), params_type::key(v), v) + .insert_hint_unique(iterator(hint), params_type::key(v), v) .first; } - iterator insert(const_iterator hint, value_type &&v) { + iterator insert(const_iterator hint, value_type &&v) { return this->tree_ - .insert_hint_unique(iterator(hint), params_type::key(v), std::move(v)) + .insert_hint_unique(iterator(hint), params_type::key(v), std::move(v)) .first; } template <typename... Args> - iterator emplace_hint(const_iterator hint, Args &&... args) { + iterator emplace_hint(const_iterator hint, Args &&... args) { init_type v(std::forward<Args>(args)...); return this->tree_ - .insert_hint_unique(iterator(hint), params_type::key(v), std::move(v)) + .insert_hint_unique(iterator(hint), params_type::key(v), std::move(v)) .first; } template <typename InputIterator> void insert(InputIterator b, InputIterator e) { - this->tree_.insert_iterator_unique(b, e, 0); + this->tree_.insert_iterator_unique(b, e, 0); } void insert(std::initializer_list<init_type> init) { - this->tree_.insert_iterator_unique(init.begin(), init.end(), 0); + this->tree_.insert_iterator_unique(init.begin(), init.end(), 0); } insert_return_type insert(node_type &&node) { if (!node) return {this->end(), false, node_type()}; std::pair<iterator, bool> res = - this->tree_.insert_unique(params_type::key(CommonAccess::GetSlot(node)), - CommonAccess::GetSlot(node)); + this->tree_.insert_unique(params_type::key(CommonAccess::GetSlot(node)), + CommonAccess::GetSlot(node)); if (res.second) { - CommonAccess::Destroy(&node); + CommonAccess::Destroy(&node); return {res.first, true, node_type()}; } else { return {res.first, false, std::move(node)}; @@ -333,8 +333,8 @@ class btree_set_container : public btree_container<Tree> { if (!node) return this->end(); std::pair<iterator, bool> res = this->tree_.insert_hint_unique( iterator(hint), params_type::key(CommonAccess::GetSlot(node)), - CommonAccess::GetSlot(node)); - if (res.second) CommonAccess::Destroy(&node); + CommonAccess::GetSlot(node)); + if (res.second) CommonAccess::Destroy(&node); return res.first; } @@ -362,7 +362,7 @@ class btree_set_container : public btree_container<Tree> { int> = 0> void merge(btree_container<T> &src) { // NOLINT for (auto src_it = src.begin(); src_it != src.end();) { - if (insert(std::move(params_type::element(src_it.slot()))).second) { + if (insert(std::move(params_type::element(src_it.slot()))).second) { src_it = src.erase(src_it); } else { ++src_it; @@ -391,7 +391,7 @@ class btree_map_container : public btree_set_container<Tree> { using params_type = typename Tree::params_type; friend class BtreeNodePeer; - private: + private: template <class K> using key_arg = typename super_type::template key_arg<K>; @@ -409,74 +409,74 @@ class btree_map_container : public btree_set_container<Tree> { btree_map_container() {} // Insertion routines. - // Note: the nullptr template arguments and extra `const M&` overloads allow - // for supporting bitfield arguments. - template <typename K = key_type, class M> - std::pair<iterator, bool> insert_or_assign(const key_arg<K> &k, - const M &obj) { - return insert_or_assign_impl(k, obj); - } - template <typename K = key_type, class M, K * = nullptr> - std::pair<iterator, bool> insert_or_assign(key_arg<K> &&k, const M &obj) { - return insert_or_assign_impl(std::forward<K>(k), obj); - } - template <typename K = key_type, class M, M * = nullptr> - std::pair<iterator, bool> insert_or_assign(const key_arg<K> &k, M &&obj) { - return insert_or_assign_impl(k, std::forward<M>(obj)); - } - template <typename K = key_type, class M, K * = nullptr, M * = nullptr> - std::pair<iterator, bool> insert_or_assign(key_arg<K> &&k, M &&obj) { - return insert_or_assign_impl(std::forward<K>(k), std::forward<M>(obj)); - } - template <typename K = key_type, class M> - iterator insert_or_assign(const_iterator hint, const key_arg<K> &k, - const M &obj) { - return insert_or_assign_hint_impl(hint, k, obj); - } - template <typename K = key_type, class M, K * = nullptr> - iterator insert_or_assign(const_iterator hint, key_arg<K> &&k, const M &obj) { - return insert_or_assign_hint_impl(hint, std::forward<K>(k), obj); - } - template <typename K = key_type, class M, M * = nullptr> - iterator insert_or_assign(const_iterator hint, const key_arg<K> &k, M &&obj) { - return insert_or_assign_hint_impl(hint, k, std::forward<M>(obj)); - } - template <typename K = key_type, class M, K * = nullptr, M * = nullptr> - iterator insert_or_assign(const_iterator hint, key_arg<K> &&k, M &&obj) { - return insert_or_assign_hint_impl(hint, std::forward<K>(k), - std::forward<M>(obj)); - } - - template <typename K = key_type, typename... Args, - typename absl::enable_if_t< - !std::is_convertible<K, const_iterator>::value, int> = 0> - std::pair<iterator, bool> try_emplace(const key_arg<K> &k, Args &&... args) { - return try_emplace_impl(k, std::forward<Args>(args)...); - } - template <typename K = key_type, typename... Args, - typename absl::enable_if_t< - !std::is_convertible<K, const_iterator>::value, int> = 0> - std::pair<iterator, bool> try_emplace(key_arg<K> &&k, Args &&... args) { - return try_emplace_impl(std::forward<K>(k), std::forward<Args>(args)...); - } - template <typename K = key_type, typename... Args> - iterator try_emplace(const_iterator hint, const key_arg<K> &k, + // Note: the nullptr template arguments and extra `const M&` overloads allow + // for supporting bitfield arguments. + template <typename K = key_type, class M> + std::pair<iterator, bool> insert_or_assign(const key_arg<K> &k, + const M &obj) { + return insert_or_assign_impl(k, obj); + } + template <typename K = key_type, class M, K * = nullptr> + std::pair<iterator, bool> insert_or_assign(key_arg<K> &&k, const M &obj) { + return insert_or_assign_impl(std::forward<K>(k), obj); + } + template <typename K = key_type, class M, M * = nullptr> + std::pair<iterator, bool> insert_or_assign(const key_arg<K> &k, M &&obj) { + return insert_or_assign_impl(k, std::forward<M>(obj)); + } + template <typename K = key_type, class M, K * = nullptr, M * = nullptr> + std::pair<iterator, bool> insert_or_assign(key_arg<K> &&k, M &&obj) { + return insert_or_assign_impl(std::forward<K>(k), std::forward<M>(obj)); + } + template <typename K = key_type, class M> + iterator insert_or_assign(const_iterator hint, const key_arg<K> &k, + const M &obj) { + return insert_or_assign_hint_impl(hint, k, obj); + } + template <typename K = key_type, class M, K * = nullptr> + iterator insert_or_assign(const_iterator hint, key_arg<K> &&k, const M &obj) { + return insert_or_assign_hint_impl(hint, std::forward<K>(k), obj); + } + template <typename K = key_type, class M, M * = nullptr> + iterator insert_or_assign(const_iterator hint, const key_arg<K> &k, M &&obj) { + return insert_or_assign_hint_impl(hint, k, std::forward<M>(obj)); + } + template <typename K = key_type, class M, K * = nullptr, M * = nullptr> + iterator insert_or_assign(const_iterator hint, key_arg<K> &&k, M &&obj) { + return insert_or_assign_hint_impl(hint, std::forward<K>(k), + std::forward<M>(obj)); + } + + template <typename K = key_type, typename... Args, + typename absl::enable_if_t< + !std::is_convertible<K, const_iterator>::value, int> = 0> + std::pair<iterator, bool> try_emplace(const key_arg<K> &k, Args &&... args) { + return try_emplace_impl(k, std::forward<Args>(args)...); + } + template <typename K = key_type, typename... Args, + typename absl::enable_if_t< + !std::is_convertible<K, const_iterator>::value, int> = 0> + std::pair<iterator, bool> try_emplace(key_arg<K> &&k, Args &&... args) { + return try_emplace_impl(std::forward<K>(k), std::forward<Args>(args)...); + } + template <typename K = key_type, typename... Args> + iterator try_emplace(const_iterator hint, const key_arg<K> &k, Args &&... args) { - return try_emplace_hint_impl(hint, k, std::forward<Args>(args)...); + return try_emplace_hint_impl(hint, k, std::forward<Args>(args)...); } - template <typename K = key_type, typename... Args> - iterator try_emplace(const_iterator hint, key_arg<K> &&k, Args &&... args) { - return try_emplace_hint_impl(hint, std::forward<K>(k), - std::forward<Args>(args)...); + template <typename K = key_type, typename... Args> + iterator try_emplace(const_iterator hint, key_arg<K> &&k, Args &&... args) { + return try_emplace_hint_impl(hint, std::forward<K>(k), + std::forward<Args>(args)...); } - - template <typename K = key_type> - mapped_type &operator[](const key_arg<K> &k) { + + template <typename K = key_type> + mapped_type &operator[](const key_arg<K> &k) { return try_emplace(k).first->second; } - template <typename K = key_type> - mapped_type &operator[](key_arg<K> &&k) { - return try_emplace(std::forward<K>(k)).first->second; + template <typename K = key_type> + mapped_type &operator[](key_arg<K> &&k) { + return try_emplace(std::forward<K>(k)).first->second; } template <typename K = key_type> @@ -493,40 +493,40 @@ class btree_map_container : public btree_set_container<Tree> { base_internal::ThrowStdOutOfRange("absl::btree_map::at"); return it->second; } - - private: - // Note: when we call `std::forward<M>(obj)` twice, it's safe because - // insert_unique/insert_hint_unique are guaranteed to not consume `obj` when - // `ret.second` is false. - template <class K, class M> - std::pair<iterator, bool> insert_or_assign_impl(K &&k, M &&obj) { - const std::pair<iterator, bool> ret = - this->tree_.insert_unique(k, std::forward<K>(k), std::forward<M>(obj)); - if (!ret.second) ret.first->second = std::forward<M>(obj); - return ret; - } - template <class K, class M> - iterator insert_or_assign_hint_impl(const_iterator hint, K &&k, M &&obj) { - const std::pair<iterator, bool> ret = this->tree_.insert_hint_unique( - iterator(hint), k, std::forward<K>(k), std::forward<M>(obj)); - if (!ret.second) ret.first->second = std::forward<M>(obj); - return ret.first; - } - - template <class K, class... Args> - std::pair<iterator, bool> try_emplace_impl(K &&k, Args &&... args) { - return this->tree_.insert_unique( - k, std::piecewise_construct, std::forward_as_tuple(std::forward<K>(k)), - std::forward_as_tuple(std::forward<Args>(args)...)); - } - template <class K, class... Args> - iterator try_emplace_hint_impl(const_iterator hint, K &&k, Args &&... args) { - return this->tree_ - .insert_hint_unique(iterator(hint), k, std::piecewise_construct, - std::forward_as_tuple(std::forward<K>(k)), - std::forward_as_tuple(std::forward<Args>(args)...)) - .first; - } + + private: + // Note: when we call `std::forward<M>(obj)` twice, it's safe because + // insert_unique/insert_hint_unique are guaranteed to not consume `obj` when + // `ret.second` is false. + template <class K, class M> + std::pair<iterator, bool> insert_or_assign_impl(K &&k, M &&obj) { + const std::pair<iterator, bool> ret = + this->tree_.insert_unique(k, std::forward<K>(k), std::forward<M>(obj)); + if (!ret.second) ret.first->second = std::forward<M>(obj); + return ret; + } + template <class K, class M> + iterator insert_or_assign_hint_impl(const_iterator hint, K &&k, M &&obj) { + const std::pair<iterator, bool> ret = this->tree_.insert_hint_unique( + iterator(hint), k, std::forward<K>(k), std::forward<M>(obj)); + if (!ret.second) ret.first->second = std::forward<M>(obj); + return ret.first; + } + + template <class K, class... Args> + std::pair<iterator, bool> try_emplace_impl(K &&k, Args &&... args) { + return this->tree_.insert_unique( + k, std::piecewise_construct, std::forward_as_tuple(std::forward<K>(k)), + std::forward_as_tuple(std::forward<Args>(args)...)); + } + template <class K, class... Args> + iterator try_emplace_hint_impl(const_iterator hint, K &&k, Args &&... args) { + return this->tree_ + .insert_hint_unique(iterator(hint), k, std::piecewise_construct, + std::forward_as_tuple(std::forward<K>(k)), + std::forward_as_tuple(std::forward<Args>(args)...)) + .first; + } }; // A common base class for btree_multiset and btree_multimap. @@ -577,15 +577,15 @@ class btree_multiset_container : public btree_container<Tree> { : btree_multiset_container(init.begin(), init.end(), alloc) {} // Insertion routines. - iterator insert(const value_type &v) { return this->tree_.insert_multi(v); } - iterator insert(value_type &&v) { - return this->tree_.insert_multi(std::move(v)); + iterator insert(const value_type &v) { return this->tree_.insert_multi(v); } + iterator insert(value_type &&v) { + return this->tree_.insert_multi(std::move(v)); } - iterator insert(const_iterator hint, const value_type &v) { - return this->tree_.insert_hint_multi(iterator(hint), v); + iterator insert(const_iterator hint, const value_type &v) { + return this->tree_.insert_hint_multi(iterator(hint), v); } - iterator insert(const_iterator hint, value_type &&v) { - return this->tree_.insert_hint_multi(iterator(hint), std::move(v)); + iterator insert(const_iterator hint, value_type &&v) { + return this->tree_.insert_hint_multi(iterator(hint), std::move(v)); } template <typename InputIterator> void insert(InputIterator b, InputIterator e) { @@ -599,25 +599,25 @@ class btree_multiset_container : public btree_container<Tree> { return this->tree_.insert_multi(init_type(std::forward<Args>(args)...)); } template <typename... Args> - iterator emplace_hint(const_iterator hint, Args &&... args) { + iterator emplace_hint(const_iterator hint, Args &&... args) { return this->tree_.insert_hint_multi( - iterator(hint), init_type(std::forward<Args>(args)...)); + iterator(hint), init_type(std::forward<Args>(args)...)); } - iterator insert(node_type &&node) { + iterator insert(node_type &&node) { if (!node) return this->end(); iterator res = - this->tree_.insert_multi(params_type::key(CommonAccess::GetSlot(node)), - CommonAccess::GetSlot(node)); - CommonAccess::Destroy(&node); + this->tree_.insert_multi(params_type::key(CommonAccess::GetSlot(node)), + CommonAccess::GetSlot(node)); + CommonAccess::Destroy(&node); return res; } iterator insert(const_iterator hint, node_type &&node) { - if (!node) return this->end(); - iterator res = this->tree_.insert_hint_multi( - iterator(hint), - std::move(params_type::element(CommonAccess::GetSlot(node)))); - CommonAccess::Destroy(&node); - return res; + if (!node) return this->end(); + iterator res = this->tree_.insert_hint_multi( + iterator(hint), + std::move(params_type::element(CommonAccess::GetSlot(node)))); + CommonAccess::Destroy(&node); + return res; } // Node extraction routines. @@ -642,9 +642,9 @@ class btree_multiset_container : public btree_container<Tree> { typename T::params_type::is_map_container>>::value, int> = 0> void merge(btree_container<T> &src) { // NOLINT - for (auto src_it = src.begin(), end = src.end(); src_it != end; ++src_it) { - insert(std::move(params_type::element(src_it.slot()))); - } + for (auto src_it = src.begin(), end = src.end(); src_it != end; ++src_it) { + insert(std::move(params_type::element(src_it.slot()))); + } src.clear(); } @@ -677,7 +677,7 @@ class btree_multimap_container : public btree_multiset_container<Tree> { }; } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_BTREE_CONTAINER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/common.h b/contrib/restricted/abseil-cpp/absl/container/internal/common.h index 030e9d4ab0..911d2c9c66 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/common.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/common.h @@ -22,7 +22,7 @@ #include "absl/types/optional.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class, class = void> @@ -56,7 +56,7 @@ class node_handle_base { public: using allocator_type = Alloc; - constexpr node_handle_base() = default; + constexpr node_handle_base() = default; node_handle_base(node_handle_base&& other) noexcept { *this = std::move(other); } @@ -109,8 +109,8 @@ class node_handle_base { allocator_type* alloc() { return std::addressof(*alloc_); } private: - absl::optional<allocator_type> alloc_ = {}; - alignas(slot_type) mutable unsigned char slot_space_[sizeof(slot_type)] = {}; + absl::optional<allocator_type> alloc_ = {}; + alignas(slot_type) mutable unsigned char slot_space_[sizeof(slot_type)] = {}; }; // For sets. @@ -138,7 +138,7 @@ class node_handle<Policy, PolicyTraits, Alloc, absl::void_t<typename Policy::mapped_type>> : public node_handle_base<PolicyTraits, Alloc> { using Base = node_handle_base<PolicyTraits, Alloc>; - using slot_type = typename PolicyTraits::slot_type; + using slot_type = typename PolicyTraits::slot_type; public: using key_type = typename Policy::key_type; @@ -146,11 +146,11 @@ class node_handle<Policy, PolicyTraits, Alloc, constexpr node_handle() {} - // When C++17 is available, we can use std::launder to provide mutable - // access to the key. Otherwise, we provide const access. - auto key() const - -> decltype(PolicyTraits::mutable_key(std::declval<slot_type*>())) { - return PolicyTraits::mutable_key(this->slot()); + // When C++17 is available, we can use std::launder to provide mutable + // access to the key. Otherwise, we provide const access. + auto key() const + -> decltype(PolicyTraits::mutable_key(std::declval<slot_type*>())) { + return PolicyTraits::mutable_key(this->slot()); } mapped_type& mapped() const { @@ -171,11 +171,11 @@ struct CommonAccess { } template <typename Node> - static void Destroy(Node* node) { - node->destroy(); - } - - template <typename Node> + static void Destroy(Node* node) { + node->destroy(); + } + + template <typename Node> static void Reset(Node* node) { node->reset(); } @@ -200,7 +200,7 @@ struct InsertReturnType { }; } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_CONTAINER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/compressed_tuple.h b/contrib/restricted/abseil-cpp/absl/container/internal/compressed_tuple.h index 5ebe164942..ed03304ab2 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/compressed_tuple.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/compressed_tuple.h @@ -48,7 +48,7 @@ #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <typename... Ts> @@ -169,34 +169,34 @@ constexpr bool ShouldAnyUseBase() { } template <typename T, typename V> -using TupleElementMoveConstructible = - typename std::conditional<std::is_reference<T>::value, - std::is_convertible<V, T>, - std::is_constructible<T, V&&>>::type; - -template <bool SizeMatches, class T, class... Vs> -struct TupleMoveConstructible : std::false_type {}; - -template <class... Ts, class... Vs> -struct TupleMoveConstructible<true, CompressedTuple<Ts...>, Vs...> - : std::integral_constant< - bool, absl::conjunction< - TupleElementMoveConstructible<Ts, Vs&&>...>::value> {}; - -template <typename T> -struct compressed_tuple_size; - -template <typename... Es> -struct compressed_tuple_size<CompressedTuple<Es...>> - : public std::integral_constant<std::size_t, sizeof...(Es)> {}; - -template <class T, class... Vs> -struct TupleItemsMoveConstructible - : std::integral_constant< - bool, TupleMoveConstructible<compressed_tuple_size<T>::value == - sizeof...(Vs), - T, Vs...>::value> {}; - +using TupleElementMoveConstructible = + typename std::conditional<std::is_reference<T>::value, + std::is_convertible<V, T>, + std::is_constructible<T, V&&>>::type; + +template <bool SizeMatches, class T, class... Vs> +struct TupleMoveConstructible : std::false_type {}; + +template <class... Ts, class... Vs> +struct TupleMoveConstructible<true, CompressedTuple<Ts...>, Vs...> + : std::integral_constant< + bool, absl::conjunction< + TupleElementMoveConstructible<Ts, Vs&&>...>::value> {}; + +template <typename T> +struct compressed_tuple_size; + +template <typename... Es> +struct compressed_tuple_size<CompressedTuple<Es...>> + : public std::integral_constant<std::size_t, sizeof...(Es)> {}; + +template <class T, class... Vs> +struct TupleItemsMoveConstructible + : std::integral_constant< + bool, TupleMoveConstructible<compressed_tuple_size<T>::value == + sizeof...(Vs), + T, Vs...>::value> {}; + } // namespace internal_compressed_tuple // Helper class to perform the Empty Base Class Optimization. @@ -241,23 +241,23 @@ class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple explicit constexpr CompressedTuple(const Ts&... base) : CompressedTuple::CompressedTupleImpl(absl::in_place, base...) {} - template <typename First, typename... Vs, + template <typename First, typename... Vs, absl::enable_if_t< absl::conjunction< // Ensure we are not hiding default copy/move constructors. absl::negation<std::is_same<void(CompressedTuple), - void(absl::decay_t<First>)>>, - internal_compressed_tuple::TupleItemsMoveConstructible< - CompressedTuple<Ts...>, First, Vs...>>::value, + void(absl::decay_t<First>)>>, + internal_compressed_tuple::TupleItemsMoveConstructible< + CompressedTuple<Ts...>, First, Vs...>>::value, bool> = true> - explicit constexpr CompressedTuple(First&& first, Vs&&... base) + explicit constexpr CompressedTuple(First&& first, Vs&&... base) : CompressedTuple::CompressedTupleImpl(absl::in_place, - absl::forward<First>(first), + absl::forward<First>(first), absl::forward<Vs>(base)...) {} template <int I> ElemT<I>& get() & { - return StorageT<I>::get(); + return StorageT<I>::get(); } template <int I> @@ -282,7 +282,7 @@ template <> class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple<> {}; } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #undef ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/container_memory.h b/contrib/restricted/abseil-cpp/absl/container/internal/container_memory.h index e67529ecb6..02161dfc29 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/container_memory.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/container_memory.h @@ -18,31 +18,31 @@ #include <cassert> #include <cstddef> #include <memory> -#include <new> +#include <new> #include <tuple> #include <type_traits> #include <utility> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/memory/memory.h" -#include "absl/meta/type_traits.h" +#include "absl/meta/type_traits.h" #include "absl/utility/utility.h" -#ifdef ABSL_HAVE_ADDRESS_SANITIZER -#include <sanitizer/asan_interface.h> -#endif - -#ifdef ABSL_HAVE_MEMORY_SANITIZER -#include <sanitizer/msan_interface.h> -#endif - +#ifdef ABSL_HAVE_ADDRESS_SANITIZER +#include <sanitizer/asan_interface.h> +#endif + +#ifdef ABSL_HAVE_MEMORY_SANITIZER +#include <sanitizer/msan_interface.h> +#endif + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { -template <size_t Alignment> -struct alignas(Alignment) AlignedType {}; - +template <size_t Alignment> +struct alignas(Alignment) AlignedType {}; + // Allocates at least n bytes aligned to the specified alignment. // Alignment must be a power of 2. It must be positive. // @@ -54,14 +54,14 @@ template <size_t Alignment, class Alloc> void* Allocate(Alloc* alloc, size_t n) { static_assert(Alignment > 0, ""); assert(n && "n must be positive"); - using M = AlignedType<Alignment>; + using M = AlignedType<Alignment>; using A = typename absl::allocator_traits<Alloc>::template rebind_alloc<M>; using AT = typename absl::allocator_traits<Alloc>::template rebind_traits<M>; - // On macOS, "mem_alloc" is a #define with one argument defined in - // rpc/types.h, so we can't name the variable "mem_alloc" and initialize it - // with the "foo(bar)" syntax. - A my_mem_alloc(*alloc); - void* p = AT::allocate(my_mem_alloc, (n + sizeof(M) - 1) / sizeof(M)); + // On macOS, "mem_alloc" is a #define with one argument defined in + // rpc/types.h, so we can't name the variable "mem_alloc" and initialize it + // with the "foo(bar)" syntax. + A my_mem_alloc(*alloc); + void* p = AT::allocate(my_mem_alloc, (n + sizeof(M) - 1) / sizeof(M)); assert(reinterpret_cast<uintptr_t>(p) % Alignment == 0 && "allocator does not respect alignment"); return p; @@ -73,14 +73,14 @@ template <size_t Alignment, class Alloc> void Deallocate(Alloc* alloc, void* p, size_t n) { static_assert(Alignment > 0, ""); assert(n && "n must be positive"); - using M = AlignedType<Alignment>; + using M = AlignedType<Alignment>; using A = typename absl::allocator_traits<Alloc>::template rebind_alloc<M>; using AT = typename absl::allocator_traits<Alloc>::template rebind_traits<M>; - // On macOS, "mem_alloc" is a #define with one argument defined in - // rpc/types.h, so we can't name the variable "mem_alloc" and initialize it - // with the "foo(bar)" syntax. - A my_mem_alloc(*alloc); - AT::deallocate(my_mem_alloc, static_cast<M*>(p), + // On macOS, "mem_alloc" is a #define with one argument defined in + // rpc/types.h, so we can't name the variable "mem_alloc" and initialize it + // with the "foo(bar)" syntax. + A my_mem_alloc(*alloc); + AT::deallocate(my_mem_alloc, static_cast<M*>(p), (n + sizeof(M) - 1) / sizeof(M)); } @@ -217,10 +217,10 @@ DecomposeValue(F&& f, Arg&& arg) { // Helper functions for asan and msan. inline void SanitizerPoisonMemoryRegion(const void* m, size_t s) { -#ifdef ABSL_HAVE_ADDRESS_SANITIZER +#ifdef ABSL_HAVE_ADDRESS_SANITIZER ASAN_POISON_MEMORY_REGION(m, s); #endif -#ifdef ABSL_HAVE_MEMORY_SANITIZER +#ifdef ABSL_HAVE_MEMORY_SANITIZER __msan_poison(m, s); #endif (void)m; @@ -228,10 +228,10 @@ inline void SanitizerPoisonMemoryRegion(const void* m, size_t s) { } inline void SanitizerUnpoisonMemoryRegion(const void* m, size_t s) { -#ifdef ABSL_HAVE_ADDRESS_SANITIZER +#ifdef ABSL_HAVE_ADDRESS_SANITIZER ASAN_UNPOISON_MEMORY_REGION(m, s); #endif -#ifdef ABSL_HAVE_MEMORY_SANITIZER +#ifdef ABSL_HAVE_MEMORY_SANITIZER __msan_unpoison(m, s); #endif (void)m; @@ -258,8 +258,8 @@ namespace memory_internal { // type, which is non-portable. template <class Pair, class = std::true_type> struct OffsetOf { - static constexpr size_t kFirst = static_cast<size_t>(-1); - static constexpr size_t kSecond = static_cast<size_t>(-1); + static constexpr size_t kFirst = static_cast<size_t>(-1); + static constexpr size_t kSecond = static_cast<size_t>(-1); }; template <class Pair> @@ -328,12 +328,12 @@ union map_slot_type { map_slot_type() {} ~map_slot_type() = delete; using value_type = std::pair<const K, V>; - using mutable_value_type = - std::pair<absl::remove_const_t<K>, absl::remove_const_t<V>>; + using mutable_value_type = + std::pair<absl::remove_const_t<K>, absl::remove_const_t<V>>; value_type value; mutable_value_type mutable_value; - absl::remove_const_t<K> key; + absl::remove_const_t<K> key; }; template <class K, class V> @@ -359,20 +359,20 @@ struct map_slot_policy { return slot->value; } - // When C++17 is available, we can use std::launder to provide mutable - // access to the key for use in node handle. -#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 - static K& mutable_key(slot_type* slot) { - // Still check for kMutableKeys so that we can avoid calling std::launder - // unless necessary because it can interfere with optimizations. - return kMutableKeys::value ? slot->key - : *std::launder(const_cast<K*>( - std::addressof(slot->value.first))); - } -#else // !(defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606) - static const K& mutable_key(slot_type* slot) { return key(slot); } -#endif - + // When C++17 is available, we can use std::launder to provide mutable + // access to the key for use in node handle. +#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 + static K& mutable_key(slot_type* slot) { + // Still check for kMutableKeys so that we can avoid calling std::launder + // unless necessary because it can interfere with optimizations. + return kMutableKeys::value ? slot->key + : *std::launder(const_cast<K*>( + std::addressof(slot->value.first))); + } +#else // !(defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606) + static const K& mutable_key(slot_type* slot) { return key(slot); } +#endif + static const K& key(const slot_type* slot) { return kMutableKeys::value ? slot->key : slot->value.first; } @@ -454,7 +454,7 @@ struct map_slot_policy { }; } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/counting_allocator.h b/contrib/restricted/abseil-cpp/absl/container/internal/counting_allocator.h index 927cf08255..d1de95bdee 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/counting_allocator.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/counting_allocator.h @@ -18,10 +18,10 @@ #include <cstdint> #include <memory> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { // This is a stateful allocator, but the state lives outside of the @@ -30,63 +30,63 @@ namespace container_internal { // containers - that chain of allocators uses the same state and is // thus easier to query for aggregate allocation information. template <typename T> -class CountingAllocator { +class CountingAllocator { public: - using Allocator = std::allocator<T>; - using AllocatorTraits = std::allocator_traits<Allocator>; - using value_type = typename AllocatorTraits::value_type; - using pointer = typename AllocatorTraits::pointer; - using const_pointer = typename AllocatorTraits::const_pointer; - using size_type = typename AllocatorTraits::size_type; - using difference_type = typename AllocatorTraits::difference_type; - - CountingAllocator() = default; - explicit CountingAllocator(int64_t* bytes_used) : bytes_used_(bytes_used) {} - CountingAllocator(int64_t* bytes_used, int64_t* instance_count) - : bytes_used_(bytes_used), instance_count_(instance_count) {} + using Allocator = std::allocator<T>; + using AllocatorTraits = std::allocator_traits<Allocator>; + using value_type = typename AllocatorTraits::value_type; + using pointer = typename AllocatorTraits::pointer; + using const_pointer = typename AllocatorTraits::const_pointer; + using size_type = typename AllocatorTraits::size_type; + using difference_type = typename AllocatorTraits::difference_type; + + CountingAllocator() = default; + explicit CountingAllocator(int64_t* bytes_used) : bytes_used_(bytes_used) {} + CountingAllocator(int64_t* bytes_used, int64_t* instance_count) + : bytes_used_(bytes_used), instance_count_(instance_count) {} template <typename U> CountingAllocator(const CountingAllocator<U>& x) - : bytes_used_(x.bytes_used_), instance_count_(x.instance_count_) {} - - pointer allocate( - size_type n, - typename AllocatorTraits::const_void_pointer hint = nullptr) { - Allocator allocator; - pointer ptr = AllocatorTraits::allocate(allocator, n, hint); - if (bytes_used_ != nullptr) { - *bytes_used_ += n * sizeof(T); - } - return ptr; + : bytes_used_(x.bytes_used_), instance_count_(x.instance_count_) {} + + pointer allocate( + size_type n, + typename AllocatorTraits::const_void_pointer hint = nullptr) { + Allocator allocator; + pointer ptr = AllocatorTraits::allocate(allocator, n, hint); + if (bytes_used_ != nullptr) { + *bytes_used_ += n * sizeof(T); + } + return ptr; } void deallocate(pointer p, size_type n) { - Allocator allocator; - AllocatorTraits::deallocate(allocator, p, n); - if (bytes_used_ != nullptr) { - *bytes_used_ -= n * sizeof(T); - } - } - - template <typename U, typename... Args> - void construct(U* p, Args&&... args) { - Allocator allocator; - AllocatorTraits::construct(allocator, p, std::forward<Args>(args)...); - if (instance_count_ != nullptr) { - *instance_count_ += 1; - } + Allocator allocator; + AllocatorTraits::deallocate(allocator, p, n); + if (bytes_used_ != nullptr) { + *bytes_used_ -= n * sizeof(T); + } } - template <typename U> - void destroy(U* p) { - Allocator allocator; - AllocatorTraits::destroy(allocator, p); - if (instance_count_ != nullptr) { - *instance_count_ -= 1; - } - } - - template <typename U> + template <typename U, typename... Args> + void construct(U* p, Args&&... args) { + Allocator allocator; + AllocatorTraits::construct(allocator, p, std::forward<Args>(args)...); + if (instance_count_ != nullptr) { + *instance_count_ += 1; + } + } + + template <typename U> + void destroy(U* p) { + Allocator allocator; + AllocatorTraits::destroy(allocator, p); + if (instance_count_ != nullptr) { + *instance_count_ -= 1; + } + } + + template <typename U> class rebind { public: using other = CountingAllocator<U>; @@ -94,8 +94,8 @@ class CountingAllocator { friend bool operator==(const CountingAllocator& a, const CountingAllocator& b) { - return a.bytes_used_ == b.bytes_used_ && - a.instance_count_ == b.instance_count_; + return a.bytes_used_ == b.bytes_used_ && + a.instance_count_ == b.instance_count_; } friend bool operator!=(const CountingAllocator& a, @@ -103,12 +103,12 @@ class CountingAllocator { return !(a == b); } - int64_t* bytes_used_ = nullptr; - int64_t* instance_count_ = nullptr; + int64_t* bytes_used_ = nullptr; + int64_t* instance_count_ = nullptr; }; } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_COUNTING_ALLOCATOR_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hash_function_defaults.h b/contrib/restricted/abseil-cpp/absl/container/internal/hash_function_defaults.h index 250e662c9d..81ff747a19 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hash_function_defaults.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hash_function_defaults.h @@ -53,11 +53,11 @@ #include "absl/base/config.h" #include "absl/hash/hash.h" -#include "absl/strings/cord.h" +#include "absl/strings/cord.h" #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { // The hash of an object of type T is computed by using absl::Hash. @@ -73,9 +73,9 @@ struct StringHash { size_t operator()(absl::string_view v) const { return absl::Hash<absl::string_view>{}(v); } - size_t operator()(const absl::Cord& v) const { - return absl::Hash<absl::Cord>{}(v); - } + size_t operator()(const absl::Cord& v) const { + return absl::Hash<absl::Cord>{}(v); + } }; struct StringEq { @@ -104,8 +104,8 @@ template <> struct HashEq<std::string> : StringHashEq {}; template <> struct HashEq<absl::string_view> : StringHashEq {}; -template <> -struct HashEq<absl::Cord> : StringHashEq {}; +template <> +struct HashEq<absl::Cord> : StringHashEq {}; // Supports heterogeneous lookup for pointers and smart pointers. template <class T> @@ -157,7 +157,7 @@ template <class T> using hash_default_eq = typename container_internal::HashEq<T>::Eq; } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_HASH_FUNCTION_DEFAULTS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hash_generator_testing.h b/contrib/restricted/abseil-cpp/absl/container/internal/hash_generator_testing.h index f1f555a5c1..ba8f6733c1 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hash_generator_testing.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hash_generator_testing.h @@ -35,7 +35,7 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace hash_internal { namespace generator_internal { @@ -176,7 +176,7 @@ struct UniqueGenerator { } // namespace hash_internal } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_HASH_GENERATOR_TESTING_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hash_policy_testing.h b/contrib/restricted/abseil-cpp/absl/container/internal/hash_policy_testing.h index 01c40d2e5c..a8478ce3ca 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hash_policy_testing.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hash_policy_testing.h @@ -30,7 +30,7 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace hash_testing_internal { @@ -163,7 +163,7 @@ auto keys(const Set& s) } } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl // ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS is false for glibcxx versions diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hash_policy_traits.h b/contrib/restricted/abseil-cpp/absl/container/internal/hash_policy_traits.h index 46c97b18a2..7647bfbf1e 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hash_policy_traits.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hash_policy_traits.h @@ -17,47 +17,47 @@ #include <cstddef> #include <memory> -#include <new> +#include <new> #include <type_traits> #include <utility> #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { // Defines how slots are initialized/destroyed/moved. template <class Policy, class = void> struct hash_policy_traits { - // The type of the keys stored in the hashtable. - using key_type = typename Policy::key_type; - + // The type of the keys stored in the hashtable. + using key_type = typename Policy::key_type; + private: struct ReturnKey { - // When C++17 is available, we can use std::launder to provide mutable - // access to the key for use in node handle. -#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 - template <class Key, - absl::enable_if_t<std::is_lvalue_reference<Key>::value, int> = 0> - static key_type& Impl(Key&& k, int) { - return *std::launder( - const_cast<key_type*>(std::addressof(std::forward<Key>(k)))); - } -#endif - - template <class Key> - static Key Impl(Key&& k, char) { - return std::forward<Key>(k); - } - + // When C++17 is available, we can use std::launder to provide mutable + // access to the key for use in node handle. +#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606 + template <class Key, + absl::enable_if_t<std::is_lvalue_reference<Key>::value, int> = 0> + static key_type& Impl(Key&& k, int) { + return *std::launder( + const_cast<key_type*>(std::addressof(std::forward<Key>(k)))); + } +#endif + + template <class Key> + static Key Impl(Key&& k, char) { + return std::forward<Key>(k); + } + // When Key=T&, we forward the lvalue reference. // When Key=T, we return by value to avoid a dangling reference. // eg, for string_hash_map. template <class Key, class... Args> - auto operator()(Key&& k, const Args&...) const - -> decltype(Impl(std::forward<Key>(k), 0)) { - return Impl(std::forward<Key>(k), 0); + auto operator()(Key&& k, const Args&...) const + -> decltype(Impl(std::forward<Key>(k), 0)) { + return Impl(std::forward<Key>(k), 0); } }; @@ -173,7 +173,7 @@ struct hash_policy_traits { // Returns the "key" portion of the slot. // Used for node handle manipulation. template <class P = Policy> - static auto mutable_key(slot_type* slot) + static auto mutable_key(slot_type* slot) -> decltype(P::apply(ReturnKey(), element(slot))) { return P::apply(ReturnKey(), element(slot)); } @@ -202,7 +202,7 @@ struct hash_policy_traits { }; } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_HASH_POLICY_TRAITS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hashtable_debug.h b/contrib/restricted/abseil-cpp/absl/container/internal/hashtable_debug.h index 19d52121d6..e3945e8a01 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hashtable_debug.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hashtable_debug.h @@ -38,7 +38,7 @@ #include "absl/container/internal/hashtable_debug_hooks.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { // Returns the number of probes required to lookup `key`. Returns 0 for a @@ -104,7 +104,7 @@ size_t LowerBoundAllocatedByteSize(size_t num_elements) { } } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_HASHTABLE_DEBUG_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hashtable_debug_hooks.h b/contrib/restricted/abseil-cpp/absl/container/internal/hashtable_debug_hooks.h index 3e9ea5954e..0582635183 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hashtable_debug_hooks.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hashtable_debug_hooks.h @@ -23,10 +23,10 @@ #include <type_traits> #include <vector> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { namespace hashtable_debug_internal { @@ -79,7 +79,7 @@ struct HashtableDebugAccess { } // namespace hashtable_debug_internal } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_HASHTABLE_DEBUG_HOOKS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.cc b/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.cc index 40cce0479e..795553f015 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.cc @@ -29,7 +29,7 @@ #include "absl/synchronization/mutex.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { constexpr int HashtablezInfo::kMaxStackDepth; @@ -39,16 +39,16 @@ ABSL_CONST_INIT std::atomic<bool> g_hashtablez_enabled{ }; ABSL_CONST_INIT std::atomic<int32_t> g_hashtablez_sample_parameter{1 << 10}; -#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) ABSL_PER_THREAD_TLS_KEYWORD absl::profiling_internal::ExponentialBiased g_exponential_biased_generator; #endif } // namespace -#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample = 0; -#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) +#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) HashtablezSampler& GlobalHashtablezSampler() { static auto* sampler = new HashtablezSampler(); @@ -65,7 +65,7 @@ void HashtablezInfo::PrepareForSampling() { capacity.store(0, std::memory_order_relaxed); size.store(0, std::memory_order_relaxed); num_erases.store(0, std::memory_order_relaxed); - num_rehashes.store(0, std::memory_order_relaxed); + num_rehashes.store(0, std::memory_order_relaxed); max_probe_length.store(0, std::memory_order_relaxed); total_probe_length.store(0, std::memory_order_relaxed); hashes_bitwise_or.store(0, std::memory_order_relaxed); @@ -109,15 +109,15 @@ HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size) { return result; } -#if !defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) +#if !defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) *next_sample = std::numeric_limits<int64_t>::max(); return nullptr; #else bool first = *next_sample < 0; - *next_sample = g_exponential_biased_generator.GetStride( + *next_sample = g_exponential_biased_generator.GetStride( g_hashtablez_sample_parameter.load(std::memory_order_relaxed)); // Small values of interval are equivalent to just sampling next time. - ABSL_ASSERT(*next_sample >= 1); + ABSL_ASSERT(*next_sample >= 1); // g_hashtablez_enabled can be dynamically flipped, we need to set a threshold // low enough that we will start sampling in a reasonable time, so we just use @@ -146,7 +146,7 @@ void RecordInsertSlow(HashtablezInfo* info, size_t hash, // SwissTables probe in groups of 16, so scale this to count items probes and // not offset from desired. size_t probe_length = distance_from_desired; -#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 probe_length /= 16; #else probe_length /= 8; @@ -186,5 +186,5 @@ void SetHashtablezMaxSamples(int32_t max) { } } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h b/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h index 91fcdb34a3..edf62dee6e 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler.h @@ -52,7 +52,7 @@ #include "absl/utility/utility.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { // Stores information about a sampled hashtable. All mutations to this *must* @@ -74,7 +74,7 @@ struct HashtablezInfo : public profiling_internal::Sample<HashtablezInfo> { std::atomic<size_t> capacity; std::atomic<size_t> size; std::atomic<size_t> num_erases; - std::atomic<size_t> num_rehashes; + std::atomic<size_t> num_rehashes; std::atomic<size_t> max_probe_length; std::atomic<size_t> total_probe_length; std::atomic<size_t> hashes_bitwise_or; @@ -95,18 +95,18 @@ struct HashtablezInfo : public profiling_internal::Sample<HashtablezInfo> { }; inline void RecordRehashSlow(HashtablezInfo* info, size_t total_probe_length) { -#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 total_probe_length /= 16; #else total_probe_length /= 8; #endif info->total_probe_length.store(total_probe_length, std::memory_order_relaxed); info->num_erases.store(0, std::memory_order_relaxed); - // There is only one concurrent writer, so `load` then `store` is sufficient - // instead of using `fetch_add`. - info->num_rehashes.store( - 1 + info->num_rehashes.load(std::memory_order_relaxed), - std::memory_order_relaxed); + // There is only one concurrent writer, so `load` then `store` is sufficient + // instead of using `fetch_add`. + info->num_rehashes.store( + 1 + info->num_rehashes.load(std::memory_order_relaxed), + std::memory_order_relaxed); } inline void RecordReservationSlow(HashtablezInfo* info, @@ -127,8 +127,8 @@ inline void RecordStorageChangedSlow(HashtablezInfo* info, size_t size, info->capacity.store(capacity, std::memory_order_relaxed); if (size == 0) { // This is a clear, reset the total/num_erases too. - info->total_probe_length.store(0, std::memory_order_relaxed); - info->num_erases.store(0, std::memory_order_relaxed); + info->total_probe_length.store(0, std::memory_order_relaxed); + info->num_erases.store(0, std::memory_order_relaxed); } } @@ -137,21 +137,21 @@ void RecordInsertSlow(HashtablezInfo* info, size_t hash, inline void RecordEraseSlow(HashtablezInfo* info) { info->size.fetch_sub(1, std::memory_order_relaxed); - // There is only one concurrent writer, so `load` then `store` is sufficient - // instead of using `fetch_add`. - info->num_erases.store( - 1 + info->num_erases.load(std::memory_order_relaxed), - std::memory_order_relaxed); + // There is only one concurrent writer, so `load` then `store` is sufficient + // instead of using `fetch_add`. + info->num_erases.store( + 1 + info->num_erases.load(std::memory_order_relaxed), + std::memory_order_relaxed); } HashtablezInfo* SampleSlow(int64_t* next_sample, size_t inline_element_size); void UnsampleSlow(HashtablezInfo* info); -#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) -#error ABSL_INTERNAL_HASHTABLEZ_SAMPLE cannot be directly set -#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) - -#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) +#error ABSL_INTERNAL_HASHTABLEZ_SAMPLE cannot be directly set +#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) + +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) class HashtablezInfoHandle { public: explicit HashtablezInfoHandle() : info_(nullptr) {} @@ -213,35 +213,35 @@ class HashtablezInfoHandle { friend class HashtablezInfoHandlePeer; HashtablezInfo* info_; }; -#else -// Ensure that when Hashtablez is turned off at compile time, HashtablezInfo can -// be removed by the linker, in order to reduce the binary size. -class HashtablezInfoHandle { - public: - explicit HashtablezInfoHandle() = default; - explicit HashtablezInfoHandle(std::nullptr_t) {} - - inline void RecordStorageChanged(size_t /*size*/, size_t /*capacity*/) {} - inline void RecordRehash(size_t /*total_probe_length*/) {} +#else +// Ensure that when Hashtablez is turned off at compile time, HashtablezInfo can +// be removed by the linker, in order to reduce the binary size. +class HashtablezInfoHandle { + public: + explicit HashtablezInfoHandle() = default; + explicit HashtablezInfoHandle(std::nullptr_t) {} + + inline void RecordStorageChanged(size_t /*size*/, size_t /*capacity*/) {} + inline void RecordRehash(size_t /*total_probe_length*/) {} inline void RecordReservation(size_t /*target_capacity*/) {} inline void RecordClearedReservation() {} - inline void RecordInsert(size_t /*hash*/, size_t /*distance_from_desired*/) {} - inline void RecordErase() {} - - friend inline void swap(HashtablezInfoHandle& /*lhs*/, - HashtablezInfoHandle& /*rhs*/) {} -}; -#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) - -#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) + inline void RecordInsert(size_t /*hash*/, size_t /*distance_from_desired*/) {} + inline void RecordErase() {} + + friend inline void swap(HashtablezInfoHandle& /*lhs*/, + HashtablezInfoHandle& /*rhs*/) {} +}; +#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) + +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) extern ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample; -#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) +#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) // Returns an RAII sampling handle that manages registration and unregistation // with the global sampler. inline HashtablezInfoHandle Sample( size_t inline_element_size ABSL_ATTRIBUTE_UNUSED) { -#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) if (ABSL_PREDICT_TRUE(--global_next_sample > 0)) { return HashtablezInfoHandle(nullptr); } @@ -275,7 +275,7 @@ void SetHashtablezMaxSamples(int32_t max); extern "C" bool ABSL_INTERNAL_C_SYMBOL(AbslContainerInternalSampleEverything)(); } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_HASHTABLEZ_SAMPLER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc b/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc index ed35a7eec3..0e05e6eea2 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc +++ b/contrib/restricted/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc @@ -17,7 +17,7 @@ #include "absl/base/attributes.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { // See hashtablez_sampler.h for details. @@ -27,5 +27,5 @@ extern "C" ABSL_ATTRIBUTE_WEAK bool ABSL_INTERNAL_C_SYMBOL( } } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/have_sse.h b/contrib/restricted/abseil-cpp/absl/container/internal/have_sse.h index e75e1a16d3..58da3b3163 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/have_sse.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/have_sse.h @@ -16,34 +16,34 @@ #ifndef ABSL_CONTAINER_INTERNAL_HAVE_SSE_H_ #define ABSL_CONTAINER_INTERNAL_HAVE_SSE_H_ -#ifndef ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 +#ifndef ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 #if defined(__SSE2__) || \ (defined(_MSC_VER) && \ (defined(_M_X64) || (defined(_M_IX86) && _M_IX86_FP >= 2))) -#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 1 +#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 1 #else -#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 0 +#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 0 #endif #endif -#ifndef ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 +#ifndef ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 #ifdef __SSSE3__ -#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 1 +#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 1 #else -#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 0 +#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 0 #endif #endif -#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 && \ - !ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 && \ + !ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 #error "Bad configuration!" #endif -#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 #include <emmintrin.h> #endif -#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 #include <tmmintrin.h> #endif diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h b/contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h index 1d7d6cda72..0750356484 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/inlined_vector.h @@ -33,7 +33,7 @@ #include "absl/types/span.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace inlined_vector_internal { // GCC does not deal very well with the below code @@ -926,7 +926,7 @@ auto Storage<T, N, A>::Swap(Storage* other_storage_ptr) -> void { #endif } // namespace inlined_vector_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_INLINED_VECTOR_INTERNAL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/layout.h b/contrib/restricted/abseil-cpp/absl/container/internal/layout.h index a59a243059..088a74843d 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/layout.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/layout.h @@ -163,7 +163,7 @@ #include <assert.h> #include <stddef.h> #include <stdint.h> - + #include <ostream> #include <string> #include <tuple> @@ -171,16 +171,16 @@ #include <typeinfo> #include <utility> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/meta/type_traits.h" #include "absl/strings/str_cat.h" #include "absl/types/span.h" #include "absl/utility/utility.h" -#ifdef ABSL_HAVE_ADDRESS_SANITIZER -#include <sanitizer/asan_interface.h> -#endif - +#ifdef ABSL_HAVE_ADDRESS_SANITIZER +#include <sanitizer/asan_interface.h> +#endif + #if defined(__GXX_RTTI) #define ABSL_INTERNAL_HAS_CXA_DEMANGLE #endif @@ -190,7 +190,7 @@ #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { // A type wrapper that instructs `Layout` to use the specific alignment for the @@ -616,7 +616,7 @@ class LayoutImpl<std::tuple<Elements...>, absl::index_sequence<SizeSeq...>, void PoisonPadding(const Char* p) const { static_assert(N < NumOffsets, "Index out of bounds"); (void)p; -#ifdef ABSL_HAVE_ADDRESS_SANITIZER +#ifdef ABSL_HAVE_ADDRESS_SANITIZER PoisonPadding<Char, N - 1>(p); // The `if` is an optimization. It doesn't affect the observable behaviour. if (ElementAlignment<N - 1>::value % ElementAlignment<N>::value) { @@ -737,7 +737,7 @@ class Layout : public internal_layout::LayoutType<sizeof...(Ts), Ts...> { }; } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_LAYOUT_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/node_hash_policy.h b/contrib/restricted/abseil-cpp/absl/container/internal/node_hash_policy.h index 4617162f0b..131f032254 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/node_hash_policy.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/node_hash_policy.h @@ -39,10 +39,10 @@ #include <type_traits> #include <utility> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class Reference, class Policy> @@ -86,7 +86,7 @@ struct node_hash_policy { }; } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_NODE_HASH_POLICY_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h index c7df2efc62..2954c234d5 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_map.h @@ -24,7 +24,7 @@ #include "absl/container/internal/raw_hash_set.h" // IWYU pragma: export namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class Policy, class Hash, class Eq, class Alloc> @@ -192,7 +192,7 @@ class raw_hash_map : public raw_hash_set<Policy, Hash, Eq, Alloc> { }; } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_MAP_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.cc b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.cc index 687bcb8a4d..e52d213a25 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.cc +++ b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.cc @@ -20,7 +20,7 @@ #include "absl/base/config.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { alignas(16) ABSL_CONST_INIT ABSL_DLL const ctrl_t kEmptyGroup[16] = { @@ -63,5 +63,5 @@ void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity) { template FindInfo find_first_non_full(const ctrl_t*, size_t, size_t); } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.h b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.h index 12682b3532..06699ae777 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set.h @@ -114,7 +114,7 @@ #include <utility> #include "absl/base/internal/endian.h" -#include "absl/base/optimization.h" +#include "absl/base/optimization.h" #include "absl/base/port.h" #include "absl/container/internal/common.h" #include "absl/container/internal/compressed_tuple.h" @@ -129,19 +129,19 @@ #include "absl/utility/utility.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { -template <typename AllocType> -void SwapAlloc(AllocType& lhs, AllocType& rhs, - std::true_type /* propagate_on_container_swap */) { - using std::swap; - swap(lhs, rhs); -} -template <typename AllocType> -void SwapAlloc(AllocType& /*lhs*/, AllocType& /*rhs*/, - std::false_type /* propagate_on_container_swap */) {} - +template <typename AllocType> +void SwapAlloc(AllocType& lhs, AllocType& rhs, + std::true_type /* propagate_on_container_swap */) { + using std::swap; + swap(lhs, rhs); +} +template <typename AllocType> +void SwapAlloc(AllocType& /*lhs*/, AllocType& /*rhs*/, + std::false_type /* propagate_on_container_swap */) {} + template <size_t Width> class probe_seq { public: @@ -189,14 +189,14 @@ struct IsDecomposable< // TODO(alkis): Switch to std::is_nothrow_swappable when gcc/clang supports it. template <class T> -constexpr bool IsNoThrowSwappable(std::true_type = {} /* is_swappable */) { +constexpr bool IsNoThrowSwappable(std::true_type = {} /* is_swappable */) { using std::swap; return noexcept(swap(std::declval<T&>(), std::declval<T&>())); } -template <class T> -constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) { - return false; -} +template <class T> +constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) { + return false; +} template <typename T> uint32_t TrailingZeros(T x) { @@ -331,7 +331,7 @@ inline bool IsFull(ctrl_t c) { return c >= static_cast<ctrl_t>(0); } inline bool IsDeleted(ctrl_t c) { return c == ctrl_t::kDeleted; } inline bool IsEmptyOrDeleted(ctrl_t c) { return c < ctrl_t::kSentinel; } -#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 // https://github.com/abseil/abseil-cpp/issues/209 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87853 @@ -365,7 +365,7 @@ struct GroupSse2Impl { // Returns a bitmask representing the positions of empty slots. BitMask<uint32_t, kWidth> MatchEmpty() const { -#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 // This only works because ctrl_t::kEmpty is -128. return BitMask<uint32_t, kWidth>( _mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl))); @@ -391,7 +391,7 @@ struct GroupSse2Impl { void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const { auto msbs = _mm_set1_epi8(static_cast<char>(-128)); auto x126 = _mm_set1_epi8(126); -#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 auto res = _mm_or_si128(_mm_shuffle_epi8(x126, ctrl), msbs); #else auto zero = _mm_setzero_si128(); @@ -403,7 +403,7 @@ struct GroupSse2Impl { __m128i ctrl; }; -#endif // ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 +#endif // ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 struct GroupPortableImpl { static constexpr size_t kWidth = 8; @@ -457,7 +457,7 @@ struct GroupPortableImpl { uint64_t ctrl; }; -#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 using Group = GroupSse2Impl; #else using Group = GroupPortableImpl; @@ -533,18 +533,18 @@ size_t SelectBucketCountForIterRange(InputIter first, InputIter last, return 0; } -inline void AssertIsFull(ctrl_t* ctrl) { - ABSL_HARDENING_ASSERT((ctrl != nullptr && IsFull(*ctrl)) && - "Invalid operation on iterator. The element might have " - "been erased, or the table might have rehashed."); -} - -inline void AssertIsValid(ctrl_t* ctrl) { - ABSL_HARDENING_ASSERT((ctrl == nullptr || IsFull(*ctrl)) && - "Invalid operation on iterator. The element might have " - "been erased, or the table might have rehashed."); -} - +inline void AssertIsFull(ctrl_t* ctrl) { + ABSL_HARDENING_ASSERT((ctrl != nullptr && IsFull(*ctrl)) && + "Invalid operation on iterator. The element might have " + "been erased, or the table might have rehashed."); +} + +inline void AssertIsValid(ctrl_t* ctrl) { + ABSL_HARDENING_ASSERT((ctrl == nullptr || IsFull(*ctrl)) && + "Invalid operation on iterator. The element might have " + "been erased, or the table might have rehashed."); +} + struct FindInfo { size_t offset; size_t probe_length; @@ -669,8 +669,8 @@ inline size_t AllocSize(size_t capacity, size_t slot_size, size_t slot_align) { // if they are equal, false if they are not. If two keys compare equal, then // their hash values as defined by Hash MUST be equal. // -// Allocator: an Allocator -// [https://en.cppreference.com/w/cpp/named_req/Allocator] with which +// Allocator: an Allocator +// [https://en.cppreference.com/w/cpp/named_req/Allocator] with which // the storage of the hashtable will be allocated and the elements will be // constructed and destroyed. template <class Policy, class Hash, class Eq, class Alloc> @@ -769,7 +769,7 @@ class raw_hash_set { // PRECONDITION: not an end() iterator. reference operator*() const { - AssertIsFull(ctrl_); + AssertIsFull(ctrl_); return PolicyTraits::element(slot_); } @@ -778,7 +778,7 @@ class raw_hash_set { // PRECONDITION: not an end() iterator. iterator& operator++() { - AssertIsFull(ctrl_); + AssertIsFull(ctrl_); ++ctrl_; ++slot_; skip_empty_or_deleted(); @@ -792,8 +792,8 @@ class raw_hash_set { } friend bool operator==(const iterator& a, const iterator& b) { - AssertIsValid(a.ctrl_); - AssertIsValid(b.ctrl_); + AssertIsValid(a.ctrl_); + AssertIsValid(b.ctrl_); return a.ctrl_ == b.ctrl_; } friend bool operator!=(const iterator& a, const iterator& b) { @@ -801,10 +801,10 @@ class raw_hash_set { } private: - iterator(ctrl_t* ctrl, slot_type* slot) : ctrl_(ctrl), slot_(slot) { - // This assumption helps the compiler know that any non-end iterator is - // not equal to any end iterator. - ABSL_INTERNAL_ASSUME(ctrl != nullptr); + iterator(ctrl_t* ctrl, slot_type* slot) : ctrl_(ctrl), slot_(slot) { + // This assumption helps the compiler know that any non-end iterator is + // not equal to any end iterator. + ABSL_INTERNAL_ASSUME(ctrl != nullptr); } void skip_empty_or_deleted() { @@ -1056,12 +1056,12 @@ class raw_hash_set { it.skip_empty_or_deleted(); return it; } - iterator end() { return {}; } + iterator end() { return {}; } const_iterator begin() const { return const_cast<raw_hash_set*>(this)->begin(); } - const_iterator end() const { return {}; } + const_iterator end() const { return {}; } const_iterator cbegin() const { return begin(); } const_iterator cend() const { return end(); } @@ -1220,7 +1220,7 @@ class raw_hash_set { template <class... Args, typename std::enable_if< !IsDecomposable<Args...>::value, int>::type = 0> std::pair<iterator, bool> emplace(Args&&... args) { - alignas(slot_type) unsigned char raw[sizeof(slot_type)]; + alignas(slot_type) unsigned char raw[sizeof(slot_type)]; slot_type* slot = reinterpret_cast<slot_type*>(&raw); PolicyTraits::construct(&alloc_ref(), slot, std::forward<Args>(args)...); @@ -1236,16 +1236,16 @@ class raw_hash_set { // Extension API: support for lazy emplace. // // Looks up key in the table. If found, returns the iterator to the element. - // Otherwise calls `f` with one argument of type `raw_hash_set::constructor`. - // - // `f` must abide by several restrictions: - // - it MUST call `raw_hash_set::constructor` with arguments as if a - // `raw_hash_set::value_type` is constructed, - // - it MUST NOT access the container before the call to - // `raw_hash_set::constructor`, and - // - it MUST NOT erase the lazily emplaced element. - // Doing any of these is undefined behavior. + // Otherwise calls `f` with one argument of type `raw_hash_set::constructor`. // + // `f` must abide by several restrictions: + // - it MUST call `raw_hash_set::constructor` with arguments as if a + // `raw_hash_set::value_type` is constructed, + // - it MUST NOT access the container before the call to + // `raw_hash_set::constructor`, and + // - it MUST NOT erase the lazily emplaced element. + // Doing any of these is undefined behavior. + // // For example: // // std::unordered_set<ArenaString> s; @@ -1324,7 +1324,7 @@ class raw_hash_set { // This overload is necessary because otherwise erase<K>(const K&) would be // a better match if non-const iterator is passed as an argument. void erase(iterator it) { - AssertIsFull(it.ctrl_); + AssertIsFull(it.ctrl_); PolicyTraits::destroy(&alloc_ref(), it.slot_); erase_meta_only(it); } @@ -1358,7 +1358,7 @@ class raw_hash_set { } node_type extract(const_iterator position) { - AssertIsFull(position.inner_.ctrl_); + AssertIsFull(position.inner_.ctrl_); auto node = CommonAccess::Transfer<node_type>(alloc_ref(), position.inner_.slot_); erase_meta_only(position); @@ -1375,8 +1375,8 @@ class raw_hash_set { void swap(raw_hash_set& that) noexcept( IsNoThrowSwappable<hasher>() && IsNoThrowSwappable<key_equal>() && - IsNoThrowSwappable<allocator_type>( - typename AllocTraits::propagate_on_container_swap{})) { + IsNoThrowSwappable<allocator_type>( + typename AllocTraits::propagate_on_container_swap{})) { using std::swap; swap(ctrl_, that.ctrl_); swap(slots_, that.slots_); @@ -1386,8 +1386,8 @@ class raw_hash_set { swap(hash_ref(), that.hash_ref()); swap(eq_ref(), that.eq_ref()); swap(infoz(), that.infoz()); - SwapAlloc(alloc_ref(), that.alloc_ref(), - typename AllocTraits::propagate_on_container_swap{}); + SwapAlloc(alloc_ref(), that.alloc_ref(), + typename AllocTraits::propagate_on_container_swap{}); } void rehash(size_t n) { @@ -1727,7 +1727,7 @@ class raw_hash_set { // mark target as FULL // repeat procedure for current slot with moved from element (target) ConvertDeletedToEmptyAndFullToDeleted(ctrl_, capacity_); - alignas(slot_type) unsigned char raw[sizeof(slot_type)]; + alignas(slot_type) unsigned char raw[sizeof(slot_type)]; size_t total_probe_length = 0; slot_type* slot = reinterpret_cast<slot_type*>(&raw); for (size_t i = 0; i != capacity_; ++i) { @@ -1956,18 +1956,18 @@ class raw_hash_set { allocator_type{}}; }; -// Erases all elements that satisfy the predicate `pred` from the container `c`. -template <typename P, typename H, typename E, typename A, typename Predicate> +// Erases all elements that satisfy the predicate `pred` from the container `c`. +template <typename P, typename H, typename E, typename A, typename Predicate> void EraseIf(Predicate& pred, raw_hash_set<P, H, E, A>* c) { - for (auto it = c->begin(), last = c->end(); it != last;) { + for (auto it = c->begin(), last = c->end(); it != last;) { if (pred(*it)) { c->erase(it++); } else { ++it; - } - } -} - + } + } +} + namespace hashtable_debug_internal { template <typename Set> struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> { @@ -2028,7 +2028,7 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> { } // namespace hashtable_debug_internal } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/test_instance_tracker.h b/contrib/restricted/abseil-cpp/absl/container/internal/test_instance_tracker.h index 5ff6fd714e..ceb1ee9d37 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/test_instance_tracker.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/test_instance_tracker.h @@ -21,7 +21,7 @@ #include "absl/types/compare.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace test_internal { // A type that counts number of occurrences of the type, the live occurrences of @@ -268,7 +268,7 @@ class MovableOnlyInstance : public BaseCountedInstance { }; } // namespace test_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_TEST_INSTANCE_TRACKER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/tracked.h b/contrib/restricted/abseil-cpp/absl/container/internal/tracked.h index 29f5829f71..96ab792723 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/tracked.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/tracked.h @@ -16,14 +16,14 @@ #define ABSL_CONTAINER_INTERNAL_TRACKED_H_ #include <stddef.h> - + #include <memory> #include <utility> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { // A class that tracks its copies and moves so that it can be queried in tests. @@ -77,7 +77,7 @@ class Tracked { }; } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_TRACKED_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h index c1d20f3c52..bef925658f 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_constructor_test.h @@ -25,7 +25,7 @@ #include "absl/container/internal/hash_policy_testing.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class UnordMap> @@ -488,7 +488,7 @@ REGISTER_TYPED_TEST_CASE_P( AssignmentFromInitializerListOverwritesExisting, AssignmentOnSelf); } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_CONSTRUCTOR_TEST_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_lookup_test.h b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_lookup_test.h index e76421e508..bbd281b7d0 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_lookup_test.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_lookup_test.h @@ -21,7 +21,7 @@ #include "absl/container/internal/hash_policy_testing.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class UnordMap> @@ -111,7 +111,7 @@ REGISTER_TYPED_TEST_CASE_P(LookupTest, At, OperatorBracket, Count, Find, EqualRange); } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_LOOKUP_TEST_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_members_test.h b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_members_test.h index 7d48cdb890..68eb00fe89 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_members_test.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_members_test.h @@ -21,7 +21,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class UnordMap> @@ -81,7 +81,7 @@ TYPED_TEST_P(MembersTest, BeginEnd) { REGISTER_TYPED_TEST_SUITE_P(MembersTest, Typedefs, SimpleFunctions, BeginEnd); } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MEMBERS_TEST_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h index d3543936f7..8784a56b8f 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_map_modifiers_test.h @@ -23,7 +23,7 @@ #include "absl/container/internal/hash_policy_testing.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class UnordMap> @@ -319,8 +319,8 @@ class UniquePtrModifiersTest : public ::testing::Test { } }; -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UniquePtrModifiersTest); - +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UniquePtrModifiersTest); + TYPED_TEST_SUITE_P(UniquePtrModifiersTest); // Test that we do not move from rvalue arguments if an insertion does not @@ -345,7 +345,7 @@ TYPED_TEST_P(UniquePtrModifiersTest, TryEmplace) { REGISTER_TYPED_TEST_SUITE_P(UniquePtrModifiersTest, TryEmplace); } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MODIFIERS_TEST_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_constructor_test.h b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_constructor_test.h index 41165b05e9..64aa1fcbe3 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_constructor_test.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_constructor_test.h @@ -26,7 +26,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class UnordMap> @@ -490,7 +490,7 @@ REGISTER_TYPED_TEST_CASE_P( AssignmentFromInitializerListOverwritesExisting, AssignmentOnSelf); } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_CONSTRUCTOR_TEST_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_lookup_test.h b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_lookup_test.h index 8f2f4b207e..9323259941 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_lookup_test.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_lookup_test.h @@ -21,7 +21,7 @@ #include "absl/container/internal/hash_policy_testing.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class UnordSet> @@ -85,7 +85,7 @@ TYPED_TEST_P(LookupTest, EqualRange) { REGISTER_TYPED_TEST_CASE_P(LookupTest, Count, Find, EqualRange); } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_LOOKUP_TEST_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_members_test.h b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_members_test.h index 4c5e104af2..ad01e1aab8 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_members_test.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_members_test.h @@ -21,7 +21,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class UnordSet> @@ -80,7 +80,7 @@ TYPED_TEST_P(MembersTest, BeginEnd) { REGISTER_TYPED_TEST_SUITE_P(MembersTest, Typedefs, SimpleFunctions, BeginEnd); } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MEMBERS_TEST_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h index 6e473e45da..a71cdd9e72 100644 --- a/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h +++ b/contrib/restricted/abseil-cpp/absl/container/internal/unordered_set_modifiers_test.h @@ -21,7 +21,7 @@ #include "absl/container/internal/hash_policy_testing.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class UnordSet> @@ -215,7 +215,7 @@ REGISTER_TYPED_TEST_CASE_P(ModifiersTest, Clear, Insert, InsertHint, Erase, EraseRange, EraseKey, Swap); } // namespace container_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MODIFIERS_TEST_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/node_hash_map.h b/contrib/restricted/abseil-cpp/absl/container/node_hash_map.h index 7a39f6284c..c2eb3f8bbe 100644 --- a/contrib/restricted/abseil-cpp/absl/container/node_hash_map.h +++ b/contrib/restricted/abseil-cpp/absl/container/node_hash_map.h @@ -48,7 +48,7 @@ #include "absl/memory/memory.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <class Key, class Value> class NodeHashMapPolicy; @@ -225,8 +225,8 @@ class node_hash_map // // size_type erase(const key_type& key): // - // Erases the element with the matching key, if it exists, returning the - // number of elements erased (0 or 1). + // Erases the element with the matching key, if it exists, returning the + // number of elements erased (0 or 1). using Base::erase; // node_hash_map::insert() @@ -375,11 +375,11 @@ class node_hash_map // key value and returns a node handle owning that extracted data. If the // `node_hash_map` does not contain an element with a matching key, this // function returns an empty node handle. - // - // NOTE: when compiled in an earlier version of C++ than C++17, - // `node_type::key()` returns a const reference to the key instead of a - // mutable reference. We cannot safely return a mutable reference without - // std::launder (which is not available before C++17). + // + // NOTE: when compiled in an earlier version of C++ than C++17, + // `node_type::key()` returns a const reference to the key instead of a + // mutable reference. We cannot safely return a mutable reference without + // std::launder (which is not available before C++17). using Base::extract; // node_hash_map::merge() @@ -520,16 +520,16 @@ class node_hash_map // // Returns the function used for comparing keys equality. using Base::key_eq; -}; +}; -// erase_if(node_hash_map<>, Pred) -// -// Erases all elements that satisfy the predicate `pred` from the container `c`. -template <typename K, typename V, typename H, typename E, typename A, - typename Predicate> -void erase_if(node_hash_map<K, V, H, E, A>& c, Predicate pred) { - container_internal::EraseIf(pred, &c); -} +// erase_if(node_hash_map<>, Pred) +// +// Erases all elements that satisfy the predicate `pred` from the container `c`. +template <typename K, typename V, typename H, typename E, typename A, + typename Predicate> +void erase_if(node_hash_map<K, V, H, E, A>& c, Predicate pred) { + container_internal::EraseIf(pred, &c); +} namespace container_internal { @@ -591,7 +591,7 @@ struct IsUnorderedContainer< } // namespace container_algorithm_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_NODE_HASH_MAP_H_ diff --git a/contrib/restricted/abseil-cpp/absl/container/node_hash_set.h b/contrib/restricted/abseil-cpp/absl/container/node_hash_set.h index 93b15f4681..f63b28c6b4 100644 --- a/contrib/restricted/abseil-cpp/absl/container/node_hash_set.h +++ b/contrib/restricted/abseil-cpp/absl/container/node_hash_set.h @@ -44,7 +44,7 @@ #include "absl/memory/memory.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace container_internal { template <typename T> struct NodeHashSetPolicy; @@ -77,7 +77,7 @@ struct NodeHashSetPolicy; // // // Create a node hash set of three strings // absl::node_hash_set<std::string> ducks = -// {"huey", "dewey", "louie"}; +// {"huey", "dewey", "louie"}; // // // Insert a new element into the node hash set // ducks.insert("donald"); @@ -111,7 +111,7 @@ class node_hash_set // * Initializer List constructor // // absl::node_hash_set<std::string> set2 = - // {{"huey"}, {"dewey"}, {"louie"}}; + // {{"huey"}, {"dewey"}, {"louie"}}; // // * Copy constructor // @@ -217,8 +217,8 @@ class node_hash_set // // size_type erase(const key_type& key): // - // Erases the element with the matching key, if it exists, returning the - // number of elements erased (0 or 1). + // Erases the element with the matching key, if it exists, returning the + // number of elements erased (0 or 1). using Base::erase; // node_hash_set::insert() @@ -428,15 +428,15 @@ class node_hash_set // // Returns the function used for comparing keys equality. using Base::key_eq; -}; +}; -// erase_if(node_hash_set<>, Pred) -// -// Erases all elements that satisfy the predicate `pred` from the container `c`. -template <typename T, typename H, typename E, typename A, typename Predicate> -void erase_if(node_hash_set<T, H, E, A>& c, Predicate pred) { - container_internal::EraseIf(pred, &c); -} +// erase_if(node_hash_set<>, Pred) +// +// Erases all elements that satisfy the predicate `pred` from the container `c`. +template <typename T, typename H, typename E, typename A, typename Predicate> +void erase_if(node_hash_set<T, H, E, A>& c, Predicate pred) { + container_internal::EraseIf(pred, &c); +} namespace container_internal { @@ -487,7 +487,7 @@ struct IsUnorderedContainer<absl::node_hash_set<Key, Hash, KeyEqual, Allocator>> : std::true_type {}; } // namespace container_algorithm_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_CONTAINER_NODE_HASH_SET_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc index 689e5979e7..7398447647 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.cc @@ -25,10 +25,10 @@ #include <unistd.h> #endif -#ifdef __APPLE__ -#include <TargetConditionals.h> -#endif - +#ifdef __APPLE__ +#include <TargetConditionals.h> +#endif + #ifdef ABSL_HAVE_MMAP #include <sys/mman.h> #endif @@ -42,7 +42,7 @@ #include <ctime> #include "absl/base/attributes.h" -#include "absl/base/internal/errno_saver.h" +#include "absl/base/internal/errno_saver.h" #include "absl/base/internal/raw_logging.h" #include "absl/base/internal/sysinfo.h" #include "absl/debugging/internal/examine_stack.h" @@ -50,15 +50,15 @@ #ifndef _WIN32 #define ABSL_HAVE_SIGACTION -// Apple WatchOS and TVOS don't allow sigaltstack -#if !(defined(TARGET_OS_WATCH) && TARGET_OS_WATCH) && \ - !(defined(TARGET_OS_TV) && TARGET_OS_TV) -#define ABSL_HAVE_SIGALTSTACK -#endif +// Apple WatchOS and TVOS don't allow sigaltstack +#if !(defined(TARGET_OS_WATCH) && TARGET_OS_WATCH) && \ + !(defined(TARGET_OS_TV) && TARGET_OS_TV) +#define ABSL_HAVE_SIGALTSTACK #endif +#endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN ABSL_CONST_INIT static FailureSignalHandlerOptions fsh_options; @@ -128,7 +128,7 @@ const char* FailureSignalToString(int signo) { } // namespace debugging_internal -#ifdef ABSL_HAVE_SIGALTSTACK +#ifdef ABSL_HAVE_SIGALTSTACK static bool SetupAlternateStackOnce() { #if defined(__wasm__) || defined (__asjms__) @@ -138,8 +138,8 @@ static bool SetupAlternateStackOnce() { #endif size_t stack_size = (std::max<size_t>(SIGSTKSZ, 65536) + page_mask) & ~page_mask; -#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \ - defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER) +#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \ + defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER) // Account for sanitizer instrumentation requiring additional stack space. stack_size *= 5; #endif @@ -181,7 +181,7 @@ static bool SetupAlternateStackOnce() { // Returns the appropriate flag for sig_action.sa_flags // if the system supports using an alternate stack. static int MaybeSetupAlternateStack() { -#ifdef ABSL_HAVE_SIGALTSTACK +#ifdef ABSL_HAVE_SIGALTSTACK ABSL_ATTRIBUTE_UNUSED static const bool kOnce = SetupAlternateStackOnce(); return SA_ONSTACK; #else @@ -217,7 +217,7 @@ static void InstallOneFailureHandler(FailureSignalData* data, #endif static void WriteToStderr(const char* data) { - absl::base_internal::ErrnoSaver errno_saver; + absl::base_internal::ErrnoSaver errno_saver; absl::raw_logging_internal::SafeWriteToStderr(data, strlen(data)); } @@ -384,5 +384,5 @@ void InstallFailureSignalHandler(const FailureSignalHandlerOptions& options) { } } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.h b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.h index 500115c0ab..ac887de789 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/failure_signal_handler.h @@ -44,10 +44,10 @@ #ifndef ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ #define ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // FailureSignalHandlerOptions // @@ -88,7 +88,7 @@ struct FailureSignalHandlerOptions { bool call_previous_handler = false; // If non-null, indicates a pointer to a callback function that will be called - // upon failure, with a string argument containing failure data. This function + // upon failure, with a string argument containing failure data. This function // may be used as a hook to write failure data to a secondary location, such // as a log file. This function will also be called with null data, as a hint // to flush any buffered data before the program may be terminated. Consider @@ -115,7 +115,7 @@ namespace debugging_internal { const char* FailureSignalToString(int signo); } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_FAILURE_SIGNAL_HANDLER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.cc b/contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.cc index 329c285f3b..0a8dbfc422 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.cc @@ -20,14 +20,14 @@ #if !defined(__linux__) || defined(__ANDROID__) namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // On platforms other than Linux, just return true. bool AddressIsReadable(const void* /* addr */) { return true; } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #else @@ -35,16 +35,16 @@ ABSL_NAMESPACE_END #include <fcntl.h> #include <sys/syscall.h> #include <unistd.h> - + #include <atomic> #include <cerrno> #include <cstdint> -#include "absl/base/internal/errno_saver.h" +#include "absl/base/internal/errno_saver.h" #include "absl/base/internal/raw_logging.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Pack a pid and two file descriptors into a 64-bit word, @@ -70,7 +70,7 @@ static void Unpack(uint64_t x, int *pid, int *read_fd, int *write_fd) { static std::atomic<uint64_t> pid_and_fds; // initially 0, an invalid pid. bool AddressIsReadable(const void *addr) { - absl::base_internal::ErrnoSaver errno_saver; + absl::base_internal::ErrnoSaver errno_saver; // We test whether a byte is readable by using write(). Normally, this would // be done via a cached file descriptor to /dev/null, but linux fails to // check whether the byte is readable when the destination is /dev/null, so @@ -133,7 +133,7 @@ bool AddressIsReadable(const void *addr) { } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.h index 4bbaf4d69b..955a180194 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/address_is_readable.h @@ -15,10 +15,10 @@ #ifndef ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_ #define ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Return whether the byte at *addr is readable, without faulting. @@ -26,7 +26,7 @@ namespace debugging_internal { bool AddressIsReadable(const void *addr); } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_ADDRESS_IS_READABLE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc b/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc index 93ae32796c..8ad372a61f 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.cc @@ -24,7 +24,7 @@ #include <limits> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { typedef struct { @@ -126,7 +126,7 @@ static const AbbrevPair kBuiltinTypeList[] = { {"Dn", "std::nullptr_t", 0}, // i.e., decltype(nullptr) {"Df", "decimal32", 0}, // IEEE 754r decimal floating point (32 bits) {"Di", "char32_t", 0}, - {"Du", "char8_t", 0}, + {"Du", "char8_t", 0}, {"Ds", "char16_t", 0}, {"Dh", "float16", 0}, // IEEE 754r half-precision float (16 bits) {nullptr, nullptr, 0}, @@ -152,7 +152,7 @@ static const AbbrevPair kSubstitutionList[] = { // frame, so every byte counts. typedef struct { int mangled_idx; // Cursor of mangled name. - int out_cur_idx; // Cursor of output string. + int out_cur_idx; // Cursor of output string. int prev_name_idx; // For constructors/destructors. signed int prev_name_length : 16; // For constructors/destructors. signed int nest_level : 15; // For nested names. @@ -173,8 +173,8 @@ static_assert(sizeof(ParseState) == 4 * sizeof(int), // Only one copy of this exists for each call to Demangle, so the size of this // struct is nearly inconsequential. typedef struct { - const char *mangled_begin; // Beginning of input string. - char *out; // Beginning of output string. + const char *mangled_begin; // Beginning of input string. + char *out; // Beginning of output string. int out_end_idx; // One past last allowed output character. int recursion_depth; // For stack exhaustion prevention. int steps; // Cap how much work we'll do, regardless of depth. @@ -414,7 +414,7 @@ static bool IsFunctionCloneSuffix(const char *str) { static bool EndsWith(State *state, const char chr) { return state->parse_state.out_cur_idx > 0 && - state->parse_state.out_cur_idx < state->out_end_idx && + state->parse_state.out_cur_idx < state->out_end_idx && chr == state->out[state->parse_state.out_cur_idx - 1]; } @@ -427,10 +427,10 @@ static void MaybeAppendWithLength(State *state, const char *const str, if (str[0] == '<' && EndsWith(state, '<')) { Append(state, " ", 1); } - // Remember the last identifier name for ctors/dtors, - // but only if we haven't yet overflown the buffer. - if (state->parse_state.out_cur_idx < state->out_end_idx && - (IsAlpha(str[0]) || str[0] == '_')) { + // Remember the last identifier name for ctors/dtors, + // but only if we haven't yet overflown the buffer. + if (state->parse_state.out_cur_idx < state->out_end_idx && + (IsAlpha(str[0]) || str[0] == '_')) { state->parse_state.prev_name_idx = state->parse_state.out_cur_idx; state->parse_state.prev_name_length = length; } @@ -970,7 +970,7 @@ static bool ParseOperatorName(State *state, int *arity) { // ::= TT <type> // ::= TI <type> // ::= TS <type> -// ::= TH <type> # thread-local +// ::= TH <type> # thread-local // ::= Tc <call-offset> <call-offset> <(base) encoding> // ::= GV <(object) name> // ::= T <call-offset> <(base) encoding> @@ -989,7 +989,7 @@ static bool ParseSpecialName(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; ParseState copy = state->parse_state; - if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "VTISH") && + if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "VTISH") && ParseType(state)) { return true; } @@ -1086,28 +1086,28 @@ static bool ParseVOffset(State *state) { return false; } -// <ctor-dtor-name> ::= C1 | C2 | C3 | CI1 <base-class-type> | CI2 -// <base-class-type> +// <ctor-dtor-name> ::= C1 | C2 | C3 | CI1 <base-class-type> | CI2 +// <base-class-type> // ::= D0 | D1 | D2 // # GCC extensions: "unified" constructor/destructor. See -// # -// https://github.com/gcc-mirror/gcc/blob/7ad17b583c3643bd4557f29b8391ca7ef08391f5/gcc/cp/mangle.c#L1847 +// # +// https://github.com/gcc-mirror/gcc/blob/7ad17b583c3643bd4557f29b8391ca7ef08391f5/gcc/cp/mangle.c#L1847 // ::= C4 | D4 static bool ParseCtorDtorName(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; ParseState copy = state->parse_state; - if (ParseOneCharToken(state, 'C')) { - if (ParseCharClass(state, "1234")) { - const char *const prev_name = - state->out + state->parse_state.prev_name_idx; - MaybeAppendWithLength(state, prev_name, - state->parse_state.prev_name_length); - return true; - } else if (ParseOneCharToken(state, 'I') && ParseCharClass(state, "12") && - ParseClassEnumType(state)) { - return true; - } + if (ParseOneCharToken(state, 'C')) { + if (ParseCharClass(state, "1234")) { + const char *const prev_name = + state->out + state->parse_state.prev_name_idx; + MaybeAppendWithLength(state, prev_name, + state->parse_state.prev_name_length); + return true; + } else if (ParseOneCharToken(state, 'I') && ParseCharClass(state, "12") && + ParseClassEnumType(state)) { + return true; + } } state->parse_state = copy; @@ -1156,7 +1156,7 @@ static bool ParseDecltype(State *state) { // ::= <decltype> // ::= <substitution> // ::= Dp <type> # pack expansion of (C++0x) -// ::= Dv <num-elems> _ # GNU vector extension +// ::= Dv <num-elems> _ # GNU vector extension // static bool ParseType(State *state) { ComplexityGuard guard(state); @@ -1223,12 +1223,12 @@ static bool ParseType(State *state) { return true; } - if (ParseTwoCharToken(state, "Dv") && ParseNumber(state, nullptr) && - ParseOneCharToken(state, '_')) { - return true; - } - state->parse_state = copy; - + if (ParseTwoCharToken(state, "Dv") && ParseNumber(state, nullptr) && + ParseOneCharToken(state, '_')) { + return true; + } + state->parse_state = copy; + return false; } @@ -1277,42 +1277,42 @@ static bool ParseBuiltinType(State *state) { return false; } -// <exception-spec> ::= Do # non-throwing -// exception-specification (e.g., -// noexcept, throw()) -// ::= DO <expression> E # computed (instantiation-dependent) -// noexcept -// ::= Dw <type>+ E # dynamic exception specification -// with instantiation-dependent types -static bool ParseExceptionSpec(State *state) { - ComplexityGuard guard(state); - if (guard.IsTooComplex()) return false; - - if (ParseTwoCharToken(state, "Do")) return true; - - ParseState copy = state->parse_state; - if (ParseTwoCharToken(state, "DO") && ParseExpression(state) && - ParseOneCharToken(state, 'E')) { - return true; - } - state->parse_state = copy; - if (ParseTwoCharToken(state, "Dw") && OneOrMore(ParseType, state) && - ParseOneCharToken(state, 'E')) { - return true; - } - state->parse_state = copy; - - return false; -} - -// <function-type> ::= [exception-spec] F [Y] <bare-function-type> [O] E +// <exception-spec> ::= Do # non-throwing +// exception-specification (e.g., +// noexcept, throw()) +// ::= DO <expression> E # computed (instantiation-dependent) +// noexcept +// ::= Dw <type>+ E # dynamic exception specification +// with instantiation-dependent types +static bool ParseExceptionSpec(State *state) { + ComplexityGuard guard(state); + if (guard.IsTooComplex()) return false; + + if (ParseTwoCharToken(state, "Do")) return true; + + ParseState copy = state->parse_state; + if (ParseTwoCharToken(state, "DO") && ParseExpression(state) && + ParseOneCharToken(state, 'E')) { + return true; + } + state->parse_state = copy; + if (ParseTwoCharToken(state, "Dw") && OneOrMore(ParseType, state) && + ParseOneCharToken(state, 'E')) { + return true; + } + state->parse_state = copy; + + return false; +} + +// <function-type> ::= [exception-spec] F [Y] <bare-function-type> [O] E static bool ParseFunctionType(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; ParseState copy = state->parse_state; - if (Optional(ParseExceptionSpec(state)) && ParseOneCharToken(state, 'F') && + if (Optional(ParseExceptionSpec(state)) && ParseOneCharToken(state, 'F') && Optional(ParseOneCharToken(state, 'Y')) && ParseBareFunctionType(state) && - Optional(ParseOneCharToken(state, 'O')) && + Optional(ParseOneCharToken(state, 'O')) && ParseOneCharToken(state, 'E')) { return true; } @@ -1950,10 +1950,10 @@ static bool Overflowed(const State *state) { bool Demangle(const char *mangled, char *out, int out_size) { State state; InitState(&state, mangled, out, out_size); - return ParseTopLevelMangledName(&state) && !Overflowed(&state) && - state.parse_state.out_cur_idx > 0; + return ParseTopLevelMangledName(&state) && !Overflowed(&state) && + state.parse_state.out_cur_idx > 0; } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.h index c314d9bc23..e68826308c 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/demangle.h @@ -53,10 +53,10 @@ #ifndef ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ #define ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Demangle `mangled`. On success, return true and write the @@ -65,7 +65,7 @@ namespace debugging_internal { bool Demangle(const char *mangled, char *out, int out_size); } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.cc b/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.cc index 29a281812b..d27e9af291 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.cc @@ -39,7 +39,7 @@ #define VERSYM_VERSION 0x7fff namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { namespace { @@ -377,7 +377,7 @@ void ElfMemImage::SymbolIterator::Update(int increment) { } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_ELF_MEM_IMAGE diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h index a894bd423e..7aaec7b986 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/elf_mem_image.h @@ -23,8 +23,8 @@ // used. #include <climits> -#include "absl/base/config.h" - +#include "absl/base/config.h" + // Maybe one day we can rewrite this file not to require the elf // symbol extensions in glibc, but for right now we need them. #ifdef ABSL_HAVE_ELF_MEM_IMAGE @@ -45,7 +45,7 @@ #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // An in-memory ELF image (may not exist on disk). @@ -130,7 +130,7 @@ class ElfMemImage { }; } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_ELF_MEM_IMAGE diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/examine_stack.cc b/contrib/restricted/abseil-cpp/absl/debugging/internal/examine_stack.cc index 589a3ef367..d75c8dbb01 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/examine_stack.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/examine_stack.cc @@ -20,10 +20,10 @@ #include <unistd.h> #endif -#ifdef __APPLE__ -#include <sys/ucontext.h> -#endif - +#ifdef __APPLE__ +#include <sys/ucontext.h> +#endif + #include <csignal> #include <cstdio> @@ -34,7 +34,7 @@ #include "absl/debugging/symbolize.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Returns the program counter from signal context, nullptr if @@ -65,8 +65,8 @@ void* GetProgramCounter(void* vuc) { return reinterpret_cast<void*>(context->uc_mcontext.gp_regs[32]); #elif defined(__powerpc__) return reinterpret_cast<void*>(context->uc_mcontext.uc_regs->gregs[32]); -#elif defined(__riscv) - return reinterpret_cast<void*>(context->uc_mcontext.__gregs[REG_PC]); +#elif defined(__riscv) + return reinterpret_cast<void*>(context->uc_mcontext.__gregs[REG_PC]); #elif defined(__s390__) && !defined(__s390x__) return reinterpret_cast<void*>(context->uc_mcontext.psw.addr & 0x7fffffff); #elif defined(__s390__) && defined(__s390x__) @@ -86,32 +86,32 @@ void* GetProgramCounter(void* vuc) { #error "Undefined Architecture." #endif } -#elif defined(__APPLE__) - if (vuc != nullptr) { - ucontext_t* signal_ucontext = reinterpret_cast<ucontext_t*>(vuc); -#if defined(__aarch64__) - return reinterpret_cast<void*>( - __darwin_arm_thread_state64_get_pc(signal_ucontext->uc_mcontext->__ss)); -#elif defined(__arm__) -#if __DARWIN_UNIX03 - return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->__ss.__pc); -#else - return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->ss.pc); -#endif -#elif defined(__i386__) -#if __DARWIN_UNIX03 - return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->__ss.__eip); -#else - return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->ss.eip); -#endif -#elif defined(__x86_64__) -#if __DARWIN_UNIX03 - return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->__ss.__rip); -#else - return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->ss.rip); -#endif -#endif - } +#elif defined(__APPLE__) + if (vuc != nullptr) { + ucontext_t* signal_ucontext = reinterpret_cast<ucontext_t*>(vuc); +#if defined(__aarch64__) + return reinterpret_cast<void*>( + __darwin_arm_thread_state64_get_pc(signal_ucontext->uc_mcontext->__ss)); +#elif defined(__arm__) +#if __DARWIN_UNIX03 + return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->__ss.__pc); +#else + return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->ss.pc); +#endif +#elif defined(__i386__) +#if __DARWIN_UNIX03 + return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->__ss.__eip); +#else + return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->ss.eip); +#endif +#elif defined(__x86_64__) +#if __DARWIN_UNIX03 + return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->__ss.__rip); +#else + return reinterpret_cast<void*>(signal_ucontext->uc_mcontext->ss.rip); +#endif +#endif + } #elif defined(__akaros__) auto* ctx = reinterpret_cast<struct user_context*>(vuc); return reinterpret_cast<void*>(get_user_ctx_pc(ctx)); @@ -199,5 +199,5 @@ void DumpPCAndFrameSizesAndStackTrace( } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/examine_stack.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/examine_stack.h index 393369131f..fe96a06be9 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/examine_stack.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/examine_stack.h @@ -17,10 +17,10 @@ #ifndef ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_ #define ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Returns the program counter from signal context, or nullptr if @@ -36,7 +36,7 @@ void DumpPCAndFrameSizesAndStackTrace( void (*writerfn)(const char*, void*), void* writerfn_arg); } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_EXAMINE_STACK_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h index f41b64c39d..66b29cb8d6 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stack_consumption.h @@ -18,19 +18,19 @@ #ifndef ABSL_DEBUGGING_INTERNAL_STACK_CONSUMPTION_H_ #define ABSL_DEBUGGING_INTERNAL_STACK_CONSUMPTION_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + // The code in this module is not portable. // Use this feature test macro to detect its availability. #ifdef ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION #error ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION cannot be set directly -#elif !defined(__APPLE__) && !defined(_WIN32) && \ - (defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || \ +#elif !defined(__APPLE__) && !defined(_WIN32) && \ + (defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || \ defined(__aarch64__) || defined(__riscv)) #define ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION 1 namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Returns the stack consumption in bytes for the code exercised by @@ -42,7 +42,7 @@ namespace debugging_internal { int GetSignalHandlerStackConsumption(void (*signal_handler)(int)); } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_INTERNAL_HAVE_DEBUGGING_STACK_CONSUMPTION diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc index f4859d7c21..7680e42413 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc @@ -77,8 +77,8 @@ static inline uintptr_t ComputeStackFrameSize(const T* low, // checks (the strictness of which is controlled by the boolean parameter // "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. template<bool STRICT_UNWINDING, bool WITH_CONTEXT> -ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. -ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. +ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. +ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. static void **NextStackFrame(void **old_frame_pointer, const void *uc) { void **new_frame_pointer = reinterpret_cast<void**>(*old_frame_pointer); bool check_frame_size = true; @@ -128,8 +128,8 @@ static void **NextStackFrame(void **old_frame_pointer, const void *uc) { } template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> -ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. -ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. +ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack. +ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, const void *ucp, int *min_dropped_frames) { #ifdef __GNUC__ @@ -187,13 +187,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return true; } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_AARCH64_INL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc index 2a1bf2e886..fc0f397051 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc @@ -1,17 +1,17 @@ -// Copyright 2017 The Abseil Authors. -// -// 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 -// -// https://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. +// Copyright 2017 The Abseil Authors. // +// 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 +// +// https://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. +// // This is inspired by Craig Silverstein's PowerPC stacktrace code. #ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_ARM_INL_H_ @@ -122,13 +122,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return false; } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_ARM_INL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h index ff21b719a0..6ee5d370a1 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_config.h @@ -30,56 +30,56 @@ #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_win32-inl.inc" -#elif defined(__APPLE__) +#elif defined(__APPLE__) #ifdef ABSL_HAVE_THREAD_LOCAL -// Thread local support required for UnwindImpl. -#define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_generic-inl.inc" +// Thread local support required for UnwindImpl. +#define ABSL_STACKTRACE_INL_HEADER \ + "absl/debugging/internal/stacktrace_generic-inl.inc" #endif // defined(ABSL_HAVE_THREAD_LOCAL) - + #elif defined(__EMSCRIPTEN__) #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_emscripten-inl.inc" #elif defined(__linux__) && !defined(__ANDROID__) -#if defined(NO_FRAME_POINTER) && \ - (defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)) -// Note: The libunwind-based implementation is not available to open-source -// users. +#if defined(NO_FRAME_POINTER) && \ + (defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)) +// Note: The libunwind-based implementation is not available to open-source +// users. #define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_libunwind-inl.inc" -#define STACKTRACE_USES_LIBUNWIND 1 -#elif defined(NO_FRAME_POINTER) && defined(__has_include) -#if __has_include(<execinfo.h>) + "absl/debugging/internal/stacktrace_libunwind-inl.inc" +#define STACKTRACE_USES_LIBUNWIND 1 +#elif defined(NO_FRAME_POINTER) && defined(__has_include) +#if __has_include(<execinfo.h>) // Note: When using glibc this may require -funwind-tables to function properly. #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_generic-inl.inc" #endif // __has_include(<execinfo.h>) -#elif defined(__i386__) || defined(__x86_64__) +#elif defined(__i386__) || defined(__x86_64__) #define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_x86-inl.inc" -#elif defined(__ppc__) || defined(__PPC__) + "absl/debugging/internal/stacktrace_x86-inl.inc" +#elif defined(__ppc__) || defined(__PPC__) #define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_powerpc-inl.inc" -#elif defined(__aarch64__) + "absl/debugging/internal/stacktrace_powerpc-inl.inc" +#elif defined(__aarch64__) #define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_aarch64-inl.inc" + "absl/debugging/internal/stacktrace_aarch64-inl.inc" #elif defined(__riscv) #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_riscv-inl.inc" -#elif defined(__has_include) -#if __has_include(<execinfo.h>) -// Note: When using glibc this may require -funwind-tables to function properly. +#elif defined(__has_include) +#if __has_include(<execinfo.h>) +// Note: When using glibc this may require -funwind-tables to function properly. #define ABSL_STACKTRACE_INL_HEADER \ - "absl/debugging/internal/stacktrace_generic-inl.inc" + "absl/debugging/internal/stacktrace_generic-inl.inc" #endif // __has_include(<execinfo.h>) #endif // defined(__has_include) #endif // defined(__linux__) && !defined(__ANDROID__) - -// Fallback to the empty implementation. -#if !defined(ABSL_STACKTRACE_INL_HEADER) + +// Fallback to the empty implementation. +#if !defined(ABSL_STACKTRACE_INL_HEADER) #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_unimplemented-inl.inc" #endif diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc index b2792a1f3a..eee5acb9c6 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc @@ -1,17 +1,17 @@ -// Copyright 2017 The Abseil Authors. +// Copyright 2017 The Abseil Authors. // -// 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 -// -// https://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. +// 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 // +// https://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. +// // Portable implementation - just use glibc // // Note: The glibc implementation may cause a call to malloc. @@ -96,13 +96,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return true; } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_GENERIC_INL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc index cf8c05160c..18912dd508 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc @@ -241,13 +241,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return true; } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc index 5b8fb191b6..6006bc8acf 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc @@ -12,13 +12,13 @@ static int UnwindImpl(void** /* result */, int* /* sizes */, } namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return false; } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_UNIMPLEMENTED_INL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc index 1c666c8b56..79e9b96de3 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc @@ -46,19 +46,19 @@ typedef USHORT NTAPI RtlCaptureStackBackTrace_Function( OUT PVOID *backtrace, OUT PULONG backtrace_hash); -// It is not possible to load RtlCaptureStackBackTrace at static init time in -// UWP. CaptureStackBackTrace is the public version of RtlCaptureStackBackTrace -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ - !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn = - &::CaptureStackBackTrace; -#else +// It is not possible to load RtlCaptureStackBackTrace at static init time in +// UWP. CaptureStackBackTrace is the public version of RtlCaptureStackBackTrace +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ + !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn = + &::CaptureStackBackTrace; +#else // Load the function we need at static init time, where we don't have // to worry about someone else holding the loader's lock. static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn = - (RtlCaptureStackBackTrace_Function*)GetProcAddress( - GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace"); -#endif // WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP + (RtlCaptureStackBackTrace_Function*)GetProcAddress( + GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace"); +#endif // WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT> static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, @@ -81,13 +81,13 @@ static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, } namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return false; } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_WIN32_INL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc index 847a547359..e5b64bb8f9 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc @@ -174,7 +174,7 @@ static void **NextStackFrame(void **old_fp, const void *uc, static const unsigned char *kernel_rt_sigreturn_address = nullptr; static const unsigned char *kernel_vsyscall_address = nullptr; if (num_push_instructions == -1) { -#ifdef ABSL_HAVE_VDSO_SUPPORT +#ifdef ABSL_HAVE_VDSO_SUPPORT absl::debugging_internal::VDSOSupport vdso; if (vdso.IsPresent()) { absl::debugging_internal::VDSOSupport::SymbolInfo @@ -203,9 +203,9 @@ static void **NextStackFrame(void **old_fp, const void *uc, } else { num_push_instructions = 0; } -#else // ABSL_HAVE_VDSO_SUPPORT - num_push_instructions = 0; -#endif // ABSL_HAVE_VDSO_SUPPORT +#else // ABSL_HAVE_VDSO_SUPPORT + num_push_instructions = 0; +#endif // ABSL_HAVE_VDSO_SUPPORT } if (num_push_instructions != 0 && kernel_rt_sigreturn_address != nullptr && old_fp[1] == kernel_rt_sigreturn_address) { @@ -352,13 +352,13 @@ static int UnwindImpl(void **result, int *sizes, int max_depth, int skip_count, } namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { bool StackTraceWorksForTest() { return true; } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_X86_INL_INC_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/symbolize.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/symbolize.h index 27d5e6521e..1a208f3bdd 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/symbolize.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/symbolize.h @@ -18,14 +18,14 @@ #ifndef ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ #define ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ -#ifdef __cplusplus - +#ifdef __cplusplus + #include <cstddef> #include <cstdint> -#include "absl/base/config.h" -#include "absl/strings/string_view.h" - +#include "absl/base/config.h" +#include "absl/strings/string_view.h" + #ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE #error ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE cannot be directly set #elif defined(__ELF__) && defined(__GLIBC__) && !defined(__native_client__) \ @@ -38,7 +38,7 @@ #include <string> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // Iterates over all sections, invoking callback on each with the section name @@ -48,7 +48,7 @@ namespace debugging_internal { // // This is not async-signal-safe. bool ForEachSection(int fd, - const std::function<bool(absl::string_view name, + const std::function<bool(absl::string_view name, const ElfW(Shdr) &)>& callback); // Gets the section header for the given name, if it exists. Returns true on @@ -57,17 +57,17 @@ bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, ElfW(Shdr) *out); } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE -#ifdef ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE -#error ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE cannot be directly set -#elif defined(__APPLE__) -#define ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE 1 -#endif - +#ifdef ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE +#error ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE cannot be directly set +#elif defined(__APPLE__) +#define ABSL_INTERNAL_HAVE_DARWIN_SYMBOLIZE 1 +#endif + #ifdef ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE #error ABSL_INTERNAL_HAVE_EMSCRIPTEN_SYMBOLIZE cannot be directly set #elif defined(__EMSCRIPTEN__) @@ -75,7 +75,7 @@ ABSL_NAMESPACE_END #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { struct SymbolDecoratorArgs { @@ -124,30 +124,30 @@ bool RemoveAllSymbolDecorators(void); // filename != nullptr // // Returns true if the file was successfully registered. -bool RegisterFileMappingHint(const void* start, const void* end, - uint64_t offset, const char* filename); +bool RegisterFileMappingHint(const void* start, const void* end, + uint64_t offset, const char* filename); // Looks up the file mapping registered by RegisterFileMappingHint for an // address range. If there is one, the file name is stored in *filename and // *start and *end are modified to reflect the registered mapping. Returns // whether any hint was found. -bool GetFileMappingHint(const void** start, const void** end, uint64_t* offset, +bool GetFileMappingHint(const void** start, const void** end, uint64_t* offset, const char** filename); } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl -#endif // __cplusplus - -#include <stdbool.h> - -#ifdef __cplusplus -extern "C" -#endif // __cplusplus - - bool - AbslInternalGetFileMappingHint(const void** start, const void** end, - uint64_t* offset, const char** filename); - +#endif // __cplusplus + +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" +#endif // __cplusplus + + bool + AbslInternalGetFileMappingHint(const void** start, const void** end, + uint64_t* offset, const char** filename); + #endif // ABSL_DEBUGGING_INTERNAL_SYMBOLIZE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/vdso_support.cc b/contrib/restricted/abseil-cpp/absl/debugging/internal/vdso_support.cc index 977a9f6b3c..21f158b8d6 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/vdso_support.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/vdso_support.cc @@ -56,7 +56,7 @@ using Elf32_auxv_t = Elf32_Auxinfo; #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { ABSL_CONST_INIT @@ -185,7 +185,7 @@ int GetCPU() { } } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_VDSO_SUPPORT diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/vdso_support.h b/contrib/restricted/abseil-cpp/absl/debugging/internal/vdso_support.h index 6562c6c235..cc2e29b1ed 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/vdso_support.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/vdso_support.h @@ -53,7 +53,7 @@ #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { // NOTE: this class may be used from within tcmalloc, and can not @@ -150,7 +150,7 @@ class VDSOSupport { int GetCPU(); } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HAVE_ELF_MEM_IMAGE diff --git a/contrib/restricted/abseil-cpp/absl/debugging/internal/ya.make b/contrib/restricted/abseil-cpp/absl/debugging/internal/ya.make index ef1dcbf7dd..6e96c2c0a7 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/internal/ya.make +++ b/contrib/restricted/abseil-cpp/absl/debugging/internal/ya.make @@ -1,43 +1,43 @@ -# Generated by devtools/yamaker. - -LIBRARY() - -OWNER(g:cpp-contrib) - -LICENSE(Apache-2.0) - +# Generated by devtools/yamaker. + +LIBRARY() + +OWNER(g:cpp-contrib) + +LICENSE(Apache-2.0) + LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -PEERDIR( - contrib/restricted/abseil-cpp/absl/base +PEERDIR( + contrib/restricted/abseil-cpp/absl/base contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc - contrib/restricted/abseil-cpp/absl/base/internal/raw_logging - contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait - contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate - contrib/restricted/abseil-cpp/absl/base/log_severity + contrib/restricted/abseil-cpp/absl/base/internal/raw_logging + contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait + contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate + contrib/restricted/abseil-cpp/absl/base/log_severity contrib/restricted/abseil-cpp/absl/debugging contrib/restricted/abseil-cpp/absl/debugging/stacktrace contrib/restricted/abseil-cpp/absl/debugging/symbolize contrib/restricted/abseil-cpp/absl/demangle - contrib/restricted/abseil-cpp/absl/numeric - contrib/restricted/abseil-cpp/absl/strings + contrib/restricted/abseil-cpp/absl/numeric + contrib/restricted/abseil-cpp/absl/strings contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal -) - -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DNOMINMAX -) - -SRCS( +) + +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DNOMINMAX +) + +SRCS( examine_stack.cc -) - -END() +) + +END() diff --git a/contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc b/contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc index 764ca0ad00..6128735e16 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/leak_check.cc @@ -22,7 +22,7 @@ #ifndef LEAK_SANITIZER namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN bool HaveLeakSanitizer() { return false; } bool LeakCheckerIsActive() { return false; } void DoIgnoreLeak(const void*) { } @@ -30,7 +30,7 @@ void RegisterLivePointers(const void*, size_t) { } void UnRegisterLivePointers(const void*, size_t) { } LeakCheckDisabler::LeakCheckDisabler() { } LeakCheckDisabler::~LeakCheckDisabler() { } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #else @@ -42,7 +42,7 @@ extern "C" ABSL_ATTRIBUTE_WEAK int __lsan_is_turned_off(); #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN bool HaveLeakSanitizer() { return true; } #if ABSL_HAVE_ATTRIBUTE_WEAK @@ -63,7 +63,7 @@ void UnRegisterLivePointers(const void* ptr, size_t size) { } LeakCheckDisabler::LeakCheckDisabler() { __lsan_disable(); } LeakCheckDisabler::~LeakCheckDisabler() { __lsan_enable(); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // LEAK_SANITIZER diff --git a/contrib/restricted/abseil-cpp/absl/debugging/leak_check.h b/contrib/restricted/abseil-cpp/absl/debugging/leak_check.h index 5fc2b052e4..8787af440c 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/leak_check.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/leak_check.h @@ -32,10 +32,10 @@ #include <cstddef> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // HaveLeakSanitizer() // @@ -127,7 +127,7 @@ void RegisterLivePointers(const void* ptr, size_t size); // `RegisterLivePointers()`, enabling leak checking of those pointers. void UnRegisterLivePointers(const void* ptr, size_t size); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_LEAK_CHECK_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/leak_check/ya.make b/contrib/restricted/abseil-cpp/absl/debugging/leak_check/ya.make index 7039d87469..723e59e67b 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/leak_check/ya.make +++ b/contrib/restricted/abseil-cpp/absl/debugging/leak_check/ya.make @@ -16,10 +16,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/debugging) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/debugging/leak_check_disable/ya.make b/contrib/restricted/abseil-cpp/absl/debugging/leak_check_disable/ya.make index 49da98034e..af70b73e55 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/leak_check_disable/ya.make +++ b/contrib/restricted/abseil-cpp/absl/debugging/leak_check_disable/ya.make @@ -16,10 +16,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/debugging) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/debugging/stacktrace.cc b/contrib/restricted/abseil-cpp/absl/debugging/stacktrace.cc index ff8069f843..334794b3fa 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/stacktrace.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/stacktrace.cc @@ -59,7 +59,7 @@ #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { typedef int (*Unwinder)(void**, int*, int, int, const void*, int*); @@ -138,5 +138,5 @@ int DefaultStackUnwinder(void** pcs, int* sizes, int depth, int skip, return n; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/debugging/stacktrace.h b/contrib/restricted/abseil-cpp/absl/debugging/stacktrace.h index 0ec0ffdabd..0ee8e73e0d 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/stacktrace.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/stacktrace.h @@ -31,10 +31,10 @@ #ifndef ABSL_DEBUGGING_STACKTRACE_H_ #define ABSL_DEBUGGING_STACKTRACE_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // GetStackFrames() // @@ -225,7 +225,7 @@ namespace debugging_internal { // working. extern bool StackTraceWorksForTest(); } // namespace debugging_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_STACKTRACE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/stacktrace/ya.make b/contrib/restricted/abseil-cpp/absl/debugging/stacktrace/ya.make index b9028022d8..1d82ec16cc 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/stacktrace/ya.make +++ b/contrib/restricted/abseil-cpp/absl/debugging/stacktrace/ya.make @@ -22,10 +22,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/debugging) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc index f1abdfda59..3fe63a4053 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc +++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize.cc @@ -14,23 +14,23 @@ #include "absl/debugging/symbolize.h" -#ifdef _WIN32 -#include <winapifamily.h> -#if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)) || \ - WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -// UWP doesn't have access to win32 APIs. -#define ABSL_INTERNAL_HAVE_SYMBOLIZE_WIN32 -#endif -#endif - +#ifdef _WIN32 +#include <winapifamily.h> +#if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)) || \ + WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +// UWP doesn't have access to win32 APIs. +#define ABSL_INTERNAL_HAVE_SYMBOLIZE_WIN32 +#endif +#endif + #if defined(ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE) #include "absl/debugging/symbolize_elf.inc" -#elif defined(ABSL_INTERNAL_HAVE_SYMBOLIZE_WIN32) +#elif defined(ABSL_INTERNAL_HAVE_SYMBOLIZE_WIN32) // The Windows Symbolizer only works if PDB files containing the debug info // are available to the program at runtime. #include "absl/debugging/symbolize_win32.inc" -#elif defined(__APPLE__) -#include "absl/debugging/symbolize_darwin.inc" +#elif defined(__APPLE__) +#include "absl/debugging/symbolize_darwin.inc" #elif defined(__EMSCRIPTEN__) #include "absl/debugging/symbolize_emscripten.inc" #else diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize.h b/contrib/restricted/abseil-cpp/absl/debugging/symbolize.h index 43d93a8682..90bb716205 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize.h +++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize.h @@ -55,7 +55,7 @@ #include "absl/debugging/internal/symbolize.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // InitializeSymbolizer() // @@ -71,7 +71,7 @@ ABSL_NAMESPACE_BEGIN // // Now you can use the symbolizer // } void InitializeSymbolizer(const char* argv0); -// +// // Symbolize() // // Symbolizes a program counter (instruction pointer value) `pc` and, on @@ -89,11 +89,11 @@ void InitializeSymbolizer(const char* argv0); // if (absl::Symbolize(pc, tmp, sizeof(tmp))) { // symbol = tmp; // } -// absl::PrintF("%p %s\n", pc, symbol); +// absl::PrintF("%p %s\n", pc, symbol); // } bool Symbolize(const void *pc, char *out, int out_size); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_DEBUGGING_SYMBOLIZE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_darwin.inc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_darwin.inc index 443ce9efc4..422004bf2c 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_darwin.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_darwin.inc @@ -1,101 +1,101 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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 <cxxabi.h> -#include <execinfo.h> - -#include <algorithm> -#include <cstring> - -#include "absl/base/internal/raw_logging.h" -#include "absl/debugging/internal/demangle.h" -#include "absl/strings/numbers.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -void InitializeSymbolizer(const char*) {} - -namespace debugging_internal { -namespace { - -static std::string GetSymbolString(absl::string_view backtrace_line) { - // Example Backtrace lines: - // 0 libimaging_shared.dylib 0x018c152a - // _ZNSt11_Deque_baseIN3nik7mediadb4PageESaIS2_EE17_M_initialize_mapEm + 3478 - // - // or - // 0 libimaging_shared.dylib 0x0000000001895c39 - // _ZN3nik4util19register_shared_ptrINS_3gpu7TextureEEEvPKvS5_ + 39 - // - // or - // 0 mysterious_app 0x0124000120120009 main + 17 - auto address_pos = backtrace_line.find(" 0x"); - if (address_pos == absl::string_view::npos) return std::string(); - absl::string_view symbol_view = backtrace_line.substr(address_pos + 1); - - auto space_pos = symbol_view.find(" "); - if (space_pos == absl::string_view::npos) return std::string(); - symbol_view = symbol_view.substr(space_pos + 1); // to mangled symbol - - auto plus_pos = symbol_view.find(" + "); - if (plus_pos == absl::string_view::npos) return std::string(); - symbol_view = symbol_view.substr(0, plus_pos); // strip remainng - - return std::string(symbol_view); -} - -} // namespace -} // namespace debugging_internal - -bool Symbolize(const void* pc, char* out, int out_size) { - if (out_size <= 0 || pc == nullptr) { - out = nullptr; - return false; - } - - // This allocates a char* array. - char** frame_strings = backtrace_symbols(const_cast<void**>(&pc), 1); - - if (frame_strings == nullptr) return false; - - std::string symbol = debugging_internal::GetSymbolString(frame_strings[0]); - free(frame_strings); - - char tmp_buf[1024]; - if (debugging_internal::Demangle(symbol.c_str(), tmp_buf, sizeof(tmp_buf))) { - size_t len = strlen(tmp_buf); - if (len + 1 <= static_cast<size_t>(out_size)) { // +1 for '\0' - assert(len < sizeof(tmp_buf)); - memmove(out, tmp_buf, len + 1); - } - } else { - strncpy(out, symbol.c_str(), out_size); - } - - if (out[out_size - 1] != '\0') { - // strncpy() does not '\0' terminate when it truncates. - static constexpr char kEllipsis[] = "..."; - int ellipsis_size = std::min<int>(sizeof(kEllipsis) - 1, out_size - 1); - memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size); - out[out_size - 1] = '\0'; - } - - return true; -} - -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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 <cxxabi.h> +#include <execinfo.h> + +#include <algorithm> +#include <cstring> + +#include "absl/base/internal/raw_logging.h" +#include "absl/debugging/internal/demangle.h" +#include "absl/strings/numbers.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +void InitializeSymbolizer(const char*) {} + +namespace debugging_internal { +namespace { + +static std::string GetSymbolString(absl::string_view backtrace_line) { + // Example Backtrace lines: + // 0 libimaging_shared.dylib 0x018c152a + // _ZNSt11_Deque_baseIN3nik7mediadb4PageESaIS2_EE17_M_initialize_mapEm + 3478 + // + // or + // 0 libimaging_shared.dylib 0x0000000001895c39 + // _ZN3nik4util19register_shared_ptrINS_3gpu7TextureEEEvPKvS5_ + 39 + // + // or + // 0 mysterious_app 0x0124000120120009 main + 17 + auto address_pos = backtrace_line.find(" 0x"); + if (address_pos == absl::string_view::npos) return std::string(); + absl::string_view symbol_view = backtrace_line.substr(address_pos + 1); + + auto space_pos = symbol_view.find(" "); + if (space_pos == absl::string_view::npos) return std::string(); + symbol_view = symbol_view.substr(space_pos + 1); // to mangled symbol + + auto plus_pos = symbol_view.find(" + "); + if (plus_pos == absl::string_view::npos) return std::string(); + symbol_view = symbol_view.substr(0, plus_pos); // strip remainng + + return std::string(symbol_view); +} + +} // namespace +} // namespace debugging_internal + +bool Symbolize(const void* pc, char* out, int out_size) { + if (out_size <= 0 || pc == nullptr) { + out = nullptr; + return false; + } + + // This allocates a char* array. + char** frame_strings = backtrace_symbols(const_cast<void**>(&pc), 1); + + if (frame_strings == nullptr) return false; + + std::string symbol = debugging_internal::GetSymbolString(frame_strings[0]); + free(frame_strings); + + char tmp_buf[1024]; + if (debugging_internal::Demangle(symbol.c_str(), tmp_buf, sizeof(tmp_buf))) { + size_t len = strlen(tmp_buf); + if (len + 1 <= static_cast<size_t>(out_size)) { // +1 for '\0' + assert(len < sizeof(tmp_buf)); + memmove(out, tmp_buf, len + 1); + } + } else { + strncpy(out, symbol.c_str(), out_size); + } + + if (out[out_size - 1] != '\0') { + // strncpy() does not '\0' terminate when it truncates. + static constexpr char kEllipsis[] = "..."; + int ellipsis_size = std::min<int>(sizeof(kEllipsis) - 1, out_size - 1); + memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size); + out[out_size - 1] = '\0'; + } + + return true; +} + +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc index 3ff343d64f..5f4f662972 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_elf.inc @@ -57,7 +57,7 @@ #include <unistd.h> #include <algorithm> -#include <array> +#include <array> #include <atomic> #include <cerrno> #include <cinttypes> @@ -75,25 +75,25 @@ #include "absl/base/port.h" #include "absl/debugging/internal/demangle.h" #include "absl/debugging/internal/vdso_support.h" -#include "absl/strings/string_view.h" +#include "absl/strings/string_view.h" #if defined(__FreeBSD__) && !defined(ElfW) #define ElfW(x) __ElfN(x) #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // Value of argv[0]. Used by MaybeInitializeObjFile(). static char *argv0_value = nullptr; void InitializeSymbolizer(const char *argv0) { -#ifdef ABSL_HAVE_VDSO_SUPPORT - // We need to make sure VDSOSupport::Init() is called before any setuid or - // chroot calls, so InitializeSymbolizer() should be called very early in the - // life of a program. - absl::debugging_internal::VDSOSupport::Init(); -#endif +#ifdef ABSL_HAVE_VDSO_SUPPORT + // We need to make sure VDSOSupport::Init() is called before any setuid or + // chroot calls, so InitializeSymbolizer() should be called very early in the + // life of a program. + absl::debugging_internal::VDSOSupport::Init(); +#endif if (argv0_value != nullptr) { free(argv0_value); argv0_value = nullptr; @@ -161,15 +161,15 @@ struct FileMappingHint { // Moreover, we are using only TryLock(), if the decorator list // is being modified (is busy), we skip all decorators, and possibly // loose some info. Sorry, that's the best we could do. -ABSL_CONST_INIT absl::base_internal::SpinLock g_decorators_mu( - absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY); +ABSL_CONST_INIT absl::base_internal::SpinLock g_decorators_mu( + absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY); const int kMaxFileMappingHints = 8; int g_num_file_mapping_hints; FileMappingHint g_file_mapping_hints[kMaxFileMappingHints]; // Protects g_file_mapping_hints. -ABSL_CONST_INIT absl::base_internal::SpinLock g_file_mapping_mu( - absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY); +ABSL_CONST_INIT absl::base_internal::SpinLock g_file_mapping_mu( + absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY); // Async-signal-safe function to zero a buffer. // memset() is not guaranteed to be async-signal-safe. @@ -189,7 +189,7 @@ struct ObjFile { fd(-1), elf_type(-1) { SafeMemZero(&elf_header, sizeof(elf_header)); - SafeMemZero(&phdr[0], sizeof(phdr)); + SafeMemZero(&phdr[0], sizeof(phdr)); } char *filename; @@ -202,10 +202,10 @@ struct ObjFile { int fd; int elf_type; ElfW(Ehdr) elf_header; - - // PT_LOAD program header describing executable code. - // Normally we expect just one, but SWIFT binaries have two. - std::array<ElfW(Phdr), 2> phdr; + + // PT_LOAD program header describing executable code. + // Normally we expect just one, but SWIFT binaries have two. + std::array<ElfW(Phdr), 2> phdr; }; // Build 4-way associative cache for symbols. Within each cache line, symbols @@ -515,7 +515,7 @@ static ABSL_ATTRIBUTE_NOINLINE bool GetSectionHeaderByType( const int kMaxSectionNameLen = 64; bool ForEachSection(int fd, - const std::function<bool(absl::string_view name, + const std::function<bool(absl::string_view name, const ElfW(Shdr) &)> &callback) { ElfW(Ehdr) elf_header; if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { @@ -537,7 +537,7 @@ bool ForEachSection(int fd, return false; } off_t name_offset = shstrtab.sh_offset + out.sh_name; - char header_name[kMaxSectionNameLen]; + char header_name[kMaxSectionNameLen]; ssize_t n_read = ReadFromOffset(fd, &header_name, kMaxSectionNameLen, name_offset); if (n_read == -1) { @@ -547,7 +547,7 @@ bool ForEachSection(int fd, return false; } - absl::string_view name(header_name, strnlen(header_name, n_read)); + absl::string_view name(header_name, strnlen(header_name, n_read)); if (!callback(name, out)) { break; } @@ -1292,36 +1292,36 @@ static bool MaybeInitializeObjFile(ObjFile *obj) { ABSL_RAW_LOG(WARNING, "%s: failed to read elf header", obj->filename); return false; } - const int phnum = obj->elf_header.e_phnum; - const int phentsize = obj->elf_header.e_phentsize; - size_t phoff = obj->elf_header.e_phoff; + const int phnum = obj->elf_header.e_phnum; + const int phentsize = obj->elf_header.e_phentsize; + size_t phoff = obj->elf_header.e_phoff; size_t num_executable_load_segments = 0; - for (int j = 0; j < phnum; j++) { - ElfW(Phdr) phdr; - if (!ReadFromOffsetExact(obj->fd, &phdr, sizeof(phdr), phoff)) { - ABSL_RAW_LOG(WARNING, "%s: failed to read program header %d", - obj->filename, j); - return false; - } - phoff += phentsize; - constexpr int rx = PF_X | PF_R; - if (phdr.p_type != PT_LOAD || (phdr.p_flags & rx) != rx) { - // Not a LOAD segment, or not executable code. - continue; - } - if (num_executable_load_segments < obj->phdr.size()) { - memcpy(&obj->phdr[num_executable_load_segments++], &phdr, sizeof(phdr)); - } else { - ABSL_RAW_LOG(WARNING, "%s: too many executable LOAD segments", - obj->filename); - break; - } - } - if (num_executable_load_segments == 0) { - // This object has no "r-x" LOAD segments. That's unexpected. - ABSL_RAW_LOG(WARNING, "%s: no executable LOAD segments", obj->filename); - return false; - } + for (int j = 0; j < phnum; j++) { + ElfW(Phdr) phdr; + if (!ReadFromOffsetExact(obj->fd, &phdr, sizeof(phdr), phoff)) { + ABSL_RAW_LOG(WARNING, "%s: failed to read program header %d", + obj->filename, j); + return false; + } + phoff += phentsize; + constexpr int rx = PF_X | PF_R; + if (phdr.p_type != PT_LOAD || (phdr.p_flags & rx) != rx) { + // Not a LOAD segment, or not executable code. + continue; + } + if (num_executable_load_segments < obj->phdr.size()) { + memcpy(&obj->phdr[num_executable_load_segments++], &phdr, sizeof(phdr)); + } else { + ABSL_RAW_LOG(WARNING, "%s: too many executable LOAD segments", + obj->filename); + break; + } + } + if (num_executable_load_segments == 0) { + // This object has no "r-x" LOAD segments. That's unexpected. + ABSL_RAW_LOG(WARNING, "%s: no executable LOAD segments", obj->filename); + return false; + } } return true; } @@ -1345,52 +1345,52 @@ const char *Symbolizer::GetSymbol(const void *const pc) { int fd = -1; if (obj != nullptr) { if (MaybeInitializeObjFile(obj)) { - const size_t start_addr = reinterpret_cast<size_t>(obj->start_addr); - if (obj->elf_type == ET_DYN && start_addr >= obj->offset) { + const size_t start_addr = reinterpret_cast<size_t>(obj->start_addr); + if (obj->elf_type == ET_DYN && start_addr >= obj->offset) { // This object was relocated. // // For obj->offset > 0, adjust the relocation since a mapping at offset // X in the file will have a start address of [true relocation]+X. - relocation = start_addr - obj->offset; - - // Note: some binaries have multiple "rx" LOAD segments. We must - // find the right one. - ElfW(Phdr) *phdr = nullptr; + relocation = start_addr - obj->offset; + + // Note: some binaries have multiple "rx" LOAD segments. We must + // find the right one. + ElfW(Phdr) *phdr = nullptr; for (size_t j = 0; j < obj->phdr.size(); j++) { - ElfW(Phdr) &p = obj->phdr[j]; - if (p.p_type != PT_LOAD) { - // We only expect PT_LOADs. This must be PT_NULL that we didn't - // write over (i.e. we exhausted all interesting PT_LOADs). - ABSL_RAW_CHECK(p.p_type == PT_NULL, "unexpected p_type"); - break; - } - if (pc < reinterpret_cast<void *>(start_addr + p.p_memsz)) { - phdr = &p; - break; - } - } - if (phdr == nullptr) { - // That's unexpected. Hope for the best. - ABSL_RAW_LOG( - WARNING, - "%s: unable to find LOAD segment for pc: %p, start_addr: %zx", - obj->filename, pc, start_addr); - } else { - // Adjust relocation in case phdr.p_vaddr != 0. - // This happens for binaries linked with `lld --rosegment`, and for - // binaries linked with BFD `ld -z separate-code`. - relocation -= phdr->p_vaddr - phdr->p_offset; - } + ElfW(Phdr) &p = obj->phdr[j]; + if (p.p_type != PT_LOAD) { + // We only expect PT_LOADs. This must be PT_NULL that we didn't + // write over (i.e. we exhausted all interesting PT_LOADs). + ABSL_RAW_CHECK(p.p_type == PT_NULL, "unexpected p_type"); + break; + } + if (pc < reinterpret_cast<void *>(start_addr + p.p_memsz)) { + phdr = &p; + break; + } + } + if (phdr == nullptr) { + // That's unexpected. Hope for the best. + ABSL_RAW_LOG( + WARNING, + "%s: unable to find LOAD segment for pc: %p, start_addr: %zx", + obj->filename, pc, start_addr); + } else { + // Adjust relocation in case phdr.p_vaddr != 0. + // This happens for binaries linked with `lld --rosegment`, and for + // binaries linked with BFD `ld -z separate-code`. + relocation -= phdr->p_vaddr - phdr->p_offset; + } } fd = obj->fd; - if (GetSymbolFromObjectFile(*obj, pc, relocation, symbol_buf_, - sizeof(symbol_buf_), tmp_buf_, - sizeof(tmp_buf_)) == SYMBOL_FOUND) { - // Only try to demangle the symbol name if it fit into symbol_buf_. - DemangleInplace(symbol_buf_, sizeof(symbol_buf_), tmp_buf_, - sizeof(tmp_buf_)); - } + if (GetSymbolFromObjectFile(*obj, pc, relocation, symbol_buf_, + sizeof(symbol_buf_), tmp_buf_, + sizeof(tmp_buf_)) == SYMBOL_FOUND) { + // Only try to demangle the symbol name if it fit into symbol_buf_. + DemangleInplace(symbol_buf_, sizeof(symbol_buf_), tmp_buf_, + sizeof(tmp_buf_)); + } } } else { #if ABSL_HAVE_VDSO_SUPPORT @@ -1461,7 +1461,7 @@ int InstallSymbolDecorator(SymbolDecorator decorator, void *arg) { if (!g_decorators_mu.TryLock()) { // Someone else is using decorators. Get out. - return -2; + return -2; } int ret = ticket; if (g_num_decorators >= kMaxDecorators) { @@ -1489,7 +1489,7 @@ bool RegisterFileMappingHint(const void *start, const void *end, uint64_t offset if (g_num_file_mapping_hints >= kMaxFileMappingHints) { ret = false; } else { - // TODO(ckennelly): Move this into a string copy routine. + // TODO(ckennelly): Move this into a string copy routine. int len = strlen(filename); char *dst = static_cast<char *>( base_internal::LowLevelAlloc::AllocWithArena(len + 1, SigSafeArena())); @@ -1540,7 +1540,7 @@ bool GetFileMappingHint(const void **start, const void **end, uint64_t *offset, bool Symbolize(const void *pc, char *out, int out_size) { // Symbolization is very slow under tsan. - ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN(); + ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN(); SAFE_ASSERT(out_size >= 0); debugging_internal::Symbolizer *s = debugging_internal::AllocateSymbolizer(); const char *name = s->GetSymbol(pc); @@ -1559,16 +1559,16 @@ bool Symbolize(const void *pc, char *out, int out_size) { } } debugging_internal::FreeSymbolizer(s); - ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END(); + ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END(); return ok; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl - -extern "C" bool AbslInternalGetFileMappingHint(const void **start, - const void **end, uint64_t *offset, - const char **filename) { - return absl::debugging_internal::GetFileMappingHint(start, end, offset, - filename); -} + +extern "C" bool AbslInternalGetFileMappingHint(const void **start, + const void **end, uint64_t *offset, + const char **filename) { + return absl::debugging_internal::GetFileMappingHint(start, end, offset, + filename); +} diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_unimplemented.inc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_unimplemented.inc index db24456b0a..9cafc47bcf 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_unimplemented.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_unimplemented.inc @@ -17,7 +17,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace debugging_internal { @@ -36,5 +36,5 @@ bool GetFileMappingHint(const void **, const void **, uint64_t *, const char **) void InitializeSymbolizer(const char*) {} bool Symbolize(const void *, char *, int) { return false; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_win32.inc b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_win32.inc index c3df46f606..34e23b66b7 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/symbolize_win32.inc +++ b/contrib/restricted/abseil-cpp/absl/debugging/symbolize_win32.inc @@ -31,7 +31,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN static HANDLE process = NULL; @@ -77,5 +77,5 @@ bool Symbolize(const void* pc, char* out, int out_size) { return true; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/debugging/ya.make b/contrib/restricted/abseil-cpp/absl/debugging/ya.make index 6233f05c45..d3f31965a6 100644 --- a/contrib/restricted/abseil-cpp/absl/debugging/ya.make +++ b/contrib/restricted/abseil-cpp/absl/debugging/ya.make @@ -21,10 +21,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCS( internal/address_is_readable.cc internal/elf_mem_image.cc diff --git a/contrib/restricted/abseil-cpp/absl/demangle/ya.make b/contrib/restricted/abseil-cpp/absl/demangle/ya.make index c0d04ae949..34c50317c4 100644 --- a/contrib/restricted/abseil-cpp/absl/demangle/ya.make +++ b/contrib/restricted/abseil-cpp/absl/demangle/ya.make @@ -23,10 +23,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/debugging/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.cc b/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.cc index 9f3b4a5a28..df10d6738f 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.cc @@ -1,34 +1,34 @@ -// -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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 "absl/flags/commandlineflag.h" - -#include <string> - -#include "absl/base/config.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -bool CommandLineFlag::IsRetired() const { return false; } -bool CommandLineFlag::ParseFrom(absl::string_view value, std::string* error) { - return ParseFrom(value, flags_internal::SET_FLAGS_VALUE, - flags_internal::kProgrammaticChange, *error); -} - -ABSL_NAMESPACE_END -} // namespace absl +// +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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 "absl/flags/commandlineflag.h" + +#include <string> + +#include "absl/base/config.h" +#include "absl/flags/internal/commandlineflag.h" +#include "absl/strings/string_view.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +bool CommandLineFlag::IsRetired() const { return false; } +bool CommandLineFlag::ParseFrom(absl::string_view value, std::string* error) { + return ParseFrom(value, flags_internal::SET_FLAGS_VALUE, + flags_internal::kProgrammaticChange, *error); +} + +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.h b/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.h index f2fa08977f..ef7b581b05 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.h +++ b/contrib/restricted/abseil-cpp/absl/flags/commandlineflag.h @@ -1,200 +1,200 @@ -// -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// File: commandlineflag.h -// ----------------------------------------------------------------------------- -// -// This header file defines the `CommandLineFlag`, which acts as a type-erased -// handle for accessing metadata about the Abseil Flag in question. -// -// Because an actual Abseil flag is of an unspecified type, you should not -// manipulate or interact directly with objects of that type. Instead, use the -// CommandLineFlag type as an intermediary. -#ifndef ABSL_FLAGS_COMMANDLINEFLAG_H_ -#define ABSL_FLAGS_COMMANDLINEFLAG_H_ - -#include <memory> -#include <string> - -#include "absl/base/config.h" -#include "absl/base/internal/fast_type_id.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { -class PrivateHandleAccessor; -} // namespace flags_internal - -// CommandLineFlag -// -// This type acts as a type-erased handle for an instance of an Abseil Flag and -// holds reflection information pertaining to that flag. Use CommandLineFlag to -// access a flag's name, location, help string etc. -// -// To obtain an absl::CommandLineFlag, invoke `absl::FindCommandLineFlag()` -// passing it the flag name string. -// -// Example: -// -// // Obtain reflection handle for a flag named "flagname". -// const absl::CommandLineFlag* my_flag_data = -// absl::FindCommandLineFlag("flagname"); -// -// // Now you can get flag info from that reflection handle. -// std::string flag_location = my_flag_data->Filename(); -// ... -class CommandLineFlag { - public: - constexpr CommandLineFlag() = default; - - // Not copyable/assignable. - CommandLineFlag(const CommandLineFlag&) = delete; - CommandLineFlag& operator=(const CommandLineFlag&) = delete; - - // absl::CommandLineFlag::IsOfType() - // - // Return true iff flag has type T. - template <typename T> - inline bool IsOfType() const { - return TypeId() == base_internal::FastTypeId<T>(); - } - - // absl::CommandLineFlag::TryGet() - // - // Attempts to retrieve the flag value. Returns value on success, - // absl::nullopt otherwise. - template <typename T> - absl::optional<T> TryGet() const { - if (IsRetired() || !IsOfType<T>()) { - return absl::nullopt; - } - - // Implementation notes: - // - // We are wrapping a union around the value of `T` to serve three purposes: - // - // 1. `U.value` has correct size and alignment for a value of type `T` - // 2. The `U.value` constructor is not invoked since U's constructor does - // not do it explicitly. - // 3. The `U.value` destructor is invoked since U's destructor does it - // explicitly. This makes `U` a kind of RAII wrapper around non default - // constructible value of T, which is destructed when we leave the - // scope. We do need to destroy U.value, which is constructed by - // CommandLineFlag::Read even though we left it in a moved-from state - // after std::move. - // - // All of this serves to avoid requiring `T` being default constructible. - union U { - T value; - U() {} - ~U() { value.~T(); } - }; - U u; - - Read(&u.value); - // allow retired flags to be "read", so we can report invalid access. - if (IsRetired()) { - return absl::nullopt; - } - return std::move(u.value); - } - - // absl::CommandLineFlag::Name() - // - // Returns name of this flag. - virtual absl::string_view Name() const = 0; - - // absl::CommandLineFlag::Filename() - // - // Returns name of the file where this flag is defined. - virtual std::string Filename() const = 0; - - // absl::CommandLineFlag::Help() - // - // Returns help message associated with this flag. - virtual std::string Help() const = 0; - - // absl::CommandLineFlag::IsRetired() - // - // Returns true iff this object corresponds to retired flag. - virtual bool IsRetired() const; - - // absl::CommandLineFlag::DefaultValue() - // - // Returns the default value for this flag. - virtual std::string DefaultValue() const = 0; - - // absl::CommandLineFlag::CurrentValue() - // - // Returns the current value for this flag. - virtual std::string CurrentValue() const = 0; - - // absl::CommandLineFlag::ParseFrom() - // - // Sets the value of the flag based on specified string `value`. If the flag - // was successfully set to new value, it returns true. Otherwise, sets `error` - // to indicate the error, leaves the flag unchanged, and returns false. - bool ParseFrom(absl::string_view value, std::string* error); - - protected: - ~CommandLineFlag() = default; - - private: - friend class flags_internal::PrivateHandleAccessor; - - // Sets the value of the flag based on specified string `value`. If the flag - // was successfully set to new value, it returns true. Otherwise, sets `error` - // to indicate the error, leaves the flag unchanged, and returns false. There - // are three ways to set the flag's value: - // * Update the current flag value - // * Update the flag's default value - // * Update the current flag value if it was never set before - // The mode is selected based on `set_mode` parameter. - virtual bool ParseFrom(absl::string_view value, - flags_internal::FlagSettingMode set_mode, - flags_internal::ValueSource source, - std::string& error) = 0; - - // Returns id of the flag's value type. - virtual flags_internal::FlagFastTypeId TypeId() const = 0; - - // Interface to save flag to some persistent state. Returns current flag state - // or nullptr if flag does not support saving and restoring a state. - virtual std::unique_ptr<flags_internal::FlagStateInterface> SaveState() = 0; - - // Copy-construct a new value of the flag's type in a memory referenced by - // the dst based on the current flag's value. - virtual void Read(void* dst) const = 0; - - // To be deleted. Used to return true if flag's current value originated from - // command line. - virtual bool IsSpecifiedOnCommandLine() const = 0; - - // Validates supplied value usign validator or parseflag routine - virtual bool ValidateInputValue(absl::string_view value) const = 0; - - // Checks that flags default value can be converted to string and back to the - // flag's value type. - virtual void CheckDefaultValueParsingRoundtrip() const = 0; -}; - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FLAGS_COMMANDLINEFLAG_H_ +// +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// File: commandlineflag.h +// ----------------------------------------------------------------------------- +// +// This header file defines the `CommandLineFlag`, which acts as a type-erased +// handle for accessing metadata about the Abseil Flag in question. +// +// Because an actual Abseil flag is of an unspecified type, you should not +// manipulate or interact directly with objects of that type. Instead, use the +// CommandLineFlag type as an intermediary. +#ifndef ABSL_FLAGS_COMMANDLINEFLAG_H_ +#define ABSL_FLAGS_COMMANDLINEFLAG_H_ + +#include <memory> +#include <string> + +#include "absl/base/config.h" +#include "absl/base/internal/fast_type_id.h" +#include "absl/flags/internal/commandlineflag.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace flags_internal { +class PrivateHandleAccessor; +} // namespace flags_internal + +// CommandLineFlag +// +// This type acts as a type-erased handle for an instance of an Abseil Flag and +// holds reflection information pertaining to that flag. Use CommandLineFlag to +// access a flag's name, location, help string etc. +// +// To obtain an absl::CommandLineFlag, invoke `absl::FindCommandLineFlag()` +// passing it the flag name string. +// +// Example: +// +// // Obtain reflection handle for a flag named "flagname". +// const absl::CommandLineFlag* my_flag_data = +// absl::FindCommandLineFlag("flagname"); +// +// // Now you can get flag info from that reflection handle. +// std::string flag_location = my_flag_data->Filename(); +// ... +class CommandLineFlag { + public: + constexpr CommandLineFlag() = default; + + // Not copyable/assignable. + CommandLineFlag(const CommandLineFlag&) = delete; + CommandLineFlag& operator=(const CommandLineFlag&) = delete; + + // absl::CommandLineFlag::IsOfType() + // + // Return true iff flag has type T. + template <typename T> + inline bool IsOfType() const { + return TypeId() == base_internal::FastTypeId<T>(); + } + + // absl::CommandLineFlag::TryGet() + // + // Attempts to retrieve the flag value. Returns value on success, + // absl::nullopt otherwise. + template <typename T> + absl::optional<T> TryGet() const { + if (IsRetired() || !IsOfType<T>()) { + return absl::nullopt; + } + + // Implementation notes: + // + // We are wrapping a union around the value of `T` to serve three purposes: + // + // 1. `U.value` has correct size and alignment for a value of type `T` + // 2. The `U.value` constructor is not invoked since U's constructor does + // not do it explicitly. + // 3. The `U.value` destructor is invoked since U's destructor does it + // explicitly. This makes `U` a kind of RAII wrapper around non default + // constructible value of T, which is destructed when we leave the + // scope. We do need to destroy U.value, which is constructed by + // CommandLineFlag::Read even though we left it in a moved-from state + // after std::move. + // + // All of this serves to avoid requiring `T` being default constructible. + union U { + T value; + U() {} + ~U() { value.~T(); } + }; + U u; + + Read(&u.value); + // allow retired flags to be "read", so we can report invalid access. + if (IsRetired()) { + return absl::nullopt; + } + return std::move(u.value); + } + + // absl::CommandLineFlag::Name() + // + // Returns name of this flag. + virtual absl::string_view Name() const = 0; + + // absl::CommandLineFlag::Filename() + // + // Returns name of the file where this flag is defined. + virtual std::string Filename() const = 0; + + // absl::CommandLineFlag::Help() + // + // Returns help message associated with this flag. + virtual std::string Help() const = 0; + + // absl::CommandLineFlag::IsRetired() + // + // Returns true iff this object corresponds to retired flag. + virtual bool IsRetired() const; + + // absl::CommandLineFlag::DefaultValue() + // + // Returns the default value for this flag. + virtual std::string DefaultValue() const = 0; + + // absl::CommandLineFlag::CurrentValue() + // + // Returns the current value for this flag. + virtual std::string CurrentValue() const = 0; + + // absl::CommandLineFlag::ParseFrom() + // + // Sets the value of the flag based on specified string `value`. If the flag + // was successfully set to new value, it returns true. Otherwise, sets `error` + // to indicate the error, leaves the flag unchanged, and returns false. + bool ParseFrom(absl::string_view value, std::string* error); + + protected: + ~CommandLineFlag() = default; + + private: + friend class flags_internal::PrivateHandleAccessor; + + // Sets the value of the flag based on specified string `value`. If the flag + // was successfully set to new value, it returns true. Otherwise, sets `error` + // to indicate the error, leaves the flag unchanged, and returns false. There + // are three ways to set the flag's value: + // * Update the current flag value + // * Update the flag's default value + // * Update the current flag value if it was never set before + // The mode is selected based on `set_mode` parameter. + virtual bool ParseFrom(absl::string_view value, + flags_internal::FlagSettingMode set_mode, + flags_internal::ValueSource source, + std::string& error) = 0; + + // Returns id of the flag's value type. + virtual flags_internal::FlagFastTypeId TypeId() const = 0; + + // Interface to save flag to some persistent state. Returns current flag state + // or nullptr if flag does not support saving and restoring a state. + virtual std::unique_ptr<flags_internal::FlagStateInterface> SaveState() = 0; + + // Copy-construct a new value of the flag's type in a memory referenced by + // the dst based on the current flag's value. + virtual void Read(void* dst) const = 0; + + // To be deleted. Used to return true if flag's current value originated from + // command line. + virtual bool IsSpecifiedOnCommandLine() const = 0; + + // Validates supplied value usign validator or parseflag routine + virtual bool ValidateInputValue(absl::string_view value) const = 0; + + // Checks that flags default value can be converted to string and back to the + // flag's value type. + virtual void CheckDefaultValueParsingRoundtrip() const = 0; +}; + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_FLAGS_COMMANDLINEFLAG_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/config.h b/contrib/restricted/abseil-cpp/absl/flags/config.h index 5ab1f311dc..2d575b2959 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/config.h +++ b/contrib/restricted/abseil-cpp/absl/flags/config.h @@ -45,32 +45,32 @@ #define ABSL_FLAGS_STRIP_HELP ABSL_FLAGS_STRIP_NAMES #endif -// ABSL_FLAGS_INTERNAL_HAS_RTTI macro is used for selecting if we can use RTTI -// for flag type identification. -#ifdef ABSL_FLAGS_INTERNAL_HAS_RTTI -#error ABSL_FLAGS_INTERNAL_HAS_RTTI cannot be directly set -#elif !defined(__GNUC__) || defined(__GXX_RTTI) -#define ABSL_FLAGS_INTERNAL_HAS_RTTI 1 -#endif // !defined(__GNUC__) || defined(__GXX_RTTI) - -// These macros represent the "source of truth" for the list of supported -// built-in types. -#define ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(A) \ - A(bool, bool) \ - A(short, short) \ - A(unsigned short, unsigned_short) \ - A(int, int) \ - A(unsigned int, unsigned_int) \ - A(long, long) \ - A(unsigned long, unsigned_long) \ - A(long long, long_long) \ - A(unsigned long long, unsigned_long_long) \ - A(double, double) \ - A(float, float) - -#define ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(A) \ - ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(A) \ - A(std::string, std_string) \ - A(std::vector<std::string>, std_vector_of_string) - +// ABSL_FLAGS_INTERNAL_HAS_RTTI macro is used for selecting if we can use RTTI +// for flag type identification. +#ifdef ABSL_FLAGS_INTERNAL_HAS_RTTI +#error ABSL_FLAGS_INTERNAL_HAS_RTTI cannot be directly set +#elif !defined(__GNUC__) || defined(__GXX_RTTI) +#define ABSL_FLAGS_INTERNAL_HAS_RTTI 1 +#endif // !defined(__GNUC__) || defined(__GXX_RTTI) + +// These macros represent the "source of truth" for the list of supported +// built-in types. +#define ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(A) \ + A(bool, bool) \ + A(short, short) \ + A(unsigned short, unsigned_short) \ + A(int, int) \ + A(unsigned int, unsigned_int) \ + A(long, long) \ + A(unsigned long, unsigned_long) \ + A(long long, long_long) \ + A(unsigned long long, unsigned_long_long) \ + A(double, double) \ + A(float, float) + +#define ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(A) \ + ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(A) \ + A(std::string, std_string) \ + A(std::vector<std::string>, std_vector_of_string) + #endif // ABSL_FLAGS_CONFIG_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/declare.h b/contrib/restricted/abseil-cpp/absl/flags/declare.h index b9794d8b85..32592e23be 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/declare.h +++ b/contrib/restricted/abseil-cpp/absl/flags/declare.h @@ -25,10 +25,10 @@ #ifndef ABSL_FLAGS_DECLARE_H_ #define ABSL_FLAGS_DECLARE_H_ -#include "absl/base/config.h" +#include "absl/base/config.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { // absl::Flag<T> represents a flag of type 'T' created by ABSL_FLAG. @@ -48,7 +48,7 @@ template <typename T> using Flag = flags_internal::Flag<T>; #endif -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl // ABSL_DECLARE_FLAG() diff --git a/contrib/restricted/abseil-cpp/absl/flags/flag.cc b/contrib/restricted/abseil-cpp/absl/flags/flag.cc index 531df1287a..4dc26f2e9e 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/flag.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/flag.cc @@ -15,12 +15,12 @@ #include "absl/flags/flag.h" -#include "absl/base/config.h" +#include "absl/base/config.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN -// This global mutex protects on-demand construction of flag objects in MSVC +// This global mutex protects on-demand construction of flag objects in MSVC // builds. #if defined(_MSC_VER) && !defined(__clang__) @@ -34,5 +34,5 @@ absl::Mutex* GetGlobalConstructionGuard() { return &construction_guard; } #endif -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/flags/flag.h b/contrib/restricted/abseil-cpp/absl/flags/flag.h index a724ccc97d..0b31ea9b02 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/flag.h +++ b/contrib/restricted/abseil-cpp/absl/flags/flag.h @@ -29,19 +29,19 @@ #ifndef ABSL_FLAGS_FLAG_H_ #define ABSL_FLAGS_FLAG_H_ -#include <string> -#include <type_traits> - +#include <string> +#include <type_traits> + #include "absl/base/attributes.h" -#include "absl/base/config.h" -#include "absl/base/optimization.h" +#include "absl/base/config.h" +#include "absl/base/optimization.h" #include "absl/flags/config.h" #include "absl/flags/internal/flag.h" -#include "absl/flags/internal/registry.h" -#include "absl/strings/string_view.h" +#include "absl/flags/internal/registry.h" +#include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // Flag // @@ -92,7 +92,7 @@ using Flag = flags_internal::Flag<T>; // std::string first_name = absl::GetFlag(FLAGS_firstname); template <typename T> ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) { - return flags_internal::FlagImplPeer::InvokeGet<T>(flag); + return flags_internal::FlagImplPeer::InvokeGet<T>(flag); } // SetFlag() @@ -104,7 +104,7 @@ ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag) { // but especially within performance-critical code. template <typename T> void SetFlag(absl::Flag<T>* flag, const T& v) { - flags_internal::FlagImplPeer::InvokeSet(*flag, v); + flags_internal::FlagImplPeer::InvokeSet(*flag, v); } // Overload of `SetFlag()` to allow callers to pass in a value that is @@ -113,25 +113,25 @@ void SetFlag(absl::Flag<T>* flag, const T& v) { template <typename T, typename V> void SetFlag(absl::Flag<T>* flag, const V& v) { T value(v); - flags_internal::FlagImplPeer::InvokeSet(*flag, value); -} - -// GetFlagReflectionHandle() -// -// Returns the reflection handle corresponding to specified Abseil Flag -// instance. Use this handle to access flag's reflection information, like name, -// location, default value etc. -// -// Example: -// -// std::string = absl::GetFlagReflectionHandle(FLAGS_count).DefaultValue(); - -template <typename T> -const CommandLineFlag& GetFlagReflectionHandle(const absl::Flag<T>& f) { - return flags_internal::FlagImplPeer::InvokeReflect(f); + flags_internal::FlagImplPeer::InvokeSet(*flag, value); } -ABSL_NAMESPACE_END +// GetFlagReflectionHandle() +// +// Returns the reflection handle corresponding to specified Abseil Flag +// instance. Use this handle to access flag's reflection information, like name, +// location, default value etc. +// +// Example: +// +// std::string = absl::GetFlagReflectionHandle(FLAGS_count).DefaultValue(); + +template <typename T> +const CommandLineFlag& GetFlagReflectionHandle(const absl::Flag<T>& f) { + return flags_internal::FlagImplPeer::InvokeReflect(f); +} + +ABSL_NAMESPACE_END } // namespace absl @@ -192,18 +192,18 @@ ABSL_NAMESPACE_END // ----------------------------------------------------------------------------- // ABSL_FLAG_IMPL macro definition conditional on ABSL_FLAGS_STRIP_NAMES -#if !defined(_MSC_VER) || defined(__clang__) -#define ABSL_FLAG_IMPL_FLAG_PTR(flag) flag -#define ABSL_FLAG_IMPL_HELP_ARG(name) \ - absl::flags_internal::HelpArg<AbslFlagHelpGenFor##name>( \ - FLAGS_help_storage_##name) -#define ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name) \ - absl::flags_internal::DefaultArg<Type, AbslFlagDefaultGenFor##name>(0) -#else -#define ABSL_FLAG_IMPL_FLAG_PTR(flag) flag.GetImpl() -#define ABSL_FLAG_IMPL_HELP_ARG(name) &AbslFlagHelpGenFor##name::NonConst -#define ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name) &AbslFlagDefaultGenFor##name::Gen -#endif +#if !defined(_MSC_VER) || defined(__clang__) +#define ABSL_FLAG_IMPL_FLAG_PTR(flag) flag +#define ABSL_FLAG_IMPL_HELP_ARG(name) \ + absl::flags_internal::HelpArg<AbslFlagHelpGenFor##name>( \ + FLAGS_help_storage_##name) +#define ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name) \ + absl::flags_internal::DefaultArg<Type, AbslFlagDefaultGenFor##name>(0) +#else +#define ABSL_FLAG_IMPL_FLAG_PTR(flag) flag.GetImpl() +#define ABSL_FLAG_IMPL_HELP_ARG(name) &AbslFlagHelpGenFor##name::NonConst +#define ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name) &AbslFlagDefaultGenFor##name::Gen +#endif #if ABSL_FLAGS_STRIP_NAMES #define ABSL_FLAG_IMPL_FLAGNAME(txt) "" @@ -232,48 +232,48 @@ ABSL_NAMESPACE_END // between the two via the call to HelpArg in absl::Flag instantiation below. // If help message expression is constexpr evaluable compiler will optimize // away this whole struct. -// TODO(rogeeff): place these generated structs into local namespace and apply -// ABSL_INTERNAL_UNIQUE_SHORT_NAME. -// TODO(rogeeff): Apply __attribute__((nodebug)) to FLAGS_help_storage_##name -#define ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, txt) \ - struct AbslFlagHelpGenFor##name { \ - /* The expression is run in the caller as part of the */ \ - /* default value argument. That keeps temporaries alive */ \ - /* long enough for NonConst to work correctly. */ \ - static constexpr absl::string_view Value( \ +// TODO(rogeeff): place these generated structs into local namespace and apply +// ABSL_INTERNAL_UNIQUE_SHORT_NAME. +// TODO(rogeeff): Apply __attribute__((nodebug)) to FLAGS_help_storage_##name +#define ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, txt) \ + struct AbslFlagHelpGenFor##name { \ + /* The expression is run in the caller as part of the */ \ + /* default value argument. That keeps temporaries alive */ \ + /* long enough for NonConst to work correctly. */ \ + static constexpr absl::string_view Value( \ absl::string_view absl_flag_help = ABSL_FLAG_IMPL_FLAGHELP(txt)) { \ return absl_flag_help; \ - } \ - static std::string NonConst() { return std::string(Value()); } \ - }; \ - constexpr auto FLAGS_help_storage_##name ABSL_INTERNAL_UNIQUE_SMALL_NAME() \ - ABSL_ATTRIBUTE_SECTION_VARIABLE(flags_help_cold) = \ - absl::flags_internal::HelpStringAsArray<AbslFlagHelpGenFor##name>( \ - 0); + } \ + static std::string NonConst() { return std::string(Value()); } \ + }; \ + constexpr auto FLAGS_help_storage_##name ABSL_INTERNAL_UNIQUE_SMALL_NAME() \ + ABSL_ATTRIBUTE_SECTION_VARIABLE(flags_help_cold) = \ + absl::flags_internal::HelpStringAsArray<AbslFlagHelpGenFor##name>( \ + 0); -#define ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \ - struct AbslFlagDefaultGenFor##name { \ - Type value = absl::flags_internal::InitDefaultValue<Type>(default_value); \ +#define ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \ + struct AbslFlagDefaultGenFor##name { \ + Type value = absl::flags_internal::InitDefaultValue<Type>(default_value); \ static void Gen(void* absl_flag_default_loc) { \ new (absl_flag_default_loc) Type(AbslFlagDefaultGenFor##name{}.value); \ - } \ - }; + } \ + }; // ABSL_FLAG_IMPL // // Note: Name of registrar object is not arbitrary. It is used to "grab" // global name for FLAGS_no<flag_name> symbol, thus preventing the possibility // of defining two flags with names foo and nofoo. -#define ABSL_FLAG_IMPL(Type, name, default_value, help) \ - namespace absl /* block flags in namespaces */ {} \ - ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \ - ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help) \ - ABSL_CONST_INIT absl::Flag<Type> FLAGS_##name{ \ - ABSL_FLAG_IMPL_FLAGNAME(#name), ABSL_FLAG_IMPL_FILENAME(), \ - ABSL_FLAG_IMPL_HELP_ARG(name), ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name)}; \ - extern absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name; \ - absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name = \ - ABSL_FLAG_IMPL_REGISTRAR(Type, FLAGS_##name) +#define ABSL_FLAG_IMPL(Type, name, default_value, help) \ + namespace absl /* block flags in namespaces */ {} \ + ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \ + ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help) \ + ABSL_CONST_INIT absl::Flag<Type> FLAGS_##name{ \ + ABSL_FLAG_IMPL_FLAGNAME(#name), ABSL_FLAG_IMPL_FILENAME(), \ + ABSL_FLAG_IMPL_HELP_ARG(name), ABSL_FLAG_IMPL_DEFAULT_ARG(Type, name)}; \ + extern absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name; \ + absl::flags_internal::FlagRegistrarEmpty FLAGS_no##name = \ + ABSL_FLAG_IMPL_REGISTRAR(Type, FLAGS_##name) // ABSL_RETIRED_FLAG // @@ -294,12 +294,12 @@ ABSL_NAMESPACE_END // // `default_value` is only used as a double check on the type. `explanation` is // unused. -// TODO(rogeeff): replace RETIRED_FLAGS with FLAGS once forward declarations of -// retired flags are cleaned up. -#define ABSL_RETIRED_FLAG(type, name, default_value, explanation) \ - static absl::flags_internal::RetiredFlag<type> RETIRED_FLAGS_##name; \ - ABSL_ATTRIBUTE_UNUSED static const auto RETIRED_FLAGS_REG_##name = \ - (RETIRED_FLAGS_##name.Retire(#name), \ - ::absl::flags_internal::FlagRegistrarEmpty{}) +// TODO(rogeeff): replace RETIRED_FLAGS with FLAGS once forward declarations of +// retired flags are cleaned up. +#define ABSL_RETIRED_FLAG(type, name, default_value, explanation) \ + static absl::flags_internal::RetiredFlag<type> RETIRED_FLAGS_##name; \ + ABSL_ATTRIBUTE_UNUSED static const auto RETIRED_FLAGS_REG_##name = \ + (RETIRED_FLAGS_##name.Retire(#name), \ + ::absl::flags_internal::FlagRegistrarEmpty{}) #endif // ABSL_FLAGS_FLAG_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag.cc b/contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag.cc index 4482955c4c..3c32c17d0b 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag.cc @@ -1,5 +1,5 @@ // -// Copyright 2020 The Abseil Authors. +// Copyright 2020 The Abseil Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,11 +16,11 @@ #include "absl/flags/internal/commandlineflag.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { -FlagStateInterface::~FlagStateInterface() {} +FlagStateInterface::~FlagStateInterface() {} } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag.h b/contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag.h index ebfe81ba1e..a97117b6d5 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag.h +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag.h @@ -16,19 +16,19 @@ #ifndef ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_ #define ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_ -#include "absl/base/config.h" -#include "absl/base/internal/fast_type_id.h" +#include "absl/base/config.h" +#include "absl/base/internal/fast_type_id.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { -// An alias for flag fast type id. This value identifies the flag value type +// An alias for flag fast type id. This value identifies the flag value type // similarly to typeid(T), without relying on RTTI being available. In most -// cases this id is enough to uniquely identify the flag's value type. In a few -// cases we'll have to resort to using actual RTTI implementation if it is -// available. -using FlagFastTypeId = absl::base_internal::FastTypeIdType; +// cases this id is enough to uniquely identify the flag's value type. In a few +// cases we'll have to resort to using actual RTTI implementation if it is +// available. +using FlagFastTypeId = absl::base_internal::FastTypeIdType; // Options that control SetCommandLineOptionWithMode. enum FlagSettingMode { @@ -43,7 +43,7 @@ enum FlagSettingMode { SET_FLAGS_DEFAULT }; -// Options that control ParseFrom: Source of a value. +// Options that control ParseFrom: Source of a value. enum ValueSource { // Flag is being set by value specified on a command line. kCommandLine, @@ -55,14 +55,14 @@ enum ValueSource { // of a flag produced this flag state from method CommandLineFlag::SaveState(). class FlagStateInterface { public: - virtual ~FlagStateInterface(); + virtual ~FlagStateInterface(); // Restores the flag originated this object to the saved state. virtual void Restore() const = 0; }; } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag/ya.make b/contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag/ya.make index e5a0389d4d..6dde2c9c9c 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag/ya.make @@ -16,10 +16,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/flags/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc index 1515022d11..e6c1f96e8e 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.cc @@ -15,162 +15,162 @@ #include "absl/flags/internal/flag.h" -#include <assert.h> -#include <stddef.h> -#include <stdint.h> -#include <string.h> - -#include <array> -#include <atomic> -#include <memory> -#include <new> -#include <string> -#include <typeinfo> - -#include "absl/base/call_once.h" -#include "absl/base/casts.h" -#include "absl/base/config.h" +#include <assert.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +#include <array> +#include <atomic> +#include <memory> +#include <new> +#include <string> +#include <typeinfo> + +#include "absl/base/call_once.h" +#include "absl/base/casts.h" +#include "absl/base/config.h" #include "absl/base/optimization.h" -#include "absl/flags/config.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/flags/usage_config.h" -#include "absl/memory/memory.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" +#include "absl/flags/config.h" +#include "absl/flags/internal/commandlineflag.h" +#include "absl/flags/usage_config.h" +#include "absl/memory/memory.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { - -// The help message indicating that the commandline flag has been -// 'stripped'. It will not show up when doing "-help" and its -// variants. The flag is stripped if ABSL_FLAGS_STRIP_HELP is set to 1 -// before including absl/flags/flag.h -const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001"; - + +// The help message indicating that the commandline flag has been +// 'stripped'. It will not show up when doing "-help" and its +// variants. The flag is stripped if ABSL_FLAGS_STRIP_HELP is set to 1 +// before including absl/flags/flag.h +const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001"; + namespace { // Currently we only validate flag values for user-defined flag types. -bool ShouldValidateFlagValue(FlagFastTypeId flag_type_id) { -#define DONT_VALIDATE(T, _) \ - if (flag_type_id == base_internal::FastTypeId<T>()) return false; - ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(DONT_VALIDATE) +bool ShouldValidateFlagValue(FlagFastTypeId flag_type_id) { +#define DONT_VALIDATE(T, _) \ + if (flag_type_id == base_internal::FastTypeId<T>()) return false; + ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(DONT_VALIDATE) #undef DONT_VALIDATE return true; } -// RAII helper used to temporarily unlock and relock `absl::Mutex`. -// This is used when we need to ensure that locks are released while -// invoking user supplied callbacks and then reacquired, since callbacks may -// need to acquire these locks themselves. -class MutexRelock { - public: - explicit MutexRelock(absl::Mutex& mu) : mu_(mu) { mu_.Unlock(); } - ~MutexRelock() { mu_.Lock(); } - - MutexRelock(const MutexRelock&) = delete; - MutexRelock& operator=(const MutexRelock&) = delete; - - private: - absl::Mutex& mu_; -}; - +// RAII helper used to temporarily unlock and relock `absl::Mutex`. +// This is used when we need to ensure that locks are released while +// invoking user supplied callbacks and then reacquired, since callbacks may +// need to acquire these locks themselves. +class MutexRelock { + public: + explicit MutexRelock(absl::Mutex& mu) : mu_(mu) { mu_.Unlock(); } + ~MutexRelock() { mu_.Lock(); } + + MutexRelock(const MutexRelock&) = delete; + MutexRelock& operator=(const MutexRelock&) = delete; + + private: + absl::Mutex& mu_; +}; + } // namespace -/////////////////////////////////////////////////////////////////////////////// -// Persistent state of the flag data. - -class FlagImpl; - -class FlagState : public flags_internal::FlagStateInterface { - public: - template <typename V> - FlagState(FlagImpl& flag_impl, const V& v, bool modified, - bool on_command_line, int64_t counter) - : flag_impl_(flag_impl), - value_(v), - modified_(modified), - on_command_line_(on_command_line), - counter_(counter) {} - - ~FlagState() override { +/////////////////////////////////////////////////////////////////////////////// +// Persistent state of the flag data. + +class FlagImpl; + +class FlagState : public flags_internal::FlagStateInterface { + public: + template <typename V> + FlagState(FlagImpl& flag_impl, const V& v, bool modified, + bool on_command_line, int64_t counter) + : flag_impl_(flag_impl), + value_(v), + modified_(modified), + on_command_line_(on_command_line), + counter_(counter) {} + + ~FlagState() override { if (flag_impl_.ValueStorageKind() != FlagValueStorageKind::kAlignedBuffer && flag_impl_.ValueStorageKind() != FlagValueStorageKind::kSequenceLocked) - return; - flags_internal::Delete(flag_impl_.op_, value_.heap_allocated); + return; + flags_internal::Delete(flag_impl_.op_, value_.heap_allocated); } - private: - friend class FlagImpl; - - // Restores the flag to the saved state. - void Restore() const override { - if (!flag_impl_.RestoreState(*this)) return; + private: + friend class FlagImpl; - ABSL_INTERNAL_LOG(INFO, - absl::StrCat("Restore saved value of ", flag_impl_.Name(), - " to: ", flag_impl_.CurrentValue())); + // Restores the flag to the saved state. + void Restore() const override { + if (!flag_impl_.RestoreState(*this)) return; + + ABSL_INTERNAL_LOG(INFO, + absl::StrCat("Restore saved value of ", flag_impl_.Name(), + " to: ", flag_impl_.CurrentValue())); } - - // Flag and saved flag data. - FlagImpl& flag_impl_; - union SavedValue { - explicit SavedValue(void* v) : heap_allocated(v) {} - explicit SavedValue(int64_t v) : one_word(v) {} - - void* heap_allocated; - int64_t one_word; - } value_; - bool modified_; - bool on_command_line_; - int64_t counter_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Flag implementation, which does not depend on flag value type. - -DynValueDeleter::DynValueDeleter(FlagOpFn op_arg) : op(op_arg) {} - -void DynValueDeleter::operator()(void* ptr) const { - if (op == nullptr) return; - - Delete(op, ptr); + + // Flag and saved flag data. + FlagImpl& flag_impl_; + union SavedValue { + explicit SavedValue(void* v) : heap_allocated(v) {} + explicit SavedValue(int64_t v) : one_word(v) {} + + void* heap_allocated; + int64_t one_word; + } value_; + bool modified_; + bool on_command_line_; + int64_t counter_; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Flag implementation, which does not depend on flag value type. + +DynValueDeleter::DynValueDeleter(FlagOpFn op_arg) : op(op_arg) {} + +void DynValueDeleter::operator()(void* ptr) const { + if (op == nullptr) return; + + Delete(op, ptr); } -void FlagImpl::Init() { - new (&data_guard_) absl::Mutex; - - auto def_kind = static_cast<FlagDefaultKind>(def_kind_); - - switch (ValueStorageKind()) { +void FlagImpl::Init() { + new (&data_guard_) absl::Mutex; + + auto def_kind = static_cast<FlagDefaultKind>(def_kind_); + + switch (ValueStorageKind()) { case FlagValueStorageKind::kValueAndInitBit: - case FlagValueStorageKind::kOneWordAtomic: { - alignas(int64_t) std::array<char, sizeof(int64_t)> buf{}; - if (def_kind == FlagDefaultKind::kGenFunc) { - (*default_value_.gen_func)(buf.data()); - } else { - assert(def_kind != FlagDefaultKind::kDynamicValue); - std::memcpy(buf.data(), &default_value_, Sizeof(op_)); - } + case FlagValueStorageKind::kOneWordAtomic: { + alignas(int64_t) std::array<char, sizeof(int64_t)> buf{}; + if (def_kind == FlagDefaultKind::kGenFunc) { + (*default_value_.gen_func)(buf.data()); + } else { + assert(def_kind != FlagDefaultKind::kDynamicValue); + std::memcpy(buf.data(), &default_value_, Sizeof(op_)); + } if (ValueStorageKind() == FlagValueStorageKind::kValueAndInitBit) { // We presume here the memory layout of FlagValueAndInitBit struct. uint8_t initialized = 1; std::memcpy(buf.data() + Sizeof(op_), &initialized, sizeof(initialized)); } - OneWordValue().store(absl::bit_cast<int64_t>(buf), - std::memory_order_release); - break; - } + OneWordValue().store(absl::bit_cast<int64_t>(buf), + std::memory_order_release); + break; + } case FlagValueStorageKind::kSequenceLocked: { - // For this storage kind the default_value_ always points to gen_func - // during initialization. - assert(def_kind == FlagDefaultKind::kGenFunc); + // For this storage kind the default_value_ always points to gen_func + // during initialization. + assert(def_kind == FlagDefaultKind::kGenFunc); (*default_value_.gen_func)(AtomicBufferValue()); - break; - } + break; + } case FlagValueStorageKind::kAlignedBuffer: // For this storage kind the default_value_ always points to gen_func // during initialization. @@ -179,95 +179,95 @@ void FlagImpl::Init() { break; } seq_lock_.MarkInitialized(); +} + +absl::Mutex* FlagImpl::DataGuard() const { + absl::call_once(const_cast<FlagImpl*>(this)->init_control_, &FlagImpl::Init, + const_cast<FlagImpl*>(this)); + + // data_guard_ is initialized inside Init. + return reinterpret_cast<absl::Mutex*>(&data_guard_); } -absl::Mutex* FlagImpl::DataGuard() const { - absl::call_once(const_cast<FlagImpl*>(this)->init_control_, &FlagImpl::Init, - const_cast<FlagImpl*>(this)); - - // data_guard_ is initialized inside Init. - return reinterpret_cast<absl::Mutex*>(&data_guard_); -} - -void FlagImpl::AssertValidType(FlagFastTypeId rhs_type_id, - const std::type_info* (*gen_rtti)()) const { - FlagFastTypeId lhs_type_id = flags_internal::FastTypeId(op_); - - // `rhs_type_id` is the fast type id corresponding to the declaration - // visibile at the call site. `lhs_type_id` is the fast type id - // corresponding to the type specified in flag definition. They must match - // for this operation to be well-defined. - if (ABSL_PREDICT_TRUE(lhs_type_id == rhs_type_id)) return; - - const std::type_info* lhs_runtime_type_id = - flags_internal::RuntimeTypeId(op_); - const std::type_info* rhs_runtime_type_id = (*gen_rtti)(); - - if (lhs_runtime_type_id == rhs_runtime_type_id) return; - -#if defined(ABSL_FLAGS_INTERNAL_HAS_RTTI) - if (*lhs_runtime_type_id == *rhs_runtime_type_id) return; -#endif - - ABSL_INTERNAL_LOG( - FATAL, absl::StrCat("Flag '", Name(), - "' is defined as one type and declared as another")); -} - -std::unique_ptr<void, DynValueDeleter> FlagImpl::MakeInitValue() const { - void* res = nullptr; - switch (DefaultKind()) { - case FlagDefaultKind::kDynamicValue: - res = flags_internal::Clone(op_, default_value_.dynamic_value); - break; - case FlagDefaultKind::kGenFunc: - res = flags_internal::Alloc(op_); - (*default_value_.gen_func)(res); - break; - default: - res = flags_internal::Clone(op_, &default_value_); - break; +void FlagImpl::AssertValidType(FlagFastTypeId rhs_type_id, + const std::type_info* (*gen_rtti)()) const { + FlagFastTypeId lhs_type_id = flags_internal::FastTypeId(op_); + + // `rhs_type_id` is the fast type id corresponding to the declaration + // visibile at the call site. `lhs_type_id` is the fast type id + // corresponding to the type specified in flag definition. They must match + // for this operation to be well-defined. + if (ABSL_PREDICT_TRUE(lhs_type_id == rhs_type_id)) return; + + const std::type_info* lhs_runtime_type_id = + flags_internal::RuntimeTypeId(op_); + const std::type_info* rhs_runtime_type_id = (*gen_rtti)(); + + if (lhs_runtime_type_id == rhs_runtime_type_id) return; + +#if defined(ABSL_FLAGS_INTERNAL_HAS_RTTI) + if (*lhs_runtime_type_id == *rhs_runtime_type_id) return; +#endif + + ABSL_INTERNAL_LOG( + FATAL, absl::StrCat("Flag '", Name(), + "' is defined as one type and declared as another")); +} + +std::unique_ptr<void, DynValueDeleter> FlagImpl::MakeInitValue() const { + void* res = nullptr; + switch (DefaultKind()) { + case FlagDefaultKind::kDynamicValue: + res = flags_internal::Clone(op_, default_value_.dynamic_value); + break; + case FlagDefaultKind::kGenFunc: + res = flags_internal::Alloc(op_); + (*default_value_.gen_func)(res); + break; + default: + res = flags_internal::Clone(op_, &default_value_); + break; } - return {res, DynValueDeleter{op_}}; -} + return {res, DynValueDeleter{op_}}; +} -void FlagImpl::StoreValue(const void* src) { - switch (ValueStorageKind()) { +void FlagImpl::StoreValue(const void* src) { + switch (ValueStorageKind()) { case FlagValueStorageKind::kValueAndInitBit: - case FlagValueStorageKind::kOneWordAtomic: { + case FlagValueStorageKind::kOneWordAtomic: { // Load the current value to avoid setting 'init' bit manualy. int64_t one_word_val = OneWordValue().load(std::memory_order_acquire); - std::memcpy(&one_word_val, src, Sizeof(op_)); - OneWordValue().store(one_word_val, std::memory_order_release); + std::memcpy(&one_word_val, src, Sizeof(op_)); + OneWordValue().store(one_word_val, std::memory_order_release); seq_lock_.IncrementModificationCount(); - break; - } + break; + } case FlagValueStorageKind::kSequenceLocked: { seq_lock_.Write(AtomicBufferValue(), src, Sizeof(op_)); - break; - } + break; + } case FlagValueStorageKind::kAlignedBuffer: Copy(op_, src, AlignedBufferValue()); seq_lock_.IncrementModificationCount(); break; - } - modified_ = true; - InvokeCallback(); -} - -absl::string_view FlagImpl::Name() const { return name_; } - -std::string FlagImpl::Filename() const { - return flags_internal::GetUsageConfig().normalize_filename(filename_); + } + modified_ = true; + InvokeCallback(); } +absl::string_view FlagImpl::Name() const { return name_; } + +std::string FlagImpl::Filename() const { + return flags_internal::GetUsageConfig().normalize_filename(filename_); +} + std::string FlagImpl::Help() const { - return HelpSourceKind() == FlagHelpKind::kLiteral ? help_.literal - : help_.gen_func(); + return HelpSourceKind() == FlagHelpKind::kLiteral ? help_.literal + : help_.gen_func(); } -FlagFastTypeId FlagImpl::TypeId() const { - return flags_internal::FastTypeId(op_); +FlagFastTypeId FlagImpl::TypeId() const { + return flags_internal::FastTypeId(op_); } int64_t FlagImpl::ModificationCount() const { @@ -282,53 +282,53 @@ bool FlagImpl::IsSpecifiedOnCommandLine() const { std::string FlagImpl::DefaultValue() const { absl::MutexLock l(DataGuard()); - auto obj = MakeInitValue(); - return flags_internal::Unparse(op_, obj.get()); + auto obj = MakeInitValue(); + return flags_internal::Unparse(op_, obj.get()); } std::string FlagImpl::CurrentValue() const { - auto* guard = DataGuard(); // Make sure flag initialized - switch (ValueStorageKind()) { + auto* guard = DataGuard(); // Make sure flag initialized + switch (ValueStorageKind()) { case FlagValueStorageKind::kValueAndInitBit: - case FlagValueStorageKind::kOneWordAtomic: { - const auto one_word_val = - absl::bit_cast<std::array<char, sizeof(int64_t)>>( - OneWordValue().load(std::memory_order_acquire)); - return flags_internal::Unparse(op_, one_word_val.data()); - } + case FlagValueStorageKind::kOneWordAtomic: { + const auto one_word_val = + absl::bit_cast<std::array<char, sizeof(int64_t)>>( + OneWordValue().load(std::memory_order_acquire)); + return flags_internal::Unparse(op_, one_word_val.data()); + } case FlagValueStorageKind::kSequenceLocked: { std::unique_ptr<void, DynValueDeleter> cloned(flags_internal::Alloc(op_), DynValueDeleter{op_}); ReadSequenceLockedData(cloned.get()); return flags_internal::Unparse(op_, cloned.get()); - } + } case FlagValueStorageKind::kAlignedBuffer: { absl::MutexLock l(guard); return flags_internal::Unparse(op_, AlignedBufferValue()); } - } + } - return ""; + return ""; } -void FlagImpl::SetCallback(const FlagCallbackFunc mutation_callback) { +void FlagImpl::SetCallback(const FlagCallbackFunc mutation_callback) { absl::MutexLock l(DataGuard()); - if (callback_ == nullptr) { - callback_ = new FlagCallback; - } - callback_->func = mutation_callback; + if (callback_ == nullptr) { + callback_ = new FlagCallback; + } + callback_->func = mutation_callback; InvokeCallback(); } -void FlagImpl::InvokeCallback() const { +void FlagImpl::InvokeCallback() const { if (!callback_) return; - // Make a copy of the C-style function pointer that we are about to invoke - // before we release the lock guarding it. - FlagCallbackFunc cb = callback_->func; - + // Make a copy of the C-style function pointer that we are about to invoke + // before we release the lock guarding it. + FlagCallbackFunc cb = callback_->func; + // If the flag has a mutation callback this function invokes it. While the // callback is being invoked the primary flag's mutex is unlocked and it is // re-locked back after call to callback is completed. Callback invocation is @@ -340,23 +340,23 @@ void FlagImpl::InvokeCallback() const { // and it also can be different by the time the callback invocation is // completed. Requires that *primary_lock be held in exclusive mode; it may be // released and reacquired by the implementation. - MutexRelock relock(*DataGuard()); - absl::MutexLock lock(&callback_->guard); - cb(); -} - -std::unique_ptr<FlagStateInterface> FlagImpl::SaveState() { - absl::MutexLock l(DataGuard()); - - bool modified = modified_; - bool on_command_line = on_command_line_; - switch (ValueStorageKind()) { + MutexRelock relock(*DataGuard()); + absl::MutexLock lock(&callback_->guard); + cb(); +} + +std::unique_ptr<FlagStateInterface> FlagImpl::SaveState() { + absl::MutexLock l(DataGuard()); + + bool modified = modified_; + bool on_command_line = on_command_line_; + switch (ValueStorageKind()) { case FlagValueStorageKind::kValueAndInitBit: - case FlagValueStorageKind::kOneWordAtomic: { - return absl::make_unique<FlagState>( - *this, OneWordValue().load(std::memory_order_acquire), modified, + case FlagValueStorageKind::kOneWordAtomic: { + return absl::make_unique<FlagState>( + *this, OneWordValue().load(std::memory_order_acquire), modified, on_command_line, ModificationCount()); - } + } case FlagValueStorageKind::kSequenceLocked: { void* cloned = flags_internal::Alloc(op_); // Read is guaranteed to be successful because we hold the lock. @@ -366,97 +366,97 @@ std::unique_ptr<FlagStateInterface> FlagImpl::SaveState() { static_cast<void>(success); return absl::make_unique<FlagState>(*this, cloned, modified, on_command_line, ModificationCount()); - } + } case FlagValueStorageKind::kAlignedBuffer: { return absl::make_unique<FlagState>( *this, flags_internal::Clone(op_, AlignedBufferValue()), modified, on_command_line, ModificationCount()); } } - return nullptr; + return nullptr; } -bool FlagImpl::RestoreState(const FlagState& flag_state) { - absl::MutexLock l(DataGuard()); +bool FlagImpl::RestoreState(const FlagState& flag_state) { + absl::MutexLock l(DataGuard()); if (flag_state.counter_ == ModificationCount()) { - return false; + return false; } - switch (ValueStorageKind()) { + switch (ValueStorageKind()) { case FlagValueStorageKind::kValueAndInitBit: case FlagValueStorageKind::kOneWordAtomic: StoreValue(&flag_state.value_.one_word); break; case FlagValueStorageKind::kSequenceLocked: - case FlagValueStorageKind::kAlignedBuffer: - StoreValue(flag_state.value_.heap_allocated); - break; - } + case FlagValueStorageKind::kAlignedBuffer: + StoreValue(flag_state.value_.heap_allocated); + break; + } - modified_ = flag_state.modified_; - on_command_line_ = flag_state.on_command_line_; + modified_ = flag_state.modified_; + on_command_line_ = flag_state.on_command_line_; return true; } -template <typename StorageT> -StorageT* FlagImpl::OffsetValue() const { - char* p = reinterpret_cast<char*>(const_cast<FlagImpl*>(this)); - // The offset is deduced via Flag value type specific op_. - size_t offset = flags_internal::ValueOffset(op_); - - return reinterpret_cast<StorageT*>(p + offset); -} - -void* FlagImpl::AlignedBufferValue() const { - assert(ValueStorageKind() == FlagValueStorageKind::kAlignedBuffer); - return OffsetValue<void>(); -} - +template <typename StorageT> +StorageT* FlagImpl::OffsetValue() const { + char* p = reinterpret_cast<char*>(const_cast<FlagImpl*>(this)); + // The offset is deduced via Flag value type specific op_. + size_t offset = flags_internal::ValueOffset(op_); + + return reinterpret_cast<StorageT*>(p + offset); +} + +void* FlagImpl::AlignedBufferValue() const { + assert(ValueStorageKind() == FlagValueStorageKind::kAlignedBuffer); + return OffsetValue<void>(); +} + std::atomic<uint64_t>* FlagImpl::AtomicBufferValue() const { assert(ValueStorageKind() == FlagValueStorageKind::kSequenceLocked); return OffsetValue<std::atomic<uint64_t>>(); } -std::atomic<int64_t>& FlagImpl::OneWordValue() const { +std::atomic<int64_t>& FlagImpl::OneWordValue() const { assert(ValueStorageKind() == FlagValueStorageKind::kOneWordAtomic || ValueStorageKind() == FlagValueStorageKind::kValueAndInitBit); - return OffsetValue<FlagOneWordValue>()->value; -} - + return OffsetValue<FlagOneWordValue>()->value; +} + // Attempts to parse supplied `value` string using parsing routine in the `flag` -// argument. If parsing successful, this function replaces the dst with newly -// parsed value. In case if any error is encountered in either step, the error -// message is stored in 'err' -std::unique_ptr<void, DynValueDeleter> FlagImpl::TryParse( - absl::string_view value, std::string& err) const { - std::unique_ptr<void, DynValueDeleter> tentative_value = MakeInitValue(); - +// argument. If parsing successful, this function replaces the dst with newly +// parsed value. In case if any error is encountered in either step, the error +// message is stored in 'err' +std::unique_ptr<void, DynValueDeleter> FlagImpl::TryParse( + absl::string_view value, std::string& err) const { + std::unique_ptr<void, DynValueDeleter> tentative_value = MakeInitValue(); + std::string parse_err; - if (!flags_internal::Parse(op_, value, tentative_value.get(), &parse_err)) { + if (!flags_internal::Parse(op_, value, tentative_value.get(), &parse_err)) { absl::string_view err_sep = parse_err.empty() ? "" : "; "; - err = absl::StrCat("Illegal value '", value, "' specified for flag '", - Name(), "'", err_sep, parse_err); - return nullptr; + err = absl::StrCat("Illegal value '", value, "' specified for flag '", + Name(), "'", err_sep, parse_err); + return nullptr; } - return tentative_value; + return tentative_value; } -void FlagImpl::Read(void* dst) const { - auto* guard = DataGuard(); // Make sure flag initialized - switch (ValueStorageKind()) { +void FlagImpl::Read(void* dst) const { + auto* guard = DataGuard(); // Make sure flag initialized + switch (ValueStorageKind()) { case FlagValueStorageKind::kValueAndInitBit: - case FlagValueStorageKind::kOneWordAtomic: { - const int64_t one_word_val = - OneWordValue().load(std::memory_order_acquire); - std::memcpy(dst, &one_word_val, Sizeof(op_)); - break; - } + case FlagValueStorageKind::kOneWordAtomic: { + const int64_t one_word_val = + OneWordValue().load(std::memory_order_acquire); + std::memcpy(dst, &one_word_val, Sizeof(op_)); + break; + } case FlagValueStorageKind::kSequenceLocked: { ReadSequenceLockedData(dst); - break; - } + break; + } case FlagValueStorageKind::kAlignedBuffer: { absl::MutexLock l(guard); flags_internal::CopyConstruct(op_, AlignedBufferValue(), dst); @@ -496,21 +496,21 @@ void FlagImpl::ReadSequenceLockedData(void* dst) const { static_cast<void>(success); } -void FlagImpl::Write(const void* src) { +void FlagImpl::Write(const void* src) { absl::MutexLock l(DataGuard()); - if (ShouldValidateFlagValue(flags_internal::FastTypeId(op_))) { - std::unique_ptr<void, DynValueDeleter> obj{flags_internal::Clone(op_, src), - DynValueDeleter{op_}}; + if (ShouldValidateFlagValue(flags_internal::FastTypeId(op_))) { + std::unique_ptr<void, DynValueDeleter> obj{flags_internal::Clone(op_, src), + DynValueDeleter{op_}}; std::string ignored_error; - std::string src_as_str = flags_internal::Unparse(op_, src); - if (!flags_internal::Parse(op_, src_as_str, obj.get(), &ignored_error)) { - ABSL_INTERNAL_LOG(ERROR, absl::StrCat("Attempt to set flag '", Name(), - "' to invalid value ", src_as_str)); + std::string src_as_str = flags_internal::Unparse(op_, src); + if (!flags_internal::Parse(op_, src_as_str, obj.get(), &ignored_error)) { + ABSL_INTERNAL_LOG(ERROR, absl::StrCat("Attempt to set flag '", Name(), + "' to invalid value ", src_as_str)); } } - StoreValue(src); + StoreValue(src); } // Sets the value of the flag based on specified string `value`. If the flag @@ -521,18 +521,18 @@ void FlagImpl::Write(const void* src) { // * Update the flag's default value // * Update the current flag value if it was never set before // The mode is selected based on 'set_mode' parameter. -bool FlagImpl::ParseFrom(absl::string_view value, FlagSettingMode set_mode, - ValueSource source, std::string& err) { +bool FlagImpl::ParseFrom(absl::string_view value, FlagSettingMode set_mode, + ValueSource source, std::string& err) { absl::MutexLock l(DataGuard()); switch (set_mode) { case SET_FLAGS_VALUE: { // set or modify the flag's value - auto tentative_value = TryParse(value, err); - if (!tentative_value) return false; - - StoreValue(tentative_value.get()); + auto tentative_value = TryParse(value, err); + if (!tentative_value) return false; + StoreValue(tentative_value.get()); + if (source == kCommandLine) { on_command_line_ = true; } @@ -540,7 +540,7 @@ bool FlagImpl::ParseFrom(absl::string_view value, FlagSettingMode set_mode, } case SET_FLAG_IF_DEFAULT: { // set the flag's value, but only if it hasn't been set by someone else - if (modified_) { + if (modified_) { // TODO(rogeeff): review and fix this semantic. Currently we do not fail // in this case if flag is modified. This is misleading since the flag's // value is not updated even though we return true. @@ -549,29 +549,29 @@ bool FlagImpl::ParseFrom(absl::string_view value, FlagSettingMode set_mode, // return false; return true; } - auto tentative_value = TryParse(value, err); - if (!tentative_value) return false; - - StoreValue(tentative_value.get()); + auto tentative_value = TryParse(value, err); + if (!tentative_value) return false; + + StoreValue(tentative_value.get()); break; } case SET_FLAGS_DEFAULT: { - auto tentative_value = TryParse(value, err); - if (!tentative_value) return false; - - if (DefaultKind() == FlagDefaultKind::kDynamicValue) { - void* old_value = default_value_.dynamic_value; - default_value_.dynamic_value = tentative_value.release(); - tentative_value.reset(old_value); - } else { - default_value_.dynamic_value = tentative_value.release(); - def_kind_ = static_cast<uint8_t>(FlagDefaultKind::kDynamicValue); - } - + auto tentative_value = TryParse(value, err); + if (!tentative_value) return false; + + if (DefaultKind() == FlagDefaultKind::kDynamicValue) { + void* old_value = default_value_.dynamic_value; + default_value_.dynamic_value = tentative_value.release(); + tentative_value.reset(old_value); + } else { + default_value_.dynamic_value = tentative_value.release(); + def_kind_ = static_cast<uint8_t>(FlagDefaultKind::kDynamicValue); + } + if (!modified_) { - // Need to set both default value *and* current, in this case. - StoreValue(default_value_.dynamic_value); - modified_ = false; + // Need to set both default value *and* current, in this case. + StoreValue(default_value_.dynamic_value); + modified_ = false; } break; } @@ -580,18 +580,18 @@ bool FlagImpl::ParseFrom(absl::string_view value, FlagSettingMode set_mode, return true; } -void FlagImpl::CheckDefaultValueParsingRoundtrip() const { +void FlagImpl::CheckDefaultValueParsingRoundtrip() const { std::string v = DefaultValue(); absl::MutexLock lock(DataGuard()); - auto dst = MakeInitValue(); + auto dst = MakeInitValue(); std::string error; - if (!flags_internal::Parse(op_, v, dst.get(), &error)) { + if (!flags_internal::Parse(op_, v, dst.get(), &error)) { ABSL_INTERNAL_LOG( FATAL, - absl::StrCat("Flag ", Name(), " (from ", Filename(), - "): string form of default value '", v, + absl::StrCat("Flag ", Name(), " (from ", Filename(), + "): string form of default value '", v, "' could not be parsed; error=", error)); } @@ -602,11 +602,11 @@ void FlagImpl::CheckDefaultValueParsingRoundtrip() const { bool FlagImpl::ValidateInputValue(absl::string_view value) const { absl::MutexLock l(DataGuard()); - auto obj = MakeInitValue(); + auto obj = MakeInitValue(); std::string ignored_error; - return flags_internal::Parse(op_, value, obj.get(), &ignored_error); + return flags_internal::Parse(op_, value, obj.get(), &ignored_error); } } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h index 124a2f1c03..6129f1b2a8 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/flag.h @@ -16,319 +16,319 @@ #ifndef ABSL_FLAGS_INTERNAL_FLAG_H_ #define ABSL_FLAGS_INTERNAL_FLAG_H_ -#include <stddef.h> -#include <stdint.h> - +#include <stddef.h> +#include <stdint.h> + #include <atomic> #include <cstring> -#include <memory> -#include <new> -#include <string> -#include <type_traits> -#include <typeinfo> - -#include "absl/base/attributes.h" -#include "absl/base/call_once.h" +#include <memory> +#include <new> +#include <string> +#include <type_traits> +#include <typeinfo> + +#include "absl/base/attributes.h" +#include "absl/base/call_once.h" #include "absl/base/casts.h" -#include "absl/base/config.h" -#include "absl/base/optimization.h" +#include "absl/base/config.h" +#include "absl/base/optimization.h" #include "absl/base/thread_annotations.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/config.h" +#include "absl/flags/commandlineflag.h" +#include "absl/flags/config.h" #include "absl/flags/internal/commandlineflag.h" #include "absl/flags/internal/registry.h" #include "absl/flags/internal/sequence_lock.h" -#include "absl/flags/marshalling.h" -#include "absl/meta/type_traits.h" -#include "absl/strings/string_view.h" +#include "absl/flags/marshalling.h" +#include "absl/meta/type_traits.h" +#include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" -#include "absl/utility/utility.h" +#include "absl/utility/utility.h" namespace absl { -ABSL_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// Forward declaration of absl::Flag<T> public API. +ABSL_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Forward declaration of absl::Flag<T> public API. namespace flags_internal { -template <typename T> -class Flag; -} // namespace flags_internal +template <typename T> +class Flag; +} // namespace flags_internal -#if defined(_MSC_VER) && !defined(__clang__) +#if defined(_MSC_VER) && !defined(__clang__) template <typename T> class Flag; -#else -template <typename T> -using Flag = flags_internal::Flag<T>; -#endif - -template <typename T> -ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag); +#else +template <typename T> +using Flag = flags_internal::Flag<T>; +#endif template <typename T> -void SetFlag(absl::Flag<T>* flag, const T& v); - -template <typename T, typename V> -void SetFlag(absl::Flag<T>* flag, const V& v); - -template <typename U> -const CommandLineFlag& GetFlagReflectionHandle(const absl::Flag<U>& f); - -/////////////////////////////////////////////////////////////////////////////// -// Flag value type operations, eg., parsing, copying, etc. are provided -// by function specific to that type with a signature matching FlagOpFn. - -namespace flags_internal { - -enum class FlagOp { - kAlloc, - kDelete, - kCopy, - kCopyConstruct, - kSizeof, - kFastTypeId, - kRuntimeTypeId, - kParse, - kUnparse, - kValueOffset, +ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag); + +template <typename T> +void SetFlag(absl::Flag<T>* flag, const T& v); + +template <typename T, typename V> +void SetFlag(absl::Flag<T>* flag, const V& v); + +template <typename U> +const CommandLineFlag& GetFlagReflectionHandle(const absl::Flag<U>& f); + +/////////////////////////////////////////////////////////////////////////////// +// Flag value type operations, eg., parsing, copying, etc. are provided +// by function specific to that type with a signature matching FlagOpFn. + +namespace flags_internal { + +enum class FlagOp { + kAlloc, + kDelete, + kCopy, + kCopyConstruct, + kSizeof, + kFastTypeId, + kRuntimeTypeId, + kParse, + kUnparse, + kValueOffset, }; -using FlagOpFn = void* (*)(FlagOp, const void*, void*, void*); - -// Forward declaration for Flag value specific operations. -template <typename T> -void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3); - -// Allocate aligned memory for a flag value. -inline void* Alloc(FlagOpFn op) { - return op(FlagOp::kAlloc, nullptr, nullptr, nullptr); -} -// Deletes memory interpreting obj as flag value type pointer. -inline void Delete(FlagOpFn op, void* obj) { - op(FlagOp::kDelete, nullptr, obj, nullptr); -} -// Copies src to dst interpreting as flag value type pointers. -inline void Copy(FlagOpFn op, const void* src, void* dst) { - op(FlagOp::kCopy, src, dst, nullptr); -} -// Construct a copy of flag value in a location pointed by dst -// based on src - pointer to the flag's value. -inline void CopyConstruct(FlagOpFn op, const void* src, void* dst) { - op(FlagOp::kCopyConstruct, src, dst, nullptr); -} -// Makes a copy of flag value pointed by obj. -inline void* Clone(FlagOpFn op, const void* obj) { - void* res = flags_internal::Alloc(op); - flags_internal::CopyConstruct(op, obj, res); - return res; -} -// Returns true if parsing of input text is successfull. -inline bool Parse(FlagOpFn op, absl::string_view text, void* dst, - std::string* error) { - return op(FlagOp::kParse, &text, dst, error) != nullptr; -} -// Returns string representing supplied value. -inline std::string Unparse(FlagOpFn op, const void* val) { - std::string result; - op(FlagOp::kUnparse, val, &result, nullptr); - return result; -} -// Returns size of flag value type. -inline size_t Sizeof(FlagOpFn op) { - // This sequence of casts reverses the sequence from - // `flags_internal::FlagOps()` - return static_cast<size_t>(reinterpret_cast<intptr_t>( - op(FlagOp::kSizeof, nullptr, nullptr, nullptr))); -} -// Returns fast type id coresponding to the value type. -inline FlagFastTypeId FastTypeId(FlagOpFn op) { - return reinterpret_cast<FlagFastTypeId>( - op(FlagOp::kFastTypeId, nullptr, nullptr, nullptr)); -} -// Returns fast type id coresponding to the value type. -inline const std::type_info* RuntimeTypeId(FlagOpFn op) { - return reinterpret_cast<const std::type_info*>( - op(FlagOp::kRuntimeTypeId, nullptr, nullptr, nullptr)); -} -// Returns offset of the field value_ from the field impl_ inside of -// absl::Flag<T> data. Given FlagImpl pointer p you can get the -// location of the corresponding value as: -// reinterpret_cast<char*>(p) + ValueOffset(). -inline ptrdiff_t ValueOffset(FlagOpFn op) { - // This sequence of casts reverses the sequence from - // `flags_internal::FlagOps()` - return static_cast<ptrdiff_t>(reinterpret_cast<intptr_t>( - op(FlagOp::kValueOffset, nullptr, nullptr, nullptr))); -} - -// Returns an address of RTTI's typeid(T). -template <typename T> -inline const std::type_info* GenRuntimeTypeId() { -#if defined(ABSL_FLAGS_INTERNAL_HAS_RTTI) - return &typeid(T); -#else - return nullptr; -#endif -} - -/////////////////////////////////////////////////////////////////////////////// -// Flag help auxiliary structs. - +using FlagOpFn = void* (*)(FlagOp, const void*, void*, void*); + +// Forward declaration for Flag value specific operations. +template <typename T> +void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3); + +// Allocate aligned memory for a flag value. +inline void* Alloc(FlagOpFn op) { + return op(FlagOp::kAlloc, nullptr, nullptr, nullptr); +} +// Deletes memory interpreting obj as flag value type pointer. +inline void Delete(FlagOpFn op, void* obj) { + op(FlagOp::kDelete, nullptr, obj, nullptr); +} +// Copies src to dst interpreting as flag value type pointers. +inline void Copy(FlagOpFn op, const void* src, void* dst) { + op(FlagOp::kCopy, src, dst, nullptr); +} +// Construct a copy of flag value in a location pointed by dst +// based on src - pointer to the flag's value. +inline void CopyConstruct(FlagOpFn op, const void* src, void* dst) { + op(FlagOp::kCopyConstruct, src, dst, nullptr); +} +// Makes a copy of flag value pointed by obj. +inline void* Clone(FlagOpFn op, const void* obj) { + void* res = flags_internal::Alloc(op); + flags_internal::CopyConstruct(op, obj, res); + return res; +} +// Returns true if parsing of input text is successfull. +inline bool Parse(FlagOpFn op, absl::string_view text, void* dst, + std::string* error) { + return op(FlagOp::kParse, &text, dst, error) != nullptr; +} +// Returns string representing supplied value. +inline std::string Unparse(FlagOpFn op, const void* val) { + std::string result; + op(FlagOp::kUnparse, val, &result, nullptr); + return result; +} +// Returns size of flag value type. +inline size_t Sizeof(FlagOpFn op) { + // This sequence of casts reverses the sequence from + // `flags_internal::FlagOps()` + return static_cast<size_t>(reinterpret_cast<intptr_t>( + op(FlagOp::kSizeof, nullptr, nullptr, nullptr))); +} +// Returns fast type id coresponding to the value type. +inline FlagFastTypeId FastTypeId(FlagOpFn op) { + return reinterpret_cast<FlagFastTypeId>( + op(FlagOp::kFastTypeId, nullptr, nullptr, nullptr)); +} +// Returns fast type id coresponding to the value type. +inline const std::type_info* RuntimeTypeId(FlagOpFn op) { + return reinterpret_cast<const std::type_info*>( + op(FlagOp::kRuntimeTypeId, nullptr, nullptr, nullptr)); +} +// Returns offset of the field value_ from the field impl_ inside of +// absl::Flag<T> data. Given FlagImpl pointer p you can get the +// location of the corresponding value as: +// reinterpret_cast<char*>(p) + ValueOffset(). +inline ptrdiff_t ValueOffset(FlagOpFn op) { + // This sequence of casts reverses the sequence from + // `flags_internal::FlagOps()` + return static_cast<ptrdiff_t>(reinterpret_cast<intptr_t>( + op(FlagOp::kValueOffset, nullptr, nullptr, nullptr))); +} + +// Returns an address of RTTI's typeid(T). +template <typename T> +inline const std::type_info* GenRuntimeTypeId() { +#if defined(ABSL_FLAGS_INTERNAL_HAS_RTTI) + return &typeid(T); +#else + return nullptr; +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +// Flag help auxiliary structs. + // This is help argument for absl::Flag encapsulating the string literal pointer // or pointer to function generating it as well as enum descriminating two // cases. using HelpGenFunc = std::string (*)(); -template <size_t N> -struct FixedCharArray { - char value[N]; - - template <size_t... I> - static constexpr FixedCharArray<N> FromLiteralString( - absl::string_view str, absl::index_sequence<I...>) { - return (void)str, FixedCharArray<N>({{str[I]..., '\0'}}); - } -}; - -template <typename Gen, size_t N = Gen::Value().size()> -constexpr FixedCharArray<N + 1> HelpStringAsArray(int) { - return FixedCharArray<N + 1>::FromLiteralString( - Gen::Value(), absl::make_index_sequence<N>{}); -} - -template <typename Gen> -constexpr std::false_type HelpStringAsArray(char) { - return std::false_type{}; -} - -union FlagHelpMsg { - constexpr explicit FlagHelpMsg(const char* help_msg) : literal(help_msg) {} - constexpr explicit FlagHelpMsg(HelpGenFunc help_gen) : gen_func(help_gen) {} - +template <size_t N> +struct FixedCharArray { + char value[N]; + + template <size_t... I> + static constexpr FixedCharArray<N> FromLiteralString( + absl::string_view str, absl::index_sequence<I...>) { + return (void)str, FixedCharArray<N>({{str[I]..., '\0'}}); + } +}; + +template <typename Gen, size_t N = Gen::Value().size()> +constexpr FixedCharArray<N + 1> HelpStringAsArray(int) { + return FixedCharArray<N + 1>::FromLiteralString( + Gen::Value(), absl::make_index_sequence<N>{}); +} + +template <typename Gen> +constexpr std::false_type HelpStringAsArray(char) { + return std::false_type{}; +} + +union FlagHelpMsg { + constexpr explicit FlagHelpMsg(const char* help_msg) : literal(help_msg) {} + constexpr explicit FlagHelpMsg(HelpGenFunc help_gen) : gen_func(help_gen) {} + const char* literal; HelpGenFunc gen_func; }; -enum class FlagHelpKind : uint8_t { kLiteral = 0, kGenFunc = 1 }; +enum class FlagHelpKind : uint8_t { kLiteral = 0, kGenFunc = 1 }; -struct FlagHelpArg { - FlagHelpMsg source; - FlagHelpKind kind; +struct FlagHelpArg { + FlagHelpMsg source; + FlagHelpKind kind; }; -extern const char kStrippedFlagHelp[]; +extern const char kStrippedFlagHelp[]; // These two HelpArg overloads allows us to select at compile time one of two // way to pass Help argument to absl::Flag. We'll be passing -// AbslFlagHelpGenFor##name as Gen and integer 0 as a single argument to prefer -// first overload if possible. If help message is evaluatable on constexpr -// context We'll be able to make FixedCharArray out of it and we'll choose first -// overload. In this case the help message expression is immediately evaluated -// and is used to construct the absl::Flag. No additionl code is generated by -// ABSL_FLAG Otherwise SFINAE kicks in and first overload is dropped from the +// AbslFlagHelpGenFor##name as Gen and integer 0 as a single argument to prefer +// first overload if possible. If help message is evaluatable on constexpr +// context We'll be able to make FixedCharArray out of it and we'll choose first +// overload. In this case the help message expression is immediately evaluated +// and is used to construct the absl::Flag. No additionl code is generated by +// ABSL_FLAG Otherwise SFINAE kicks in and first overload is dropped from the // consideration, in which case the second overload will be used. The second // overload does not attempt to evaluate the help message expression // immediately and instead delays the evaluation by returing the function // pointer (&T::NonConst) genering the help message when necessary. This is // evaluatable in constexpr context, but the cost is an extra function being // generated in the ABSL_FLAG code. -template <typename Gen, size_t N> -constexpr FlagHelpArg HelpArg(const FixedCharArray<N>& value) { - return {FlagHelpMsg(value.value), FlagHelpKind::kLiteral}; +template <typename Gen, size_t N> +constexpr FlagHelpArg HelpArg(const FixedCharArray<N>& value) { + return {FlagHelpMsg(value.value), FlagHelpKind::kLiteral}; } -template <typename Gen> -constexpr FlagHelpArg HelpArg(std::false_type) { - return {FlagHelpMsg(&Gen::NonConst), FlagHelpKind::kGenFunc}; +template <typename Gen> +constexpr FlagHelpArg HelpArg(std::false_type) { + return {FlagHelpMsg(&Gen::NonConst), FlagHelpKind::kGenFunc}; } -/////////////////////////////////////////////////////////////////////////////// -// Flag default value auxiliary structs. - -// Signature for the function generating the initial flag value (usually +/////////////////////////////////////////////////////////////////////////////// +// Flag default value auxiliary structs. + +// Signature for the function generating the initial flag value (usually // based on default value supplied in flag's definition) -using FlagDfltGenFunc = void (*)(void*); - -union FlagDefaultSrc { - constexpr explicit FlagDefaultSrc(FlagDfltGenFunc gen_func_arg) - : gen_func(gen_func_arg) {} - -#define ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE(T, name) \ - T name##_value; \ - constexpr explicit FlagDefaultSrc(T value) : name##_value(value) {} // NOLINT - ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE) -#undef ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE - - void* dynamic_value; - FlagDfltGenFunc gen_func; -}; - -enum class FlagDefaultKind : uint8_t { - kDynamicValue = 0, - kGenFunc = 1, - kOneWord = 2 // for default values UP to one word in size -}; - -struct FlagDefaultArg { - FlagDefaultSrc source; - FlagDefaultKind kind; -}; - -// This struct and corresponding overload to InitDefaultValue are used to -// facilitate usage of {} as default value in ABSL_FLAG macro. -// TODO(rogeeff): Fix handling types with explicit constructors. -struct EmptyBraces {}; - -template <typename T> -constexpr T InitDefaultValue(T t) { - return t; -} - -template <typename T> -constexpr T InitDefaultValue(EmptyBraces) { - return T{}; -} - -template <typename ValueT, typename GenT, - typename std::enable_if<std::is_integral<ValueT>::value, int>::type = +using FlagDfltGenFunc = void (*)(void*); + +union FlagDefaultSrc { + constexpr explicit FlagDefaultSrc(FlagDfltGenFunc gen_func_arg) + : gen_func(gen_func_arg) {} + +#define ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE(T, name) \ + T name##_value; \ + constexpr explicit FlagDefaultSrc(T value) : name##_value(value) {} // NOLINT + ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE) +#undef ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE + + void* dynamic_value; + FlagDfltGenFunc gen_func; +}; + +enum class FlagDefaultKind : uint8_t { + kDynamicValue = 0, + kGenFunc = 1, + kOneWord = 2 // for default values UP to one word in size +}; + +struct FlagDefaultArg { + FlagDefaultSrc source; + FlagDefaultKind kind; +}; + +// This struct and corresponding overload to InitDefaultValue are used to +// facilitate usage of {} as default value in ABSL_FLAG macro. +// TODO(rogeeff): Fix handling types with explicit constructors. +struct EmptyBraces {}; + +template <typename T> +constexpr T InitDefaultValue(T t) { + return t; +} + +template <typename T> +constexpr T InitDefaultValue(EmptyBraces) { + return T{}; +} + +template <typename ValueT, typename GenT, + typename std::enable_if<std::is_integral<ValueT>::value, int>::type = ((void)GenT{}, 0)> -constexpr FlagDefaultArg DefaultArg(int) { - return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kOneWord}; -} - -template <typename ValueT, typename GenT> -constexpr FlagDefaultArg DefaultArg(char) { - return {FlagDefaultSrc(&GenT::Gen), FlagDefaultKind::kGenFunc}; -} - -/////////////////////////////////////////////////////////////////////////////// -// Flag current value auxiliary structs. - -constexpr int64_t UninitializedFlagValue() { return 0xababababababababll; } - -template <typename T> +constexpr FlagDefaultArg DefaultArg(int) { + return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kOneWord}; +} + +template <typename ValueT, typename GenT> +constexpr FlagDefaultArg DefaultArg(char) { + return {FlagDefaultSrc(&GenT::Gen), FlagDefaultKind::kGenFunc}; +} + +/////////////////////////////////////////////////////////////////////////////// +// Flag current value auxiliary structs. + +constexpr int64_t UninitializedFlagValue() { return 0xababababababababll; } + +template <typename T> using FlagUseValueAndInitBitStorage = std::integral_constant< bool, absl::type_traits_internal::is_trivially_copyable<T>::value && std::is_default_constructible<T>::value && (sizeof(T) < 8)>; template <typename T> -using FlagUseOneWordStorage = std::integral_constant< - bool, absl::type_traits_internal::is_trivially_copyable<T>::value && - (sizeof(T) <= 8)>; - +using FlagUseOneWordStorage = std::integral_constant< + bool, absl::type_traits_internal::is_trivially_copyable<T>::value && + (sizeof(T) <= 8)>; + template <class T> using FlagUseSequenceLockStorage = std::integral_constant< - bool, absl::type_traits_internal::is_trivially_copyable<T>::value && + bool, absl::type_traits_internal::is_trivially_copyable<T>::value && (sizeof(T) > 8)>; - -enum class FlagValueStorageKind : uint8_t { + +enum class FlagValueStorageKind : uint8_t { kValueAndInitBit = 0, - kOneWordAtomic = 1, + kOneWordAtomic = 1, kSequenceLocked = 2, kAlignedBuffer = 3, -}; - -template <typename T> -static constexpr FlagValueStorageKind StorageKind() { +}; + +template <typename T> +static constexpr FlagValueStorageKind StorageKind() { return FlagUseValueAndInitBitStorage<T>::value ? FlagValueStorageKind::kValueAndInitBit : FlagUseOneWordStorage<T>::value @@ -336,13 +336,13 @@ static constexpr FlagValueStorageKind StorageKind() { : FlagUseSequenceLockStorage<T>::value ? FlagValueStorageKind::kSequenceLocked : FlagValueStorageKind::kAlignedBuffer; -} - -struct FlagOneWordValue { +} + +struct FlagOneWordValue { constexpr explicit FlagOneWordValue(int64_t v) : value(v) {} - std::atomic<int64_t> value; -}; - + std::atomic<int64_t> value; +}; + template <typename T> struct alignas(8) FlagValueAndInitBit { T value; @@ -351,11 +351,11 @@ struct alignas(8) FlagValueAndInitBit { uint8_t init; }; -template <typename T, - FlagValueStorageKind Kind = flags_internal::StorageKind<T>()> -struct FlagValue; - -template <typename T> +template <typename T, + FlagValueStorageKind Kind = flags_internal::StorageKind<T>()> +struct FlagValue; + +template <typename T> struct FlagValue<T, FlagValueStorageKind::kValueAndInitBit> : FlagOneWordValue { constexpr FlagValue() : FlagOneWordValue(0) {} bool Get(const SequenceLock&, T& dst) const { @@ -366,34 +366,34 @@ struct FlagValue<T, FlagValueStorageKind::kValueAndInitBit> : FlagOneWordValue { dst = absl::bit_cast<FlagValueAndInitBit<T>>(storage).value; return true; } -}; - -template <typename T> -struct FlagValue<T, FlagValueStorageKind::kOneWordAtomic> : FlagOneWordValue { +}; + +template <typename T> +struct FlagValue<T, FlagValueStorageKind::kOneWordAtomic> : FlagOneWordValue { constexpr FlagValue() : FlagOneWordValue(UninitializedFlagValue()) {} bool Get(const SequenceLock&, T& dst) const { - int64_t one_word_val = value.load(std::memory_order_acquire); - if (ABSL_PREDICT_FALSE(one_word_val == UninitializedFlagValue())) { - return false; - } - std::memcpy(&dst, static_cast<const void*>(&one_word_val), sizeof(T)); - return true; - } -}; - -template <typename T> + int64_t one_word_val = value.load(std::memory_order_acquire); + if (ABSL_PREDICT_FALSE(one_word_val == UninitializedFlagValue())) { + return false; + } + std::memcpy(&dst, static_cast<const void*>(&one_word_val), sizeof(T)); + return true; + } +}; + +template <typename T> struct FlagValue<T, FlagValueStorageKind::kSequenceLocked> { bool Get(const SequenceLock& lock, T& dst) const { return lock.TryRead(&dst, value_words, sizeof(T)); - } + } static constexpr int kNumWords = flags_internal::AlignUp(sizeof(T), sizeof(uint64_t)) / sizeof(uint64_t); alignas(T) alignas( std::atomic<uint64_t>) std::atomic<uint64_t> value_words[kNumWords]; -}; - +}; + template <typename T> struct FlagValue<T, FlagValueStorageKind::kAlignedBuffer> { bool Get(const SequenceLock&, T&) const { return false; } @@ -401,54 +401,54 @@ struct FlagValue<T, FlagValueStorageKind::kAlignedBuffer> { alignas(T) char value[sizeof(T)]; }; -/////////////////////////////////////////////////////////////////////////////// -// Flag callback auxiliary structs. - +/////////////////////////////////////////////////////////////////////////////// +// Flag callback auxiliary structs. + // Signature for the mutation callback used by watched Flags // The callback is noexcept. // TODO(rogeeff): add noexcept after C++17 support is added. -using FlagCallbackFunc = void (*)(); - -struct FlagCallback { - FlagCallbackFunc func; - absl::Mutex guard; // Guard for concurrent callback invocations. -}; - -/////////////////////////////////////////////////////////////////////////////// -// Flag implementation, which does not depend on flag value type. -// The class encapsulates the Flag's data and access to it. - -struct DynValueDeleter { - explicit DynValueDeleter(FlagOpFn op_arg = nullptr); - void operator()(void* ptr) const; - - FlagOpFn op; -}; - -class FlagState; - -class FlagImpl final : public CommandLineFlag { +using FlagCallbackFunc = void (*)(); + +struct FlagCallback { + FlagCallbackFunc func; + absl::Mutex guard; // Guard for concurrent callback invocations. +}; + +/////////////////////////////////////////////////////////////////////////////// +// Flag implementation, which does not depend on flag value type. +// The class encapsulates the Flag's data and access to it. + +struct DynValueDeleter { + explicit DynValueDeleter(FlagOpFn op_arg = nullptr); + void operator()(void* ptr) const; + + FlagOpFn op; +}; + +class FlagState; + +class FlagImpl final : public CommandLineFlag { public: - constexpr FlagImpl(const char* name, const char* filename, FlagOpFn op, - FlagHelpArg help, FlagValueStorageKind value_kind, - FlagDefaultArg default_arg) - : name_(name), - filename_(filename), - op_(op), + constexpr FlagImpl(const char* name, const char* filename, FlagOpFn op, + FlagHelpArg help, FlagValueStorageKind value_kind, + FlagDefaultArg default_arg) + : name_(name), + filename_(filename), + op_(op), help_(help.source), - help_source_kind_(static_cast<uint8_t>(help.kind)), - value_storage_kind_(static_cast<uint8_t>(value_kind)), - def_kind_(static_cast<uint8_t>(default_arg.kind)), - modified_(false), - on_command_line_(false), - callback_(nullptr), - default_value_(default_arg.source), - data_guard_{} {} + help_source_kind_(static_cast<uint8_t>(help.kind)), + value_storage_kind_(static_cast<uint8_t>(value_kind)), + def_kind_(static_cast<uint8_t>(default_arg.kind)), + modified_(false), + on_command_line_(false), + callback_(nullptr), + default_value_(default_arg.source), + data_guard_{} {} // Constant access methods int64_t ReadOneWord() const ABSL_LOCKS_EXCLUDED(*DataGuard()); bool ReadOneBool() const ABSL_LOCKS_EXCLUDED(*DataGuard()); - void Read(void* dst) const override ABSL_LOCKS_EXCLUDED(*DataGuard()); + void Read(void* dst) const override ABSL_LOCKS_EXCLUDED(*DataGuard()); void Read(bool* value) const ABSL_LOCKS_EXCLUDED(*DataGuard()) { *value = ReadOneBool(); } @@ -469,193 +469,193 @@ class FlagImpl final : public CommandLineFlag { } // Mutating access methods - void Write(const void* src) ABSL_LOCKS_EXCLUDED(*DataGuard()); + void Write(const void* src) ABSL_LOCKS_EXCLUDED(*DataGuard()); // Interfaces to operate on callbacks. - void SetCallback(const FlagCallbackFunc mutation_callback) - ABSL_LOCKS_EXCLUDED(*DataGuard()); - void InvokeCallback() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); - - // Used in read/write operations to validate source/target has correct type. - // For example if flag is declared as absl::Flag<int> FLAGS_foo, a call to - // absl::GetFlag(FLAGS_foo) validates that the type of FLAGS_foo is indeed - // int. To do that we pass the "assumed" type id (which is deduced from type - // int) as an argument `type_id`, which is in turn is validated against the - // type id stored in flag object by flag definition statement. - void AssertValidType(FlagFastTypeId type_id, - const std::type_info* (*gen_rtti)()) const; - - private: + void SetCallback(const FlagCallbackFunc mutation_callback) + ABSL_LOCKS_EXCLUDED(*DataGuard()); + void InvokeCallback() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); + + // Used in read/write operations to validate source/target has correct type. + // For example if flag is declared as absl::Flag<int> FLAGS_foo, a call to + // absl::GetFlag(FLAGS_foo) validates that the type of FLAGS_foo is indeed + // int. To do that we pass the "assumed" type id (which is deduced from type + // int) as an argument `type_id`, which is in turn is validated against the + // type id stored in flag object by flag definition statement. + void AssertValidType(FlagFastTypeId type_id, + const std::type_info* (*gen_rtti)()) const; + + private: template <typename T> - friend class Flag; - friend class FlagState; - - // Ensures that `data_guard_` is initialized and returns it. - absl::Mutex* DataGuard() const - ABSL_LOCK_RETURNED(reinterpret_cast<absl::Mutex*>(data_guard_)); - // Returns heap allocated value of type T initialized with default value. - std::unique_ptr<void, DynValueDeleter> MakeInitValue() const - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); - // Flag initialization called via absl::call_once. - void Init(); - - // Offset value access methods. One per storage kind. These methods to not - // respect const correctness, so be very carefull using them. - - // This is a shared helper routine which encapsulates most of the magic. Since - // it is only used inside the three routines below, which are defined in - // flag.cc, we can define it in that file as well. - template <typename StorageT> - StorageT* OffsetValue() const; + friend class Flag; + friend class FlagState; + + // Ensures that `data_guard_` is initialized and returns it. + absl::Mutex* DataGuard() const + ABSL_LOCK_RETURNED(reinterpret_cast<absl::Mutex*>(data_guard_)); + // Returns heap allocated value of type T initialized with default value. + std::unique_ptr<void, DynValueDeleter> MakeInitValue() const + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); + // Flag initialization called via absl::call_once. + void Init(); + + // Offset value access methods. One per storage kind. These methods to not + // respect const correctness, so be very carefull using them. + + // This is a shared helper routine which encapsulates most of the magic. Since + // it is only used inside the three routines below, which are defined in + // flag.cc, we can define it in that file as well. + template <typename StorageT> + StorageT* OffsetValue() const; // This is an accessor for a value stored in an aligned buffer storage // used for non-trivially-copyable data types. - // Returns a mutable pointer to the start of a buffer. - void* AlignedBufferValue() const; + // Returns a mutable pointer to the start of a buffer. + void* AlignedBufferValue() const; // The same as above, but used for sequencelock-protected storage. std::atomic<uint64_t>* AtomicBufferValue() const; - // This is an accessor for a value stored as one word atomic. Returns a - // mutable reference to an atomic value. - std::atomic<int64_t>& OneWordValue() const; - - // Attempts to parse supplied `value` string. If parsing is successful, - // returns new value. Otherwise returns nullptr. - std::unique_ptr<void, DynValueDeleter> TryParse(absl::string_view value, - std::string& err) const - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); - // Stores the flag value based on the pointer to the source. - void StoreValue(const void* src) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); - + // This is an accessor for a value stored as one word atomic. Returns a + // mutable reference to an atomic value. + std::atomic<int64_t>& OneWordValue() const; + + // Attempts to parse supplied `value` string. If parsing is successful, + // returns new value. Otherwise returns nullptr. + std::unique_ptr<void, DynValueDeleter> TryParse(absl::string_view value, + std::string& err) const + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); + // Stores the flag value based on the pointer to the source. + void StoreValue(const void* src) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); + // Copy the flag data, protected by `seq_lock_` into `dst`. // // REQUIRES: ValueStorageKind() == kSequenceLocked. void ReadSequenceLockedData(void* dst) const ABSL_LOCKS_EXCLUDED(*DataGuard()); - FlagHelpKind HelpSourceKind() const { - return static_cast<FlagHelpKind>(help_source_kind_); - } - FlagValueStorageKind ValueStorageKind() const { - return static_cast<FlagValueStorageKind>(value_storage_kind_); - } - FlagDefaultKind DefaultKind() const - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()) { - return static_cast<FlagDefaultKind>(def_kind_); + FlagHelpKind HelpSourceKind() const { + return static_cast<FlagHelpKind>(help_source_kind_); } - - // CommandLineFlag interface implementation - absl::string_view Name() const override; - std::string Filename() const override; - std::string Help() const override; - FlagFastTypeId TypeId() const override; - bool IsSpecifiedOnCommandLine() const override - ABSL_LOCKS_EXCLUDED(*DataGuard()); - std::string DefaultValue() const override ABSL_LOCKS_EXCLUDED(*DataGuard()); - std::string CurrentValue() const override ABSL_LOCKS_EXCLUDED(*DataGuard()); - bool ValidateInputValue(absl::string_view value) const override - ABSL_LOCKS_EXCLUDED(*DataGuard()); - void CheckDefaultValueParsingRoundtrip() const override - ABSL_LOCKS_EXCLUDED(*DataGuard()); + FlagValueStorageKind ValueStorageKind() const { + return static_cast<FlagValueStorageKind>(value_storage_kind_); + } + FlagDefaultKind DefaultKind() const + ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()) { + return static_cast<FlagDefaultKind>(def_kind_); + } + + // CommandLineFlag interface implementation + absl::string_view Name() const override; + std::string Filename() const override; + std::string Help() const override; + FlagFastTypeId TypeId() const override; + bool IsSpecifiedOnCommandLine() const override + ABSL_LOCKS_EXCLUDED(*DataGuard()); + std::string DefaultValue() const override ABSL_LOCKS_EXCLUDED(*DataGuard()); + std::string CurrentValue() const override ABSL_LOCKS_EXCLUDED(*DataGuard()); + bool ValidateInputValue(absl::string_view value) const override + ABSL_LOCKS_EXCLUDED(*DataGuard()); + void CheckDefaultValueParsingRoundtrip() const override + ABSL_LOCKS_EXCLUDED(*DataGuard()); int64_t ModificationCount() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); - // Interfaces to save and restore flags to/from persistent state. - // Returns current flag state or nullptr if flag does not support - // saving and restoring a state. - std::unique_ptr<FlagStateInterface> SaveState() override - ABSL_LOCKS_EXCLUDED(*DataGuard()); - - // Restores the flag state to the supplied state object. If there is - // nothing to restore returns false. Otherwise returns true. - bool RestoreState(const FlagState& flag_state) - ABSL_LOCKS_EXCLUDED(*DataGuard()); - - bool ParseFrom(absl::string_view value, FlagSettingMode set_mode, - ValueSource source, std::string& error) override - ABSL_LOCKS_EXCLUDED(*DataGuard()); - - // Immutable flag's state. - - // Flags name passed to ABSL_FLAG as second arg. - const char* const name_; - // The file name where ABSL_FLAG resides. - const char* const filename_; - // Type-specific operations "vtable". - const FlagOpFn op_; - // Help message literal or function to generate it. - const FlagHelpMsg help_; + // Interfaces to save and restore flags to/from persistent state. + // Returns current flag state or nullptr if flag does not support + // saving and restoring a state. + std::unique_ptr<FlagStateInterface> SaveState() override + ABSL_LOCKS_EXCLUDED(*DataGuard()); + + // Restores the flag state to the supplied state object. If there is + // nothing to restore returns false. Otherwise returns true. + bool RestoreState(const FlagState& flag_state) + ABSL_LOCKS_EXCLUDED(*DataGuard()); + + bool ParseFrom(absl::string_view value, FlagSettingMode set_mode, + ValueSource source, std::string& error) override + ABSL_LOCKS_EXCLUDED(*DataGuard()); + + // Immutable flag's state. + + // Flags name passed to ABSL_FLAG as second arg. + const char* const name_; + // The file name where ABSL_FLAG resides. + const char* const filename_; + // Type-specific operations "vtable". + const FlagOpFn op_; + // Help message literal or function to generate it. + const FlagHelpMsg help_; // Indicates if help message was supplied as literal or generator func. - const uint8_t help_source_kind_ : 1; - // Kind of storage this flag is using for the flag's value. - const uint8_t value_storage_kind_ : 2; - - uint8_t : 0; // The bytes containing the const bitfields must not be - // shared with bytes containing the mutable bitfields. - - // Mutable flag's state (guarded by `data_guard_`). - - // def_kind_ is not guard by DataGuard() since it is accessed in Init without - // locks. - uint8_t def_kind_ : 2; - // Has this flag's value been modified? - bool modified_ : 1 ABSL_GUARDED_BY(*DataGuard()); - // Has this flag been specified on command line. - bool on_command_line_ : 1 ABSL_GUARDED_BY(*DataGuard()); - - // Unique tag for absl::call_once call to initialize this flag. - absl::once_flag init_control_; - + const uint8_t help_source_kind_ : 1; + // Kind of storage this flag is using for the flag's value. + const uint8_t value_storage_kind_ : 2; + + uint8_t : 0; // The bytes containing the const bitfields must not be + // shared with bytes containing the mutable bitfields. + + // Mutable flag's state (guarded by `data_guard_`). + + // def_kind_ is not guard by DataGuard() since it is accessed in Init without + // locks. + uint8_t def_kind_ : 2; + // Has this flag's value been modified? + bool modified_ : 1 ABSL_GUARDED_BY(*DataGuard()); + // Has this flag been specified on command line. + bool on_command_line_ : 1 ABSL_GUARDED_BY(*DataGuard()); + + // Unique tag for absl::call_once call to initialize this flag. + absl::once_flag init_control_; + // Sequence lock / mutation counter. flags_internal::SequenceLock seq_lock_; - // Optional flag's callback and absl::Mutex to guard the invocations. - FlagCallback* callback_ ABSL_GUARDED_BY(*DataGuard()); - // Either a pointer to the function generating the default value based on the - // value specified in ABSL_FLAG or pointer to the dynamically set default - // value via SetCommandLineOptionWithMode. def_kind_ is used to distinguish - // these two cases. - FlagDefaultSrc default_value_; - - // This is reserved space for an absl::Mutex to guard flag data. It will be - // initialized in FlagImpl::Init via placement new. - // We can't use "absl::Mutex data_guard_", since this class is not literal. - // We do not want to use "absl::Mutex* data_guard_", since this would require - // heap allocation during initialization, which is both slows program startup - // and can fail. Using reserved space + placement new allows us to avoid both - // problems. - alignas(absl::Mutex) mutable char data_guard_[sizeof(absl::Mutex)]; + // Optional flag's callback and absl::Mutex to guard the invocations. + FlagCallback* callback_ ABSL_GUARDED_BY(*DataGuard()); + // Either a pointer to the function generating the default value based on the + // value specified in ABSL_FLAG or pointer to the dynamically set default + // value via SetCommandLineOptionWithMode. def_kind_ is used to distinguish + // these two cases. + FlagDefaultSrc default_value_; + + // This is reserved space for an absl::Mutex to guard flag data. It will be + // initialized in FlagImpl::Init via placement new. + // We can't use "absl::Mutex data_guard_", since this class is not literal. + // We do not want to use "absl::Mutex* data_guard_", since this would require + // heap allocation during initialization, which is both slows program startup + // and can fail. Using reserved space + placement new allows us to avoid both + // problems. + alignas(absl::Mutex) mutable char data_guard_[sizeof(absl::Mutex)]; }; -/////////////////////////////////////////////////////////////////////////////// -// The Flag object parameterized by the flag's value type. This class implements -// flag reflection handle interface. - +/////////////////////////////////////////////////////////////////////////////// +// The Flag object parameterized by the flag's value type. This class implements +// flag reflection handle interface. + template <typename T> -class Flag { +class Flag { public: - constexpr Flag(const char* name, const char* filename, FlagHelpArg help, - const FlagDefaultArg default_arg) - : impl_(name, filename, &FlagOps<T>, help, - flags_internal::StorageKind<T>(), default_arg), - value_() {} - - // CommandLineFlag interface - absl::string_view Name() const { return impl_.Name(); } - std::string Filename() const { return impl_.Filename(); } - std::string Help() const { return impl_.Help(); } - // Do not use. To be removed. - bool IsSpecifiedOnCommandLine() const { - return impl_.IsSpecifiedOnCommandLine(); - } - std::string DefaultValue() const { return impl_.DefaultValue(); } - std::string CurrentValue() const { return impl_.CurrentValue(); } - - private: - template <typename, bool> - friend class FlagRegistrar; - friend class FlagImplPeer; - + constexpr Flag(const char* name, const char* filename, FlagHelpArg help, + const FlagDefaultArg default_arg) + : impl_(name, filename, &FlagOps<T>, help, + flags_internal::StorageKind<T>(), default_arg), + value_() {} + + // CommandLineFlag interface + absl::string_view Name() const { return impl_.Name(); } + std::string Filename() const { return impl_.Filename(); } + std::string Help() const { return impl_.Help(); } + // Do not use. To be removed. + bool IsSpecifiedOnCommandLine() const { + return impl_.IsSpecifiedOnCommandLine(); + } + std::string DefaultValue() const { return impl_.DefaultValue(); } + std::string CurrentValue() const { return impl_.CurrentValue(); } + + private: + template <typename, bool> + friend class FlagRegistrar; + friend class FlagImplPeer; + T Get() const { // See implementation notes in CommandLineFlag::Get(). union U { @@ -665,110 +665,110 @@ class Flag { }; U u; -#if !defined(NDEBUG) - impl_.AssertValidType(base_internal::FastTypeId<T>(), &GenRuntimeTypeId<T>); -#endif - +#if !defined(NDEBUG) + impl_.AssertValidType(base_internal::FastTypeId<T>(), &GenRuntimeTypeId<T>); +#endif + if (ABSL_PREDICT_FALSE(!value_.Get(impl_.seq_lock_, u.value))) { impl_.Read(&u.value); } return std::move(u.value); } - void Set(const T& v) { - impl_.AssertValidType(base_internal::FastTypeId<T>(), &GenRuntimeTypeId<T>); - impl_.Write(&v); + void Set(const T& v) { + impl_.AssertValidType(base_internal::FastTypeId<T>(), &GenRuntimeTypeId<T>); + impl_.Write(&v); } - // Access to the reflection. - const CommandLineFlag& Reflect() const { return impl_; } - - // Flag's data - // The implementation depends on value_ field to be placed exactly after the - // impl_ field, so that impl_ can figure out the offset to the value and - // access it. - FlagImpl impl_; - FlagValue<T> value_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Trampoline for friend access - -class FlagImplPeer { - public: - template <typename T, typename FlagType> - static T InvokeGet(const FlagType& flag) { - return flag.Get(); + // Access to the reflection. + const CommandLineFlag& Reflect() const { return impl_; } + + // Flag's data + // The implementation depends on value_ field to be placed exactly after the + // impl_ field, so that impl_ can figure out the offset to the value and + // access it. + FlagImpl impl_; + FlagValue<T> value_; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Trampoline for friend access + +class FlagImplPeer { + public: + template <typename T, typename FlagType> + static T InvokeGet(const FlagType& flag) { + return flag.Get(); } - template <typename FlagType, typename T> - static void InvokeSet(FlagType& flag, const T& v) { - flag.Set(v); + template <typename FlagType, typename T> + static void InvokeSet(FlagType& flag, const T& v) { + flag.Set(v); } - template <typename FlagType> - static const CommandLineFlag& InvokeReflect(const FlagType& f) { - return f.Reflect(); + template <typename FlagType> + static const CommandLineFlag& InvokeReflect(const FlagType& f) { + return f.Reflect(); } }; -/////////////////////////////////////////////////////////////////////////////// -// Implementation of Flag value specific operations routine. +/////////////////////////////////////////////////////////////////////////////// +// Implementation of Flag value specific operations routine. template <typename T> -void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3) { - switch (op) { - case FlagOp::kAlloc: { - std::allocator<T> alloc; - return std::allocator_traits<std::allocator<T>>::allocate(alloc, 1); - } - case FlagOp::kDelete: { - T* p = static_cast<T*>(v2); - p->~T(); - std::allocator<T> alloc; - std::allocator_traits<std::allocator<T>>::deallocate(alloc, p, 1); - return nullptr; - } - case FlagOp::kCopy: - *static_cast<T*>(v2) = *static_cast<const T*>(v1); - return nullptr; - case FlagOp::kCopyConstruct: - new (v2) T(*static_cast<const T*>(v1)); - return nullptr; - case FlagOp::kSizeof: - return reinterpret_cast<void*>(static_cast<uintptr_t>(sizeof(T))); - case FlagOp::kFastTypeId: - return const_cast<void*>(base_internal::FastTypeId<T>()); - case FlagOp::kRuntimeTypeId: - return const_cast<std::type_info*>(GenRuntimeTypeId<T>()); - case FlagOp::kParse: { - // Initialize the temporary instance of type T based on current value in - // destination (which is going to be flag's default value). - T temp(*static_cast<T*>(v2)); - if (!absl::ParseFlag<T>(*static_cast<const absl::string_view*>(v1), &temp, - static_cast<std::string*>(v3))) { - return nullptr; - } - *static_cast<T*>(v2) = std::move(temp); - return v2; - } - case FlagOp::kUnparse: - *static_cast<std::string*>(v2) = - absl::UnparseFlag<T>(*static_cast<const T*>(v1)); - return nullptr; - case FlagOp::kValueOffset: { - // Round sizeof(FlagImp) to a multiple of alignof(FlagValue<T>) to get the - // offset of the data. - ptrdiff_t round_to = alignof(FlagValue<T>); - ptrdiff_t offset = - (sizeof(FlagImpl) + round_to - 1) / round_to * round_to; - return reinterpret_cast<void*>(offset); - } +void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3) { + switch (op) { + case FlagOp::kAlloc: { + std::allocator<T> alloc; + return std::allocator_traits<std::allocator<T>>::allocate(alloc, 1); + } + case FlagOp::kDelete: { + T* p = static_cast<T*>(v2); + p->~T(); + std::allocator<T> alloc; + std::allocator_traits<std::allocator<T>>::deallocate(alloc, p, 1); + return nullptr; + } + case FlagOp::kCopy: + *static_cast<T*>(v2) = *static_cast<const T*>(v1); + return nullptr; + case FlagOp::kCopyConstruct: + new (v2) T(*static_cast<const T*>(v1)); + return nullptr; + case FlagOp::kSizeof: + return reinterpret_cast<void*>(static_cast<uintptr_t>(sizeof(T))); + case FlagOp::kFastTypeId: + return const_cast<void*>(base_internal::FastTypeId<T>()); + case FlagOp::kRuntimeTypeId: + return const_cast<std::type_info*>(GenRuntimeTypeId<T>()); + case FlagOp::kParse: { + // Initialize the temporary instance of type T based on current value in + // destination (which is going to be flag's default value). + T temp(*static_cast<T*>(v2)); + if (!absl::ParseFlag<T>(*static_cast<const absl::string_view*>(v1), &temp, + static_cast<std::string*>(v3))) { + return nullptr; + } + *static_cast<T*>(v2) = std::move(temp); + return v2; + } + case FlagOp::kUnparse: + *static_cast<std::string*>(v2) = + absl::UnparseFlag<T>(*static_cast<const T*>(v1)); + return nullptr; + case FlagOp::kValueOffset: { + // Round sizeof(FlagImp) to a multiple of alignof(FlagValue<T>) to get the + // offset of the data. + ptrdiff_t round_to = alignof(FlagValue<T>); + ptrdiff_t offset = + (sizeof(FlagImpl) + round_to - 1) / round_to * round_to; + return reinterpret_cast<void*>(offset); + } } - return nullptr; + return nullptr; } -/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// // This class facilitates Flag object registration and tail expression-based // flag definition, for example: // ABSL_FLAG(int, foo, 42, "Foo help").OnUpdate(NotifyFooWatcher); -struct FlagRegistrarEmpty {}; +struct FlagRegistrarEmpty {}; template <typename T, bool do_register> class FlagRegistrar { public: @@ -777,22 +777,22 @@ class FlagRegistrar { flags_internal::RegisterCommandLineFlag(flag_.impl_, filename); } - FlagRegistrar OnUpdate(FlagCallbackFunc cb) && { - flag_.impl_.SetCallback(cb); + FlagRegistrar OnUpdate(FlagCallbackFunc cb) && { + flag_.impl_.SetCallback(cb); return *this; } - // Make the registrar "die" gracefully as an empty struct on a line where - // registration happens. Registrar objects are intended to live only as - // temporary. - operator FlagRegistrarEmpty() const { return {}; } // NOLINT + // Make the registrar "die" gracefully as an empty struct on a line where + // registration happens. Registrar objects are intended to live only as + // temporary. + operator FlagRegistrarEmpty() const { return {}; } // NOLINT private: - Flag<T>& flag_; // Flag being registered (not owned). + Flag<T>& flag_; // Flag being registered (not owned). }; } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_FLAG_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/parse.h b/contrib/restricted/abseil-cpp/absl/flags/internal/parse.h index de706c8984..1d99a287fc 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/parse.h +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/parse.h @@ -19,9 +19,9 @@ #include <string> #include <vector> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/flags/declare.h" -#include "absl/strings/string_view.h" +#include "absl/strings/string_view.h" ABSL_DECLARE_FLAG(std::vector<std::string>, flagfile); ABSL_DECLARE_FLAG(std::vector<std::string>, fromenv); @@ -29,7 +29,7 @@ ABSL_DECLARE_FLAG(std::vector<std::string>, tryfromenv); ABSL_DECLARE_FLAG(std::vector<std::string>, undefok); namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { enum class ArgvListAction { kRemoveParsedArgs, kKeepParsedArgs }; @@ -45,15 +45,15 @@ std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], UsageFlagsAction usage_flag_act, OnUndefinedFlag on_undef_flag); -// -------------------------------------------------------------------- -// Inspect original command line - -// Returns true if flag with specified name was either present on the original -// command line or specified in flag file present on the original command line. -bool WasPresentOnCommandLine(absl::string_view flag_name); - +// -------------------------------------------------------------------- +// Inspect original command line + +// Returns true if flag with specified name was either present on the original +// command line or specified in flag file present on the original command line. +bool WasPresentOnCommandLine(absl::string_view flag_name); + } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_PARSE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/path_util.h b/contrib/restricted/abseil-cpp/absl/flags/internal/path_util.h index a6594d3347..60f6080f03 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/path_util.h +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/path_util.h @@ -16,11 +16,11 @@ #ifndef ABSL_FLAGS_INTERNAL_PATH_UTIL_H_ #define ABSL_FLAGS_INTERNAL_PATH_UTIL_H_ -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { // A portable interface that returns the basename of the filename passed as an @@ -56,7 +56,7 @@ inline absl::string_view Package(absl::string_view filename) { } } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_PATH_UTIL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.cc b/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.cc index a7eb58b6d4..b0f3f42fc6 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.cc @@ -1,65 +1,65 @@ -// -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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 "absl/flags/internal/private_handle_accessor.h" - -#include <memory> -#include <string> - -#include "absl/base/config.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -FlagFastTypeId PrivateHandleAccessor::TypeId(const CommandLineFlag& flag) { - return flag.TypeId(); -} - -std::unique_ptr<FlagStateInterface> PrivateHandleAccessor::SaveState( - CommandLineFlag& flag) { - return flag.SaveState(); -} - -bool PrivateHandleAccessor::IsSpecifiedOnCommandLine( - const CommandLineFlag& flag) { - return flag.IsSpecifiedOnCommandLine(); -} - -bool PrivateHandleAccessor::ValidateInputValue(const CommandLineFlag& flag, - absl::string_view value) { - return flag.ValidateInputValue(value); -} - -void PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip( - const CommandLineFlag& flag) { - flag.CheckDefaultValueParsingRoundtrip(); -} - -bool PrivateHandleAccessor::ParseFrom(CommandLineFlag& flag, - absl::string_view value, - flags_internal::FlagSettingMode set_mode, - flags_internal::ValueSource source, - std::string& error) { - return flag.ParseFrom(value, set_mode, source, error); -} - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl - +// +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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 "absl/flags/internal/private_handle_accessor.h" + +#include <memory> +#include <string> + +#include "absl/base/config.h" +#include "absl/flags/commandlineflag.h" +#include "absl/flags/internal/commandlineflag.h" +#include "absl/strings/string_view.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace flags_internal { + +FlagFastTypeId PrivateHandleAccessor::TypeId(const CommandLineFlag& flag) { + return flag.TypeId(); +} + +std::unique_ptr<FlagStateInterface> PrivateHandleAccessor::SaveState( + CommandLineFlag& flag) { + return flag.SaveState(); +} + +bool PrivateHandleAccessor::IsSpecifiedOnCommandLine( + const CommandLineFlag& flag) { + return flag.IsSpecifiedOnCommandLine(); +} + +bool PrivateHandleAccessor::ValidateInputValue(const CommandLineFlag& flag, + absl::string_view value) { + return flag.ValidateInputValue(value); +} + +void PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip( + const CommandLineFlag& flag) { + flag.CheckDefaultValueParsingRoundtrip(); +} + +bool PrivateHandleAccessor::ParseFrom(CommandLineFlag& flag, + absl::string_view value, + flags_internal::FlagSettingMode set_mode, + flags_internal::ValueSource source, + std::string& error) { + return flag.ParseFrom(value, set_mode, source, error); +} + +} // namespace flags_internal +ABSL_NAMESPACE_END +} // namespace absl + diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.h b/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.h index c64435cd61..67a9d0d5c9 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.h +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor.h @@ -1,61 +1,61 @@ -// -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. - -#ifndef ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_ -#define ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_ - -#include <memory> -#include <string> - -#include "absl/base/config.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -// This class serves as a trampoline to access private methods of -// CommandLineFlag. This class is intended for use exclusively internally inside -// of the Abseil Flags implementation. -class PrivateHandleAccessor { - public: - // Access to CommandLineFlag::TypeId. - static FlagFastTypeId TypeId(const CommandLineFlag& flag); - - // Access to CommandLineFlag::SaveState. - static std::unique_ptr<FlagStateInterface> SaveState(CommandLineFlag& flag); - - // Access to CommandLineFlag::IsSpecifiedOnCommandLine. - static bool IsSpecifiedOnCommandLine(const CommandLineFlag& flag); - - // Access to CommandLineFlag::ValidateInputValue. - static bool ValidateInputValue(const CommandLineFlag& flag, - absl::string_view value); - - // Access to CommandLineFlag::CheckDefaultValueParsingRoundtrip. - static void CheckDefaultValueParsingRoundtrip(const CommandLineFlag& flag); - - static bool ParseFrom(CommandLineFlag& flag, absl::string_view value, - flags_internal::FlagSettingMode set_mode, - flags_internal::ValueSource source, std::string& error); -}; - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_ +// +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. + +#ifndef ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_ +#define ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_ + +#include <memory> +#include <string> + +#include "absl/base/config.h" +#include "absl/flags/commandlineflag.h" +#include "absl/flags/internal/commandlineflag.h" +#include "absl/strings/string_view.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace flags_internal { + +// This class serves as a trampoline to access private methods of +// CommandLineFlag. This class is intended for use exclusively internally inside +// of the Abseil Flags implementation. +class PrivateHandleAccessor { + public: + // Access to CommandLineFlag::TypeId. + static FlagFastTypeId TypeId(const CommandLineFlag& flag); + + // Access to CommandLineFlag::SaveState. + static std::unique_ptr<FlagStateInterface> SaveState(CommandLineFlag& flag); + + // Access to CommandLineFlag::IsSpecifiedOnCommandLine. + static bool IsSpecifiedOnCommandLine(const CommandLineFlag& flag); + + // Access to CommandLineFlag::ValidateInputValue. + static bool ValidateInputValue(const CommandLineFlag& flag, + absl::string_view value); + + // Access to CommandLineFlag::CheckDefaultValueParsingRoundtrip. + static void CheckDefaultValueParsingRoundtrip(const CommandLineFlag& flag); + + static bool ParseFrom(CommandLineFlag& flag, absl::string_view value, + flags_internal::FlagSettingMode set_mode, + flags_internal::ValueSource source, std::string& error); +}; + +} // namespace flags_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor/ya.make b/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor/ya.make index 80a55d0f76..962c786fba 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor/ya.make @@ -30,10 +30,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/flags/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/program_name.cc b/contrib/restricted/abseil-cpp/absl/flags/internal/program_name.cc index 51d698da8b..84e1d84d67 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/program_name.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/program_name.cc @@ -17,16 +17,16 @@ #include <string> -#include "absl/base/attributes.h" -#include "absl/base/config.h" -#include "absl/base/const_init.h" -#include "absl/base/thread_annotations.h" +#include "absl/base/attributes.h" +#include "absl/base/config.h" +#include "absl/base/const_init.h" +#include "absl/base/thread_annotations.h" #include "absl/flags/internal/path_util.h" -#include "absl/strings/string_view.h" +#include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { ABSL_CONST_INIT static absl::Mutex program_name_guard(absl::kConstInit); @@ -56,5 +56,5 @@ void SetProgramInvocationName(absl::string_view prog_name_str) { } } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/program_name.h b/contrib/restricted/abseil-cpp/absl/flags/internal/program_name.h index b99b94fe18..4a3821ec79 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/program_name.h +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/program_name.h @@ -18,14 +18,14 @@ #include <string> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/strings/string_view.h" // -------------------------------------------------------------------- // Program name namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { // Returns program invocation name or "UNKNOWN" if `SetProgramInvocationName()` @@ -44,7 +44,7 @@ std::string ShortProgramInvocationName(); void SetProgramInvocationName(absl::string_view prog_name_str); } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_PROGRAM_NAME_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/program_name/ya.make b/contrib/restricted/abseil-cpp/absl/flags/internal/program_name/ya.make index 701fef73c0..1f41129e97 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/program_name/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/program_name/ya.make @@ -37,10 +37,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/flags/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/registry.h b/contrib/restricted/abseil-cpp/absl/flags/internal/registry.h index 4b68c85f5c..de075a5195 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/registry.h +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/registry.h @@ -18,28 +18,28 @@ #include <functional> -#include "absl/base/config.h" -#include "absl/flags/commandlineflag.h" +#include "absl/base/config.h" +#include "absl/flags/commandlineflag.h" #include "absl/flags/internal/commandlineflag.h" -#include "absl/strings/string_view.h" +#include "absl/strings/string_view.h" // -------------------------------------------------------------------- // Global flags registry API. namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { // Executes specified visitor for each non-retired flag in the registry. While // callback are executed, the registry is locked and can't be changed. -void ForEachFlag(std::function<void(CommandLineFlag&)> visitor); +void ForEachFlag(std::function<void(CommandLineFlag&)> visitor); //----------------------------------------------------------------------------- bool RegisterCommandLineFlag(CommandLineFlag&, const char* filename); -void FinalizeRegistry(); - +void FinalizeRegistry(); + //----------------------------------------------------------------------------- // Retired registrations: // @@ -73,25 +73,25 @@ void FinalizeRegistry(); // // Retire flag with name "name" and type indicated by ops. -void Retire(const char* name, FlagFastTypeId type_id, char* buf); - -constexpr size_t kRetiredFlagObjSize = 3 * sizeof(void*); -constexpr size_t kRetiredFlagObjAlignment = alignof(void*); +void Retire(const char* name, FlagFastTypeId type_id, char* buf); +constexpr size_t kRetiredFlagObjSize = 3 * sizeof(void*); +constexpr size_t kRetiredFlagObjAlignment = alignof(void*); + // Registered a retired flag with name 'flag_name' and type 'T'. template <typename T> -class RetiredFlag { +class RetiredFlag { public: - void Retire(const char* flag_name) { - flags_internal::Retire(flag_name, base_internal::FastTypeId<T>(), buf_); - } + void Retire(const char* flag_name) { + flags_internal::Retire(flag_name, base_internal::FastTypeId<T>(), buf_); + } private: - alignas(kRetiredFlagObjAlignment) char buf_[kRetiredFlagObjSize]; + alignas(kRetiredFlagObjAlignment) char buf_[kRetiredFlagObjSize]; }; } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_REGISTRY_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc b/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc index 949709e883..3448d2688a 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/usage.cc @@ -15,23 +15,23 @@ #include "absl/flags/internal/usage.h" -#include <stdint.h> - -#include <functional> +#include <stdint.h> + +#include <functional> #include <map> -#include <ostream> +#include <ostream> #include <string> -#include <utility> -#include <vector> +#include <utility> +#include <vector> -#include "absl/base/config.h" -#include "absl/flags/commandlineflag.h" +#include "absl/base/config.h" +#include "absl/flags/commandlineflag.h" #include "absl/flags/flag.h" -#include "absl/flags/internal/flag.h" +#include "absl/flags/internal/flag.h" #include "absl/flags/internal/path_util.h" -#include "absl/flags/internal/private_handle_accessor.h" +#include "absl/flags/internal/private_handle_accessor.h" #include "absl/flags/internal/program_name.h" -#include "absl/flags/internal/registry.h" +#include "absl/flags/internal/registry.h" #include "absl/flags/usage_config.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_split.h" @@ -48,7 +48,7 @@ bool FLAGS_helpon = false; bool FLAGS_helpmatch = false; namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { namespace { @@ -111,7 +111,7 @@ class FlagHelpPrettyPrinter { // to that stream. FlagHelpPrettyPrinter(size_t max_line_len, size_t min_line_len, size_t wrapped_line_indent, std::ostream& out) - : out_(out), + : out_(out), max_line_len_(max_line_len), min_line_len_(min_line_len), wrapped_line_indent_(wrapped_line_indent), @@ -119,14 +119,14 @@ class FlagHelpPrettyPrinter { first_line_(true) {} void Write(absl::string_view str, bool wrap_line = false) { - // Empty string - do nothing. + // Empty string - do nothing. if (str.empty()) return; std::vector<absl::string_view> tokens; if (wrap_line) { for (auto line : absl::StrSplit(str, absl::ByAnyChar("\n\r"))) { if (!tokens.empty()) { - // Keep line separators in the input string. + // Keep line separators in the input string. tokens.push_back("\n"); } for (auto token : @@ -141,15 +141,15 @@ class FlagHelpPrettyPrinter { for (auto token : tokens) { bool new_line = (line_len_ == 0); - // Respect line separators in the input string. + // Respect line separators in the input string. if (token == "\n") { EndLine(); continue; } - // Write the token, ending the string first if necessary/possible. - if (!new_line && - (line_len_ + static_cast<int>(token.size()) >= max_line_len_)) { + // Write the token, ending the string first if necessary/possible. + if (!new_line && + (line_len_ + static_cast<int>(token.size()) >= max_line_len_)) { EndLine(); new_line = true; } @@ -189,11 +189,11 @@ class FlagHelpPrettyPrinter { bool first_line_; }; -void FlagHelpHumanReadable(const CommandLineFlag& flag, std::ostream& out) { +void FlagHelpHumanReadable(const CommandLineFlag& flag, std::ostream& out) { FlagHelpPrettyPrinter printer(kHrfMaxLineLength, 4, 2, out); // Flag name. - printer.Write(absl::StrCat("--", flag.Name())); + printer.Write(absl::StrCat("--", flag.Name())); // Flag help. printer.Write(absl::StrCat("(", flag.Help(), ");"), /*wrap_line=*/true); @@ -203,15 +203,15 @@ void FlagHelpHumanReadable(const CommandLineFlag& flag, std::ostream& out) { // subsequently been modified using SetCommandLineOption() with mode // SET_FLAGS_DEFAULT. std::string dflt_val = flag.DefaultValue(); - std::string curr_val = flag.CurrentValue(); - bool is_modified = curr_val != dflt_val; - + std::string curr_val = flag.CurrentValue(); + bool is_modified = curr_val != dflt_val; + if (flag.IsOfType<std::string>()) { dflt_val = absl::StrCat("\"", dflt_val, "\""); } printer.Write(absl::StrCat("default: ", dflt_val, ";")); - if (is_modified) { + if (is_modified) { if (flag.IsOfType<std::string>()) { curr_val = absl::StrCat("\"", curr_val, "\""); } @@ -251,28 +251,28 @@ void FlagsHelpImpl(std::ostream& out, PerFlagFilter filter_cb, // This map is used to output matching flags grouped by package and file // name. std::map<std::string, - std::map<std::string, std::vector<const absl::CommandLineFlag*>>> + std::map<std::string, std::vector<const absl::CommandLineFlag*>>> matching_flags; - flags_internal::ForEachFlag([&](absl::CommandLineFlag& flag) { + flags_internal::ForEachFlag([&](absl::CommandLineFlag& flag) { // Ignore retired flags. - if (flag.IsRetired()) return; + if (flag.IsRetired()) return; // If the flag has been stripped, pretend that it doesn't exist. - if (flag.Help() == flags_internal::kStrippedFlagHelp) return; + if (flag.Help() == flags_internal::kStrippedFlagHelp) return; // Make sure flag satisfies the filter if (!filter_cb(flag)) return; - std::string flag_filename = flag.Filename(); - + std::string flag_filename = flag.Filename(); + matching_flags[std::string(flags_internal::Package(flag_filename))] [flag_filename] - .push_back(&flag); + .push_back(&flag); }); - absl::string_view package_separator; // controls blank lines between packages - absl::string_view file_separator; // controls blank lines between files + absl::string_view package_separator; // controls blank lines between packages + absl::string_view file_separator; // controls blank lines between files for (auto& package : matching_flags) { if (format == HelpFormat::kHumanReadable) { out << package_separator; @@ -332,10 +332,10 @@ void FlagsHelpImpl(std::ostream& out, // -------------------------------------------------------------------- // Produces the help message describing specific flag. -void FlagHelp(std::ostream& out, const CommandLineFlag& flag, +void FlagHelp(std::ostream& out, const CommandLineFlag& flag, HelpFormat format) { if (format == HelpFormat::kHumanReadable) - flags_internal::FlagHelpHumanReadable(flag, out); + flags_internal::FlagHelpHumanReadable(flag, out); } // -------------------------------------------------------------------- @@ -520,5 +520,5 @@ bool DeduceUsageFlags(absl::string_view name, absl::string_view value) { } } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/usage.h b/contrib/restricted/abseil-cpp/absl/flags/internal/usage.h index c0bcac5762..856bdf2e04 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/usage.h +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/usage.h @@ -19,8 +19,8 @@ #include <iosfwd> #include <string> -#include "absl/base/config.h" -#include "absl/flags/commandlineflag.h" +#include "absl/base/config.h" +#include "absl/flags/commandlineflag.h" #include "absl/flags/declare.h" #include "absl/strings/string_view.h" @@ -28,7 +28,7 @@ // Usage reporting interfaces namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { // The format to report the help messages in. @@ -36,9 +36,9 @@ enum class HelpFormat { kHumanReadable, }; -// Streams the help message describing `flag` to `out`. -// The default value for `flag` is included in the output. -void FlagHelp(std::ostream& out, const CommandLineFlag& flag, +// Streams the help message describing `flag` to `out`. +// The default value for `flag` is included in the output. +void FlagHelp(std::ostream& out, const CommandLineFlag& flag, HelpFormat format = HelpFormat::kHumanReadable); // Produces the help messages for all flags matching the filter. A flag matches @@ -98,7 +98,7 @@ void SetFlagsHelpFormat(HelpFormat); bool DeduceUsageFlags(absl::string_view name, absl::string_view value); } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_INTERNAL_USAGE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/internal/usage/ya.make b/contrib/restricted/abseil-cpp/absl/flags/internal/usage/ya.make index 358744df59..22a9226f4c 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/internal/usage/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/internal/usage/ya.make @@ -1,20 +1,20 @@ -# Generated by devtools/yamaker. - -LIBRARY() - +# Generated by devtools/yamaker. + +LIBRARY() + WITHOUT_LICENSE_TEXTS() -OWNER(g:cpp-contrib) - -LICENSE(Apache-2.0) - -PEERDIR( - contrib/restricted/abseil-cpp/absl/base +OWNER(g:cpp-contrib) + +LICENSE(Apache-2.0) + +PEERDIR( + contrib/restricted/abseil-cpp/absl/base contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc - contrib/restricted/abseil-cpp/absl/base/internal/raw_logging - contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait - contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate - contrib/restricted/abseil-cpp/absl/base/log_severity + contrib/restricted/abseil-cpp/absl/base/internal/raw_logging + contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait + contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate + contrib/restricted/abseil-cpp/absl/base/log_severity contrib/restricted/abseil-cpp/absl/city contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set @@ -33,9 +33,9 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/flags/usage_config contrib/restricted/abseil-cpp/absl/hash contrib/restricted/abseil-cpp/absl/hash/internal - contrib/restricted/abseil-cpp/absl/numeric + contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased - contrib/restricted/abseil-cpp/absl/strings + contrib/restricted/abseil-cpp/absl/strings contrib/restricted/abseil-cpp/absl/strings/cord contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal @@ -49,25 +49,25 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/time/civil_time contrib/restricted/abseil-cpp/absl/time/time_zone contrib/restricted/abseil-cpp/absl/types/bad_optional_access - contrib/restricted/abseil-cpp/absl/types/bad_variant_access -) - -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DNOMINMAX -) - + contrib/restricted/abseil-cpp/absl/types/bad_variant_access +) + +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/flags/internal) - -SRCS( + +SRCS( usage.cc -) - -END() +) + +END() diff --git a/contrib/restricted/abseil-cpp/absl/flags/marshalling.cc b/contrib/restricted/abseil-cpp/absl/flags/marshalling.cc index 81f9cebd6f..e11f138849 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/marshalling.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/marshalling.cc @@ -15,28 +15,28 @@ #include "absl/flags/marshalling.h" -#include <stddef.h> - -#include <cmath> +#include <stddef.h> + +#include <cmath> #include <limits> -#include <string> +#include <string> #include <type_traits> -#include <vector> +#include <vector> -#include "absl/base/config.h" -#include "absl/base/log_severity.h" +#include "absl/base/config.h" +#include "absl/base/log_severity.h" #include "absl/base/macros.h" -#include "absl/strings/ascii.h" +#include "absl/strings/ascii.h" #include "absl/strings/match.h" #include "absl/strings/numbers.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/str_join.h" #include "absl/strings/str_split.h" -#include "absl/strings/string_view.h" +#include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { // -------------------------------------------------------------------- @@ -74,16 +74,16 @@ static int NumericBase(absl::string_view text) { } template <typename IntType> -inline bool ParseFlagImpl(absl::string_view text, IntType& dst) { +inline bool ParseFlagImpl(absl::string_view text, IntType& dst) { text = absl::StripAsciiWhitespace(text); - return absl::numbers_internal::safe_strtoi_base(text, &dst, - NumericBase(text)); + return absl::numbers_internal::safe_strtoi_base(text, &dst, + NumericBase(text)); } bool AbslParseFlag(absl::string_view text, short* dst, std::string*) { int val; - if (!ParseFlagImpl(text, val)) return false; + if (!ParseFlagImpl(text, val)) return false; if (static_cast<short>(val) != val) // worked, but number out of range return false; *dst = static_cast<short>(val); @@ -92,7 +92,7 @@ bool AbslParseFlag(absl::string_view text, short* dst, std::string*) { bool AbslParseFlag(absl::string_view text, unsigned short* dst, std::string*) { unsigned int val; - if (!ParseFlagImpl(text, val)) return false; + if (!ParseFlagImpl(text, val)) return false; if (static_cast<unsigned short>(val) != val) // worked, but number out of range return false; @@ -101,28 +101,28 @@ bool AbslParseFlag(absl::string_view text, unsigned short* dst, std::string*) { } bool AbslParseFlag(absl::string_view text, int* dst, std::string*) { - return ParseFlagImpl(text, *dst); + return ParseFlagImpl(text, *dst); } bool AbslParseFlag(absl::string_view text, unsigned int* dst, std::string*) { - return ParseFlagImpl(text, *dst); + return ParseFlagImpl(text, *dst); } bool AbslParseFlag(absl::string_view text, long* dst, std::string*) { - return ParseFlagImpl(text, *dst); + return ParseFlagImpl(text, *dst); } bool AbslParseFlag(absl::string_view text, unsigned long* dst, std::string*) { - return ParseFlagImpl(text, *dst); + return ParseFlagImpl(text, *dst); } bool AbslParseFlag(absl::string_view text, long long* dst, std::string*) { - return ParseFlagImpl(text, *dst); + return ParseFlagImpl(text, *dst); } bool AbslParseFlag(absl::string_view text, unsigned long long* dst, std::string*) { - return ParseFlagImpl(text, *dst); + return ParseFlagImpl(text, *dst); } // -------------------------------------------------------------------- @@ -173,7 +173,7 @@ std::string Unparse(long long v) { return absl::StrCat(v); } std::string Unparse(unsigned long long v) { return absl::StrCat(v); } template <typename T> std::string UnparseFloatingPointVal(T v) { - // digits10 is guaranteed to roundtrip correctly in string -> value -> string + // digits10 is guaranteed to roundtrip correctly in string -> value -> string // conversions, but may not be enough to represent all the values correctly. std::string digit10_str = absl::StrFormat("%.*g", std::numeric_limits<T>::digits10, v); @@ -237,5 +237,5 @@ std::string AbslUnparseFlag(absl::LogSeverity v) { return absl::UnparseFlag(static_cast<int>(v)); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/flags/marshalling.h b/contrib/restricted/abseil-cpp/absl/flags/marshalling.h index 7cbc136d57..46d3d1916b 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/marshalling.h +++ b/contrib/restricted/abseil-cpp/absl/flags/marshalling.h @@ -33,7 +33,7 @@ // * `double` // * `std::string` // * `std::vector<std::string>` -// * `absl::LogSeverity` (provided natively for layering reasons) +// * `absl::LogSeverity` (provided natively for layering reasons) // // Note that support for integral types is implemented using overloads for // variable-width fundamental types (`short`, `int`, `long`, etc.). However, @@ -41,8 +41,8 @@ // etc.) we've noted above within flag definitions. // // In addition, several Abseil libraries provide their own custom support for -// Abseil flags. Documentation for these formats is provided in the type's -// `AbslParseFlag()` definition. +// Abseil flags. Documentation for these formats is provided in the type's +// `AbslParseFlag()` definition. // // The Abseil time library provides the following support for civil time values: // @@ -165,11 +165,11 @@ #include <string> #include <vector> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { // Overloads of `AbslParseFlag()` and `AbslUnparseFlag()` for fundamental types. @@ -258,7 +258,7 @@ enum class LogSeverity : int; bool AbslParseFlag(absl::string_view, absl::LogSeverity*, std::string*); std::string AbslUnparseFlag(absl::LogSeverity); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_MARSHALLING_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/parse.cc b/contrib/restricted/abseil-cpp/absl/flags/parse.cc index dd1a6796ca..63cbceaabe 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/parse.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/parse.cc @@ -17,45 +17,45 @@ #include <stdlib.h> -#include <algorithm> +#include <algorithm> #include <fstream> #include <iostream> -#include <iterator> -#include <string> +#include <iterator> +#include <string> #include <tuple> -#include <utility> -#include <vector> +#include <utility> +#include <vector> #ifdef _WIN32 #include <windows.h> #endif -#include "absl/base/attributes.h" -#include "absl/base/config.h" -#include "absl/base/const_init.h" -#include "absl/base/thread_annotations.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/config.h" +#include "absl/base/attributes.h" +#include "absl/base/config.h" +#include "absl/base/const_init.h" +#include "absl/base/thread_annotations.h" +#include "absl/flags/commandlineflag.h" +#include "absl/flags/config.h" #include "absl/flags/flag.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/flags/internal/flag.h" -#include "absl/flags/internal/parse.h" -#include "absl/flags/internal/private_handle_accessor.h" +#include "absl/flags/internal/commandlineflag.h" +#include "absl/flags/internal/flag.h" +#include "absl/flags/internal/parse.h" +#include "absl/flags/internal/private_handle_accessor.h" #include "absl/flags/internal/program_name.h" #include "absl/flags/internal/usage.h" -#include "absl/flags/reflection.h" +#include "absl/flags/reflection.h" #include "absl/flags/usage.h" #include "absl/flags/usage_config.h" -#include "absl/strings/ascii.h" +#include "absl/strings/ascii.h" #include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" +#include "absl/strings/string_view.h" #include "absl/strings/strip.h" #include "absl/synchronization/mutex.h" // -------------------------------------------------------------------- namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { namespace { @@ -68,25 +68,25 @@ ABSL_CONST_INIT bool fromenv_needs_processing ABSL_CONST_INIT bool tryfromenv_needs_processing ABSL_GUARDED_BY(processing_checks_guard) = false; -ABSL_CONST_INIT absl::Mutex specified_flags_guard(absl::kConstInit); -ABSL_CONST_INIT std::vector<const CommandLineFlag*>* specified_flags - ABSL_GUARDED_BY(specified_flags_guard) = nullptr; - -struct SpecifiedFlagsCompare { - bool operator()(const CommandLineFlag* a, const CommandLineFlag* b) const { - return a->Name() < b->Name(); - } - bool operator()(const CommandLineFlag* a, absl::string_view b) const { - return a->Name() < b; - } - bool operator()(absl::string_view a, const CommandLineFlag* b) const { - return a < b->Name(); - } -}; - +ABSL_CONST_INIT absl::Mutex specified_flags_guard(absl::kConstInit); +ABSL_CONST_INIT std::vector<const CommandLineFlag*>* specified_flags + ABSL_GUARDED_BY(specified_flags_guard) = nullptr; + +struct SpecifiedFlagsCompare { + bool operator()(const CommandLineFlag* a, const CommandLineFlag* b) const { + return a->Name() < b->Name(); + } + bool operator()(const CommandLineFlag* a, absl::string_view b) const { + return a->Name() < b; + } + bool operator()(absl::string_view a, const CommandLineFlag* b) const { + return a < b->Name(); + } +}; + } // namespace } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl ABSL_FLAG(std::vector<std::string>, flagfile, {}, @@ -144,7 +144,7 @@ ABSL_FLAG(std::vector<std::string>, undefok, {}, "with that name"); namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { namespace { @@ -223,7 +223,7 @@ bool ArgsList::ReadFromFlagfile(const std::string& flag_file_name) { // Reads the environment variable with name `name` and stores results in // `value`. If variable is not present in environment returns false, otherwise // returns true. -bool GetEnvVar(const char* var_name, std::string& var_value) { +bool GetEnvVar(const char* var_name, std::string& var_value) { #ifdef _WIN32 char buf[1024]; auto get_res = GetEnvironmentVariableA(var_name, buf, sizeof(buf)); @@ -235,14 +235,14 @@ bool GetEnvVar(const char* var_name, std::string& var_value) { return false; } - var_value = std::string(buf, get_res); + var_value = std::string(buf, get_res); #else const char* val = ::getenv(var_name); if (val == nullptr) { return false; } - var_value = val; + var_value = val; #endif return true; @@ -290,11 +290,11 @@ std::tuple<absl::string_view, absl::string_view, bool> SplitNameAndValue( // found flag or nullptr // is negative in case of --nofoo std::tuple<CommandLineFlag*, bool> LocateFlag(absl::string_view flag_name) { - CommandLineFlag* flag = absl::FindCommandLineFlag(flag_name); + CommandLineFlag* flag = absl::FindCommandLineFlag(flag_name); bool is_negative = false; if (!flag && absl::ConsumePrefix(&flag_name, "no")) { - flag = absl::FindCommandLineFlag(flag_name); + flag = absl::FindCommandLineFlag(flag_name); is_negative = true; } @@ -307,17 +307,17 @@ std::tuple<CommandLineFlag*, bool> LocateFlag(absl::string_view flag_name) { // back. void CheckDefaultValuesParsingRoundtrip() { #ifndef NDEBUG - flags_internal::ForEachFlag([&](CommandLineFlag& flag) { - if (flag.IsRetired()) return; + flags_internal::ForEachFlag([&](CommandLineFlag& flag) { + if (flag.IsRetired()) return; -#define ABSL_FLAGS_INTERNAL_IGNORE_TYPE(T, _) \ - if (flag.IsOfType<T>()) return; +#define ABSL_FLAGS_INTERNAL_IGNORE_TYPE(T, _) \ + if (flag.IsOfType<T>()) return; - ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(ABSL_FLAGS_INTERNAL_IGNORE_TYPE) -#undef ABSL_FLAGS_INTERNAL_IGNORE_TYPE + ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(ABSL_FLAGS_INTERNAL_IGNORE_TYPE) +#undef ABSL_FLAGS_INTERNAL_IGNORE_TYPE - flags_internal::PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip( - flag); + flags_internal::PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip( + flag); }); #endif } @@ -330,13 +330,13 @@ void CheckDefaultValuesParsingRoundtrip() { // the first flagfile in the input list are processed before the second flagfile // etc. bool ReadFlagfiles(const std::vector<std::string>& flagfiles, - std::vector<ArgsList>& input_args) { + std::vector<ArgsList>& input_args) { bool success = true; for (auto it = flagfiles.rbegin(); it != flagfiles.rend(); ++it) { ArgsList al; if (al.ReadFromFlagfile(*it)) { - input_args.push_back(al); + input_args.push_back(al); } else { success = false; } @@ -351,7 +351,7 @@ bool ReadFlagfiles(const std::vector<std::string>& flagfiles, // `flag_name` is a string from the input flag_names list. If successful we // append a single ArgList at the end of the input_args. bool ReadFlagsFromEnv(const std::vector<std::string>& flag_names, - std::vector<ArgsList>& input_args, + std::vector<ArgsList>& input_args, bool fail_on_absent_in_env) { bool success = true; std::vector<std::string> args; @@ -372,7 +372,7 @@ bool ReadFlagsFromEnv(const std::vector<std::string>& flag_names, const std::string envname = absl::StrCat("FLAGS_", flag_name); std::string envval; - if (!GetEnvVar(envname.c_str(), envval)) { + if (!GetEnvVar(envname.c_str(), envval)) { if (fail_on_absent_in_env) { flags_internal::ReportUsageError( absl::StrCat(envname, " not found in environment"), true); @@ -387,7 +387,7 @@ bool ReadFlagsFromEnv(const std::vector<std::string>& flag_names, } if (success) { - input_args.emplace_back(args); + input_args.emplace_back(args); } return success; @@ -397,8 +397,8 @@ bool ReadFlagsFromEnv(const std::vector<std::string>& flag_names, // Returns success status, which is true if were able to handle all generator // flags (flagfile, fromenv, tryfromemv) successfully. -bool HandleGeneratorFlags(std::vector<ArgsList>& input_args, - std::vector<std::string>& flagfile_value) { +bool HandleGeneratorFlags(std::vector<ArgsList>& input_args, + std::vector<std::string>& flagfile_value) { bool success = true; absl::MutexLock l(&flags_internal::processing_checks_guard); @@ -423,9 +423,9 @@ bool HandleGeneratorFlags(std::vector<ArgsList>& input_args, if (flags_internal::flagfile_needs_processing) { auto flagfiles = absl::GetFlag(FLAGS_flagfile); - if (input_args.size() == 1) { - flagfile_value.insert(flagfile_value.end(), flagfiles.begin(), - flagfiles.end()); + if (input_args.size() == 1) { + flagfile_value.insert(flagfile_value.end(), flagfiles.begin(), + flagfiles.end()); } success &= ReadFlagfiles(flagfiles, input_args); @@ -552,12 +552,12 @@ std::tuple<bool, absl::string_view> DeduceFlagValue(const CommandLineFlag& flag, curr_list->PopFront(); value = curr_list->Front(); - // Heuristic to detect the case where someone treats a string arg + // Heuristic to detect the case where someone treats a string arg // like a bool or just forgets to pass a value: // --my_string_var --foo=bar - // We look for a flag of string type, whose value begins with a + // We look for a flag of string type, whose value begins with a // dash and corresponds to known flag or standalone --. - if (!value.empty() && value[0] == '-' && flag.IsOfType<std::string>()) { + if (!value.empty() && value[0] == '-' && flag.IsOfType<std::string>()) { auto maybe_flag_name = std::get<0>(SplitNameAndValue(value.substr(1))); if (maybe_flag_name.empty() || @@ -594,28 +594,28 @@ bool CanIgnoreUndefinedFlag(absl::string_view flag_name) { // -------------------------------------------------------------------- -bool WasPresentOnCommandLine(absl::string_view flag_name) { - absl::MutexLock l(&specified_flags_guard); - ABSL_INTERNAL_CHECK(specified_flags != nullptr, - "ParseCommandLine is not invoked yet"); - - return std::binary_search(specified_flags->begin(), specified_flags->end(), - flag_name, SpecifiedFlagsCompare{}); -} - -// -------------------------------------------------------------------- - +bool WasPresentOnCommandLine(absl::string_view flag_name) { + absl::MutexLock l(&specified_flags_guard); + ABSL_INTERNAL_CHECK(specified_flags != nullptr, + "ParseCommandLine is not invoked yet"); + + return std::binary_search(specified_flags->begin(), specified_flags->end(), + flag_name, SpecifiedFlagsCompare{}); +} + +// -------------------------------------------------------------------- + std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], ArgvListAction arg_list_act, UsageFlagsAction usage_flag_act, OnUndefinedFlag on_undef_flag) { ABSL_INTERNAL_CHECK(argc > 0, "Missing argv[0]"); - // Once parsing has started we will not have more flag registrations. - // If we did, they would be missing during parsing, which is a problem on - // itself. - flags_internal::FinalizeRegistry(); - + // Once parsing has started we will not have more flag registrations. + // If we did, they would be missing during parsing, which is a problem on + // itself. + flags_internal::FinalizeRegistry(); + // This routine does not return anything since we abort on failure. CheckDefaultValuesParsingRoundtrip(); @@ -640,20 +640,20 @@ std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], } output_args.push_back(argv[0]); - absl::MutexLock l(&specified_flags_guard); - if (specified_flags == nullptr) { - specified_flags = new std::vector<const CommandLineFlag*>; - } else { - specified_flags->clear(); - } - + absl::MutexLock l(&specified_flags_guard); + if (specified_flags == nullptr) { + specified_flags = new std::vector<const CommandLineFlag*>; + } else { + specified_flags->clear(); + } + // Iterate through the list of the input arguments. First level are arguments // originated from argc/argv. Following levels are arguments originated from // recursive parsing of flagfile(s). bool success = true; while (!input_args.empty()) { // 10. First we process the built-in generator flags. - success &= HandleGeneratorFlags(input_args, flagfile_value); + success &= HandleGeneratorFlags(input_args, flagfile_value); // 30. Select top-most (most recent) arguments list. If it is empty drop it // and re-try. @@ -688,7 +688,7 @@ std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], // 60. Split the current argument on '=' to figure out the argument // name and value. If flag name is empty it means we've got "--". value - // can be empty either if there were no '=' in argument string at all or + // can be empty either if there were no '=' in argument string at all or // an argument looked like "--foo=". In a latter case is_empty_value is // true. absl::string_view flag_name; @@ -739,17 +739,17 @@ std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], } // 100. Set the located flag to a new new value, unless it is retired. - // Setting retired flag fails, but we ignoring it here while also reporting - // access to retired flag. - std::string error; - if (!flags_internal::PrivateHandleAccessor::ParseFrom( - *flag, value, SET_FLAGS_VALUE, kCommandLine, error)) { - if (flag->IsRetired()) continue; + // Setting retired flag fails, but we ignoring it here while also reporting + // access to retired flag. + std::string error; + if (!flags_internal::PrivateHandleAccessor::ParseFrom( + *flag, value, SET_FLAGS_VALUE, kCommandLine, error)) { + if (flag->IsRetired()) continue; flags_internal::ReportUsageError(error, true); success = false; - } else { - specified_flags->push_back(flag); + } else { + specified_flags->push_back(flag); } } @@ -801,10 +801,10 @@ std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], } } - // Trim and sort the vector. - specified_flags->shrink_to_fit(); - std::sort(specified_flags->begin(), specified_flags->end(), - SpecifiedFlagsCompare{}); + // Trim and sort the vector. + specified_flags->shrink_to_fit(); + std::sort(specified_flags->begin(), specified_flags->end(), + SpecifiedFlagsCompare{}); return output_args; } @@ -819,5 +819,5 @@ std::vector<char*> ParseCommandLine(int argc, char* argv[]) { flags_internal::OnUndefinedFlag::kAbortIfUndefined); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/flags/parse.h b/contrib/restricted/abseil-cpp/absl/flags/parse.h index 929de2cb40..b1c48a5355 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/parse.h +++ b/contrib/restricted/abseil-cpp/absl/flags/parse.h @@ -25,11 +25,11 @@ #include <vector> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/flags/internal/parse.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ParseCommandLine() // @@ -54,7 +54,7 @@ ABSL_NAMESPACE_BEGIN // help messages and then exits the program. std::vector<char*> ParseCommandLine(int argc, char* argv[]); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_PARSE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/parse/ya.make b/contrib/restricted/abseil-cpp/absl/flags/parse/ya.make index 267b3e4a97..226b264963 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/parse/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/parse/ya.make @@ -62,10 +62,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/flags) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/flags/reflection.cc b/contrib/restricted/abseil-cpp/absl/flags/reflection.cc index dbce4032ab..846abe9b80 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/reflection.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/reflection.cc @@ -1,115 +1,115 @@ -// -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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 "absl/flags/reflection.h" - -#include <assert.h> - -#include <atomic> -#include <string> - -#include "absl/base/config.h" -#include "absl/base/thread_annotations.h" +// +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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 "absl/flags/reflection.h" + +#include <assert.h> + +#include <atomic> +#include <string> + +#include "absl/base/config.h" +#include "absl/base/thread_annotations.h" #include "absl/container/flat_hash_map.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/internal/private_handle_accessor.h" -#include "absl/flags/internal/registry.h" -#include "absl/flags/usage_config.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "absl/synchronization/mutex.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -// -------------------------------------------------------------------- -// FlagRegistry -// A FlagRegistry singleton object holds all flag objects indexed by their -// names so that if you know a flag's name, you can access or set it. If the -// function is named FooLocked(), you must own the registry lock before -// calling the function; otherwise, you should *not* hold the lock, and the -// function will acquire it itself if needed. -// -------------------------------------------------------------------- - -class FlagRegistry { - public: - FlagRegistry() = default; - ~FlagRegistry() = default; - - // Store a flag in this registry. Takes ownership of *flag. +#include "absl/flags/commandlineflag.h" +#include "absl/flags/internal/private_handle_accessor.h" +#include "absl/flags/internal/registry.h" +#include "absl/flags/usage_config.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "absl/synchronization/mutex.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace flags_internal { + +// -------------------------------------------------------------------- +// FlagRegistry +// A FlagRegistry singleton object holds all flag objects indexed by their +// names so that if you know a flag's name, you can access or set it. If the +// function is named FooLocked(), you must own the registry lock before +// calling the function; otherwise, you should *not* hold the lock, and the +// function will acquire it itself if needed. +// -------------------------------------------------------------------- + +class FlagRegistry { + public: + FlagRegistry() = default; + ~FlagRegistry() = default; + + // Store a flag in this registry. Takes ownership of *flag. void RegisterFlag(CommandLineFlag& flag, const char* filename); - - void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); } - void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); } - - // Returns the flag object for the specified name, or nullptr if not found. - // Will emit a warning if a 'retired' flag is specified. - CommandLineFlag* FindFlag(absl::string_view name); - - static FlagRegistry& GlobalRegistry(); // returns a singleton registry - - private: - friend class flags_internal::FlagSaverImpl; // reads all the flags in order - // to copy them - friend void ForEachFlag(std::function<void(CommandLineFlag&)> visitor); - friend void FinalizeRegistry(); - - // The map from name to flag, for FindFlag(). + + void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); } + void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); } + + // Returns the flag object for the specified name, or nullptr if not found. + // Will emit a warning if a 'retired' flag is specified. + CommandLineFlag* FindFlag(absl::string_view name); + + static FlagRegistry& GlobalRegistry(); // returns a singleton registry + + private: + friend class flags_internal::FlagSaverImpl; // reads all the flags in order + // to copy them + friend void ForEachFlag(std::function<void(CommandLineFlag&)> visitor); + friend void FinalizeRegistry(); + + // The map from name to flag, for FindFlag(). using FlagMap = absl::flat_hash_map<absl::string_view, CommandLineFlag*>; - using FlagIterator = FlagMap::iterator; - using FlagConstIterator = FlagMap::const_iterator; - FlagMap flags_; - std::vector<CommandLineFlag*> flat_flags_; - std::atomic<bool> finalized_flags_{false}; - - absl::Mutex lock_; - - // Disallow - FlagRegistry(const FlagRegistry&); - FlagRegistry& operator=(const FlagRegistry&); -}; - -namespace { - -class FlagRegistryLock { - public: - explicit FlagRegistryLock(FlagRegistry& fr) : fr_(fr) { fr_.Lock(); } - ~FlagRegistryLock() { fr_.Unlock(); } - - private: - FlagRegistry& fr_; -}; - -} // namespace - -CommandLineFlag* FlagRegistry::FindFlag(absl::string_view name) { - if (finalized_flags_.load(std::memory_order_acquire)) { - // We could save some gcus here if we make `Name()` be non-virtual. - // We could move the `const char*` name to the base class. - auto it = std::partition_point( - flat_flags_.begin(), flat_flags_.end(), - [=](CommandLineFlag* f) { return f->Name() < name; }); - if (it != flat_flags_.end() && (*it)->Name() == name) return *it; - } - - FlagRegistryLock frl(*this); - auto it = flags_.find(name); - return it != flags_.end() ? it->second : nullptr; -} - + using FlagIterator = FlagMap::iterator; + using FlagConstIterator = FlagMap::const_iterator; + FlagMap flags_; + std::vector<CommandLineFlag*> flat_flags_; + std::atomic<bool> finalized_flags_{false}; + + absl::Mutex lock_; + + // Disallow + FlagRegistry(const FlagRegistry&); + FlagRegistry& operator=(const FlagRegistry&); +}; + +namespace { + +class FlagRegistryLock { + public: + explicit FlagRegistryLock(FlagRegistry& fr) : fr_(fr) { fr_.Lock(); } + ~FlagRegistryLock() { fr_.Unlock(); } + + private: + FlagRegistry& fr_; +}; + +} // namespace + +CommandLineFlag* FlagRegistry::FindFlag(absl::string_view name) { + if (finalized_flags_.load(std::memory_order_acquire)) { + // We could save some gcus here if we make `Name()` be non-virtual. + // We could move the `const char*` name to the base class. + auto it = std::partition_point( + flat_flags_.begin(), flat_flags_.end(), + [=](CommandLineFlag* f) { return f->Name() < name; }); + if (it != flat_flags_.end() && (*it)->Name() == name) return *it; + } + + FlagRegistryLock frl(*this); + auto it = flags_.find(name); + return it != flags_.end() ? it->second : nullptr; +} + void FlagRegistry::RegisterFlag(CommandLineFlag& flag, const char* filename) { if (filename != nullptr && flag.Filename() != GetUsageConfig().normalize_filename(filename)) { @@ -124,231 +124,231 @@ void FlagRegistry::RegisterFlag(CommandLineFlag& flag, const char* filename) { std::exit(1); } - FlagRegistryLock registry_lock(*this); - - std::pair<FlagIterator, bool> ins = - flags_.insert(FlagMap::value_type(flag.Name(), &flag)); - if (ins.second == false) { // means the name was already in the map - CommandLineFlag& old_flag = *ins.first->second; - if (flag.IsRetired() != old_flag.IsRetired()) { - // All registrations must agree on the 'retired' flag. - flags_internal::ReportUsageError( - absl::StrCat( - "Retired flag '", flag.Name(), "' was defined normally in file '", - (flag.IsRetired() ? old_flag.Filename() : flag.Filename()), "'."), - true); - } else if (flags_internal::PrivateHandleAccessor::TypeId(flag) != - flags_internal::PrivateHandleAccessor::TypeId(old_flag)) { - flags_internal::ReportUsageError( - absl::StrCat("Flag '", flag.Name(), - "' was defined more than once but with " - "differing types. Defined in files '", - old_flag.Filename(), "' and '", flag.Filename(), "'."), - true); - } else if (old_flag.IsRetired()) { - return; - } else if (old_flag.Filename() != flag.Filename()) { - flags_internal::ReportUsageError( - absl::StrCat("Flag '", flag.Name(), - "' was defined more than once (in files '", - old_flag.Filename(), "' and '", flag.Filename(), "')."), - true); - } else { - flags_internal::ReportUsageError( - absl::StrCat( - "Something is wrong with flag '", flag.Name(), "' in file '", - flag.Filename(), "'. One possibility: file '", flag.Filename(), - "' is being linked both statically and dynamically into this " - "executable. e.g. some files listed as srcs to a test and also " - "listed as srcs of some shared lib deps of the same test."), - true); - } - // All cases above are fatal, except for the retired flags. - std::exit(1); - } -} - -FlagRegistry& FlagRegistry::GlobalRegistry() { - static FlagRegistry* global_registry = new FlagRegistry; - return *global_registry; -} - -// -------------------------------------------------------------------- - -void ForEachFlag(std::function<void(CommandLineFlag&)> visitor) { - FlagRegistry& registry = FlagRegistry::GlobalRegistry(); - - if (registry.finalized_flags_.load(std::memory_order_acquire)) { - for (const auto& i : registry.flat_flags_) visitor(*i); - } - - FlagRegistryLock frl(registry); - for (const auto& i : registry.flags_) visitor(*i.second); -} - -// -------------------------------------------------------------------- - + FlagRegistryLock registry_lock(*this); + + std::pair<FlagIterator, bool> ins = + flags_.insert(FlagMap::value_type(flag.Name(), &flag)); + if (ins.second == false) { // means the name was already in the map + CommandLineFlag& old_flag = *ins.first->second; + if (flag.IsRetired() != old_flag.IsRetired()) { + // All registrations must agree on the 'retired' flag. + flags_internal::ReportUsageError( + absl::StrCat( + "Retired flag '", flag.Name(), "' was defined normally in file '", + (flag.IsRetired() ? old_flag.Filename() : flag.Filename()), "'."), + true); + } else if (flags_internal::PrivateHandleAccessor::TypeId(flag) != + flags_internal::PrivateHandleAccessor::TypeId(old_flag)) { + flags_internal::ReportUsageError( + absl::StrCat("Flag '", flag.Name(), + "' was defined more than once but with " + "differing types. Defined in files '", + old_flag.Filename(), "' and '", flag.Filename(), "'."), + true); + } else if (old_flag.IsRetired()) { + return; + } else if (old_flag.Filename() != flag.Filename()) { + flags_internal::ReportUsageError( + absl::StrCat("Flag '", flag.Name(), + "' was defined more than once (in files '", + old_flag.Filename(), "' and '", flag.Filename(), "')."), + true); + } else { + flags_internal::ReportUsageError( + absl::StrCat( + "Something is wrong with flag '", flag.Name(), "' in file '", + flag.Filename(), "'. One possibility: file '", flag.Filename(), + "' is being linked both statically and dynamically into this " + "executable. e.g. some files listed as srcs to a test and also " + "listed as srcs of some shared lib deps of the same test."), + true); + } + // All cases above are fatal, except for the retired flags. + std::exit(1); + } +} + +FlagRegistry& FlagRegistry::GlobalRegistry() { + static FlagRegistry* global_registry = new FlagRegistry; + return *global_registry; +} + +// -------------------------------------------------------------------- + +void ForEachFlag(std::function<void(CommandLineFlag&)> visitor) { + FlagRegistry& registry = FlagRegistry::GlobalRegistry(); + + if (registry.finalized_flags_.load(std::memory_order_acquire)) { + for (const auto& i : registry.flat_flags_) visitor(*i); + } + + FlagRegistryLock frl(registry); + for (const auto& i : registry.flags_) visitor(*i.second); +} + +// -------------------------------------------------------------------- + bool RegisterCommandLineFlag(CommandLineFlag& flag, const char* filename) { FlagRegistry::GlobalRegistry().RegisterFlag(flag, filename); - return true; -} - -void FinalizeRegistry() { - auto& registry = FlagRegistry::GlobalRegistry(); - FlagRegistryLock frl(registry); - if (registry.finalized_flags_.load(std::memory_order_relaxed)) { - // Was already finalized. Ignore the second time. - return; - } - registry.flat_flags_.reserve(registry.flags_.size()); - for (const auto& f : registry.flags_) { - registry.flat_flags_.push_back(f.second); - } + return true; +} + +void FinalizeRegistry() { + auto& registry = FlagRegistry::GlobalRegistry(); + FlagRegistryLock frl(registry); + if (registry.finalized_flags_.load(std::memory_order_relaxed)) { + // Was already finalized. Ignore the second time. + return; + } + registry.flat_flags_.reserve(registry.flags_.size()); + for (const auto& f : registry.flags_) { + registry.flat_flags_.push_back(f.second); + } std::sort(std::begin(registry.flat_flags_), std::end(registry.flat_flags_), [](const CommandLineFlag* lhs, const CommandLineFlag* rhs) { return lhs->Name() < rhs->Name(); }); - registry.flags_.clear(); - registry.finalized_flags_.store(true, std::memory_order_release); -} - -// -------------------------------------------------------------------- - -namespace { - -class RetiredFlagObj final : public CommandLineFlag { - public: - constexpr RetiredFlagObj(const char* name, FlagFastTypeId type_id) - : name_(name), type_id_(type_id) {} - - private: - absl::string_view Name() const override { return name_; } - std::string Filename() const override { - OnAccess(); - return "RETIRED"; - } - FlagFastTypeId TypeId() const override { return type_id_; } - std::string Help() const override { - OnAccess(); - return ""; - } - bool IsRetired() const override { return true; } - bool IsSpecifiedOnCommandLine() const override { - OnAccess(); - return false; - } - std::string DefaultValue() const override { - OnAccess(); - return ""; - } - std::string CurrentValue() const override { - OnAccess(); - return ""; - } - - // Any input is valid - bool ValidateInputValue(absl::string_view) const override { - OnAccess(); - return true; - } - - std::unique_ptr<flags_internal::FlagStateInterface> SaveState() override { - return nullptr; - } - - bool ParseFrom(absl::string_view, flags_internal::FlagSettingMode, - flags_internal::ValueSource, std::string&) override { - OnAccess(); - return false; - } - - void CheckDefaultValueParsingRoundtrip() const override { OnAccess(); } - - void Read(void*) const override { OnAccess(); } - - void OnAccess() const { - flags_internal::ReportUsageError( - absl::StrCat("Accessing retired flag '", name_, "'"), false); - } - - // Data members - const char* const name_; - const FlagFastTypeId type_id_; -}; - -} // namespace - -void Retire(const char* name, FlagFastTypeId type_id, char* buf) { - static_assert(sizeof(RetiredFlagObj) == kRetiredFlagObjSize, ""); - static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment, ""); - auto* flag = ::new (static_cast<void*>(buf)) - flags_internal::RetiredFlagObj(name, type_id); + registry.flags_.clear(); + registry.finalized_flags_.store(true, std::memory_order_release); +} + +// -------------------------------------------------------------------- + +namespace { + +class RetiredFlagObj final : public CommandLineFlag { + public: + constexpr RetiredFlagObj(const char* name, FlagFastTypeId type_id) + : name_(name), type_id_(type_id) {} + + private: + absl::string_view Name() const override { return name_; } + std::string Filename() const override { + OnAccess(); + return "RETIRED"; + } + FlagFastTypeId TypeId() const override { return type_id_; } + std::string Help() const override { + OnAccess(); + return ""; + } + bool IsRetired() const override { return true; } + bool IsSpecifiedOnCommandLine() const override { + OnAccess(); + return false; + } + std::string DefaultValue() const override { + OnAccess(); + return ""; + } + std::string CurrentValue() const override { + OnAccess(); + return ""; + } + + // Any input is valid + bool ValidateInputValue(absl::string_view) const override { + OnAccess(); + return true; + } + + std::unique_ptr<flags_internal::FlagStateInterface> SaveState() override { + return nullptr; + } + + bool ParseFrom(absl::string_view, flags_internal::FlagSettingMode, + flags_internal::ValueSource, std::string&) override { + OnAccess(); + return false; + } + + void CheckDefaultValueParsingRoundtrip() const override { OnAccess(); } + + void Read(void*) const override { OnAccess(); } + + void OnAccess() const { + flags_internal::ReportUsageError( + absl::StrCat("Accessing retired flag '", name_, "'"), false); + } + + // Data members + const char* const name_; + const FlagFastTypeId type_id_; +}; + +} // namespace + +void Retire(const char* name, FlagFastTypeId type_id, char* buf) { + static_assert(sizeof(RetiredFlagObj) == kRetiredFlagObjSize, ""); + static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment, ""); + auto* flag = ::new (static_cast<void*>(buf)) + flags_internal::RetiredFlagObj(name, type_id); FlagRegistry::GlobalRegistry().RegisterFlag(*flag, nullptr); -} - -// -------------------------------------------------------------------- - -class FlagSaverImpl { - public: - FlagSaverImpl() = default; - FlagSaverImpl(const FlagSaverImpl&) = delete; - void operator=(const FlagSaverImpl&) = delete; - - // Saves the flag states from the flag registry into this object. - // It's an error to call this more than once. - void SaveFromRegistry() { - assert(backup_registry_.empty()); // call only once! - flags_internal::ForEachFlag([&](CommandLineFlag& flag) { - if (auto flag_state = - flags_internal::PrivateHandleAccessor::SaveState(flag)) { - backup_registry_.emplace_back(std::move(flag_state)); - } - }); - } - - // Restores the saved flag states into the flag registry. - void RestoreToRegistry() { - for (const auto& flag_state : backup_registry_) { - flag_state->Restore(); - } - } - - private: - std::vector<std::unique_ptr<flags_internal::FlagStateInterface>> - backup_registry_; -}; - -} // namespace flags_internal - -FlagSaver::FlagSaver() : impl_(new flags_internal::FlagSaverImpl) { - impl_->SaveFromRegistry(); -} - -FlagSaver::~FlagSaver() { - if (!impl_) return; - - impl_->RestoreToRegistry(); - delete impl_; -} - -// -------------------------------------------------------------------- - -CommandLineFlag* FindCommandLineFlag(absl::string_view name) { - if (name.empty()) return nullptr; - flags_internal::FlagRegistry& registry = - flags_internal::FlagRegistry::GlobalRegistry(); - return registry.FindFlag(name); -} - -// -------------------------------------------------------------------- - -absl::flat_hash_map<absl::string_view, absl::CommandLineFlag*> GetAllFlags() { - absl::flat_hash_map<absl::string_view, absl::CommandLineFlag*> res; - flags_internal::ForEachFlag([&](CommandLineFlag& flag) { +} + +// -------------------------------------------------------------------- + +class FlagSaverImpl { + public: + FlagSaverImpl() = default; + FlagSaverImpl(const FlagSaverImpl&) = delete; + void operator=(const FlagSaverImpl&) = delete; + + // Saves the flag states from the flag registry into this object. + // It's an error to call this more than once. + void SaveFromRegistry() { + assert(backup_registry_.empty()); // call only once! + flags_internal::ForEachFlag([&](CommandLineFlag& flag) { + if (auto flag_state = + flags_internal::PrivateHandleAccessor::SaveState(flag)) { + backup_registry_.emplace_back(std::move(flag_state)); + } + }); + } + + // Restores the saved flag states into the flag registry. + void RestoreToRegistry() { + for (const auto& flag_state : backup_registry_) { + flag_state->Restore(); + } + } + + private: + std::vector<std::unique_ptr<flags_internal::FlagStateInterface>> + backup_registry_; +}; + +} // namespace flags_internal + +FlagSaver::FlagSaver() : impl_(new flags_internal::FlagSaverImpl) { + impl_->SaveFromRegistry(); +} + +FlagSaver::~FlagSaver() { + if (!impl_) return; + + impl_->RestoreToRegistry(); + delete impl_; +} + +// -------------------------------------------------------------------- + +CommandLineFlag* FindCommandLineFlag(absl::string_view name) { + if (name.empty()) return nullptr; + flags_internal::FlagRegistry& registry = + flags_internal::FlagRegistry::GlobalRegistry(); + return registry.FindFlag(name); +} + +// -------------------------------------------------------------------- + +absl::flat_hash_map<absl::string_view, absl::CommandLineFlag*> GetAllFlags() { + absl::flat_hash_map<absl::string_view, absl::CommandLineFlag*> res; + flags_internal::ForEachFlag([&](CommandLineFlag& flag) { if (!flag.IsRetired()) res.insert({flag.Name(), &flag}); - }); - return res; -} - -ABSL_NAMESPACE_END -} // namespace absl + }); + return res; +} + +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/flags/reflection.h b/contrib/restricted/abseil-cpp/absl/flags/reflection.h index e6baf5de4b..f42ef67858 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/reflection.h +++ b/contrib/restricted/abseil-cpp/absl/flags/reflection.h @@ -1,90 +1,90 @@ -// -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// File: reflection.h -// ----------------------------------------------------------------------------- -// -// This file defines the routines to access and operate on an Abseil Flag's -// reflection handle. - -#ifndef ABSL_FLAGS_REFLECTION_H_ -#define ABSL_FLAGS_REFLECTION_H_ - -#include <string> - -#include "absl/base/config.h" -#include "absl/container/flat_hash_map.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/internal/commandlineflag.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { -class FlagSaverImpl; -} // namespace flags_internal - -// FindCommandLineFlag() -// -// Returns the reflection handle of an Abseil flag of the specified name, or -// `nullptr` if not found. This function will emit a warning if the name of a -// 'retired' flag is specified. -absl::CommandLineFlag* FindCommandLineFlag(absl::string_view name); - -// Returns current state of the Flags registry in a form of mapping from flag -// name to a flag reflection handle. -absl::flat_hash_map<absl::string_view, absl::CommandLineFlag*> GetAllFlags(); - -//------------------------------------------------------------------------------ -// FlagSaver -//------------------------------------------------------------------------------ -// -// A FlagSaver object stores the state of flags in the scope where the FlagSaver -// is defined, allowing modification of those flags within that scope and -// automatic restoration of the flags to their previous state upon leaving the -// scope. -// -// A FlagSaver can be used within tests to temporarily change the test -// environment and restore the test case to its previous state. -// -// Example: -// -// void MyFunc() { -// absl::FlagSaver fs; -// ... +// +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// File: reflection.h +// ----------------------------------------------------------------------------- +// +// This file defines the routines to access and operate on an Abseil Flag's +// reflection handle. + +#ifndef ABSL_FLAGS_REFLECTION_H_ +#define ABSL_FLAGS_REFLECTION_H_ + +#include <string> + +#include "absl/base/config.h" +#include "absl/container/flat_hash_map.h" +#include "absl/flags/commandlineflag.h" +#include "absl/flags/internal/commandlineflag.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace flags_internal { +class FlagSaverImpl; +} // namespace flags_internal + +// FindCommandLineFlag() +// +// Returns the reflection handle of an Abseil flag of the specified name, or +// `nullptr` if not found. This function will emit a warning if the name of a +// 'retired' flag is specified. +absl::CommandLineFlag* FindCommandLineFlag(absl::string_view name); + +// Returns current state of the Flags registry in a form of mapping from flag +// name to a flag reflection handle. +absl::flat_hash_map<absl::string_view, absl::CommandLineFlag*> GetAllFlags(); + +//------------------------------------------------------------------------------ +// FlagSaver +//------------------------------------------------------------------------------ +// +// A FlagSaver object stores the state of flags in the scope where the FlagSaver +// is defined, allowing modification of those flags within that scope and +// automatic restoration of the flags to their previous state upon leaving the +// scope. +// +// A FlagSaver can be used within tests to temporarily change the test +// environment and restore the test case to its previous state. +// +// Example: +// +// void MyFunc() { +// absl::FlagSaver fs; +// ... // absl::SetFlag(&FLAGS_myFlag, otherValue); -// ... -// } // scope of FlagSaver left, flags return to previous state -// -// This class is thread-safe. - -class FlagSaver { - public: - FlagSaver(); - ~FlagSaver(); - - FlagSaver(const FlagSaver&) = delete; - void operator=(const FlagSaver&) = delete; - - private: - flags_internal::FlagSaverImpl* impl_; -}; - -//----------------------------------------------------------------------------- - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FLAGS_REFLECTION_H_ +// ... +// } // scope of FlagSaver left, flags return to previous state +// +// This class is thread-safe. + +class FlagSaver { + public: + FlagSaver(); + ~FlagSaver(); + + FlagSaver(const FlagSaver&) = delete; + void operator=(const FlagSaver&) = delete; + + private: + flags_internal::FlagSaverImpl* impl_; +}; + +//----------------------------------------------------------------------------- + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_FLAGS_REFLECTION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/reflection/ya.make b/contrib/restricted/abseil-cpp/absl/flags/reflection/ya.make index f75bc1c67d..3f8cbe6b2e 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/reflection/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/reflection/ya.make @@ -1,20 +1,20 @@ -# Generated by devtools/yamaker. - -LIBRARY() - +# Generated by devtools/yamaker. + +LIBRARY() + WITHOUT_LICENSE_TEXTS() -OWNER(g:cpp-contrib) - -LICENSE(Apache-2.0) - -PEERDIR( - contrib/restricted/abseil-cpp/absl/base +OWNER(g:cpp-contrib) + +LICENSE(Apache-2.0) + +PEERDIR( + contrib/restricted/abseil-cpp/absl/base contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc - contrib/restricted/abseil-cpp/absl/base/internal/raw_logging - contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait - contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate - contrib/restricted/abseil-cpp/absl/base/log_severity + contrib/restricted/abseil-cpp/absl/base/internal/raw_logging + contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait + contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate + contrib/restricted/abseil-cpp/absl/base/log_severity contrib/restricted/abseil-cpp/absl/city contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set @@ -29,9 +29,9 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/flags/usage_config contrib/restricted/abseil-cpp/absl/hash contrib/restricted/abseil-cpp/absl/hash/internal - contrib/restricted/abseil-cpp/absl/numeric + contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased - contrib/restricted/abseil-cpp/absl/strings + contrib/restricted/abseil-cpp/absl/strings contrib/restricted/abseil-cpp/absl/strings/cord contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal @@ -44,25 +44,25 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/time/civil_time contrib/restricted/abseil-cpp/absl/time/time_zone contrib/restricted/abseil-cpp/absl/types/bad_optional_access - contrib/restricted/abseil-cpp/absl/types/bad_variant_access -) - -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DNOMINMAX -) - + contrib/restricted/abseil-cpp/absl/types/bad_variant_access +) + +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/flags) - -SRCS( + +SRCS( reflection.cc -) - -END() +) + +END() diff --git a/contrib/restricted/abseil-cpp/absl/flags/usage.cc b/contrib/restricted/abseil-cpp/absl/flags/usage.cc index 452f667512..009b12a823 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/usage.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/usage.cc @@ -14,20 +14,20 @@ // limitations under the License. #include "absl/flags/usage.h" -#include <stdlib.h> - +#include <stdlib.h> + #include <string> -#include "absl/base/attributes.h" -#include "absl/base/config.h" -#include "absl/base/const_init.h" -#include "absl/base/thread_annotations.h" +#include "absl/base/attributes.h" +#include "absl/base/config.h" +#include "absl/base/const_init.h" +#include "absl/base/thread_annotations.h" #include "absl/flags/internal/usage.h" -#include "absl/strings/string_view.h" +#include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { namespace { ABSL_CONST_INIT absl::Mutex usage_message_guard(absl::kConstInit); @@ -61,5 +61,5 @@ absl::string_view ProgramUsageMessage() { : "Warning: SetProgramUsageMessage() never called"; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/flags/usage.h b/contrib/restricted/abseil-cpp/absl/flags/usage.h index ad12ab7ad9..3870fa3e7f 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/usage.h +++ b/contrib/restricted/abseil-cpp/absl/flags/usage.h @@ -16,14 +16,14 @@ #ifndef ABSL_FLAGS_USAGE_H_ #define ABSL_FLAGS_USAGE_H_ -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/strings/string_view.h" // -------------------------------------------------------------------- // Usage reporting interfaces namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // Sets the "usage" message to be used by help reporting routines. // For example: @@ -37,7 +37,7 @@ void SetProgramUsageMessage(absl::string_view new_usage_message); // Returns the usage message set by SetProgramUsageMessage(). absl::string_view ProgramUsageMessage(); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FLAGS_USAGE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/flags/usage/ya.make b/contrib/restricted/abseil-cpp/absl/flags/usage/ya.make index f6b243c84c..41bfb0fd99 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/usage/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/usage/ya.make @@ -15,24 +15,24 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/city - contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler - contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set + contrib/restricted/abseil-cpp/absl/city + contrib/restricted/abseil-cpp/absl/container/internal/absl_hashtablez_sampler + contrib/restricted/abseil-cpp/absl/container/internal/raw_hash_set contrib/restricted/abseil-cpp/absl/debugging contrib/restricted/abseil-cpp/absl/debugging/stacktrace contrib/restricted/abseil-cpp/absl/debugging/symbolize contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/flags - contrib/restricted/abseil-cpp/absl/flags/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/commandlineflag contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag contrib/restricted/abseil-cpp/absl/flags/internal/flag - contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor + contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor contrib/restricted/abseil-cpp/absl/flags/internal/program_name contrib/restricted/abseil-cpp/absl/flags/internal/usage contrib/restricted/abseil-cpp/absl/flags/marshalling - contrib/restricted/abseil-cpp/absl/flags/reflection + contrib/restricted/abseil-cpp/absl/flags/reflection contrib/restricted/abseil-cpp/absl/flags/usage_config - contrib/restricted/abseil-cpp/absl/hash + contrib/restricted/abseil-cpp/absl/hash contrib/restricted/abseil-cpp/absl/hash/internal contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased @@ -50,7 +50,7 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/time/civil_time contrib/restricted/abseil-cpp/absl/time/time_zone contrib/restricted/abseil-cpp/absl/types/bad_optional_access - contrib/restricted/abseil-cpp/absl/types/bad_variant_access + contrib/restricted/abseil-cpp/absl/types/bad_variant_access ) ADDINCL( @@ -61,10 +61,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/flags) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/flags/usage_config.cc b/contrib/restricted/abseil-cpp/absl/flags/usage_config.cc index 5d7426db31..da958741dd 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/usage_config.cc +++ b/contrib/restricted/abseil-cpp/absl/flags/usage_config.cc @@ -15,18 +15,18 @@ #include "absl/flags/usage_config.h" -#include <functional> +#include <functional> #include <iostream> -#include <string> +#include <string> #include "absl/base/attributes.h" -#include "absl/base/config.h" -#include "absl/base/const_init.h" -#include "absl/base/thread_annotations.h" +#include "absl/base/config.h" +#include "absl/base/const_init.h" +#include "absl/base/thread_annotations.h" #include "absl/flags/internal/path_util.h" #include "absl/flags/internal/program_name.h" -#include "absl/strings/match.h" -#include "absl/strings/string_view.h" +#include "absl/strings/match.h" +#include "absl/strings/string_view.h" #include "absl/strings/strip.h" #include "absl/synchronization/mutex.h" @@ -40,7 +40,7 @@ ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL( } // extern "C" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { namespace { @@ -52,15 +52,15 @@ namespace { bool ContainsHelpshortFlags(absl::string_view filename) { // By default we only want flags in binary's main. We expect the main // routine to reside in <program>.cc or <program>-main.cc or - // <program>_main.cc, where the <program> is the name of the binary - // (without .exe on Windows). + // <program>_main.cc, where the <program> is the name of the binary + // (without .exe on Windows). auto suffix = flags_internal::Basename(filename); - auto program_name = flags_internal::ShortProgramInvocationName(); - absl::string_view program_name_ref = program_name; -#if defined(_WIN32) - absl::ConsumeSuffix(&program_name_ref, ".exe"); -#endif - if (!absl::ConsumePrefix(&suffix, program_name_ref)) + auto program_name = flags_internal::ShortProgramInvocationName(); + absl::string_view program_name_ref = program_name; +#if defined(_WIN32) + absl::ConsumeSuffix(&program_name_ref, ".exe"); +#endif + if (!absl::ConsumePrefix(&suffix, program_name_ref)) return false; return absl::StartsWith(suffix, ".") || absl::StartsWith(suffix, "-main.") || absl::StartsWith(suffix, "_main."); @@ -161,5 +161,5 @@ void SetFlagsUsageConfig(FlagsUsageConfig usage_config) { flags_internal::custom_usage_config = new FlagsUsageConfig(usage_config); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/flags/usage_config.h b/contrib/restricted/abseil-cpp/absl/flags/usage_config.h index ded70300f0..3d6bb68c8e 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/usage_config.h +++ b/contrib/restricted/abseil-cpp/absl/flags/usage_config.h @@ -27,7 +27,7 @@ #include <functional> #include <string> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/strings/string_view.h" // ----------------------------------------------------------------------------- @@ -55,7 +55,7 @@ // Shows help on modules whose name contains the specified substring namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace flags_internal { using FlagKindFilter = std::function<bool (absl::string_view)>; @@ -90,7 +90,7 @@ struct FlagsUsageConfig { // program output. flags_internal::FlagKindFilter contains_helppackage_flags; - // Generates string containing program version. This is the string reported + // Generates string containing program version. This is the string reported // when user specifies --version in a command line. std::function<std::string()> version_string; @@ -120,7 +120,7 @@ FlagsUsageConfig GetUsageConfig(); void ReportUsageError(absl::string_view msg, bool is_fatal); } // namespace flags_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl extern "C" { diff --git a/contrib/restricted/abseil-cpp/absl/flags/usage_config/ya.make b/contrib/restricted/abseil-cpp/absl/flags/usage_config/ya.make index adeb527aee..a606c617c0 100644 --- a/contrib/restricted/abseil-cpp/absl/flags/usage_config/ya.make +++ b/contrib/restricted/abseil-cpp/absl/flags/usage_config/ya.make @@ -38,10 +38,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/flags) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/functional/bind_front.h b/contrib/restricted/abseil-cpp/absl/functional/bind_front.h index 5b47970e35..e81d946154 100644 --- a/contrib/restricted/abseil-cpp/absl/functional/bind_front.h +++ b/contrib/restricted/abseil-cpp/absl/functional/bind_front.h @@ -1,184 +1,184 @@ -// Copyright 2018 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// File: bind_front.h -// ----------------------------------------------------------------------------- -// -// `absl::bind_front()` returns a functor by binding a number of arguments to -// the front of a provided (usually more generic) functor. Unlike `std::bind`, -// it does not require the use of argument placeholders. The simpler syntax of -// `absl::bind_front()` allows you to avoid known misuses with `std::bind()`. -// -// `absl::bind_front()` is meant as a drop-in replacement for C++20's upcoming -// `std::bind_front()`, which similarly resolves these issues with -// `std::bind()`. Both `bind_front()` alternatives, unlike `std::bind()`, allow -// partial function application. (See -// https://en.wikipedia.org/wiki/Partial_application). - -#ifndef ABSL_FUNCTIONAL_BIND_FRONT_H_ -#define ABSL_FUNCTIONAL_BIND_FRONT_H_ - -#include "absl/functional/internal/front_binder.h" -#include "absl/utility/utility.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -// bind_front() -// -// Binds the first N arguments of an invocable object and stores them by value. -// -// Like `std::bind()`, `absl::bind_front()` is implicitly convertible to -// `std::function`. In particular, it may be used as a simpler replacement for -// `std::bind()` in most cases, as it does not require placeholders to be -// specified. More importantly, it provides more reliable correctness guarantees -// than `std::bind()`; while `std::bind()` will silently ignore passing more -// parameters than expected, for example, `absl::bind_front()` will report such -// mis-uses as errors. -// -// absl::bind_front(a...) can be seen as storing the results of -// std::make_tuple(a...). -// -// Example: Binding a free function. -// -// int Minus(int a, int b) { return a - b; } -// -// assert(absl::bind_front(Minus)(3, 2) == 3 - 2); -// assert(absl::bind_front(Minus, 3)(2) == 3 - 2); -// assert(absl::bind_front(Minus, 3, 2)() == 3 - 2); -// -// Example: Binding a member function. -// -// struct Math { -// int Double(int a) const { return 2 * a; } -// }; -// -// Math math; -// -// assert(absl::bind_front(&Math::Double)(&math, 3) == 2 * 3); -// // Stores a pointer to math inside the functor. -// assert(absl::bind_front(&Math::Double, &math)(3) == 2 * 3); -// // Stores a copy of math inside the functor. -// assert(absl::bind_front(&Math::Double, math)(3) == 2 * 3); -// // Stores std::unique_ptr<Math> inside the functor. -// assert(absl::bind_front(&Math::Double, -// std::unique_ptr<Math>(new Math))(3) == 2 * 3); -// -// Example: Using `absl::bind_front()`, instead of `std::bind()`, with -// `std::function`. -// -// class FileReader { -// public: -// void ReadFileAsync(const std::string& filename, std::string* content, -// const std::function<void()>& done) { -// // Calls Executor::Schedule(std::function<void()>). -// Executor::DefaultExecutor()->Schedule( -// absl::bind_front(&FileReader::BlockingRead, this, -// filename, content, done)); -// } -// -// private: -// void BlockingRead(const std::string& filename, std::string* content, -// const std::function<void()>& done) { -// CHECK_OK(file::GetContents(filename, content, {})); -// done(); -// } -// }; -// -// `absl::bind_front()` stores bound arguments explicitly using the type passed -// rather than implicitly based on the type accepted by its functor. -// -// Example: Binding arguments explicitly. -// -// void LogStringView(absl::string_view sv) { -// LOG(INFO) << sv; -// } -// -// Executor* e = Executor::DefaultExecutor(); -// std::string s = "hello"; -// absl::string_view sv = s; -// -// // absl::bind_front(LogStringView, arg) makes a copy of arg and stores it. -// e->Schedule(absl::bind_front(LogStringView, sv)); // ERROR: dangling -// // string_view. -// -// e->Schedule(absl::bind_front(LogStringView, s)); // OK: stores a copy of -// // s. -// -// To store some of the arguments passed to `absl::bind_front()` by reference, -// use std::ref()` and `std::cref()`. -// -// Example: Storing some of the bound arguments by reference. -// -// class Service { -// public: -// void Serve(const Request& req, std::function<void()>* done) { -// // The request protocol buffer won't be deleted until done is called. -// // It's safe to store a reference to it inside the functor. -// Executor::DefaultExecutor()->Schedule( -// absl::bind_front(&Service::BlockingServe, this, std::cref(req), -// done)); -// } -// -// private: -// void BlockingServe(const Request& req, std::function<void()>* done); -// }; -// -// Example: Storing bound arguments by reference. -// -// void Print(const std::string& a, const std::string& b) { -// std::cerr << a << b; -// } -// -// std::string hi = "Hello, "; -// std::vector<std::string> names = {"Chuk", "Gek"}; -// // Doesn't copy hi. -// for_each(names.begin(), names.end(), -// absl::bind_front(Print, std::ref(hi))); -// -// // DO NOT DO THIS: the functor may outlive "hi", resulting in -// // dangling references. -// foo->DoInFuture(absl::bind_front(Print, std::ref(hi), "Guest")); // BAD! -// auto f = absl::bind_front(Print, std::ref(hi), "Guest"); // BAD! -// -// Example: Storing reference-like types. -// -// void Print(absl::string_view a, const std::string& b) { -// std::cerr << a << b; -// } -// -// std::string hi = "Hello, "; -// // Copies "hi". -// absl::bind_front(Print, hi)("Chuk"); -// -// // Compile error: std::reference_wrapper<const string> is not implicitly -// // convertible to string_view. -// // absl::bind_front(Print, std::cref(hi))("Chuk"); -// -// // Doesn't copy "hi". -// absl::bind_front(Print, absl::string_view(hi))("Chuk"); -// -template <class F, class... BoundArgs> -constexpr functional_internal::bind_front_t<F, BoundArgs...> bind_front( - F&& func, BoundArgs&&... args) { - return functional_internal::bind_front_t<F, BoundArgs...>( - absl::in_place, absl::forward<F>(func), - absl::forward<BoundArgs>(args)...); -} - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FUNCTIONAL_BIND_FRONT_H_ +// Copyright 2018 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// File: bind_front.h +// ----------------------------------------------------------------------------- +// +// `absl::bind_front()` returns a functor by binding a number of arguments to +// the front of a provided (usually more generic) functor. Unlike `std::bind`, +// it does not require the use of argument placeholders. The simpler syntax of +// `absl::bind_front()` allows you to avoid known misuses with `std::bind()`. +// +// `absl::bind_front()` is meant as a drop-in replacement for C++20's upcoming +// `std::bind_front()`, which similarly resolves these issues with +// `std::bind()`. Both `bind_front()` alternatives, unlike `std::bind()`, allow +// partial function application. (See +// https://en.wikipedia.org/wiki/Partial_application). + +#ifndef ABSL_FUNCTIONAL_BIND_FRONT_H_ +#define ABSL_FUNCTIONAL_BIND_FRONT_H_ + +#include "absl/functional/internal/front_binder.h" +#include "absl/utility/utility.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +// bind_front() +// +// Binds the first N arguments of an invocable object and stores them by value. +// +// Like `std::bind()`, `absl::bind_front()` is implicitly convertible to +// `std::function`. In particular, it may be used as a simpler replacement for +// `std::bind()` in most cases, as it does not require placeholders to be +// specified. More importantly, it provides more reliable correctness guarantees +// than `std::bind()`; while `std::bind()` will silently ignore passing more +// parameters than expected, for example, `absl::bind_front()` will report such +// mis-uses as errors. +// +// absl::bind_front(a...) can be seen as storing the results of +// std::make_tuple(a...). +// +// Example: Binding a free function. +// +// int Minus(int a, int b) { return a - b; } +// +// assert(absl::bind_front(Minus)(3, 2) == 3 - 2); +// assert(absl::bind_front(Minus, 3)(2) == 3 - 2); +// assert(absl::bind_front(Minus, 3, 2)() == 3 - 2); +// +// Example: Binding a member function. +// +// struct Math { +// int Double(int a) const { return 2 * a; } +// }; +// +// Math math; +// +// assert(absl::bind_front(&Math::Double)(&math, 3) == 2 * 3); +// // Stores a pointer to math inside the functor. +// assert(absl::bind_front(&Math::Double, &math)(3) == 2 * 3); +// // Stores a copy of math inside the functor. +// assert(absl::bind_front(&Math::Double, math)(3) == 2 * 3); +// // Stores std::unique_ptr<Math> inside the functor. +// assert(absl::bind_front(&Math::Double, +// std::unique_ptr<Math>(new Math))(3) == 2 * 3); +// +// Example: Using `absl::bind_front()`, instead of `std::bind()`, with +// `std::function`. +// +// class FileReader { +// public: +// void ReadFileAsync(const std::string& filename, std::string* content, +// const std::function<void()>& done) { +// // Calls Executor::Schedule(std::function<void()>). +// Executor::DefaultExecutor()->Schedule( +// absl::bind_front(&FileReader::BlockingRead, this, +// filename, content, done)); +// } +// +// private: +// void BlockingRead(const std::string& filename, std::string* content, +// const std::function<void()>& done) { +// CHECK_OK(file::GetContents(filename, content, {})); +// done(); +// } +// }; +// +// `absl::bind_front()` stores bound arguments explicitly using the type passed +// rather than implicitly based on the type accepted by its functor. +// +// Example: Binding arguments explicitly. +// +// void LogStringView(absl::string_view sv) { +// LOG(INFO) << sv; +// } +// +// Executor* e = Executor::DefaultExecutor(); +// std::string s = "hello"; +// absl::string_view sv = s; +// +// // absl::bind_front(LogStringView, arg) makes a copy of arg and stores it. +// e->Schedule(absl::bind_front(LogStringView, sv)); // ERROR: dangling +// // string_view. +// +// e->Schedule(absl::bind_front(LogStringView, s)); // OK: stores a copy of +// // s. +// +// To store some of the arguments passed to `absl::bind_front()` by reference, +// use std::ref()` and `std::cref()`. +// +// Example: Storing some of the bound arguments by reference. +// +// class Service { +// public: +// void Serve(const Request& req, std::function<void()>* done) { +// // The request protocol buffer won't be deleted until done is called. +// // It's safe to store a reference to it inside the functor. +// Executor::DefaultExecutor()->Schedule( +// absl::bind_front(&Service::BlockingServe, this, std::cref(req), +// done)); +// } +// +// private: +// void BlockingServe(const Request& req, std::function<void()>* done); +// }; +// +// Example: Storing bound arguments by reference. +// +// void Print(const std::string& a, const std::string& b) { +// std::cerr << a << b; +// } +// +// std::string hi = "Hello, "; +// std::vector<std::string> names = {"Chuk", "Gek"}; +// // Doesn't copy hi. +// for_each(names.begin(), names.end(), +// absl::bind_front(Print, std::ref(hi))); +// +// // DO NOT DO THIS: the functor may outlive "hi", resulting in +// // dangling references. +// foo->DoInFuture(absl::bind_front(Print, std::ref(hi), "Guest")); // BAD! +// auto f = absl::bind_front(Print, std::ref(hi), "Guest"); // BAD! +// +// Example: Storing reference-like types. +// +// void Print(absl::string_view a, const std::string& b) { +// std::cerr << a << b; +// } +// +// std::string hi = "Hello, "; +// // Copies "hi". +// absl::bind_front(Print, hi)("Chuk"); +// +// // Compile error: std::reference_wrapper<const string> is not implicitly +// // convertible to string_view. +// // absl::bind_front(Print, std::cref(hi))("Chuk"); +// +// // Doesn't copy "hi". +// absl::bind_front(Print, absl::string_view(hi))("Chuk"); +// +template <class F, class... BoundArgs> +constexpr functional_internal::bind_front_t<F, BoundArgs...> bind_front( + F&& func, BoundArgs&&... args) { + return functional_internal::bind_front_t<F, BoundArgs...>( + absl::in_place, absl::forward<F>(func), + absl::forward<BoundArgs>(args)...); +} + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_FUNCTIONAL_BIND_FRONT_H_ diff --git a/contrib/restricted/abseil-cpp/absl/functional/function_ref.h b/contrib/restricted/abseil-cpp/absl/functional/function_ref.h index 824e3cea9d..88bf666cb6 100644 --- a/contrib/restricted/abseil-cpp/absl/functional/function_ref.h +++ b/contrib/restricted/abseil-cpp/absl/functional/function_ref.h @@ -55,7 +55,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // FunctionRef // @@ -91,7 +91,7 @@ class FunctionRef<R(Args...)> { // Used to disable constructors for objects that are not compatible with the // signature of this FunctionRef. template <typename F, - typename FR = absl::base_internal::invoke_result_t<F, Args&&...>> + typename FR = absl::base_internal::invoke_result_t<F, Args&&...>> using EnableIfCompatible = typename std::enable_if<std::is_void<R>::value || std::is_convertible<FR, R>::value>::type; @@ -136,7 +136,7 @@ class FunctionRef<R(Args...)> { absl::functional_internal::Invoker<R, Args...> invoker_; }; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FUNCTIONAL_FUNCTION_REF_H_ diff --git a/contrib/restricted/abseil-cpp/absl/functional/internal/front_binder.h b/contrib/restricted/abseil-cpp/absl/functional/internal/front_binder.h index 45f52de73d..6e0cd1c33f 100644 --- a/contrib/restricted/abseil-cpp/absl/functional/internal/front_binder.h +++ b/contrib/restricted/abseil-cpp/absl/functional/internal/front_binder.h @@ -1,95 +1,95 @@ -// Copyright 2018 The Abseil Authors. -// -// 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 -// -// https://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. - -// Implementation details for `absl::bind_front()`. - -#ifndef ABSL_FUNCTIONAL_INTERNAL_FRONT_BINDER_H_ -#define ABSL_FUNCTIONAL_INTERNAL_FRONT_BINDER_H_ - -#include <cstddef> -#include <type_traits> -#include <utility> - -#include "absl/base/internal/invoke.h" -#include "absl/container/internal/compressed_tuple.h" -#include "absl/meta/type_traits.h" -#include "absl/utility/utility.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace functional_internal { - -// Invoke the method, expanding the tuple of bound arguments. -template <class R, class Tuple, size_t... Idx, class... Args> -R Apply(Tuple&& bound, absl::index_sequence<Idx...>, Args&&... free) { - return base_internal::invoke( - absl::forward<Tuple>(bound).template get<Idx>()..., - absl::forward<Args>(free)...); -} - -template <class F, class... BoundArgs> -class FrontBinder { - using BoundArgsT = absl::container_internal::CompressedTuple<F, BoundArgs...>; - using Idx = absl::make_index_sequence<sizeof...(BoundArgs) + 1>; - - BoundArgsT bound_args_; - - public: - template <class... Ts> - constexpr explicit FrontBinder(absl::in_place_t, Ts&&... ts) - : bound_args_(absl::forward<Ts>(ts)...) {} - - template <class... FreeArgs, class R = base_internal::invoke_result_t< - F&, BoundArgs&..., FreeArgs&&...>> - R operator()(FreeArgs&&... free_args) & { - return functional_internal::Apply<R>(bound_args_, Idx(), - absl::forward<FreeArgs>(free_args)...); - } - - template <class... FreeArgs, - class R = base_internal::invoke_result_t< - const F&, const BoundArgs&..., FreeArgs&&...>> - R operator()(FreeArgs&&... free_args) const& { - return functional_internal::Apply<R>(bound_args_, Idx(), - absl::forward<FreeArgs>(free_args)...); - } - - template <class... FreeArgs, class R = base_internal::invoke_result_t< - F&&, BoundArgs&&..., FreeArgs&&...>> - R operator()(FreeArgs&&... free_args) && { - // This overload is called when *this is an rvalue. If some of the bound - // arguments are stored by value or rvalue reference, we move them. - return functional_internal::Apply<R>(absl::move(bound_args_), Idx(), - absl::forward<FreeArgs>(free_args)...); - } - - template <class... FreeArgs, - class R = base_internal::invoke_result_t< - const F&&, const BoundArgs&&..., FreeArgs&&...>> - R operator()(FreeArgs&&... free_args) const&& { - // This overload is called when *this is an rvalue. If some of the bound - // arguments are stored by value or rvalue reference, we move them. - return functional_internal::Apply<R>(absl::move(bound_args_), Idx(), - absl::forward<FreeArgs>(free_args)...); - } -}; - -template <class F, class... BoundArgs> -using bind_front_t = FrontBinder<decay_t<F>, absl::decay_t<BoundArgs>...>; - -} // namespace functional_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FUNCTIONAL_INTERNAL_FRONT_BINDER_H_ +// Copyright 2018 The Abseil Authors. +// +// 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 +// +// https://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. + +// Implementation details for `absl::bind_front()`. + +#ifndef ABSL_FUNCTIONAL_INTERNAL_FRONT_BINDER_H_ +#define ABSL_FUNCTIONAL_INTERNAL_FRONT_BINDER_H_ + +#include <cstddef> +#include <type_traits> +#include <utility> + +#include "absl/base/internal/invoke.h" +#include "absl/container/internal/compressed_tuple.h" +#include "absl/meta/type_traits.h" +#include "absl/utility/utility.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace functional_internal { + +// Invoke the method, expanding the tuple of bound arguments. +template <class R, class Tuple, size_t... Idx, class... Args> +R Apply(Tuple&& bound, absl::index_sequence<Idx...>, Args&&... free) { + return base_internal::invoke( + absl::forward<Tuple>(bound).template get<Idx>()..., + absl::forward<Args>(free)...); +} + +template <class F, class... BoundArgs> +class FrontBinder { + using BoundArgsT = absl::container_internal::CompressedTuple<F, BoundArgs...>; + using Idx = absl::make_index_sequence<sizeof...(BoundArgs) + 1>; + + BoundArgsT bound_args_; + + public: + template <class... Ts> + constexpr explicit FrontBinder(absl::in_place_t, Ts&&... ts) + : bound_args_(absl::forward<Ts>(ts)...) {} + + template <class... FreeArgs, class R = base_internal::invoke_result_t< + F&, BoundArgs&..., FreeArgs&&...>> + R operator()(FreeArgs&&... free_args) & { + return functional_internal::Apply<R>(bound_args_, Idx(), + absl::forward<FreeArgs>(free_args)...); + } + + template <class... FreeArgs, + class R = base_internal::invoke_result_t< + const F&, const BoundArgs&..., FreeArgs&&...>> + R operator()(FreeArgs&&... free_args) const& { + return functional_internal::Apply<R>(bound_args_, Idx(), + absl::forward<FreeArgs>(free_args)...); + } + + template <class... FreeArgs, class R = base_internal::invoke_result_t< + F&&, BoundArgs&&..., FreeArgs&&...>> + R operator()(FreeArgs&&... free_args) && { + // This overload is called when *this is an rvalue. If some of the bound + // arguments are stored by value or rvalue reference, we move them. + return functional_internal::Apply<R>(absl::move(bound_args_), Idx(), + absl::forward<FreeArgs>(free_args)...); + } + + template <class... FreeArgs, + class R = base_internal::invoke_result_t< + const F&&, const BoundArgs&&..., FreeArgs&&...>> + R operator()(FreeArgs&&... free_args) const&& { + // This overload is called when *this is an rvalue. If some of the bound + // arguments are stored by value or rvalue reference, we move them. + return functional_internal::Apply<R>(absl::move(bound_args_), Idx(), + absl::forward<FreeArgs>(free_args)...); + } +}; + +template <class F, class... BoundArgs> +using bind_front_t = FrontBinder<decay_t<F>, absl::decay_t<BoundArgs>...>; + +} // namespace functional_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_FUNCTIONAL_INTERNAL_FRONT_BINDER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/functional/internal/function_ref.h b/contrib/restricted/abseil-cpp/absl/functional/internal/function_ref.h index b5bb8b430a..03bf1d097e 100644 --- a/contrib/restricted/abseil-cpp/absl/functional/internal/function_ref.h +++ b/contrib/restricted/abseil-cpp/absl/functional/internal/function_ref.h @@ -23,7 +23,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace functional_internal { // Like a void* that can handle function pointers as well. The standard does not @@ -71,14 +71,14 @@ template <typename Obj, typename R, typename... Args> R InvokeObject(VoidPtr ptr, typename ForwardT<Args>::type... args) { auto o = static_cast<const Obj*>(ptr.obj); return static_cast<R>( - absl::base_internal::invoke(*o, std::forward<Args>(args)...)); + absl::base_internal::invoke(*o, std::forward<Args>(args)...)); } template <typename Fun, typename R, typename... Args> R InvokeFunction(VoidPtr ptr, typename ForwardT<Args>::type... args) { auto f = reinterpret_cast<Fun>(ptr.fun); return static_cast<R>( - absl::base_internal::invoke(f, std::forward<Args>(args)...)); + absl::base_internal::invoke(f, std::forward<Args>(args)...)); } template <typename Sig> @@ -100,7 +100,7 @@ template <bool C> using EnableIf = typename ::std::enable_if<C, int>::type; } // namespace functional_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_FUNCTIONAL_INTERNAL_FUNCTION_REF_H_ diff --git a/contrib/restricted/abseil-cpp/absl/hash/hash.h b/contrib/restricted/abseil-cpp/absl/hash/hash.h index 8282ea53c6..5d8753d7fc 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/hash.h +++ b/contrib/restricted/abseil-cpp/absl/hash/hash.h @@ -37,12 +37,12 @@ // types. Hashing of that combined state is separately done by `absl::Hash`. // // One should assume that a hash algorithm is chosen randomly at the start of -// each process. E.g., `absl::Hash<int>{}(9)` in one process and -// `absl::Hash<int>{}(9)` in another process are likely to differ. -// -// `absl::Hash` is intended to strongly mix input bits with a target of passing -// an [Avalanche Test](https://en.wikipedia.org/wiki/Avalanche_effect). +// each process. E.g., `absl::Hash<int>{}(9)` in one process and +// `absl::Hash<int>{}(9)` in another process are likely to differ. // +// `absl::Hash` is intended to strongly mix input bits with a target of passing +// an [Avalanche Test](https://en.wikipedia.org/wiki/Avalanche_effect). +// // Example: // // // Suppose we have a class `Circle` for which we want to add hashing: @@ -78,7 +78,7 @@ #include "absl/hash/internal/hash.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // `absl::Hash` @@ -102,7 +102,7 @@ ABSL_NAMESPACE_BEGIN // * std::tuple<Ts...>, if all the Ts... are hashable // * std::unique_ptr and std::shared_ptr // * All string-like types including: -// * absl::Cord +// * absl::Cord // * std::string // * std::string_view (as well as any instance of std::basic_string that // uses char and std::char_traits) @@ -341,7 +341,7 @@ class HashState : public hash_internal::HashStateBase<HashState> { void (*combine_contiguous_)(void*, const unsigned char*, size_t); }; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HASH_HASH_H_ diff --git a/contrib/restricted/abseil-cpp/absl/hash/hash_testing.h b/contrib/restricted/abseil-cpp/absl/hash/hash_testing.h index 1e1c574149..154f850fb3 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/hash_testing.h +++ b/contrib/restricted/abseil-cpp/absl/hash/hash_testing.h @@ -28,7 +28,7 @@ #include "absl/types/variant.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // Run the absl::Hash algorithm over all the elements passed in and verify that // their hash expansion is congruent with their `==` operator. @@ -372,7 +372,7 @@ VerifyTypeImplementsAbslHashCorrectly(std::initializer_list<T> values, equals); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HASH_HASH_TESTING_H_ diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/city.cc b/contrib/restricted/abseil-cpp/absl/hash/internal/city.cc index 5460134e57..d62b623e58 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/internal/city.cc +++ b/contrib/restricted/abseil-cpp/absl/hash/internal/city.cc @@ -30,7 +30,7 @@ #include "absl/base/optimization.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace hash_internal { #ifdef ABSL_IS_BIG_ENDIAN @@ -254,8 +254,8 @@ static uint64_t HashLen17to32(const char *s, size_t len) { // Return a 16-byte hash for 48 bytes. Quick and dirty. // Callers do best to use "random-looking" values for a and b. -static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds( - uint64_t w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) { +static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds( + uint64_t w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) { a += w; b = Rotate(b + a + z, 21); uint64_t c = a; @@ -266,9 +266,9 @@ static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds( } // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. -static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds(const char *s, - uint64_t a, - uint64_t b) { +static std::pair<uint64_t, uint64_t> WeakHashLen32WithSeeds(const char *s, + uint64_t a, + uint64_t b) { return WeakHashLen32WithSeeds(Fetch64(s), Fetch64(s + 8), Fetch64(s + 16), Fetch64(s + 24), a, b); } @@ -311,10 +311,10 @@ uint64_t CityHash64(const char *s, size_t len) { uint64_t x = Fetch64(s + len - 40); uint64_t y = Fetch64(s + len - 16) + Fetch64(s + len - 56); uint64_t z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24)); - std::pair<uint64_t, uint64_t> v = - WeakHashLen32WithSeeds(s + len - 64, len, z); - std::pair<uint64_t, uint64_t> w = - WeakHashLen32WithSeeds(s + len - 32, y + k1, x); + std::pair<uint64_t, uint64_t> v = + WeakHashLen32WithSeeds(s + len - 64, len, z); + std::pair<uint64_t, uint64_t> w = + WeakHashLen32WithSeeds(s + len - 32, y + k1, x); x = x * k1 + Fetch64(s); // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. @@ -340,10 +340,10 @@ uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed) { } uint64_t CityHash64WithSeeds(const char *s, size_t len, uint64_t seed0, - uint64_t seed1) { + uint64_t seed1) { return HashLen16(CityHash64(s, len) - seed0, seed1); } } // namespace hash_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/city.h b/contrib/restricted/abseil-cpp/absl/hash/internal/city.h index 393da0b95d..f0c53435ae 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/internal/city.h +++ b/contrib/restricted/abseil-cpp/absl/hash/internal/city.h @@ -47,13 +47,13 @@ #include <stdint.h> #include <stdlib.h> // for size_t. - + #include <utility> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace hash_internal { // Hash function for a byte array. @@ -66,13 +66,13 @@ uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed); // Hash function for a byte array. For convenience, two seeds are also // hashed into the result. uint64_t CityHash64WithSeeds(const char *s, size_t len, uint64_t seed0, - uint64_t seed1); + uint64_t seed1); // Hash function for a byte array. Most useful in 32-bit binaries. uint32_t CityHash32(const char *s, size_t len); } // namespace hash_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HASH_INTERNAL_CITY_H_ diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc index 11451e575c..d1cc902b6f 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc +++ b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.cc @@ -15,7 +15,7 @@ #include "absl/hash/internal/hash.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace hash_internal { uint64_t MixingHashState::CombineLargeContiguousImpl32( @@ -65,5 +65,5 @@ uint64_t MixingHashState::LowLevelHashImpl(const unsigned char* data, } } // namespace hash_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h index b1e33caf4c..3545efa34a 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h +++ b/contrib/restricted/abseil-cpp/absl/hash/internal/hash.h @@ -53,68 +53,68 @@ #include "absl/utility/utility.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace hash_internal { // Internal detail: Large buffers are hashed in smaller chunks. This function // returns the size of these chunks. -constexpr size_t PiecewiseChunkSize() { return 1024; } - -// PiecewiseCombiner -// -// PiecewiseCombiner is an internal-only helper class for hashing a piecewise -// buffer of `char` or `unsigned char` as though it were contiguous. This class -// provides two methods: -// -// H add_buffer(state, data, size) -// H finalize(state) -// -// `add_buffer` can be called zero or more times, followed by a single call to -// `finalize`. This will produce the same hash expansion as concatenating each -// buffer piece into a single contiguous buffer, and passing this to -// `H::combine_contiguous`. -// -// Example usage: -// PiecewiseCombiner combiner; -// for (const auto& piece : pieces) { -// state = combiner.add_buffer(std::move(state), piece.data, piece.size); -// } -// return combiner.finalize(std::move(state)); -class PiecewiseCombiner { - public: - PiecewiseCombiner() : position_(0) {} - PiecewiseCombiner(const PiecewiseCombiner&) = delete; - PiecewiseCombiner& operator=(const PiecewiseCombiner&) = delete; - - // PiecewiseCombiner::add_buffer() - // - // Appends the given range of bytes to the sequence to be hashed, which may - // modify the provided hash state. - template <typename H> - H add_buffer(H state, const unsigned char* data, size_t size); - template <typename H> - H add_buffer(H state, const char* data, size_t size) { - return add_buffer(std::move(state), - reinterpret_cast<const unsigned char*>(data), size); - } - - // PiecewiseCombiner::finalize() - // - // Finishes combining the hash sequence, which may may modify the provided - // hash state. - // - // Once finalize() is called, add_buffer() may no longer be called. The - // resulting hash state will be the same as if the pieces passed to - // add_buffer() were concatenated into a single flat buffer, and then provided - // to H::combine_contiguous(). - template <typename H> - H finalize(H state); - - private: - unsigned char buf_[PiecewiseChunkSize()]; - size_t position_; -}; - +constexpr size_t PiecewiseChunkSize() { return 1024; } + +// PiecewiseCombiner +// +// PiecewiseCombiner is an internal-only helper class for hashing a piecewise +// buffer of `char` or `unsigned char` as though it were contiguous. This class +// provides two methods: +// +// H add_buffer(state, data, size) +// H finalize(state) +// +// `add_buffer` can be called zero or more times, followed by a single call to +// `finalize`. This will produce the same hash expansion as concatenating each +// buffer piece into a single contiguous buffer, and passing this to +// `H::combine_contiguous`. +// +// Example usage: +// PiecewiseCombiner combiner; +// for (const auto& piece : pieces) { +// state = combiner.add_buffer(std::move(state), piece.data, piece.size); +// } +// return combiner.finalize(std::move(state)); +class PiecewiseCombiner { + public: + PiecewiseCombiner() : position_(0) {} + PiecewiseCombiner(const PiecewiseCombiner&) = delete; + PiecewiseCombiner& operator=(const PiecewiseCombiner&) = delete; + + // PiecewiseCombiner::add_buffer() + // + // Appends the given range of bytes to the sequence to be hashed, which may + // modify the provided hash state. + template <typename H> + H add_buffer(H state, const unsigned char* data, size_t size); + template <typename H> + H add_buffer(H state, const char* data, size_t size) { + return add_buffer(std::move(state), + reinterpret_cast<const unsigned char*>(data), size); + } + + // PiecewiseCombiner::finalize() + // + // Finishes combining the hash sequence, which may may modify the provided + // hash state. + // + // Once finalize() is called, add_buffer() may no longer be called. The + // resulting hash state will be the same as if the pieces passed to + // add_buffer() were concatenated into a single flat buffer, and then provided + // to H::combine_contiguous(). + template <typename H> + H finalize(H state); + + private: + unsigned char buf_[PiecewiseChunkSize()]; + size_t position_; +}; + // HashStateBase // // A hash state object represents an intermediate state in the computation @@ -181,7 +181,7 @@ class HashStateBase { template <typename T> static H combine_contiguous(H state, const T* data, size_t size); - using AbslInternalPiecewiseCombiner = PiecewiseCombiner; + using AbslInternalPiecewiseCombiner = PiecewiseCombiner; }; // is_uniquely_represented @@ -413,7 +413,7 @@ H AbslHashValue(H hash_state, const std::shared_ptr<T>& ptr) { // All the string-like types supported here provide the same hash expansion for // the same character sequence. These types are: // -// - `absl::Cord` +// - `absl::Cord` // - `std::string` (and std::basic_string<char, std::char_traits<char>, A> for // any allocator A) // - `absl::string_view` and `std::string_view` @@ -576,13 +576,13 @@ typename std::enable_if<is_hashable<Key>::value, H>::type AbslHashValue( // AbslHashValue for Wrapper Types // ----------------------------------------------------------------------------- -// AbslHashValue for hashing std::reference_wrapper -template <typename H, typename T> -typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue( - H hash_state, std::reference_wrapper<T> opt) { - return H::combine(std::move(hash_state), opt.get()); -} - +// AbslHashValue for hashing std::reference_wrapper +template <typename H, typename T> +typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue( + H hash_state, std::reference_wrapper<T> opt) { + return H::combine(std::move(hash_state), opt.get()); +} + // AbslHashValue for hashing absl::optional template <typename H, typename T> typename std::enable_if<is_hashable<T>::value, H>::type AbslHashValue( @@ -1057,18 +1057,18 @@ H PiecewiseCombiner::add_buffer(H state, const unsigned char* data, // This partial chunk does not fill our existing buffer memcpy(buf_ + position_, data, size); position_ += size; - return state; + return state; } - // If the buffer is partially filled we need to complete the buffer - // and hash it. - if (position_ != 0) { - const size_t bytes_needed = PiecewiseChunkSize() - position_; - memcpy(buf_ + position_, data, bytes_needed); - state = H::combine_contiguous(std::move(state), buf_, PiecewiseChunkSize()); - data += bytes_needed; - size -= bytes_needed; - } + // If the buffer is partially filled we need to complete the buffer + // and hash it. + if (position_ != 0) { + const size_t bytes_needed = PiecewiseChunkSize() - position_; + memcpy(buf_ + position_, data, bytes_needed); + state = H::combine_contiguous(std::move(state), buf_, PiecewiseChunkSize()); + data += bytes_needed; + size -= bytes_needed; + } // Hash whatever chunks we can without copying while (size >= PiecewiseChunkSize()) { @@ -1079,7 +1079,7 @@ H PiecewiseCombiner::add_buffer(H state, const unsigned char* data, // Fill the buffer with the remainder memcpy(buf_, data, size); position_ = size; - return state; + return state; } // HashStateBase::PiecewiseCombiner::finalize() @@ -1090,7 +1090,7 @@ H PiecewiseCombiner::finalize(H state) { } } // namespace hash_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HASH_INTERNAL_HASH_H_ diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/spy_hash_state.h b/contrib/restricted/abseil-cpp/absl/hash/internal/spy_hash_state.h index c083120811..067843d75a 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/internal/spy_hash_state.h +++ b/contrib/restricted/abseil-cpp/absl/hash/internal/spy_hash_state.h @@ -25,7 +25,7 @@ #include "absl/strings/str_join.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace hash_internal { // SpyHashState is an implementation of the HashState API that simply @@ -225,7 +225,7 @@ void AbslHashValue(SpyHashStateImpl<T>, const U&); using SpyHashState = SpyHashStateImpl<void>; } // namespace hash_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_HASH_INTERNAL_SPY_HASH_STATE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/hash/internal/ya.make b/contrib/restricted/abseil-cpp/absl/hash/internal/ya.make index a46b84191e..fa69ad6990 100644 --- a/contrib/restricted/abseil-cpp/absl/hash/internal/ya.make +++ b/contrib/restricted/abseil-cpp/absl/hash/internal/ya.make @@ -24,10 +24,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCS( low_level_hash.cc ) diff --git a/contrib/restricted/abseil-cpp/absl/memory/memory.h b/contrib/restricted/abseil-cpp/absl/memory/memory.h index 7a5063ee69..030e117d37 100644 --- a/contrib/restricted/abseil-cpp/absl/memory/memory.h +++ b/contrib/restricted/abseil-cpp/absl/memory/memory.h @@ -34,7 +34,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // Function Template: WrapUnique() @@ -420,8 +420,8 @@ struct pointer_traits<T*> { // A C++11 compatible implementation of C++17's std::allocator_traits. // #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -using std::allocator_traits; -#else // __cplusplus >= 201703L +using std::allocator_traits; +#else // __cplusplus >= 201703L template <typename Alloc> struct allocator_traits { using allocator_type = Alloc; @@ -611,7 +611,7 @@ struct allocator_traits { return a; } }; -#endif // __cplusplus >= 201703L +#endif // __cplusplus >= 201703L namespace memory_internal { @@ -692,7 +692,7 @@ void CopyRange(Allocator& alloc, Iterator destination, InputIterator first, } } } // namespace memory_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_MEMORY_MEMORY_H_ diff --git a/contrib/restricted/abseil-cpp/absl/meta/type_traits.h b/contrib/restricted/abseil-cpp/absl/meta/type_traits.h index d886cb30a8..3f59df60f2 100644 --- a/contrib/restricted/abseil-cpp/absl/meta/type_traits.h +++ b/contrib/restricted/abseil-cpp/absl/meta/type_traits.h @@ -41,12 +41,12 @@ #include "absl/base/config.h" -// MSVC constructibility traits do not detect destructor properties and so our -// implementations should not use them as a source-of-truth. -#if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__) -#define ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION 1 -#endif - +// MSVC constructibility traits do not detect destructor properties and so our +// implementations should not use them as a source-of-truth. +#if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__) +#define ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION 1 +#endif + // Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is a C++17 // feature. #if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) @@ -56,14 +56,14 @@ #endif // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) namespace absl { -ABSL_NAMESPACE_BEGIN - -// Defined and documented later on in this file. -template <typename T> -struct is_trivially_destructible; +ABSL_NAMESPACE_BEGIN // Defined and documented later on in this file. template <typename T> +struct is_trivially_destructible; + +// Defined and documented later on in this file. +template <typename T> struct is_trivially_move_assignable; namespace type_traits_internal { @@ -85,20 +85,20 @@ union SingleMemberUnion { #endif // defined(_MSC_VER) && !defined(__GNUC__) template <class T> -struct IsTriviallyMoveConstructibleObject - : std::integral_constant< - bool, std::is_move_constructible< - type_traits_internal::SingleMemberUnion<T>>::value && - absl::is_trivially_destructible<T>::value> {}; - -template <class T> -struct IsTriviallyCopyConstructibleObject - : std::integral_constant< - bool, std::is_copy_constructible< - type_traits_internal::SingleMemberUnion<T>>::value && - absl::is_trivially_destructible<T>::value> {}; - -template <class T> +struct IsTriviallyMoveConstructibleObject + : std::integral_constant< + bool, std::is_move_constructible< + type_traits_internal::SingleMemberUnion<T>>::value && + absl::is_trivially_destructible<T>::value> {}; + +template <class T> +struct IsTriviallyCopyConstructibleObject + : std::integral_constant< + bool, std::is_copy_constructible< + type_traits_internal::SingleMemberUnion<T>>::value && + absl::is_trivially_destructible<T>::value> {}; + +template <class T> struct IsTriviallyMoveAssignableReference : std::false_type {}; template <class T> @@ -227,7 +227,7 @@ using void_t = typename type_traits_internal::VoidTImpl<Ts...>::type; // This metafunction is designed to be a drop-in replacement for the C++17 // `std::conjunction` metafunction. template <typename... Ts> -struct conjunction : std::true_type {}; +struct conjunction : std::true_type {}; template <typename T, typename... Ts> struct conjunction<T, Ts...> @@ -246,7 +246,7 @@ struct conjunction<T> : T {}; // This metafunction is designed to be a drop-in replacement for the C++17 // `std::disjunction` metafunction. template <typename... Ts> -struct disjunction : std::false_type {}; +struct disjunction : std::false_type {}; template <typename T, typename... Ts> struct disjunction<T, Ts...> : @@ -350,9 +350,9 @@ struct is_trivially_default_constructible : std::integral_constant<bool, __has_trivial_constructor(T) && std::is_default_constructible<T>::value && is_trivially_destructible<T>::value> { -#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ - !defined( \ - ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) +#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ + !defined( \ + ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) private: static constexpr bool compliant = std::is_trivially_default_constructible<T>::value == @@ -383,11 +383,11 @@ template <typename T> struct is_trivially_move_constructible : std::conditional< std::is_object<T>::value && !std::is_array<T>::value, - type_traits_internal::IsTriviallyMoveConstructibleObject<T>, + type_traits_internal::IsTriviallyMoveConstructibleObject<T>, std::is_reference<T>>::type::type { -#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ - !defined( \ - ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) +#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ + !defined( \ + ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) private: static constexpr bool compliant = std::is_trivially_move_constructible<T>::value == @@ -418,11 +418,11 @@ template <typename T> struct is_trivially_copy_constructible : std::conditional< std::is_object<T>::value && !std::is_array<T>::value, - type_traits_internal::IsTriviallyCopyConstructibleObject<T>, + type_traits_internal::IsTriviallyCopyConstructibleObject<T>, std::is_lvalue_reference<T>>::type::type { -#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ - !defined( \ - ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) +#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) && \ + !defined( \ + ABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION) private: static constexpr bool compliant = std::is_trivially_copy_constructible<T>::value == @@ -454,8 +454,8 @@ struct is_trivially_copy_constructible template <typename T> struct is_trivially_move_assignable : std::conditional< - std::is_object<T>::value && !std::is_array<T>::value && - std::is_move_assignable<T>::value, + std::is_object<T>::value && !std::is_array<T>::value && + std::is_move_assignable<T>::value, std::is_move_assignable<type_traits_internal::SingleMemberUnion<T>>, type_traits_internal::IsTriviallyMoveAssignableReference<T>>::type:: type { @@ -791,7 +791,7 @@ using swap_internal::Swap; using swap_internal::StdSwapIsUnconstrained; } // namespace type_traits_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_META_TYPE_TRAITS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/numeric/int128.cc b/contrib/restricted/abseil-cpp/absl/numeric/int128.cc index 4f91e48463..5f74d9ac49 100644 --- a/contrib/restricted/abseil-cpp/absl/numeric/int128.cc +++ b/contrib/restricted/abseil-cpp/absl/numeric/int128.cc @@ -15,7 +15,7 @@ #include "absl/numeric/int128.h" #include <stddef.h> - + #include <cassert> #include <iomanip> #include <ostream> // NOLINT(readability/streams) @@ -23,38 +23,38 @@ #include <string> #include <type_traits> -#include "absl/base/optimization.h" +#include "absl/base/optimization.h" #include "absl/numeric/bits.h" - + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN -ABSL_DLL const uint128 kuint128max = MakeUint128( - std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max()); +ABSL_DLL const uint128 kuint128max = MakeUint128( + std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max()); namespace { // Returns the 0-based position of the last set bit (i.e., most significant bit) -// in the given uint128. The argument is not 0. +// in the given uint128. The argument is not 0. // // For example: // Given: 5 (decimal) == 101 (binary) // Returns: 2 -inline ABSL_ATTRIBUTE_ALWAYS_INLINE int Fls128(uint128 n) { +inline ABSL_ATTRIBUTE_ALWAYS_INLINE int Fls128(uint128 n) { if (uint64_t hi = Uint128High64(n)) { - ABSL_INTERNAL_ASSUME(hi != 0); + ABSL_INTERNAL_ASSUME(hi != 0); return 127 - countl_zero(hi); } - const uint64_t low = Uint128Low64(n); - ABSL_INTERNAL_ASSUME(low != 0); + const uint64_t low = Uint128Low64(n); + ABSL_INTERNAL_ASSUME(low != 0); return 63 - countl_zero(low); } // Long division/modulo for uint128 implemented using the shift-subtract // division algorithm adapted from: // https://stackoverflow.com/questions/5386377/division-without-using -inline void DivModImpl(uint128 dividend, uint128 divisor, uint128* quotient_ret, - uint128* remainder_ret) { +inline void DivModImpl(uint128 dividend, uint128 divisor, uint128* quotient_ret, + uint128* remainder_ret) { assert(divisor != 0); if (divisor > dividend) { @@ -312,7 +312,7 @@ std::ostream& operator<<(std::ostream& os, int128 v) { break; case std::ios::internal: if (print_as_decimal && (rep[0] == '+' || rep[0] == '-')) { - rep.insert((size_t)1, width - rep.size(), os.fill()); + rep.insert((size_t)1, width - rep.size(), os.fill()); } else if ((flags & std::ios::basefield) == std::ios::hex && (flags & std::ios::showbase) && v != 0) { rep.insert((size_t)2, width - rep.size(), os.fill()); @@ -329,7 +329,7 @@ std::ostream& operator<<(std::ostream& os, int128 v) { return os << rep; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl namespace std { diff --git a/contrib/restricted/abseil-cpp/absl/numeric/int128.h b/contrib/restricted/abseil-cpp/absl/numeric/int128.h index c7ad96befd..8e047a491b 100644 --- a/contrib/restricted/abseil-cpp/absl/numeric/int128.h +++ b/contrib/restricted/abseil-cpp/absl/numeric/int128.h @@ -53,7 +53,7 @@ #endif // defined(_MSC_VER) namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN class int128; @@ -238,7 +238,7 @@ class // Prefer to use the constexpr `Uint128Max()`. // // TODO(absl-team) deprecate kuint128max once migration tool is released. -ABSL_DLL extern const uint128 kuint128max; +ABSL_DLL extern const uint128 kuint128max; // allow uint128 to be logged std::ostream& operator<<(std::ostream& os, uint128 v); @@ -250,7 +250,7 @@ constexpr uint128 Uint128Max() { (std::numeric_limits<uint64_t>::max)()); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl // Specialized numeric_limits for uint128. @@ -299,7 +299,7 @@ class numeric_limits<absl::uint128> { } // namespace std namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // int128 // @@ -485,7 +485,7 @@ constexpr int128 Int128Min() { return int128((std::numeric_limits<int64_t>::min)(), 0); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl // Specialized numeric_limits for int128. @@ -537,7 +537,7 @@ class numeric_limits<absl::int128> { // Implementation details follow // -------------------------------------------------------------------------- namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN constexpr uint128 MakeUint128(uint64_t high, uint64_t low) { return uint128(high, low); @@ -799,14 +799,14 @@ constexpr bool operator==(uint128 lhs, uint128 rhs) { constexpr bool operator!=(uint128 lhs, uint128 rhs) { return !(lhs == rhs); } constexpr bool operator<(uint128 lhs, uint128 rhs) { -#ifdef ABSL_HAVE_INTRINSIC_INT128 - return static_cast<unsigned __int128>(lhs) < - static_cast<unsigned __int128>(rhs); -#else +#ifdef ABSL_HAVE_INTRINSIC_INT128 + return static_cast<unsigned __int128>(lhs) < + static_cast<unsigned __int128>(rhs); +#else return (Uint128High64(lhs) == Uint128High64(rhs)) ? (Uint128Low64(lhs) < Uint128Low64(rhs)) : (Uint128High64(lhs) < Uint128High64(rhs)); -#endif +#endif } constexpr bool operator>(uint128 lhs, uint128 rhs) { return rhs < lhs; } @@ -901,9 +901,9 @@ inline uint128& uint128::operator^=(uint128 other) { // Arithmetic operators. constexpr uint128 operator<<(uint128 lhs, int amount) { -#ifdef ABSL_HAVE_INTRINSIC_INT128 - return static_cast<unsigned __int128>(lhs) << amount; -#else +#ifdef ABSL_HAVE_INTRINSIC_INT128 + return static_cast<unsigned __int128>(lhs) << amount; +#else // uint64_t shifts of >= 64 are undefined, so we will need some // special-casing. return amount >= 64 ? MakeUint128(Uint128Low64(lhs) << (amount - 64), 0) @@ -911,13 +911,13 @@ constexpr uint128 operator<<(uint128 lhs, int amount) { : MakeUint128((Uint128High64(lhs) << amount) | (Uint128Low64(lhs) >> (64 - amount)), Uint128Low64(lhs) << amount); -#endif +#endif } constexpr uint128 operator>>(uint128 lhs, int amount) { -#ifdef ABSL_HAVE_INTRINSIC_INT128 - return static_cast<unsigned __int128>(lhs) >> amount; -#else +#ifdef ABSL_HAVE_INTRINSIC_INT128 + return static_cast<unsigned __int128>(lhs) >> amount; +#else // uint64_t shifts of >= 64 are undefined, so we will need some // special-casing. return amount >= 64 ? MakeUint128(0, Uint128High64(lhs) >> (amount - 64)) @@ -925,7 +925,7 @@ constexpr uint128 operator>>(uint128 lhs, int amount) { : MakeUint128(Uint128High64(lhs) >> amount, (Uint128Low64(lhs) >> amount) | (Uint128High64(lhs) << (64 - amount))); -#endif +#endif } #if !defined(ABSL_HAVE_INTRINSIC_INT128) @@ -1157,7 +1157,7 @@ constexpr int64_t BitCastToSigned(uint64_t v) { #include "absl/numeric/int128_no_intrinsic.inc" // IWYU pragma: export #endif // ABSL_HAVE_INTRINSIC_INT128 -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #undef ABSL_INTERNAL_WCHAR_T diff --git a/contrib/restricted/abseil-cpp/absl/numeric/ya.make b/contrib/restricted/abseil-cpp/absl/numeric/ya.make index b82fbcf1cd..13627787c9 100644 --- a/contrib/restricted/abseil-cpp/absl/numeric/ya.make +++ b/contrib/restricted/abseil-cpp/absl/numeric/ya.make @@ -16,10 +16,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCS( int128.cc ) diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc index 81d9a75765..0bde9ecd12 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.cc @@ -16,7 +16,7 @@ #include <stdint.h> -#include <algorithm> +#include <algorithm> #include <atomic> #include <cmath> #include <limits> @@ -25,7 +25,7 @@ #include "absl/base/optimization.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace profiling_internal { // The algorithm generates a random number between 0 and 1 and applies the @@ -38,7 +38,7 @@ namespace profiling_internal { // -log_e(q)/m = x // log_2(q) * (-log_e(2) * 1/m) = x // In the code, q is actually in the range 1 to 2**26, hence the -26 below -int64_t ExponentialBiased::GetSkipCount(int64_t mean) { +int64_t ExponentialBiased::GetSkipCount(int64_t mean) { if (ABSL_PREDICT_FALSE(!initialized_)) { Initialize(); } @@ -53,24 +53,24 @@ int64_t ExponentialBiased::GetSkipCount(int64_t mean) { // under piii debug for some binaries. double q = static_cast<uint32_t>(rng >> (kPrngNumBits - 26)) + 1.0; // Put the computed p-value through the CDF of a geometric. - double interval = bias_ + (std::log2(q) - 26) * (-std::log(2.0) * mean); - // Very large values of interval overflow int64_t. To avoid that, we will - // cheat and clamp any huge values to (int64_t max)/2. This is a potential - // source of bias, but the mean would need to be such a large value that it's - // not likely to come up. For example, with a mean of 1e18, the probability of - // hitting this condition is about 1/1000. For a mean of 1e17, standard - // calculators claim that this event won't happen. + double interval = bias_ + (std::log2(q) - 26) * (-std::log(2.0) * mean); + // Very large values of interval overflow int64_t. To avoid that, we will + // cheat and clamp any huge values to (int64_t max)/2. This is a potential + // source of bias, but the mean would need to be such a large value that it's + // not likely to come up. For example, with a mean of 1e18, the probability of + // hitting this condition is about 1/1000. For a mean of 1e17, standard + // calculators claim that this event won't happen. if (interval > static_cast<double>(std::numeric_limits<int64_t>::max() / 2)) { - // Assume huge values are bias neutral, retain bias for next call. + // Assume huge values are bias neutral, retain bias for next call. return std::numeric_limits<int64_t>::max() / 2; } double value = std::rint(interval); - bias_ = interval - value; - return value; -} + bias_ = interval - value; + return value; +} -int64_t ExponentialBiased::GetStride(int64_t mean) { - return GetSkipCount(mean - 1) + 1; +int64_t ExponentialBiased::GetStride(int64_t mean) { + return GetSkipCount(mean - 1) + 1; } void ExponentialBiased::Initialize() { @@ -89,5 +89,5 @@ void ExponentialBiased::Initialize() { } } // namespace profiling_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h index d31f7782e8..390a599d23 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased.h @@ -17,87 +17,87 @@ #include <stdint.h> -#include "absl/base/config.h" -#include "absl/base/macros.h" - +#include "absl/base/config.h" +#include "absl/base/macros.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace profiling_internal { // ExponentialBiased provides a small and fast random number generator for a -// rounded exponential distribution. This generator manages very little state, -// and imposes no synchronization overhead. This makes it useful in specialized -// scenarios requiring minimum overhead, such as stride based periodic sampling. -// -// ExponentialBiased provides two closely related functions, GetSkipCount() and -// GetStride(), both returning a rounded integer defining a number of events -// required before some event with a given mean probability occurs. -// -// The distribution is useful to generate a random wait time or some periodic -// event with a given mean probability. For example, if an action is supposed to -// happen on average once every 'N' events, then we can get a random 'stride' -// counting down how long before the event to happen. For example, if we'd want -// to sample one in every 1000 'Frobber' calls, our code could look like this: -// -// Frobber::Frobber() { -// stride_ = exponential_biased_.GetStride(1000); -// } -// -// void Frobber::Frob(int arg) { -// if (--stride == 0) { -// SampleFrob(arg); -// stride_ = exponential_biased_.GetStride(1000); -// } -// ... -// } +// rounded exponential distribution. This generator manages very little state, +// and imposes no synchronization overhead. This makes it useful in specialized +// scenarios requiring minimum overhead, such as stride based periodic sampling. // -// The rounding of the return value creates a bias, especially for smaller means -// where the distribution of the fraction is not evenly distributed. We correct -// this bias by tracking the fraction we rounded up or down on each iteration, -// effectively tracking the distance between the cumulative value, and the -// rounded cumulative value. For example, given a mean of 2: +// ExponentialBiased provides two closely related functions, GetSkipCount() and +// GetStride(), both returning a rounded integer defining a number of events +// required before some event with a given mean probability occurs. // -// raw = 1.63076, cumulative = 1.63076, rounded = 2, bias = -0.36923 -// raw = 0.14624, cumulative = 1.77701, rounded = 2, bias = 0.14624 -// raw = 4.93194, cumulative = 6.70895, rounded = 7, bias = -0.06805 -// raw = 0.24206, cumulative = 6.95101, rounded = 7, bias = 0.24206 -// etc... +// The distribution is useful to generate a random wait time or some periodic +// event with a given mean probability. For example, if an action is supposed to +// happen on average once every 'N' events, then we can get a random 'stride' +// counting down how long before the event to happen. For example, if we'd want +// to sample one in every 1000 'Frobber' calls, our code could look like this: // -// Adjusting with rounding bias is relatively trivial: -// -// double value = bias_ + exponential_distribution(mean)(); +// Frobber::Frobber() { +// stride_ = exponential_biased_.GetStride(1000); +// } +// +// void Frobber::Frob(int arg) { +// if (--stride == 0) { +// SampleFrob(arg); +// stride_ = exponential_biased_.GetStride(1000); +// } +// ... +// } +// +// The rounding of the return value creates a bias, especially for smaller means +// where the distribution of the fraction is not evenly distributed. We correct +// this bias by tracking the fraction we rounded up or down on each iteration, +// effectively tracking the distance between the cumulative value, and the +// rounded cumulative value. For example, given a mean of 2: +// +// raw = 1.63076, cumulative = 1.63076, rounded = 2, bias = -0.36923 +// raw = 0.14624, cumulative = 1.77701, rounded = 2, bias = 0.14624 +// raw = 4.93194, cumulative = 6.70895, rounded = 7, bias = -0.06805 +// raw = 0.24206, cumulative = 6.95101, rounded = 7, bias = 0.24206 +// etc... +// +// Adjusting with rounding bias is relatively trivial: +// +// double value = bias_ + exponential_distribution(mean)(); // double rounded_value = std::rint(value); -// bias_ = value - rounded_value; -// return rounded_value; -// +// bias_ = value - rounded_value; +// return rounded_value; +// // This class is thread-compatible. class ExponentialBiased { public: // The number of bits set by NextRandom. static constexpr int kPrngNumBits = 48; - // `GetSkipCount()` returns the number of events to skip before some chosen - // event happens. For example, randomly tossing a coin, we will on average - // throw heads once before we get tails. We can simulate random coin tosses - // using GetSkipCount() as: - // - // ExponentialBiased eb; - // for (...) { - // int number_of_heads_before_tail = eb.GetSkipCount(1); - // for (int flips = 0; flips < number_of_heads_before_tail; ++flips) { - // printf("head..."); - // } - // printf("tail\n"); - // } - // - int64_t GetSkipCount(int64_t mean); - - // GetStride() returns the number of events required for a specific event to - // happen. See the class comments for a usage example. `GetStride()` is - // equivalent to `GetSkipCount(mean - 1) + 1`. When to use `GetStride()` or - // `GetSkipCount()` depends mostly on what best fits the use case. - int64_t GetStride(int64_t mean); + // `GetSkipCount()` returns the number of events to skip before some chosen + // event happens. For example, randomly tossing a coin, we will on average + // throw heads once before we get tails. We can simulate random coin tosses + // using GetSkipCount() as: + // + // ExponentialBiased eb; + // for (...) { + // int number_of_heads_before_tail = eb.GetSkipCount(1); + // for (int flips = 0; flips < number_of_heads_before_tail; ++flips) { + // printf("head..."); + // } + // printf("tail\n"); + // } + // + int64_t GetSkipCount(int64_t mean); + // GetStride() returns the number of events required for a specific event to + // happen. See the class comments for a usage example. `GetStride()` is + // equivalent to `GetSkipCount(mean - 1) + 1`. When to use `GetStride()` or + // `GetSkipCount()` depends mostly on what best fits the use case. + int64_t GetStride(int64_t mean); + // Computes a random number in the range [0, 1<<(kPrngNumBits+1) - 1] // // This is public to enable testing. @@ -107,7 +107,7 @@ class ExponentialBiased { void Initialize(); uint64_t rng_{0}; - double bias_{0}; + double bias_{0}; bool initialized_{false}; }; @@ -124,7 +124,7 @@ inline uint64_t ExponentialBiased::NextRandom(uint64_t rnd) { } } // namespace profiling_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_PROFILING_INTERNAL_EXPONENTIAL_BIASED_H_ diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make index 14f60647fc..7fd2470a41 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased/ya.make @@ -16,10 +16,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/profiling/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc index a738a82c86..9c6ff3928d 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.cc @@ -19,11 +19,11 @@ #include "absl/profiling/internal/exponential_biased.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace profiling_internal { int64_t PeriodicSamplerBase::GetExponentialBiased(int period) noexcept { - return rng_.GetStride(period); + return rng_.GetStride(period); } bool PeriodicSamplerBase::SubtleConfirmSample() noexcept { @@ -37,17 +37,17 @@ bool PeriodicSamplerBase::SubtleConfirmSample() noexcept { // Check if this is the first call to Sample() if (ABSL_PREDICT_FALSE(stride_ == 1)) { - stride_ = static_cast<uint64_t>(-GetExponentialBiased(current_period)); + stride_ = static_cast<uint64_t>(-GetExponentialBiased(current_period)); if (static_cast<int64_t>(stride_) < -1) { ++stride_; return false; } } - - stride_ = static_cast<uint64_t>(-GetExponentialBiased(current_period)); + + stride_ = static_cast<uint64_t>(-GetExponentialBiased(current_period)); return true; } } // namespace profiling_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h index 54f0af452b..0ed64c0dff 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler.h @@ -23,7 +23,7 @@ #include "absl/profiling/internal/exponential_biased.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace profiling_internal { // PeriodicSamplerBase provides the basic period sampler implementation. @@ -205,7 +205,7 @@ template <typename Tag, int default_period> std::atomic<int> PeriodicSampler<Tag, default_period>::period_(default_period); } // namespace profiling_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_PROFILING_INTERNAL_PERIODIC_SAMPLER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make index 841a35bc53..c384f18d7e 100644 --- a/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make +++ b/contrib/restricted/abseil-cpp/absl/profiling/internal/periodic_sampler/ya.make @@ -20,10 +20,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/profiling/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make b/contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make index 73d9caa424..254205714d 100644 --- a/contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make @@ -27,10 +27,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/random) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h b/contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h index 25bd0d5ca4..9334e888ab 100644 --- a/contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h +++ b/contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h @@ -24,7 +24,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // absl::bernoulli_distribution is a drop in replacement for // std::bernoulli_distribution. It guarantees that (given a perfect @@ -194,7 +194,7 @@ bool bernoulli_distribution::Generate(double p, } } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_BERNOULLI_DISTRIBUTION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/beta_distribution.h b/contrib/restricted/abseil-cpp/absl/random/beta_distribution.h index c154066fb8..b43c4fe8ff 100644 --- a/contrib/restricted/abseil-cpp/absl/random/beta_distribution.h +++ b/contrib/restricted/abseil-cpp/absl/random/beta_distribution.h @@ -29,7 +29,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // absl::beta_distribution: // Generate a floating-point variate conforming to a Beta distribution: @@ -421,7 +421,7 @@ std::basic_istream<CharT, Traits>& operator>>( return is; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_BETA_DISTRIBUTION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/bit_gen_ref.h b/contrib/restricted/abseil-cpp/absl/random/bit_gen_ref.h index 9555460fd4..f5133c3956 100644 --- a/contrib/restricted/abseil-cpp/absl/random/bit_gen_ref.h +++ b/contrib/restricted/abseil-cpp/absl/random/bit_gen_ref.h @@ -1,181 +1,181 @@ -// -// Copyright 2018 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// File: bit_gen_ref.h -// ----------------------------------------------------------------------------- -// -// This header defines a bit generator "reference" class, for use in interfaces -// that take both Abseil (e.g. `absl::BitGen`) and standard library (e.g. -// `std::mt19937`) bit generators. - -#ifndef ABSL_RANDOM_BIT_GEN_REF_H_ -#define ABSL_RANDOM_BIT_GEN_REF_H_ - -#include "absl/base/internal/fast_type_id.h" -#include "absl/base/macros.h" -#include "absl/meta/type_traits.h" -#include "absl/random/internal/distribution_caller.h" -#include "absl/random/internal/fast_uniform_bits.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -template <typename URBG, typename = void, typename = void, typename = void> -struct is_urbg : std::false_type {}; - -template <typename URBG> -struct is_urbg< - URBG, - absl::enable_if_t<std::is_same< - typename URBG::result_type, - typename std::decay<decltype((URBG::min)())>::type>::value>, - absl::enable_if_t<std::is_same< - typename URBG::result_type, - typename std::decay<decltype((URBG::max)())>::type>::value>, - absl::enable_if_t<std::is_same< - typename URBG::result_type, - typename std::decay<decltype(std::declval<URBG>()())>::type>::value>> - : std::true_type {}; - -template <typename> -struct DistributionCaller; -class MockHelpers; - -} // namespace random_internal - -// ----------------------------------------------------------------------------- -// absl::BitGenRef -// ----------------------------------------------------------------------------- -// -// `absl::BitGenRef` is a type-erasing class that provides a generator-agnostic -// non-owning "reference" interface for use in place of any specific uniform -// random bit generator (URBG). This class may be used for both Abseil -// (e.g. `absl::BitGen`, `absl::InsecureBitGen`) and Standard library (e.g -// `std::mt19937`, `std::minstd_rand`) bit generators. -// -// Like other reference classes, `absl::BitGenRef` does not own the -// underlying bit generator, and the underlying instance must outlive the -// `absl::BitGenRef`. -// -// `absl::BitGenRef` is particularly useful when used with an -// `absl::MockingBitGen` to test specific paths in functions which use random -// values. -// -// Example: -// void TakesBitGenRef(absl::BitGenRef gen) { -// int x = absl::Uniform<int>(gen, 0, 1000); -// } -// -class BitGenRef { - // SFINAE to detect whether the URBG type includes a member matching - // bool InvokeMock(base_internal::FastTypeIdType, void*, void*). - // - // These live inside BitGenRef so that they have friend access - // to MockingBitGen. (see similar methods in DistributionCaller). - template <template <class...> class Trait, class AlwaysVoid, class... Args> - struct detector : std::false_type {}; - template <template <class...> class Trait, class... Args> - struct detector<Trait, absl::void_t<Trait<Args...>>, Args...> - : std::true_type {}; - - template <class T> - using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock( - std::declval<base_internal::FastTypeIdType>(), std::declval<void*>(), - std::declval<void*>())); - - template <typename T> - using HasInvokeMock = typename detector<invoke_mock_t, void, T>::type; - - public: - BitGenRef(const BitGenRef&) = default; - BitGenRef(BitGenRef&&) = default; - BitGenRef& operator=(const BitGenRef&) = default; - BitGenRef& operator=(BitGenRef&&) = default; - - template <typename URBG, typename absl::enable_if_t< - (!std::is_same<URBG, BitGenRef>::value && - random_internal::is_urbg<URBG>::value && - !HasInvokeMock<URBG>::value)>* = nullptr> - BitGenRef(URBG& gen) // NOLINT - : t_erased_gen_ptr_(reinterpret_cast<uintptr_t>(&gen)), - mock_call_(NotAMock), - generate_impl_fn_(ImplFn<URBG>) {} - - template <typename URBG, - typename absl::enable_if_t<(!std::is_same<URBG, BitGenRef>::value && - random_internal::is_urbg<URBG>::value && - HasInvokeMock<URBG>::value)>* = nullptr> - BitGenRef(URBG& gen) // NOLINT - : t_erased_gen_ptr_(reinterpret_cast<uintptr_t>(&gen)), - mock_call_(&MockCall<URBG>), - generate_impl_fn_(ImplFn<URBG>) {} - - using result_type = uint64_t; - - static constexpr result_type(min)() { - return (std::numeric_limits<result_type>::min)(); - } - - static constexpr result_type(max)() { - return (std::numeric_limits<result_type>::max)(); - } - - result_type operator()() { return generate_impl_fn_(t_erased_gen_ptr_); } - - private: - using impl_fn = result_type (*)(uintptr_t); - using mock_call_fn = bool (*)(uintptr_t, base_internal::FastTypeIdType, void*, - void*); - - template <typename URBG> - static result_type ImplFn(uintptr_t ptr) { - // Ensure that the return values from operator() fill the entire - // range promised by result_type, min() and max(). - absl::random_internal::FastUniformBits<result_type> fast_uniform_bits; - return fast_uniform_bits(*reinterpret_cast<URBG*>(ptr)); - } - - // Get a type-erased InvokeMock pointer. - template <typename URBG> - static bool MockCall(uintptr_t gen_ptr, base_internal::FastTypeIdType type, - void* result, void* arg_tuple) { - return reinterpret_cast<URBG*>(gen_ptr)->InvokeMock(type, result, - arg_tuple); - } - static bool NotAMock(uintptr_t, base_internal::FastTypeIdType, void*, void*) { - return false; - } - - inline bool InvokeMock(base_internal::FastTypeIdType type, void* args_tuple, - void* result) { - if (mock_call_ == NotAMock) return false; // avoids an indirect call. - return mock_call_(t_erased_gen_ptr_, type, args_tuple, result); - } - - uintptr_t t_erased_gen_ptr_; - mock_call_fn mock_call_; - impl_fn generate_impl_fn_; - - template <typename> - friend struct ::absl::random_internal::DistributionCaller; // for InvokeMock - friend class ::absl::random_internal::MockHelpers; // for InvokeMock -}; - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_BIT_GEN_REF_H_ +// +// Copyright 2018 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// File: bit_gen_ref.h +// ----------------------------------------------------------------------------- +// +// This header defines a bit generator "reference" class, for use in interfaces +// that take both Abseil (e.g. `absl::BitGen`) and standard library (e.g. +// `std::mt19937`) bit generators. + +#ifndef ABSL_RANDOM_BIT_GEN_REF_H_ +#define ABSL_RANDOM_BIT_GEN_REF_H_ + +#include "absl/base/internal/fast_type_id.h" +#include "absl/base/macros.h" +#include "absl/meta/type_traits.h" +#include "absl/random/internal/distribution_caller.h" +#include "absl/random/internal/fast_uniform_bits.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace random_internal { + +template <typename URBG, typename = void, typename = void, typename = void> +struct is_urbg : std::false_type {}; + +template <typename URBG> +struct is_urbg< + URBG, + absl::enable_if_t<std::is_same< + typename URBG::result_type, + typename std::decay<decltype((URBG::min)())>::type>::value>, + absl::enable_if_t<std::is_same< + typename URBG::result_type, + typename std::decay<decltype((URBG::max)())>::type>::value>, + absl::enable_if_t<std::is_same< + typename URBG::result_type, + typename std::decay<decltype(std::declval<URBG>()())>::type>::value>> + : std::true_type {}; + +template <typename> +struct DistributionCaller; +class MockHelpers; + +} // namespace random_internal + +// ----------------------------------------------------------------------------- +// absl::BitGenRef +// ----------------------------------------------------------------------------- +// +// `absl::BitGenRef` is a type-erasing class that provides a generator-agnostic +// non-owning "reference" interface for use in place of any specific uniform +// random bit generator (URBG). This class may be used for both Abseil +// (e.g. `absl::BitGen`, `absl::InsecureBitGen`) and Standard library (e.g +// `std::mt19937`, `std::minstd_rand`) bit generators. +// +// Like other reference classes, `absl::BitGenRef` does not own the +// underlying bit generator, and the underlying instance must outlive the +// `absl::BitGenRef`. +// +// `absl::BitGenRef` is particularly useful when used with an +// `absl::MockingBitGen` to test specific paths in functions which use random +// values. +// +// Example: +// void TakesBitGenRef(absl::BitGenRef gen) { +// int x = absl::Uniform<int>(gen, 0, 1000); +// } +// +class BitGenRef { + // SFINAE to detect whether the URBG type includes a member matching + // bool InvokeMock(base_internal::FastTypeIdType, void*, void*). + // + // These live inside BitGenRef so that they have friend access + // to MockingBitGen. (see similar methods in DistributionCaller). + template <template <class...> class Trait, class AlwaysVoid, class... Args> + struct detector : std::false_type {}; + template <template <class...> class Trait, class... Args> + struct detector<Trait, absl::void_t<Trait<Args...>>, Args...> + : std::true_type {}; + + template <class T> + using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock( + std::declval<base_internal::FastTypeIdType>(), std::declval<void*>(), + std::declval<void*>())); + + template <typename T> + using HasInvokeMock = typename detector<invoke_mock_t, void, T>::type; + + public: + BitGenRef(const BitGenRef&) = default; + BitGenRef(BitGenRef&&) = default; + BitGenRef& operator=(const BitGenRef&) = default; + BitGenRef& operator=(BitGenRef&&) = default; + + template <typename URBG, typename absl::enable_if_t< + (!std::is_same<URBG, BitGenRef>::value && + random_internal::is_urbg<URBG>::value && + !HasInvokeMock<URBG>::value)>* = nullptr> + BitGenRef(URBG& gen) // NOLINT + : t_erased_gen_ptr_(reinterpret_cast<uintptr_t>(&gen)), + mock_call_(NotAMock), + generate_impl_fn_(ImplFn<URBG>) {} + + template <typename URBG, + typename absl::enable_if_t<(!std::is_same<URBG, BitGenRef>::value && + random_internal::is_urbg<URBG>::value && + HasInvokeMock<URBG>::value)>* = nullptr> + BitGenRef(URBG& gen) // NOLINT + : t_erased_gen_ptr_(reinterpret_cast<uintptr_t>(&gen)), + mock_call_(&MockCall<URBG>), + generate_impl_fn_(ImplFn<URBG>) {} + + using result_type = uint64_t; + + static constexpr result_type(min)() { + return (std::numeric_limits<result_type>::min)(); + } + + static constexpr result_type(max)() { + return (std::numeric_limits<result_type>::max)(); + } + + result_type operator()() { return generate_impl_fn_(t_erased_gen_ptr_); } + + private: + using impl_fn = result_type (*)(uintptr_t); + using mock_call_fn = bool (*)(uintptr_t, base_internal::FastTypeIdType, void*, + void*); + + template <typename URBG> + static result_type ImplFn(uintptr_t ptr) { + // Ensure that the return values from operator() fill the entire + // range promised by result_type, min() and max(). + absl::random_internal::FastUniformBits<result_type> fast_uniform_bits; + return fast_uniform_bits(*reinterpret_cast<URBG*>(ptr)); + } + + // Get a type-erased InvokeMock pointer. + template <typename URBG> + static bool MockCall(uintptr_t gen_ptr, base_internal::FastTypeIdType type, + void* result, void* arg_tuple) { + return reinterpret_cast<URBG*>(gen_ptr)->InvokeMock(type, result, + arg_tuple); + } + static bool NotAMock(uintptr_t, base_internal::FastTypeIdType, void*, void*) { + return false; + } + + inline bool InvokeMock(base_internal::FastTypeIdType type, void* args_tuple, + void* result) { + if (mock_call_ == NotAMock) return false; // avoids an indirect call. + return mock_call_(t_erased_gen_ptr_, type, args_tuple, result); + } + + uintptr_t t_erased_gen_ptr_; + mock_call_fn mock_call_; + impl_fn generate_impl_fn_; + + template <typename> + friend struct ::absl::random_internal::DistributionCaller; // for InvokeMock + friend class ::absl::random_internal::MockHelpers; // for InvokeMock +}; + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_RANDOM_BIT_GEN_REF_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc b/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc index 081accee52..996813860b 100644 --- a/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc +++ b/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc @@ -15,7 +15,7 @@ #include "absl/random/discrete_distribution.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // Initializes the distribution table for Walker's Aliasing algorithm, described @@ -94,5 +94,5 @@ std::vector<std::pair<double, size_t>> InitDiscreteDistribution( } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h b/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h index 171aa11a1e..eb5e9096c3 100644 --- a/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h +++ b/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h @@ -29,7 +29,7 @@ #include "absl/random/uniform_int_distribution.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // absl::discrete_distribution // @@ -241,7 +241,7 @@ std::basic_istream<CharT, Traits>& operator>>( return is; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_DISCRETE_DISTRIBUTION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/distributions.h b/contrib/restricted/abseil-cpp/absl/random/distributions.h index 31c79694e5..feae218ba9 100644 --- a/contrib/restricted/abseil-cpp/absl/random/distributions.h +++ b/contrib/restricted/abseil-cpp/absl/random/distributions.h @@ -57,7 +57,7 @@ #include "absl/random/beta_distribution.h" #include "absl/random/exponential_distribution.h" #include "absl/random/gaussian_distribution.h" -#include "absl/random/internal/distribution_caller.h" // IWYU pragma: export +#include "absl/random/internal/distribution_caller.h" // IWYU pragma: export #include "absl/random/internal/uniform_helper.h" // IWYU pragma: export #include "absl/random/log_uniform_int_distribution.h" #include "absl/random/poisson_distribution.h" @@ -66,7 +66,7 @@ #include "absl/random/zipf_distribution.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalClosedClosedTag, IntervalClosedClosed, {}); @@ -128,10 +128,10 @@ Uniform(TagType tag, auto a = random_internal::uniform_lower_bound(tag, lo, hi); auto b = random_internal::uniform_upper_bound(tag, lo, hi); - if (!random_internal::is_uniform_range_valid(a, b)) return lo; + if (!random_internal::is_uniform_range_valid(a, b)) return lo; return random_internal::DistributionCaller<gen_t>::template Call< - distribution_t>(&urbg, tag, lo, hi); + distribution_t>(&urbg, tag, lo, hi); } // absl::Uniform<T>(bitgen, lo, hi) @@ -144,14 +144,14 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) R lo, R hi) { using gen_t = absl::decay_t<URBG>; using distribution_t = random_internal::UniformDistributionWrapper<R>; - constexpr auto tag = absl::IntervalClosedOpen; + constexpr auto tag = absl::IntervalClosedOpen; auto a = random_internal::uniform_lower_bound(tag, lo, hi); auto b = random_internal::uniform_upper_bound(tag, lo, hi); - if (!random_internal::is_uniform_range_valid(a, b)) return lo; + if (!random_internal::is_uniform_range_valid(a, b)) return lo; return random_internal::DistributionCaller<gen_t>::template Call< - distribution_t>(&urbg, lo, hi); + distribution_t>(&urbg, lo, hi); } // absl::Uniform(tag, bitgen, lo, hi) @@ -172,10 +172,10 @@ Uniform(TagType tag, auto a = random_internal::uniform_lower_bound<return_t>(tag, lo, hi); auto b = random_internal::uniform_upper_bound<return_t>(tag, lo, hi); - if (!random_internal::is_uniform_range_valid(a, b)) return lo; + if (!random_internal::is_uniform_range_valid(a, b)) return lo; return random_internal::DistributionCaller<gen_t>::template Call< - distribution_t>(&urbg, tag, static_cast<return_t>(lo), + distribution_t>(&urbg, tag, static_cast<return_t>(lo), static_cast<return_t>(hi)); } @@ -196,10 +196,10 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) constexpr auto tag = absl::IntervalClosedOpen; auto a = random_internal::uniform_lower_bound<return_t>(tag, lo, hi); auto b = random_internal::uniform_upper_bound<return_t>(tag, lo, hi); - if (!random_internal::is_uniform_range_valid(a, b)) return lo; + if (!random_internal::is_uniform_range_valid(a, b)) return lo; return random_internal::DistributionCaller<gen_t>::template Call< - distribution_t>(&urbg, static_cast<return_t>(lo), + distribution_t>(&urbg, static_cast<return_t>(lo), static_cast<return_t>(hi)); } @@ -214,7 +214,7 @@ Uniform(URBG&& urbg) { // NOLINT(runtime/references) using distribution_t = random_internal::UniformDistributionWrapper<R>; return random_internal::DistributionCaller<gen_t>::template Call< - distribution_t>(&urbg); + distribution_t>(&urbg); } // ----------------------------------------------------------------------------- @@ -244,7 +244,7 @@ bool Bernoulli(URBG&& urbg, // NOLINT(runtime/references) using distribution_t = absl::bernoulli_distribution; return random_internal::DistributionCaller<gen_t>::template Call< - distribution_t>(&urbg, p); + distribution_t>(&urbg, p); } // ----------------------------------------------------------------------------- @@ -276,17 +276,17 @@ RealType Beta(URBG&& urbg, // NOLINT(runtime/references) using distribution_t = typename absl::beta_distribution<RealType>; return random_internal::DistributionCaller<gen_t>::template Call< - distribution_t>(&urbg, alpha, beta); + distribution_t>(&urbg, alpha, beta); } // ----------------------------------------------------------------------------- // absl::Exponential<T>(bitgen, lambda = 1) // ----------------------------------------------------------------------------- // -// `absl::Exponential` produces a floating point number representing the -// distance (time) between two consecutive events in a point process of events -// occurring continuously and independently at a constant average rate. `T` must -// be a floating point type, but may be inferred from the type of `lambda`. +// `absl::Exponential` produces a floating point number representing the +// distance (time) between two consecutive events in a point process of events +// occurring continuously and independently at a constant average rate. `T` must +// be a floating point type, but may be inferred from the type of `lambda`. // // See https://en.wikipedia.org/wiki/Exponential_distribution. // @@ -308,7 +308,7 @@ RealType Exponential(URBG&& urbg, // NOLINT(runtime/references) using distribution_t = typename absl::exponential_distribution<RealType>; return random_internal::DistributionCaller<gen_t>::template Call< - distribution_t>(&urbg, lambda); + distribution_t>(&urbg, lambda); } // ----------------------------------------------------------------------------- @@ -339,7 +339,7 @@ RealType Gaussian(URBG&& urbg, // NOLINT(runtime/references) using distribution_t = typename absl::gaussian_distribution<RealType>; return random_internal::DistributionCaller<gen_t>::template Call< - distribution_t>(&urbg, mean, stddev); + distribution_t>(&urbg, mean, stddev); } // ----------------------------------------------------------------------------- @@ -381,7 +381,7 @@ IntType LogUniform(URBG&& urbg, // NOLINT(runtime/references) using distribution_t = typename absl::log_uniform_int_distribution<IntType>; return random_internal::DistributionCaller<gen_t>::template Call< - distribution_t>(&urbg, lo, hi, base); + distribution_t>(&urbg, lo, hi, base); } // ----------------------------------------------------------------------------- @@ -411,7 +411,7 @@ IntType Poisson(URBG&& urbg, // NOLINT(runtime/references) using distribution_t = typename absl::poisson_distribution<IntType>; return random_internal::DistributionCaller<gen_t>::template Call< - distribution_t>(&urbg, mean); + distribution_t>(&urbg, mean); } // ----------------------------------------------------------------------------- @@ -443,10 +443,10 @@ IntType Zipf(URBG&& urbg, // NOLINT(runtime/references) using distribution_t = typename absl::zipf_distribution<IntType>; return random_internal::DistributionCaller<gen_t>::template Call< - distribution_t>(&urbg, hi, q, v); + distribution_t>(&urbg, hi, q, v); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_DISTRIBUTIONS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h b/contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h index b5caf8a1e1..67d37eb17b 100644 --- a/contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h +++ b/contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h @@ -27,7 +27,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // absl::exponential_distribution: // Generates a number conforming to an exponential distribution and is @@ -159,7 +159,7 @@ std::basic_istream<CharT, Traits>& operator>>( return is; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_EXPONENTIAL_DISTRIBUTION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.cc b/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.cc index c7a72cb2f6..d602a8b5c7 100644 --- a/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.cc +++ b/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.cc @@ -4,7 +4,7 @@ #include "absl/random/gaussian_distribution.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { const gaussian_distribution_base::Tables @@ -97,7 +97,7 @@ const gaussian_distribution_base::Tables 0.9362826816850632339, 0.9635996931270905952, 1}}; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl // clang-format on diff --git a/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h b/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h index 4b07a5c0af..9b4fbf5d19 100644 --- a/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h +++ b/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h @@ -28,13 +28,13 @@ #include <limits> #include <type_traits> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/random/internal/fast_uniform_bits.h" #include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // absl::gaussian_distribution_base implements the underlying ziggurat algorithm @@ -44,7 +44,7 @@ namespace random_internal { // The specific algorithm has some of the improvements suggested by the // 2005 paper, "An Improved Ziggurat Method to Generate Normal Random Samples", // Jurgen A Doornik. (https://www.doornik.com/research/ziggurat.pdf) -class ABSL_DLL gaussian_distribution_base { +class ABSL_DLL gaussian_distribution_base { public: template <typename URBG> inline double zignor(URBG& g); // NOLINT(runtime/references) @@ -269,7 +269,7 @@ inline double gaussian_distribution_base::zignor( } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_GAUSSIAN_DISTRIBUTION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make index 340d08c827..943a6a9dea 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make @@ -28,10 +28,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc b/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc index 640d48cea6..178941bb21 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc @@ -19,7 +19,7 @@ #include "absl/random/internal/distribution_test_util.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { namespace { @@ -228,5 +228,5 @@ double ChiSquarePValue(double chi_square, int dof) { } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.h b/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.h index 07f4fbe522..7bfca597e5 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.h @@ -26,10 +26,10 @@ #include <cassert> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { constexpr const char kChiSquared[] = "chi-squared"; @@ -83,7 +83,7 @@ double ChiSquareValue(int dof, double p); double ChiSquarePValue(double chi_square, int dof); } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_CHI_SQUARE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h index fc81b787eb..f1cc0901a6 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h @@ -19,12 +19,12 @@ #include <utility> -#include "absl/base/config.h" -#include "absl/base/internal/fast_type_id.h" -#include "absl/utility/utility.h" - +#include "absl/base/config.h" +#include "absl/base/internal/fast_type_id.h" +#include "absl/utility/utility.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // DistributionCaller provides an opportunity to overload the general @@ -32,61 +32,61 @@ namespace random_internal { // to intercept such calls. template <typename URBG> struct DistributionCaller { - // SFINAE to detect whether the URBG type includes a member matching - // bool InvokeMock(base_internal::FastTypeIdType, void*, void*). + // SFINAE to detect whether the URBG type includes a member matching + // bool InvokeMock(base_internal::FastTypeIdType, void*, void*). // - // These live inside BitGenRef so that they have friend access - // to MockingBitGen. (see similar methods in DistributionCaller). - template <template <class...> class Trait, class AlwaysVoid, class... Args> - struct detector : std::false_type {}; - template <template <class...> class Trait, class... Args> - struct detector<Trait, absl::void_t<Trait<Args...>>, Args...> - : std::true_type {}; - - template <class T> - using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock( - std::declval<::absl::base_internal::FastTypeIdType>(), - std::declval<void*>(), std::declval<void*>())); - - using HasInvokeMock = typename detector<invoke_mock_t, void, URBG>::type; - - // Default implementation of distribution caller. - template <typename DistrT, typename... Args> - static typename DistrT::result_type Impl(std::false_type, URBG* urbg, - Args&&... args) { + // These live inside BitGenRef so that they have friend access + // to MockingBitGen. (see similar methods in DistributionCaller). + template <template <class...> class Trait, class AlwaysVoid, class... Args> + struct detector : std::false_type {}; + template <template <class...> class Trait, class... Args> + struct detector<Trait, absl::void_t<Trait<Args...>>, Args...> + : std::true_type {}; + + template <class T> + using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock( + std::declval<::absl::base_internal::FastTypeIdType>(), + std::declval<void*>(), std::declval<void*>())); + + using HasInvokeMock = typename detector<invoke_mock_t, void, URBG>::type; + + // Default implementation of distribution caller. + template <typename DistrT, typename... Args> + static typename DistrT::result_type Impl(std::false_type, URBG* urbg, + Args&&... args) { DistrT dist(std::forward<Args>(args)...); return dist(*urbg); } - - // Mock implementation of distribution caller. - // The underlying KeyT must match the KeyT constructed by MockOverloadSet. - template <typename DistrT, typename... Args> - static typename DistrT::result_type Impl(std::true_type, URBG* urbg, - Args&&... args) { - using ResultT = typename DistrT::result_type; - using ArgTupleT = std::tuple<absl::decay_t<Args>...>; - using KeyT = ResultT(DistrT, ArgTupleT); - - ArgTupleT arg_tuple(std::forward<Args>(args)...); - ResultT result; - if (!urbg->InvokeMock(::absl::base_internal::FastTypeId<KeyT>(), &arg_tuple, - &result)) { - auto dist = absl::make_from_tuple<DistrT>(arg_tuple); - result = dist(*urbg); - } - return result; - } - - // Default implementation of distribution caller. - template <typename DistrT, typename... Args> - static typename DistrT::result_type Call(URBG* urbg, Args&&... args) { - return Impl<DistrT, Args...>(HasInvokeMock{}, urbg, - std::forward<Args>(args)...); - } + + // Mock implementation of distribution caller. + // The underlying KeyT must match the KeyT constructed by MockOverloadSet. + template <typename DistrT, typename... Args> + static typename DistrT::result_type Impl(std::true_type, URBG* urbg, + Args&&... args) { + using ResultT = typename DistrT::result_type; + using ArgTupleT = std::tuple<absl::decay_t<Args>...>; + using KeyT = ResultT(DistrT, ArgTupleT); + + ArgTupleT arg_tuple(std::forward<Args>(args)...); + ResultT result; + if (!urbg->InvokeMock(::absl::base_internal::FastTypeId<KeyT>(), &arg_tuple, + &result)) { + auto dist = absl::make_from_tuple<DistrT>(arg_tuple); + result = dist(*urbg); + } + return result; + } + + // Default implementation of distribution caller. + template <typename DistrT, typename... Args> + static typename DistrT::result_type Call(URBG* urbg, Args&&... args) { + return Impl<DistrT, Args...>(HasInvokeMock{}, urbg, + std::forward<Args>(args)...); + } }; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.cc b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.cc index e9005658c0..29bc2ca28a 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.cc @@ -25,7 +25,7 @@ #include "absl/strings/str_format.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { namespace { @@ -414,5 +414,5 @@ double MaxErrorTolerance(double acceptance_probability) { } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h index 6d94cf6c97..5c680cc19f 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h @@ -26,7 +26,7 @@ // non-test code. namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // http://webspace.ship.edu/pgmarr/Geo441/Lectures/Lec%205%20-%20Normality%20Testing.pdf @@ -107,7 +107,7 @@ double BetaIncomplete(double x, double p, double q); double BetaIncompleteInv(double p, double q, double alpha); } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_TEST_UTIL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h b/contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h index 25f791535f..f3c1976010 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h @@ -22,11 +22,11 @@ #include <iterator> #include <vector> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/base/internal/endian.h" - + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // This class conforms to the C++ Standard "Seed Sequence" concept @@ -86,7 +86,7 @@ class ExplicitSeedSeq { }; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_EXPLICIT_SEED_SEQ_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/fast_uniform_bits.h b/contrib/restricted/abseil-cpp/absl/random/internal/fast_uniform_bits.h index 425aaf7d83..8ce246e402 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/fast_uniform_bits.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/fast_uniform_bits.h @@ -20,11 +20,11 @@ #include <limits> #include <type_traits> -#include "absl/base/config.h" -#include "absl/meta/type_traits.h" - +#include "absl/base/config.h" +#include "absl/meta/type_traits.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // Returns true if the input value is zero or a power of two. Useful for // determining if the range of output values in a URBG @@ -39,17 +39,17 @@ constexpr bool IsPowerOfTwoOrZero(UIntType n) { template <typename URBG> constexpr typename URBG::result_type RangeSize() { using result_type = typename URBG::result_type; - static_assert((URBG::max)() != (URBG::min)(), "URBG range cannot be 0."); + static_assert((URBG::max)() != (URBG::min)(), "URBG range cannot be 0."); return ((URBG::max)() == (std::numeric_limits<result_type>::max)() && (URBG::min)() == std::numeric_limits<result_type>::lowest()) ? result_type{0} - : ((URBG::max)() - (URBG::min)() + result_type{1}); + : ((URBG::max)() - (URBG::min)() + result_type{1}); } // Computes the floor of the log. (i.e., std::floor(std::log2(N)); template <typename UIntType> constexpr UIntType IntegerLog2(UIntType n) { - return (n <= 1) ? 0 : 1 + IntegerLog2(n >> 1); + return (n <= 1) ? 0 : 1 + IntegerLog2(n >> 1); } // Returns the number of bits of randomness returned through @@ -58,23 +58,23 @@ template <typename URBG> constexpr size_t NumBits() { return RangeSize<URBG>() == 0 ? std::numeric_limits<typename URBG::result_type>::digits - : IntegerLog2(RangeSize<URBG>()); + : IntegerLog2(RangeSize<URBG>()); } // Given a shift value `n`, constructs a mask with exactly the low `n` bits set. // If `n == 0`, all bits are set. template <typename UIntType> -constexpr UIntType MaskFromShift(size_t n) { +constexpr UIntType MaskFromShift(size_t n) { return ((n % std::numeric_limits<UIntType>::digits) == 0) ? ~UIntType{0} : (UIntType{1} << n) - UIntType{1}; } -// Tags used to dispatch FastUniformBits::generate to the simple or more complex -// entropy extraction algorithm. -struct SimplifiedLoopTag {}; -struct RejectionLoopTag {}; - +// Tags used to dispatch FastUniformBits::generate to the simple or more complex +// entropy extraction algorithm. +struct SimplifiedLoopTag {}; +struct RejectionLoopTag {}; + // FastUniformBits implements a fast path to acquire uniform independent bits // from a type which conforms to the [rand.req.urbg] concept. // Parameterized by: @@ -103,15 +103,15 @@ class FastUniformBits { "an unsigned type."); // Generate() generates a random value, dispatched on whether - // the underlying URBG must use rejection sampling to generate a value, - // or whether a simplified loop will suffice. + // the underlying URBG must use rejection sampling to generate a value, + // or whether a simplified loop will suffice. template <typename URBG> result_type Generate(URBG& g, // NOLINT(runtime/references) - SimplifiedLoopTag); + SimplifiedLoopTag); template <typename URBG> result_type Generate(URBG& g, // NOLINT(runtime/references) - RejectionLoopTag); + RejectionLoopTag); }; template <typename UIntType> @@ -123,47 +123,47 @@ FastUniformBits<UIntType>::operator()(URBG& g) { // NOLINT(runtime/references) // Y = (2 ^ kRange) - 1 static_assert((URBG::max)() > (URBG::min)(), "URBG::max and URBG::min may not be equal."); - - using tag = absl::conditional_t<IsPowerOfTwoOrZero(RangeSize<URBG>()), - SimplifiedLoopTag, RejectionLoopTag>; - return Generate(g, tag{}); + + using tag = absl::conditional_t<IsPowerOfTwoOrZero(RangeSize<URBG>()), + SimplifiedLoopTag, RejectionLoopTag>; + return Generate(g, tag{}); } template <typename UIntType> template <typename URBG> typename FastUniformBits<UIntType>::result_type FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references) - SimplifiedLoopTag) { - // The simplified version of FastUniformBits works only on URBGs that have - // a range that is a power of 2. In this case we simply loop and shift without - // attempting to balance the bits across calls. - static_assert(IsPowerOfTwoOrZero(RangeSize<URBG>()), - "incorrect Generate tag for URBG instance"); - - static constexpr size_t kResultBits = - std::numeric_limits<result_type>::digits; - static constexpr size_t kUrbgBits = NumBits<URBG>(); - static constexpr size_t kIters = - (kResultBits / kUrbgBits) + (kResultBits % kUrbgBits != 0); - static constexpr size_t kShift = (kIters == 1) ? 0 : kUrbgBits; - static constexpr auto kMin = (URBG::min)(); - - result_type r = static_cast<result_type>(g() - kMin); - for (size_t n = 1; n < kIters; ++n) { - r = (r << kShift) + static_cast<result_type>(g() - kMin); - } - return r; + SimplifiedLoopTag) { + // The simplified version of FastUniformBits works only on URBGs that have + // a range that is a power of 2. In this case we simply loop and shift without + // attempting to balance the bits across calls. + static_assert(IsPowerOfTwoOrZero(RangeSize<URBG>()), + "incorrect Generate tag for URBG instance"); + + static constexpr size_t kResultBits = + std::numeric_limits<result_type>::digits; + static constexpr size_t kUrbgBits = NumBits<URBG>(); + static constexpr size_t kIters = + (kResultBits / kUrbgBits) + (kResultBits % kUrbgBits != 0); + static constexpr size_t kShift = (kIters == 1) ? 0 : kUrbgBits; + static constexpr auto kMin = (URBG::min)(); + + result_type r = static_cast<result_type>(g() - kMin); + for (size_t n = 1; n < kIters; ++n) { + r = (r << kShift) + static_cast<result_type>(g() - kMin); + } + return r; } template <typename UIntType> template <typename URBG> typename FastUniformBits<UIntType>::result_type FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references) - RejectionLoopTag) { - static_assert(!IsPowerOfTwoOrZero(RangeSize<URBG>()), - "incorrect Generate tag for URBG instance"); - using urbg_result_type = typename URBG::result_type; - + RejectionLoopTag) { + static_assert(!IsPowerOfTwoOrZero(RangeSize<URBG>()), + "incorrect Generate tag for URBG instance"); + using urbg_result_type = typename URBG::result_type; + // See [rand.adapt.ibits] for more details on the constants calculated below. // // It is preferable to use roughly the same number of bits from each generator @@ -176,44 +176,44 @@ FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references) // `kSmallIters` and `kLargeIters` times respectively such // that // - // `kResultBits == kSmallIters * kSmallBits - // + kLargeIters * kLargeBits` + // `kResultBits == kSmallIters * kSmallBits + // + kLargeIters * kLargeBits` // - // where `kResultBits` is the total number of bits in `result_type`. + // where `kResultBits` is the total number of bits in `result_type`. // - static constexpr size_t kResultBits = - std::numeric_limits<result_type>::digits; // w - static constexpr urbg_result_type kUrbgRange = RangeSize<URBG>(); // R - static constexpr size_t kUrbgBits = NumBits<URBG>(); // m - - // compute the initial estimate of the bits used. - // [rand.adapt.ibits] 2 (c) - static constexpr size_t kA = // ceil(w/m) - (kResultBits / kUrbgBits) + ((kResultBits % kUrbgBits) != 0); // n' - - static constexpr size_t kABits = kResultBits / kA; // w0' - static constexpr urbg_result_type kARejection = - ((kUrbgRange >> kABits) << kABits); // y0' - - // refine the selection to reduce the rejection frequency. - static constexpr size_t kTotalIters = - ((kUrbgRange - kARejection) <= (kARejection / kA)) ? kA : (kA + 1); // n - - // [rand.adapt.ibits] 2 (b) - static constexpr size_t kSmallIters = - kTotalIters - (kResultBits % kTotalIters); // n0 - static constexpr size_t kSmallBits = kResultBits / kTotalIters; // w0 - static constexpr urbg_result_type kSmallRejection = - ((kUrbgRange >> kSmallBits) << kSmallBits); // y0 - - static constexpr size_t kLargeBits = kSmallBits + 1; // w0+1 - static constexpr urbg_result_type kLargeRejection = - ((kUrbgRange >> kLargeBits) << kLargeBits); // y1 - + static constexpr size_t kResultBits = + std::numeric_limits<result_type>::digits; // w + static constexpr urbg_result_type kUrbgRange = RangeSize<URBG>(); // R + static constexpr size_t kUrbgBits = NumBits<URBG>(); // m + + // compute the initial estimate of the bits used. + // [rand.adapt.ibits] 2 (c) + static constexpr size_t kA = // ceil(w/m) + (kResultBits / kUrbgBits) + ((kResultBits % kUrbgBits) != 0); // n' + + static constexpr size_t kABits = kResultBits / kA; // w0' + static constexpr urbg_result_type kARejection = + ((kUrbgRange >> kABits) << kABits); // y0' + + // refine the selection to reduce the rejection frequency. + static constexpr size_t kTotalIters = + ((kUrbgRange - kARejection) <= (kARejection / kA)) ? kA : (kA + 1); // n + + // [rand.adapt.ibits] 2 (b) + static constexpr size_t kSmallIters = + kTotalIters - (kResultBits % kTotalIters); // n0 + static constexpr size_t kSmallBits = kResultBits / kTotalIters; // w0 + static constexpr urbg_result_type kSmallRejection = + ((kUrbgRange >> kSmallBits) << kSmallBits); // y0 + + static constexpr size_t kLargeBits = kSmallBits + 1; // w0+1 + static constexpr urbg_result_type kLargeRejection = + ((kUrbgRange >> kLargeBits) << kLargeBits); // y1 + // - // Because `kLargeBits == kSmallBits + 1`, it follows that + // Because `kLargeBits == kSmallBits + 1`, it follows that // - // `kResultBits == kSmallIters * kSmallBits + kLargeIters` + // `kResultBits == kSmallIters * kSmallBits + kLargeIters` // // and therefore // @@ -224,45 +224,45 @@ FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references) // mentioned above, if the URBG width is a divisor of `kTotalWidth`, then // there would be no need for any large iterations (i.e., one loop would // suffice), and indeed, in this case, `kLargeIters` would be zero. - static_assert(kResultBits == kSmallIters * kSmallBits + - (kTotalIters - kSmallIters) * kLargeBits, - "Error in looping constant calculations."); - - // The small shift is essentially small bits, but due to the potential - // of generating a smaller result_type from a larger urbg type, the actual - // shift might be 0. - static constexpr size_t kSmallShift = kSmallBits % kResultBits; - static constexpr auto kSmallMask = - MaskFromShift<urbg_result_type>(kSmallShift); - static constexpr size_t kLargeShift = kLargeBits % kResultBits; - static constexpr auto kLargeMask = - MaskFromShift<urbg_result_type>(kLargeShift); - - static constexpr auto kMin = (URBG::min)(); - + static_assert(kResultBits == kSmallIters * kSmallBits + + (kTotalIters - kSmallIters) * kLargeBits, + "Error in looping constant calculations."); + + // The small shift is essentially small bits, but due to the potential + // of generating a smaller result_type from a larger urbg type, the actual + // shift might be 0. + static constexpr size_t kSmallShift = kSmallBits % kResultBits; + static constexpr auto kSmallMask = + MaskFromShift<urbg_result_type>(kSmallShift); + static constexpr size_t kLargeShift = kLargeBits % kResultBits; + static constexpr auto kLargeMask = + MaskFromShift<urbg_result_type>(kLargeShift); + + static constexpr auto kMin = (URBG::min)(); + result_type s = 0; for (size_t n = 0; n < kSmallIters; ++n) { - urbg_result_type v; - do { - v = g() - kMin; - } while (v >= kSmallRejection); + urbg_result_type v; + do { + v = g() - kMin; + } while (v >= kSmallRejection); - s = (s << kSmallShift) + static_cast<result_type>(v & kSmallMask); + s = (s << kSmallShift) + static_cast<result_type>(v & kSmallMask); } - for (size_t n = kSmallIters; n < kTotalIters; ++n) { - urbg_result_type v; - do { - v = g() - kMin; - } while (v >= kLargeRejection); + for (size_t n = kSmallIters; n < kTotalIters; ++n) { + urbg_result_type v; + do { + v = g() - kMin; + } while (v >= kLargeRejection); - s = (s << kLargeShift) + static_cast<result_type>(v & kLargeMask); - } + s = (s << kLargeShift) + static_cast<result_type>(v & kLargeMask); + } return s; } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/fastmath.h b/contrib/restricted/abseil-cpp/absl/random/internal/fastmath.h index 963b7690f1..1edb161fd8 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/fastmath.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/fastmath.h @@ -25,7 +25,7 @@ #include "absl/numeric/bits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // Compute log2(n) using integer operations. @@ -51,7 +51,7 @@ inline double StirlingLogFactorial(double n) { } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_FASTMATH_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h b/contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h index d5fbb44c24..c23ce06378 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h @@ -29,7 +29,7 @@ #include "absl/random/internal/traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // Tristate tag types controlling the output of GenerateRealFromBits. @@ -138,7 +138,7 @@ inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) { } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h b/contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h index e6e242ee1e..9df689c2c2 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h @@ -24,7 +24,7 @@ #include "absl/numeric/int128.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // The null_state_saver does nothing. @@ -192,8 +192,8 @@ struct stream_u128_helper<absl::uint128> { template <typename OStream> inline void write(absl::uint128 val, OStream& out) { - uint64_t h = absl::Uint128High64(val); - uint64_t l = absl::Uint128Low64(val); + uint64_t h = absl::Uint128High64(val); + uint64_t l = absl::Uint128Low64(val); out << h << out.fill() << l; } }; @@ -239,7 +239,7 @@ inline FloatType read_floating_point(IStream& is) { } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/mock_helpers.h b/contrib/restricted/abseil-cpp/absl/random/internal/mock_helpers.h index 9d6ab21ef5..2203a7afa7 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/mock_helpers.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/mock_helpers.h @@ -1,85 +1,85 @@ -// -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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. - -#ifndef ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_ -#define ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_ - -#include <tuple> -#include <type_traits> - -#include "absl/base/internal/fast_type_id.h" -#include "absl/types/optional.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -// MockHelpers works in conjunction with MockOverloadSet, MockingBitGen, and -// BitGenRef to enable the mocking capability for absl distribution functions. -// -// MockingBitGen registers mocks based on the typeid of a mock signature, KeyT, -// which is used to generate a unique id. -// -// KeyT is a signature of the form: -// result_type(discriminator_type, std::tuple<args...>) -// The mocked function signature will be composed from KeyT as: -// result_type(args...) -// -class MockHelpers { - using IdType = ::absl::base_internal::FastTypeIdType; - - // Given a key signature type used to index the mock, extract the components. - // KeyT is expected to have the form: - // result_type(discriminator_type, arg_tuple_type) - template <typename KeyT> - struct KeySignature; - - template <typename ResultT, typename DiscriminatorT, typename ArgTupleT> - struct KeySignature<ResultT(DiscriminatorT, ArgTupleT)> { - using result_type = ResultT; - using discriminator_type = DiscriminatorT; - using arg_tuple_type = ArgTupleT; - }; - - // Detector for InvokeMock. - template <class T> - using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock( - std::declval<IdType>(), std::declval<void*>(), std::declval<void*>())); - - // Empty implementation of InvokeMock. - template <typename KeyT, typename ReturnT, typename ArgTupleT, typename URBG, - typename... Args> - static absl::optional<ReturnT> InvokeMockImpl(char, URBG*, Args&&...) { - return absl::nullopt; - } - - // Non-empty implementation of InvokeMock. - template <typename KeyT, typename ReturnT, typename ArgTupleT, typename URBG, - typename = invoke_mock_t<URBG>, typename... Args> - static absl::optional<ReturnT> InvokeMockImpl(int, URBG* urbg, - Args&&... args) { - ArgTupleT arg_tuple(std::forward<Args>(args)...); - ReturnT result; - if (urbg->InvokeMock(::absl::base_internal::FastTypeId<KeyT>(), &arg_tuple, - &result)) { - return result; - } - return absl::nullopt; - } - - public: +// +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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. + +#ifndef ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_ +#define ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_ + +#include <tuple> +#include <type_traits> + +#include "absl/base/internal/fast_type_id.h" +#include "absl/types/optional.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace random_internal { + +// MockHelpers works in conjunction with MockOverloadSet, MockingBitGen, and +// BitGenRef to enable the mocking capability for absl distribution functions. +// +// MockingBitGen registers mocks based on the typeid of a mock signature, KeyT, +// which is used to generate a unique id. +// +// KeyT is a signature of the form: +// result_type(discriminator_type, std::tuple<args...>) +// The mocked function signature will be composed from KeyT as: +// result_type(args...) +// +class MockHelpers { + using IdType = ::absl::base_internal::FastTypeIdType; + + // Given a key signature type used to index the mock, extract the components. + // KeyT is expected to have the form: + // result_type(discriminator_type, arg_tuple_type) + template <typename KeyT> + struct KeySignature; + + template <typename ResultT, typename DiscriminatorT, typename ArgTupleT> + struct KeySignature<ResultT(DiscriminatorT, ArgTupleT)> { + using result_type = ResultT; + using discriminator_type = DiscriminatorT; + using arg_tuple_type = ArgTupleT; + }; + + // Detector for InvokeMock. + template <class T> + using invoke_mock_t = decltype(std::declval<T*>()->InvokeMock( + std::declval<IdType>(), std::declval<void*>(), std::declval<void*>())); + + // Empty implementation of InvokeMock. + template <typename KeyT, typename ReturnT, typename ArgTupleT, typename URBG, + typename... Args> + static absl::optional<ReturnT> InvokeMockImpl(char, URBG*, Args&&...) { + return absl::nullopt; + } + + // Non-empty implementation of InvokeMock. + template <typename KeyT, typename ReturnT, typename ArgTupleT, typename URBG, + typename = invoke_mock_t<URBG>, typename... Args> + static absl::optional<ReturnT> InvokeMockImpl(int, URBG* urbg, + Args&&... args) { + ArgTupleT arg_tuple(std::forward<Args>(args)...); + ReturnT result; + if (urbg->InvokeMock(::absl::base_internal::FastTypeId<KeyT>(), &arg_tuple, + &result)) { + return result; + } + return absl::nullopt; + } + + public: // InvokeMock is private; this provides access for some specialized use cases. template <typename URBG> static inline bool PrivateInvokeMock(URBG* urbg, IdType type, @@ -87,48 +87,48 @@ class MockHelpers { return urbg->InvokeMock(type, args_tuple, result); } - // Invoke a mock for the KeyT (may or may not be a signature). - // - // KeyT is used to generate a typeid-based lookup key for the mock. - // KeyT is a signature of the form: - // result_type(discriminator_type, std::tuple<args...>) - // The mocked function signature will be composed from KeyT as: - // result_type(args...) - // - // An instance of arg_tuple_type must be constructable from Args..., since - // the underlying mechanism requires a pointer to an argument tuple. - template <typename KeyT, typename URBG, typename... Args> - static auto MaybeInvokeMock(URBG* urbg, Args&&... args) - -> absl::optional<typename KeySignature<KeyT>::result_type> { - // Use function overloading to dispatch to the implemenation since - // more modern patterns (e.g. require + constexpr) are not supported in all - // compiler configurations. - return InvokeMockImpl<KeyT, typename KeySignature<KeyT>::result_type, - typename KeySignature<KeyT>::arg_tuple_type, URBG>( - 0, urbg, std::forward<Args>(args)...); - } - - // Acquire a mock for the KeyT (may or may not be a signature). - // - // KeyT is used to generate a typeid-based lookup for the mock. - // KeyT is a signature of the form: - // result_type(discriminator_type, std::tuple<args...>) - // The mocked function signature will be composed from KeyT as: - // result_type(args...) - template <typename KeyT, typename MockURBG> + // Invoke a mock for the KeyT (may or may not be a signature). + // + // KeyT is used to generate a typeid-based lookup key for the mock. + // KeyT is a signature of the form: + // result_type(discriminator_type, std::tuple<args...>) + // The mocked function signature will be composed from KeyT as: + // result_type(args...) + // + // An instance of arg_tuple_type must be constructable from Args..., since + // the underlying mechanism requires a pointer to an argument tuple. + template <typename KeyT, typename URBG, typename... Args> + static auto MaybeInvokeMock(URBG* urbg, Args&&... args) + -> absl::optional<typename KeySignature<KeyT>::result_type> { + // Use function overloading to dispatch to the implemenation since + // more modern patterns (e.g. require + constexpr) are not supported in all + // compiler configurations. + return InvokeMockImpl<KeyT, typename KeySignature<KeyT>::result_type, + typename KeySignature<KeyT>::arg_tuple_type, URBG>( + 0, urbg, std::forward<Args>(args)...); + } + + // Acquire a mock for the KeyT (may or may not be a signature). + // + // KeyT is used to generate a typeid-based lookup for the mock. + // KeyT is a signature of the form: + // result_type(discriminator_type, std::tuple<args...>) + // The mocked function signature will be composed from KeyT as: + // result_type(args...) + template <typename KeyT, typename MockURBG> static auto MockFor(MockURBG& m) -> decltype(m.template RegisterMock< typename KeySignature<KeyT>::result_type, typename KeySignature<KeyT>::arg_tuple_type>( m, std::declval<IdType>())) { - return m.template RegisterMock<typename KeySignature<KeyT>::result_type, - typename KeySignature<KeyT>::arg_tuple_type>( + return m.template RegisterMock<typename KeySignature<KeyT>::result_type, + typename KeySignature<KeyT>::arg_tuple_type>( m, ::absl::base_internal::FastTypeId<KeyT>()); - } -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_ + } +}; + +} // namespace random_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/mock_overload_set.h b/contrib/restricted/abseil-cpp/absl/random/internal/mock_overload_set.h index 0d9c6c120c..48d39fe08b 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/mock_overload_set.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/mock_overload_set.h @@ -1,100 +1,100 @@ -// -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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. - -#ifndef ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ -#define ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ - -#include <type_traits> - -#include "gmock/gmock.h" -#include "absl/random/internal/mock_helpers.h" -#include "absl/random/mocking_bit_gen.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { - -template <typename DistrT, typename Fn> -struct MockSingleOverload; - -// MockSingleOverload -// -// MockSingleOverload hooks in to gMock's `ON_CALL` and `EXPECT_CALL` macros. -// EXPECT_CALL(mock_single_overload, Call(...))` will expand to a call to -// `mock_single_overload.gmock_Call(...)`. Because expectations are stored on -// the MockingBitGen (an argument passed inside `Call(...)`), this forwards to -// arguments to MockingBitGen::Register. -// -// The underlying KeyT must match the KeyT constructed by DistributionCaller. -template <typename DistrT, typename Ret, typename... Args> -struct MockSingleOverload<DistrT, Ret(MockingBitGen&, Args...)> { - static_assert(std::is_same<typename DistrT::result_type, Ret>::value, - "Overload signature must have return type matching the " - "distribution result_type."); - using KeyT = Ret(DistrT, std::tuple<Args...>); +// +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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. + +#ifndef ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ +#define ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ + +#include <type_traits> + +#include "gmock/gmock.h" +#include "absl/random/internal/mock_helpers.h" +#include "absl/random/mocking_bit_gen.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace random_internal { + +template <typename DistrT, typename Fn> +struct MockSingleOverload; + +// MockSingleOverload +// +// MockSingleOverload hooks in to gMock's `ON_CALL` and `EXPECT_CALL` macros. +// EXPECT_CALL(mock_single_overload, Call(...))` will expand to a call to +// `mock_single_overload.gmock_Call(...)`. Because expectations are stored on +// the MockingBitGen (an argument passed inside `Call(...)`), this forwards to +// arguments to MockingBitGen::Register. +// +// The underlying KeyT must match the KeyT constructed by DistributionCaller. +template <typename DistrT, typename Ret, typename... Args> +struct MockSingleOverload<DistrT, Ret(MockingBitGen&, Args...)> { + static_assert(std::is_same<typename DistrT::result_type, Ret>::value, + "Overload signature must have return type matching the " + "distribution result_type."); + using KeyT = Ret(DistrT, std::tuple<Args...>); template <typename MockURBG> auto gmock_Call(MockURBG& gen, const ::testing::Matcher<Args>&... matchers) - -> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...)) { + -> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...)) { static_assert(std::is_base_of<MockingBitGen, MockURBG>::value, "Mocking requires an absl::MockingBitGen"); - return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...); - } -}; - -template <typename DistrT, typename Ret, typename Arg, typename... Args> -struct MockSingleOverload<DistrT, Ret(Arg, MockingBitGen&, Args...)> { - static_assert(std::is_same<typename DistrT::result_type, Ret>::value, - "Overload signature must have return type matching the " - "distribution result_type."); - using KeyT = Ret(DistrT, std::tuple<Arg, Args...>); + return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...); + } +}; + +template <typename DistrT, typename Ret, typename Arg, typename... Args> +struct MockSingleOverload<DistrT, Ret(Arg, MockingBitGen&, Args...)> { + static_assert(std::is_same<typename DistrT::result_type, Ret>::value, + "Overload signature must have return type matching the " + "distribution result_type."); + using KeyT = Ret(DistrT, std::tuple<Arg, Args...>); template <typename MockURBG> auto gmock_Call(const ::testing::Matcher<Arg>& matcher, MockURBG& gen, const ::testing::Matcher<Args>&... matchers) - -> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher, - matchers...)) { + -> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher, + matchers...)) { static_assert(std::is_base_of<MockingBitGen, MockURBG>::value, "Mocking requires an absl::MockingBitGen"); - return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher, matchers...); - } -}; - -// MockOverloadSet -// -// MockOverloadSet takes a distribution and a collection of signatures and -// performs overload resolution amongst all the overloads. This makes -// `EXPECT_CALL(mock_overload_set, Call(...))` expand and do overload resolution -// correctly. -template <typename DistrT, typename... Signatures> -struct MockOverloadSet; - -template <typename DistrT, typename Sig> -struct MockOverloadSet<DistrT, Sig> : public MockSingleOverload<DistrT, Sig> { - using MockSingleOverload<DistrT, Sig>::gmock_Call; -}; - -template <typename DistrT, typename FirstSig, typename... Rest> -struct MockOverloadSet<DistrT, FirstSig, Rest...> - : public MockSingleOverload<DistrT, FirstSig>, - public MockOverloadSet<DistrT, Rest...> { - using MockSingleOverload<DistrT, FirstSig>::gmock_Call; - using MockOverloadSet<DistrT, Rest...>::gmock_Call; -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl -#endif // ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ + return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher, matchers...); + } +}; + +// MockOverloadSet +// +// MockOverloadSet takes a distribution and a collection of signatures and +// performs overload resolution amongst all the overloads. This makes +// `EXPECT_CALL(mock_overload_set, Call(...))` expand and do overload resolution +// correctly. +template <typename DistrT, typename... Signatures> +struct MockOverloadSet; + +template <typename DistrT, typename Sig> +struct MockOverloadSet<DistrT, Sig> : public MockSingleOverload<DistrT, Sig> { + using MockSingleOverload<DistrT, Sig>::gmock_Call; +}; + +template <typename DistrT, typename FirstSig, typename... Rest> +struct MockOverloadSet<DistrT, FirstSig, Rest...> + : public MockSingleOverload<DistrT, FirstSig>, + public MockOverloadSet<DistrT, Rest...> { + using MockSingleOverload<DistrT, FirstSig>::gmock_Call; + using MockOverloadSet<DistrT, Rest...>::gmock_Call; +}; + +} // namespace random_internal +ABSL_NAMESPACE_END +} // namespace absl +#endif // ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/nanobenchmark.h b/contrib/restricted/abseil-cpp/absl/random/internal/nanobenchmark.h index a5097ba27b..d64056fdcb 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/nanobenchmark.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/nanobenchmark.h @@ -50,10 +50,10 @@ #include <stddef.h> #include <stdint.h> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal_nanobenchmark { // Input influencing the function being measured (e.g. number of bytes to copy). @@ -166,7 +166,7 @@ static inline size_t MeasureClosure(const Closure& closure, } } // namespace random_internal_nanobenchmark -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_NANOBENCHMARK_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/nonsecure_base.h b/contrib/restricted/abseil-cpp/absl/random/internal/nonsecure_base.h index 730fa2ea12..c161a824be 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/nonsecure_base.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/nonsecure_base.h @@ -33,7 +33,7 @@ #include "absl/types/span.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // Each instance of NonsecureURBGBase<URBG> will be seeded by variates produced @@ -144,7 +144,7 @@ class NonsecureURBGBase { }; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/pcg_engine.h b/contrib/restricted/abseil-cpp/absl/random/internal/pcg_engine.h index 8efaf2e09a..35a5d0fffc 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/pcg_engine.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/pcg_engine.h @@ -25,7 +25,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // pcg_engine is a simplified implementation of Melissa O'Neil's PCG engine in @@ -302,7 +302,7 @@ using pcg32_2018_engine = pcg_engine< random_internal::pcg_xsh_rr_64_32>; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc index 725100a415..71a12eb221 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc @@ -37,7 +37,7 @@ using absl::base_internal::SpinLock; using absl::base_internal::SpinLockHolder; namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { namespace { @@ -249,5 +249,5 @@ template class RandenPool<uint32_t>; template class RandenPool<uint64_t>; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.h b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.h index 05721929f5..37a32521c5 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.h @@ -22,7 +22,7 @@ #include "absl/types/span.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // RandenPool is a thread-safe random number generator [random.req.urbg] that @@ -125,7 +125,7 @@ class PoolURBG { }; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_POOL_URBG_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make index fd4e1c1f4d..b6efad57a7 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make @@ -18,7 +18,7 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/random/internal/randen contrib/restricted/abseil-cpp/absl/random/internal/randen_detect contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes - contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys + contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys contrib/restricted/abseil-cpp/absl/random/internal/randen_slow contrib/restricted/abseil-cpp/absl/random/internal/seed_material contrib/restricted/abseil-cpp/absl/random/seed_gen_exception @@ -35,10 +35,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen.cc b/contrib/restricted/abseil-cpp/absl/random/internal/randen.cc index c1bc044435..8e77715a97 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen.cc @@ -41,7 +41,7 @@ // structured/low-entropy counters to digits of Pi. namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { namespace { @@ -87,5 +87,5 @@ Randen::Randen() { } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen.h index 9a3840b8f1..18b870f6ec 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen.h @@ -23,7 +23,7 @@ #include "absl/random/internal/randen_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // RANDen = RANDom generator or beetroots in Swiss High German. @@ -96,7 +96,7 @@ class Randen { }; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_RANDEN_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/randen/ya.make index 150b9e0714..4ba1583f29 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen/ya.make @@ -11,7 +11,7 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/random/internal/randen_detect contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes - contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys + contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys contrib/restricted/abseil-cpp/absl/random/internal/randen_slow ) @@ -23,10 +23,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc index bbe7b96532..f56fa59373 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc @@ -95,7 +95,7 @@ static uint32_t GetAuxval(uint32_t hwcap_type) { #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // The default return at the end of the function might be unreachable depending @@ -217,5 +217,5 @@ bool CPUSupportsRandenHwAes() { #endif } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.h index f283f43226..e70a0ff0e9 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.h @@ -15,10 +15,10 @@ #ifndef ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_ #define ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // Returns whether the current CPU supports RandenHwAes implementation. @@ -27,7 +27,7 @@ namespace random_internal { bool CPUSupportsRandenHwAes(); } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect/ya.make index 62059877ba..b381eb19e0 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect/ya.make @@ -10,7 +10,7 @@ LICENSE(Apache-2.0) PEERDIR( contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes - contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys + contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys ) ADDINCL( @@ -21,10 +21,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h index 372c3ac2bd..cfcb9ee702 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h @@ -29,7 +29,7 @@ #include "absl/random/internal/randen.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // Deterministic pseudorandom byte generator with backtracking resistance @@ -233,7 +233,7 @@ class alignas(16) randen_engine { }; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc index fee6677cb4..0efaa35d79 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc @@ -25,7 +25,7 @@ #include "absl/base/attributes.h" #include "absl/numeric/int128.h" #include "absl/random/internal/platform.h" -#include "absl/random/internal/randen_traits.h" +#include "absl/random/internal/randen_traits.h" // ABSL_RANDEN_HWAES_IMPL indicates whether this file will contain // a hardware accelerated implementation of randen, or whether it @@ -47,7 +47,7 @@ #include <cstdlib> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // No accelerated implementation. @@ -79,7 +79,7 @@ void RandenHwAes::Generate(const void*, void*) { } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #else // defined(ABSL_RANDEN_HWAES_IMPL) @@ -87,12 +87,12 @@ ABSL_NAMESPACE_END // Accelerated implementations are supported. // We need the per-architecture includes and defines. // -namespace { - -using absl::random_internal::RandenTraits; +namespace { -} // namespace +using absl::random_internal::RandenTraits; +} // namespace + // TARGET_CRYPTO defines a crypto attribute for each architecture. // // NOTE: Evaluate whether we should eliminate ABSL_TARGET_CRYPTO. @@ -116,7 +116,7 @@ using absl::random_internal::RandenTraits; #include <altivec.h> // <altivec.h> #defines vector __vector; in C++, this is bad form. #undef vector -#undef bool +#undef bool // Rely on the PowerPC AltiVec vector operations for accelerated AES // instructions. GCC support of the PPC vector types is described in: @@ -153,8 +153,8 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, // Enables native loads in the round loop by pre-swapping. inline ABSL_TARGET_CRYPTO void SwapEndian(absl::uint128* state) { - for (uint32_t block = 0; block < RandenTraits::kFeistelBlocks; ++block) { - Vector128Store(ReverseBytes(Vector128Load(state + block)), state + block); + for (uint32_t block = 0; block < RandenTraits::kFeistelBlocks; ++block) { + Vector128Store(ReverseBytes(Vector128Load(state + block)), state + block); } } @@ -205,7 +205,7 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, return vaesmcq_u8(vaeseq_u8(state, uint8x16_t{})) ^ round_key; } -inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {} +inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {} } // namespace @@ -251,7 +251,7 @@ inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, return Vector128(_mm_aesenc_si128(state.data(), round_key.data())); } -inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {} +inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {} } // namespace @@ -273,50 +273,50 @@ inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {} // // PROVIDES: absl::random_internal::RandenHwAes::Absorb // PROVIDES: absl::random_internal::RandenHwAes::Generate -namespace { +namespace { // Block shuffles applies a shuffle to the entire state between AES rounds. // Improved odd-even shuffle from "New criterion for diffusion property". inline ABSL_TARGET_CRYPTO void BlockShuffle(absl::uint128* state) { - static_assert(RandenTraits::kFeistelBlocks == 16, - "Expecting 16 FeistelBlocks."); - - constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = { - 7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12}; - - const Vector128 v0 = Vector128Load(state + shuffle[0]); - const Vector128 v1 = Vector128Load(state + shuffle[1]); - const Vector128 v2 = Vector128Load(state + shuffle[2]); - const Vector128 v3 = Vector128Load(state + shuffle[3]); - const Vector128 v4 = Vector128Load(state + shuffle[4]); - const Vector128 v5 = Vector128Load(state + shuffle[5]); - const Vector128 v6 = Vector128Load(state + shuffle[6]); - const Vector128 v7 = Vector128Load(state + shuffle[7]); - const Vector128 w0 = Vector128Load(state + shuffle[8]); - const Vector128 w1 = Vector128Load(state + shuffle[9]); - const Vector128 w2 = Vector128Load(state + shuffle[10]); - const Vector128 w3 = Vector128Load(state + shuffle[11]); - const Vector128 w4 = Vector128Load(state + shuffle[12]); - const Vector128 w5 = Vector128Load(state + shuffle[13]); - const Vector128 w6 = Vector128Load(state + shuffle[14]); - const Vector128 w7 = Vector128Load(state + shuffle[15]); - - Vector128Store(v0, state + 0); - Vector128Store(v1, state + 1); - Vector128Store(v2, state + 2); - Vector128Store(v3, state + 3); - Vector128Store(v4, state + 4); - Vector128Store(v5, state + 5); - Vector128Store(v6, state + 6); - Vector128Store(v7, state + 7); - Vector128Store(w0, state + 8); - Vector128Store(w1, state + 9); - Vector128Store(w2, state + 10); - Vector128Store(w3, state + 11); - Vector128Store(w4, state + 12); - Vector128Store(w5, state + 13); - Vector128Store(w6, state + 14); - Vector128Store(w7, state + 15); + static_assert(RandenTraits::kFeistelBlocks == 16, + "Expecting 16 FeistelBlocks."); + + constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = { + 7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12}; + + const Vector128 v0 = Vector128Load(state + shuffle[0]); + const Vector128 v1 = Vector128Load(state + shuffle[1]); + const Vector128 v2 = Vector128Load(state + shuffle[2]); + const Vector128 v3 = Vector128Load(state + shuffle[3]); + const Vector128 v4 = Vector128Load(state + shuffle[4]); + const Vector128 v5 = Vector128Load(state + shuffle[5]); + const Vector128 v6 = Vector128Load(state + shuffle[6]); + const Vector128 v7 = Vector128Load(state + shuffle[7]); + const Vector128 w0 = Vector128Load(state + shuffle[8]); + const Vector128 w1 = Vector128Load(state + shuffle[9]); + const Vector128 w2 = Vector128Load(state + shuffle[10]); + const Vector128 w3 = Vector128Load(state + shuffle[11]); + const Vector128 w4 = Vector128Load(state + shuffle[12]); + const Vector128 w5 = Vector128Load(state + shuffle[13]); + const Vector128 w6 = Vector128Load(state + shuffle[14]); + const Vector128 w7 = Vector128Load(state + shuffle[15]); + + Vector128Store(v0, state + 0); + Vector128Store(v1, state + 1); + Vector128Store(v2, state + 2); + Vector128Store(v3, state + 3); + Vector128Store(v4, state + 4); + Vector128Store(v5, state + 5); + Vector128Store(v6, state + 6); + Vector128Store(v7, state + 7); + Vector128Store(w0, state + 8); + Vector128Store(w1, state + 9); + Vector128Store(w2, state + 10); + Vector128Store(w3, state + 11); + Vector128Store(w4, state + 12); + Vector128Store(w5, state + 13); + Vector128Store(w6, state + 14); + Vector128Store(w7, state + 15); } // Feistel round function using two AES subrounds. Very similar to F() @@ -327,27 +327,27 @@ inline ABSL_TARGET_CRYPTO void BlockShuffle(absl::uint128* state) { inline ABSL_TARGET_CRYPTO const absl::uint128* FeistelRound( absl::uint128* state, const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) { - static_assert(RandenTraits::kFeistelBlocks == 16, - "Expecting 16 FeistelBlocks."); + static_assert(RandenTraits::kFeistelBlocks == 16, + "Expecting 16 FeistelBlocks."); // MSVC does a horrible job at unrolling loops. // So we unroll the loop by hand to improve the performance. - const Vector128 s0 = Vector128Load(state + 0); - const Vector128 s1 = Vector128Load(state + 1); - const Vector128 s2 = Vector128Load(state + 2); - const Vector128 s3 = Vector128Load(state + 3); - const Vector128 s4 = Vector128Load(state + 4); - const Vector128 s5 = Vector128Load(state + 5); - const Vector128 s6 = Vector128Load(state + 6); - const Vector128 s7 = Vector128Load(state + 7); - const Vector128 s8 = Vector128Load(state + 8); - const Vector128 s9 = Vector128Load(state + 9); - const Vector128 s10 = Vector128Load(state + 10); - const Vector128 s11 = Vector128Load(state + 11); - const Vector128 s12 = Vector128Load(state + 12); - const Vector128 s13 = Vector128Load(state + 13); - const Vector128 s14 = Vector128Load(state + 14); - const Vector128 s15 = Vector128Load(state + 15); + const Vector128 s0 = Vector128Load(state + 0); + const Vector128 s1 = Vector128Load(state + 1); + const Vector128 s2 = Vector128Load(state + 2); + const Vector128 s3 = Vector128Load(state + 3); + const Vector128 s4 = Vector128Load(state + 4); + const Vector128 s5 = Vector128Load(state + 5); + const Vector128 s6 = Vector128Load(state + 6); + const Vector128 s7 = Vector128Load(state + 7); + const Vector128 s8 = Vector128Load(state + 8); + const Vector128 s9 = Vector128Load(state + 9); + const Vector128 s10 = Vector128Load(state + 10); + const Vector128 s11 = Vector128Load(state + 11); + const Vector128 s12 = Vector128Load(state + 12); + const Vector128 s13 = Vector128Load(state + 13); + const Vector128 s14 = Vector128Load(state + 14); + const Vector128 s15 = Vector128Load(state + 15); // Encode even blocks with keys. const Vector128 e0 = AesRound(s0, Vector128Load(keys + 0)); @@ -370,14 +370,14 @@ inline ABSL_TARGET_CRYPTO const absl::uint128* FeistelRound( const Vector128 o15 = AesRound(e14, s15); // Store odd blocks. (These will be shuffled later). - Vector128Store(o1, state + 1); - Vector128Store(o3, state + 3); - Vector128Store(o5, state + 5); - Vector128Store(o7, state + 7); - Vector128Store(o9, state + 9); - Vector128Store(o11, state + 11); - Vector128Store(o13, state + 13); - Vector128Store(o15, state + 15); + Vector128Store(o1, state + 1); + Vector128Store(o3, state + 3); + Vector128Store(o5, state + 5); + Vector128Store(o7, state + 7); + Vector128Store(o9, state + 9); + Vector128Store(o11, state + 11); + Vector128Store(o13, state + 13); + Vector128Store(o15, state + 15); return keys + 8; } @@ -393,8 +393,8 @@ inline ABSL_TARGET_CRYPTO void Permute( #ifdef __clang__ #pragma clang loop unroll_count(2) #endif - for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) { - keys = FeistelRound(state, keys); + for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) { + keys = FeistelRound(state, keys); BlockShuffle(state); } } @@ -402,7 +402,7 @@ inline ABSL_TARGET_CRYPTO void Permute( } // namespace namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { bool HasRandenHwAesImplementation() { return true; } @@ -410,93 +410,93 @@ bool HasRandenHwAesImplementation() { return true; } const void* ABSL_TARGET_CRYPTO RandenHwAes::GetKeys() { // Round keys for one AES per Feistel round and branch. // The canonical implementation uses first digits of Pi. -#if defined(ABSL_ARCH_PPC) - return kRandenRoundKeysBE; -#else - return kRandenRoundKeys; -#endif +#if defined(ABSL_ARCH_PPC) + return kRandenRoundKeysBE; +#else + return kRandenRoundKeys; +#endif } // NOLINTNEXTLINE void ABSL_TARGET_CRYPTO RandenHwAes::Absorb(const void* seed_void, void* state_void) { - static_assert(RandenTraits::kCapacityBytes / sizeof(Vector128) == 1, - "Unexpected Randen kCapacityBlocks"); - static_assert(RandenTraits::kStateBytes / sizeof(Vector128) == 16, - "Unexpected Randen kStateBlocks"); + static_assert(RandenTraits::kCapacityBytes / sizeof(Vector128) == 1, + "Unexpected Randen kCapacityBlocks"); + static_assert(RandenTraits::kStateBytes / sizeof(Vector128) == 16, + "Unexpected Randen kStateBlocks"); auto* state = reinterpret_cast<absl::uint128 * ABSL_RANDOM_INTERNAL_RESTRICT>( state_void); - const auto* seed = + const auto* seed = reinterpret_cast<const absl::uint128 * ABSL_RANDOM_INTERNAL_RESTRICT>( seed_void); - Vector128 b1 = Vector128Load(state + 1); - b1 ^= Vector128Load(seed + 0); - Vector128Store(b1, state + 1); + Vector128 b1 = Vector128Load(state + 1); + b1 ^= Vector128Load(seed + 0); + Vector128Store(b1, state + 1); - Vector128 b2 = Vector128Load(state + 2); - b2 ^= Vector128Load(seed + 1); - Vector128Store(b2, state + 2); + Vector128 b2 = Vector128Load(state + 2); + b2 ^= Vector128Load(seed + 1); + Vector128Store(b2, state + 2); - Vector128 b3 = Vector128Load(state + 3); - b3 ^= Vector128Load(seed + 2); - Vector128Store(b3, state + 3); + Vector128 b3 = Vector128Load(state + 3); + b3 ^= Vector128Load(seed + 2); + Vector128Store(b3, state + 3); - Vector128 b4 = Vector128Load(state + 4); - b4 ^= Vector128Load(seed + 3); - Vector128Store(b4, state + 4); + Vector128 b4 = Vector128Load(state + 4); + b4 ^= Vector128Load(seed + 3); + Vector128Store(b4, state + 4); - Vector128 b5 = Vector128Load(state + 5); - b5 ^= Vector128Load(seed + 4); - Vector128Store(b5, state + 5); + Vector128 b5 = Vector128Load(state + 5); + b5 ^= Vector128Load(seed + 4); + Vector128Store(b5, state + 5); - Vector128 b6 = Vector128Load(state + 6); - b6 ^= Vector128Load(seed + 5); - Vector128Store(b6, state + 6); + Vector128 b6 = Vector128Load(state + 6); + b6 ^= Vector128Load(seed + 5); + Vector128Store(b6, state + 6); - Vector128 b7 = Vector128Load(state + 7); - b7 ^= Vector128Load(seed + 6); - Vector128Store(b7, state + 7); + Vector128 b7 = Vector128Load(state + 7); + b7 ^= Vector128Load(seed + 6); + Vector128Store(b7, state + 7); - Vector128 b8 = Vector128Load(state + 8); - b8 ^= Vector128Load(seed + 7); - Vector128Store(b8, state + 8); + Vector128 b8 = Vector128Load(state + 8); + b8 ^= Vector128Load(seed + 7); + Vector128Store(b8, state + 8); - Vector128 b9 = Vector128Load(state + 9); - b9 ^= Vector128Load(seed + 8); - Vector128Store(b9, state + 9); + Vector128 b9 = Vector128Load(state + 9); + b9 ^= Vector128Load(seed + 8); + Vector128Store(b9, state + 9); - Vector128 b10 = Vector128Load(state + 10); - b10 ^= Vector128Load(seed + 9); - Vector128Store(b10, state + 10); + Vector128 b10 = Vector128Load(state + 10); + b10 ^= Vector128Load(seed + 9); + Vector128Store(b10, state + 10); - Vector128 b11 = Vector128Load(state + 11); - b11 ^= Vector128Load(seed + 10); - Vector128Store(b11, state + 11); + Vector128 b11 = Vector128Load(state + 11); + b11 ^= Vector128Load(seed + 10); + Vector128Store(b11, state + 11); - Vector128 b12 = Vector128Load(state + 12); - b12 ^= Vector128Load(seed + 11); - Vector128Store(b12, state + 12); + Vector128 b12 = Vector128Load(state + 12); + b12 ^= Vector128Load(seed + 11); + Vector128Store(b12, state + 12); - Vector128 b13 = Vector128Load(state + 13); - b13 ^= Vector128Load(seed + 12); - Vector128Store(b13, state + 13); + Vector128 b13 = Vector128Load(state + 13); + b13 ^= Vector128Load(seed + 12); + Vector128Store(b13, state + 13); - Vector128 b14 = Vector128Load(state + 14); - b14 ^= Vector128Load(seed + 13); - Vector128Store(b14, state + 14); + Vector128 b14 = Vector128Load(state + 14); + b14 ^= Vector128Load(seed + 13); + Vector128Store(b14, state + 14); - Vector128 b15 = Vector128Load(state + 15); - b15 ^= Vector128Load(seed + 14); - Vector128Store(b15, state + 15); + Vector128 b15 = Vector128Load(state + 15); + b15 ^= Vector128Load(seed + 14); + Vector128Store(b15, state + 15); } // NOLINTNEXTLINE -void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys_void, +void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys_void, void* state_void) { - static_assert(RandenTraits::kCapacityBytes == sizeof(Vector128), - "Capacity mismatch"); + static_assert(RandenTraits::kCapacityBytes == sizeof(Vector128), + "Capacity mismatch"); auto* state = reinterpret_cast<absl::uint128*>(state_void); const auto* keys = reinterpret_cast<const absl::uint128*>(keys_void); @@ -505,7 +505,7 @@ void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys_void, SwapEndian(state); - Permute(state, keys); + Permute(state, keys); SwapEndian(state); @@ -520,7 +520,7 @@ void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys_void, #endif } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // (ABSL_RANDEN_HWAES_IMPL) diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.h index 71a7f69f25..d172e76529 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.h @@ -15,15 +15,15 @@ #ifndef ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_ #define ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_ -#include "absl/base/config.h" - +#include "absl/base/config.h" + // HERMETIC NOTE: The randen_hwaes target must not introduce duplicate // symbols from arbitrary system and other headers, since it may be built // with different flags from other targets, using different levels of // optimization, potentially introducing ODR violations. namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // RANDen = RANDom generator or beetroots in Swiss High German. @@ -44,7 +44,7 @@ class RandenHwAes { bool HasRandenHwAesImplementation(); } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes/ya.make index 267ce26c5f..bc84bf7c1b 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes/ya.make @@ -8,10 +8,10 @@ OWNER(g:cpp-contrib) LICENSE(Apache-2.0) -PEERDIR( - contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys -) - +PEERDIR( + contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys +) + ADDINCL( GLOBAL contrib/restricted/abseil-cpp ) @@ -20,10 +20,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys.cc b/contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys.cc index 5fb3ca556d..3cc0ea0979 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys.cc @@ -1,462 +1,462 @@ -// Copyright 2017 The Abseil Authors. -// -// 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 -// -// https://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 "absl/random/internal/randen_traits.h" - -// This file contains only the round keys for randen. -// -// "Nothing up my sleeve" numbers from the first hex digits of Pi, obtained -// from http://hexpi.sourceforge.net/. The array was generated by following -// Python script: - -/* -python >tmp.cc << EOF -"""Generates Randen round keys array from pi-hex.62500.txt file.""" -import binascii - -KEYS = 17 * 8 - -def chunks(l, n): - """Yield successive n-sized chunks from l.""" - for i in range(0, len(l), n): - yield l[i:i + n] - -def pairwise(t): - """Transforms sequence into sequence of pairs.""" - it = iter(t) - return zip(it,it) - -def digits_from_pi(): - """Reads digits from hexpi.sourceforge.net file.""" - with open("pi-hex.62500.txt") as file: - return file.read() - -def digits_from_urandom(): - """Reads digits from /dev/urandom.""" - with open("/dev/urandom") as file: - return binascii.hexlify(file.read(KEYS * 16)) - -def print_row(b) - print(" 0x{0}, 0x{1}, 0x{2}, 0x{3}, 0x{4}, 0x{5}, 0x{6}, 0x{7}, 0x{8}, 0x{9}, -0x{10}, 0x{11}, 0x{12}, 0x{13}, 0x{14}, 0x{15},".format(*b)) - - -digits = digits_from_pi() -#digits = digits_from_urandom() - -print("namespace {") -print("static constexpr size_t kKeyBytes = {0};\n".format(KEYS * 16)) -print("}") - -print("alignas(16) const unsigned char kRandenRoundKeysBE[kKeyBytes] = {") - -for i, u16 in zip(range(KEYS), chunks(digits, 32)): - b = list(chunks(u16, 2)) - print_row(b) - -print("};") - -print("alignas(16) const unsigned char kRandenRoundKeys[kKeyBytes] = {") - -for i, u16 in zip(range(KEYS), chunks(digits, 32)): - b = list(chunks(u16, 2)) - b.reverse() - print_row(b) - -print("};") - -EOF - -*/ - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace random_internal { -namespace { -static constexpr size_t kKeyBytes = 2176; -} - -alignas(16) const unsigned char kRandenRoundKeysBE[kKeyBytes] = { - 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, 0x13, 0x19, 0x8A, 0x2E, - 0x03, 0x70, 0x73, 0x44, 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, - 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89, 0x45, 0x28, 0x21, 0xE6, - 0x38, 0xD0, 0x13, 0x77, 0xBE, 0x54, 0x66, 0xCF, 0x34, 0xE9, 0x0C, 0x6C, - 0xC0, 0xAC, 0x29, 0xB7, 0xC9, 0x7C, 0x50, 0xDD, 0x3F, 0x84, 0xD5, 0xB5, - 0xB5, 0x47, 0x09, 0x17, 0x92, 0x16, 0xD5, 0xD9, 0x89, 0x79, 0xFB, 0x1B, - 0xD1, 0x31, 0x0B, 0xA6, 0x98, 0xDF, 0xB5, 0xAC, 0x2F, 0xFD, 0x72, 0xDB, - 0xD0, 0x1A, 0xDF, 0xB7, 0xB8, 0xE1, 0xAF, 0xED, 0x6A, 0x26, 0x7E, 0x96, - 0xBA, 0x7C, 0x90, 0x45, 0xF1, 0x2C, 0x7F, 0x99, 0x24, 0xA1, 0x99, 0x47, - 0xB3, 0x91, 0x6C, 0xF7, 0x08, 0x01, 0xF2, 0xE2, 0x85, 0x8E, 0xFC, 0x16, - 0x63, 0x69, 0x20, 0xD8, 0x71, 0x57, 0x4E, 0x69, 0xA4, 0x58, 0xFE, 0xA3, - 0xF4, 0x93, 0x3D, 0x7E, 0x0D, 0x95, 0x74, 0x8F, 0x72, 0x8E, 0xB6, 0x58, - 0x71, 0x8B, 0xCD, 0x58, 0x82, 0x15, 0x4A, 0xEE, 0x7B, 0x54, 0xA4, 0x1D, - 0xC2, 0x5A, 0x59, 0xB5, 0x9C, 0x30, 0xD5, 0x39, 0x2A, 0xF2, 0x60, 0x13, - 0xC5, 0xD1, 0xB0, 0x23, 0x28, 0x60, 0x85, 0xF0, 0xCA, 0x41, 0x79, 0x18, - 0xB8, 0xDB, 0x38, 0xEF, 0x8E, 0x79, 0xDC, 0xB0, 0x60, 0x3A, 0x18, 0x0E, - 0x6C, 0x9E, 0x0E, 0x8B, 0xB0, 0x1E, 0x8A, 0x3E, 0xD7, 0x15, 0x77, 0xC1, - 0xBD, 0x31, 0x4B, 0x27, 0x78, 0xAF, 0x2F, 0xDA, 0x55, 0x60, 0x5C, 0x60, - 0xE6, 0x55, 0x25, 0xF3, 0xAA, 0x55, 0xAB, 0x94, 0x57, 0x48, 0x98, 0x62, - 0x63, 0xE8, 0x14, 0x40, 0x55, 0xCA, 0x39, 0x6A, 0x2A, 0xAB, 0x10, 0xB6, - 0xB4, 0xCC, 0x5C, 0x34, 0x11, 0x41, 0xE8, 0xCE, 0xA1, 0x54, 0x86, 0xAF, - 0x7C, 0x72, 0xE9, 0x93, 0xB3, 0xEE, 0x14, 0x11, 0x63, 0x6F, 0xBC, 0x2A, - 0x2B, 0xA9, 0xC5, 0x5D, 0x74, 0x18, 0x31, 0xF6, 0xCE, 0x5C, 0x3E, 0x16, - 0x9B, 0x87, 0x93, 0x1E, 0xAF, 0xD6, 0xBA, 0x33, 0x6C, 0x24, 0xCF, 0x5C, - 0x7A, 0x32, 0x53, 0x81, 0x28, 0x95, 0x86, 0x77, 0x3B, 0x8F, 0x48, 0x98, - 0x6B, 0x4B, 0xB9, 0xAF, 0xC4, 0xBF, 0xE8, 0x1B, 0x66, 0x28, 0x21, 0x93, - 0x61, 0xD8, 0x09, 0xCC, 0xFB, 0x21, 0xA9, 0x91, 0x48, 0x7C, 0xAC, 0x60, - 0x5D, 0xEC, 0x80, 0x32, 0xEF, 0x84, 0x5D, 0x5D, 0xE9, 0x85, 0x75, 0xB1, - 0xDC, 0x26, 0x23, 0x02, 0xEB, 0x65, 0x1B, 0x88, 0x23, 0x89, 0x3E, 0x81, - 0xD3, 0x96, 0xAC, 0xC5, 0x0F, 0x6D, 0x6F, 0xF3, 0x83, 0xF4, 0x42, 0x39, - 0x2E, 0x0B, 0x44, 0x82, 0xA4, 0x84, 0x20, 0x04, 0x69, 0xC8, 0xF0, 0x4A, - 0x9E, 0x1F, 0x9B, 0x5E, 0x21, 0xC6, 0x68, 0x42, 0xF6, 0xE9, 0x6C, 0x9A, - 0x67, 0x0C, 0x9C, 0x61, 0xAB, 0xD3, 0x88, 0xF0, 0x6A, 0x51, 0xA0, 0xD2, - 0xD8, 0x54, 0x2F, 0x68, 0x96, 0x0F, 0xA7, 0x28, 0xAB, 0x51, 0x33, 0xA3, - 0x6E, 0xEF, 0x0B, 0x6C, 0x13, 0x7A, 0x3B, 0xE4, 0xBA, 0x3B, 0xF0, 0x50, - 0x7E, 0xFB, 0x2A, 0x98, 0xA1, 0xF1, 0x65, 0x1D, 0x39, 0xAF, 0x01, 0x76, - 0x66, 0xCA, 0x59, 0x3E, 0x82, 0x43, 0x0E, 0x88, 0x8C, 0xEE, 0x86, 0x19, - 0x45, 0x6F, 0x9F, 0xB4, 0x7D, 0x84, 0xA5, 0xC3, 0x3B, 0x8B, 0x5E, 0xBE, - 0xE0, 0x6F, 0x75, 0xD8, 0x85, 0xC1, 0x20, 0x73, 0x40, 0x1A, 0x44, 0x9F, - 0x56, 0xC1, 0x6A, 0xA6, 0x4E, 0xD3, 0xAA, 0x62, 0x36, 0x3F, 0x77, 0x06, - 0x1B, 0xFE, 0xDF, 0x72, 0x42, 0x9B, 0x02, 0x3D, 0x37, 0xD0, 0xD7, 0x24, - 0xD0, 0x0A, 0x12, 0x48, 0xDB, 0x0F, 0xEA, 0xD3, 0x49, 0xF1, 0xC0, 0x9B, - 0x07, 0x53, 0x72, 0xC9, 0x80, 0x99, 0x1B, 0x7B, 0x25, 0xD4, 0x79, 0xD8, - 0xF6, 0xE8, 0xDE, 0xF7, 0xE3, 0xFE, 0x50, 0x1A, 0xB6, 0x79, 0x4C, 0x3B, - 0x97, 0x6C, 0xE0, 0xBD, 0x04, 0xC0, 0x06, 0xBA, 0xC1, 0xA9, 0x4F, 0xB6, - 0x40, 0x9F, 0x60, 0xC4, 0x5E, 0x5C, 0x9E, 0xC2, 0x19, 0x6A, 0x24, 0x63, - 0x68, 0xFB, 0x6F, 0xAF, 0x3E, 0x6C, 0x53, 0xB5, 0x13, 0x39, 0xB2, 0xEB, - 0x3B, 0x52, 0xEC, 0x6F, 0x6D, 0xFC, 0x51, 0x1F, 0x9B, 0x30, 0x95, 0x2C, - 0xCC, 0x81, 0x45, 0x44, 0xAF, 0x5E, 0xBD, 0x09, 0xBE, 0xE3, 0xD0, 0x04, - 0xDE, 0x33, 0x4A, 0xFD, 0x66, 0x0F, 0x28, 0x07, 0x19, 0x2E, 0x4B, 0xB3, - 0xC0, 0xCB, 0xA8, 0x57, 0x45, 0xC8, 0x74, 0x0F, 0xD2, 0x0B, 0x5F, 0x39, - 0xB9, 0xD3, 0xFB, 0xDB, 0x55, 0x79, 0xC0, 0xBD, 0x1A, 0x60, 0x32, 0x0A, - 0xD6, 0xA1, 0x00, 0xC6, 0x40, 0x2C, 0x72, 0x79, 0x67, 0x9F, 0x25, 0xFE, - 0xFB, 0x1F, 0xA3, 0xCC, 0x8E, 0xA5, 0xE9, 0xF8, 0xDB, 0x32, 0x22, 0xF8, - 0x3C, 0x75, 0x16, 0xDF, 0xFD, 0x61, 0x6B, 0x15, 0x2F, 0x50, 0x1E, 0xC8, - 0xAD, 0x05, 0x52, 0xAB, 0x32, 0x3D, 0xB5, 0xFA, 0xFD, 0x23, 0x87, 0x60, - 0x53, 0x31, 0x7B, 0x48, 0x3E, 0x00, 0xDF, 0x82, 0x9E, 0x5C, 0x57, 0xBB, - 0xCA, 0x6F, 0x8C, 0xA0, 0x1A, 0x87, 0x56, 0x2E, 0xDF, 0x17, 0x69, 0xDB, - 0xD5, 0x42, 0xA8, 0xF6, 0x28, 0x7E, 0xFF, 0xC3, 0xAC, 0x67, 0x32, 0xC6, - 0x8C, 0x4F, 0x55, 0x73, 0x69, 0x5B, 0x27, 0xB0, 0xBB, 0xCA, 0x58, 0xC8, - 0xE1, 0xFF, 0xA3, 0x5D, 0xB8, 0xF0, 0x11, 0xA0, 0x10, 0xFA, 0x3D, 0x98, - 0xFD, 0x21, 0x83, 0xB8, 0x4A, 0xFC, 0xB5, 0x6C, 0x2D, 0xD1, 0xD3, 0x5B, - 0x9A, 0x53, 0xE4, 0x79, 0xB6, 0xF8, 0x45, 0x65, 0xD2, 0x8E, 0x49, 0xBC, - 0x4B, 0xFB, 0x97, 0x90, 0xE1, 0xDD, 0xF2, 0xDA, 0xA4, 0xCB, 0x7E, 0x33, - 0x62, 0xFB, 0x13, 0x41, 0xCE, 0xE4, 0xC6, 0xE8, 0xEF, 0x20, 0xCA, 0xDA, - 0x36, 0x77, 0x4C, 0x01, 0xD0, 0x7E, 0x9E, 0xFE, 0x2B, 0xF1, 0x1F, 0xB4, - 0x95, 0xDB, 0xDA, 0x4D, 0xAE, 0x90, 0x91, 0x98, 0xEA, 0xAD, 0x8E, 0x71, - 0x6B, 0x93, 0xD5, 0xA0, 0xD0, 0x8E, 0xD1, 0xD0, 0xAF, 0xC7, 0x25, 0xE0, - 0x8E, 0x3C, 0x5B, 0x2F, 0x8E, 0x75, 0x94, 0xB7, 0x8F, 0xF6, 0xE2, 0xFB, - 0xF2, 0x12, 0x2B, 0x64, 0x88, 0x88, 0xB8, 0x12, 0x90, 0x0D, 0xF0, 0x1C, - 0x4F, 0xAD, 0x5E, 0xA0, 0x68, 0x8F, 0xC3, 0x1C, 0xD1, 0xCF, 0xF1, 0x91, - 0xB3, 0xA8, 0xC1, 0xAD, 0x2F, 0x2F, 0x22, 0x18, 0xBE, 0x0E, 0x17, 0x77, - 0xEA, 0x75, 0x2D, 0xFE, 0x8B, 0x02, 0x1F, 0xA1, 0xE5, 0xA0, 0xCC, 0x0F, - 0xB5, 0x6F, 0x74, 0xE8, 0x18, 0xAC, 0xF3, 0xD6, 0xCE, 0x89, 0xE2, 0x99, - 0xB4, 0xA8, 0x4F, 0xE0, 0xFD, 0x13, 0xE0, 0xB7, 0x7C, 0xC4, 0x3B, 0x81, - 0xD2, 0xAD, 0xA8, 0xD9, 0x16, 0x5F, 0xA2, 0x66, 0x80, 0x95, 0x77, 0x05, - 0x93, 0xCC, 0x73, 0x14, 0x21, 0x1A, 0x14, 0x77, 0xE6, 0xAD, 0x20, 0x65, - 0x77, 0xB5, 0xFA, 0x86, 0xC7, 0x54, 0x42, 0xF5, 0xFB, 0x9D, 0x35, 0xCF, - 0xEB, 0xCD, 0xAF, 0x0C, 0x7B, 0x3E, 0x89, 0xA0, 0xD6, 0x41, 0x1B, 0xD3, - 0xAE, 0x1E, 0x7E, 0x49, 0x00, 0x25, 0x0E, 0x2D, 0x20, 0x71, 0xB3, 0x5E, - 0x22, 0x68, 0x00, 0xBB, 0x57, 0xB8, 0xE0, 0xAF, 0x24, 0x64, 0x36, 0x9B, - 0xF0, 0x09, 0xB9, 0x1E, 0x55, 0x63, 0x91, 0x1D, 0x59, 0xDF, 0xA6, 0xAA, - 0x78, 0xC1, 0x43, 0x89, 0xD9, 0x5A, 0x53, 0x7F, 0x20, 0x7D, 0x5B, 0xA2, - 0x02, 0xE5, 0xB9, 0xC5, 0x83, 0x26, 0x03, 0x76, 0x62, 0x95, 0xCF, 0xA9, - 0x11, 0xC8, 0x19, 0x68, 0x4E, 0x73, 0x4A, 0x41, 0xB3, 0x47, 0x2D, 0xCA, - 0x7B, 0x14, 0xA9, 0x4A, 0x1B, 0x51, 0x00, 0x52, 0x9A, 0x53, 0x29, 0x15, - 0xD6, 0x0F, 0x57, 0x3F, 0xBC, 0x9B, 0xC6, 0xE4, 0x2B, 0x60, 0xA4, 0x76, - 0x81, 0xE6, 0x74, 0x00, 0x08, 0xBA, 0x6F, 0xB5, 0x57, 0x1B, 0xE9, 0x1F, - 0xF2, 0x96, 0xEC, 0x6B, 0x2A, 0x0D, 0xD9, 0x15, 0xB6, 0x63, 0x65, 0x21, - 0xE7, 0xB9, 0xF9, 0xB6, 0xFF, 0x34, 0x05, 0x2E, 0xC5, 0x85, 0x56, 0x64, - 0x53, 0xB0, 0x2D, 0x5D, 0xA9, 0x9F, 0x8F, 0xA1, 0x08, 0xBA, 0x47, 0x99, - 0x6E, 0x85, 0x07, 0x6A, 0x4B, 0x7A, 0x70, 0xE9, 0xB5, 0xB3, 0x29, 0x44, - 0xDB, 0x75, 0x09, 0x2E, 0xC4, 0x19, 0x26, 0x23, 0xAD, 0x6E, 0xA6, 0xB0, - 0x49, 0xA7, 0xDF, 0x7D, 0x9C, 0xEE, 0x60, 0xB8, 0x8F, 0xED, 0xB2, 0x66, - 0xEC, 0xAA, 0x8C, 0x71, 0x69, 0x9A, 0x18, 0xFF, 0x56, 0x64, 0x52, 0x6C, - 0xC2, 0xB1, 0x9E, 0xE1, 0x19, 0x36, 0x02, 0xA5, 0x75, 0x09, 0x4C, 0x29, - 0xA0, 0x59, 0x13, 0x40, 0xE4, 0x18, 0x3A, 0x3E, 0x3F, 0x54, 0x98, 0x9A, - 0x5B, 0x42, 0x9D, 0x65, 0x6B, 0x8F, 0xE4, 0xD6, 0x99, 0xF7, 0x3F, 0xD6, - 0xA1, 0xD2, 0x9C, 0x07, 0xEF, 0xE8, 0x30, 0xF5, 0x4D, 0x2D, 0x38, 0xE6, - 0xF0, 0x25, 0x5D, 0xC1, 0x4C, 0xDD, 0x20, 0x86, 0x84, 0x70, 0xEB, 0x26, - 0x63, 0x82, 0xE9, 0xC6, 0x02, 0x1E, 0xCC, 0x5E, 0x09, 0x68, 0x6B, 0x3F, - 0x3E, 0xBA, 0xEF, 0xC9, 0x3C, 0x97, 0x18, 0x14, 0x6B, 0x6A, 0x70, 0xA1, - 0x68, 0x7F, 0x35, 0x84, 0x52, 0xA0, 0xE2, 0x86, 0xB7, 0x9C, 0x53, 0x05, - 0xAA, 0x50, 0x07, 0x37, 0x3E, 0x07, 0x84, 0x1C, 0x7F, 0xDE, 0xAE, 0x5C, - 0x8E, 0x7D, 0x44, 0xEC, 0x57, 0x16, 0xF2, 0xB8, 0xB0, 0x3A, 0xDA, 0x37, - 0xF0, 0x50, 0x0C, 0x0D, 0xF0, 0x1C, 0x1F, 0x04, 0x02, 0x00, 0xB3, 0xFF, - 0xAE, 0x0C, 0xF5, 0x1A, 0x3C, 0xB5, 0x74, 0xB2, 0x25, 0x83, 0x7A, 0x58, - 0xDC, 0x09, 0x21, 0xBD, 0xD1, 0x91, 0x13, 0xF9, 0x7C, 0xA9, 0x2F, 0xF6, - 0x94, 0x32, 0x47, 0x73, 0x22, 0xF5, 0x47, 0x01, 0x3A, 0xE5, 0xE5, 0x81, - 0x37, 0xC2, 0xDA, 0xDC, 0xC8, 0xB5, 0x76, 0x34, 0x9A, 0xF3, 0xDD, 0xA7, - 0xA9, 0x44, 0x61, 0x46, 0x0F, 0xD0, 0x03, 0x0E, 0xEC, 0xC8, 0xC7, 0x3E, - 0xA4, 0x75, 0x1E, 0x41, 0xE2, 0x38, 0xCD, 0x99, 0x3B, 0xEA, 0x0E, 0x2F, - 0x32, 0x80, 0xBB, 0xA1, 0x18, 0x3E, 0xB3, 0x31, 0x4E, 0x54, 0x8B, 0x38, - 0x4F, 0x6D, 0xB9, 0x08, 0x6F, 0x42, 0x0D, 0x03, 0xF6, 0x0A, 0x04, 0xBF, - 0x2C, 0xB8, 0x12, 0x90, 0x24, 0x97, 0x7C, 0x79, 0x56, 0x79, 0xB0, 0x72, - 0xBC, 0xAF, 0x89, 0xAF, 0xDE, 0x9A, 0x77, 0x1F, 0xD9, 0x93, 0x08, 0x10, - 0xB3, 0x8B, 0xAE, 0x12, 0xDC, 0xCF, 0x3F, 0x2E, 0x55, 0x12, 0x72, 0x1F, - 0x2E, 0x6B, 0x71, 0x24, 0x50, 0x1A, 0xDD, 0xE6, 0x9F, 0x84, 0xCD, 0x87, - 0x7A, 0x58, 0x47, 0x18, 0x74, 0x08, 0xDA, 0x17, 0xBC, 0x9F, 0x9A, 0xBC, - 0xE9, 0x4B, 0x7D, 0x8C, 0xEC, 0x7A, 0xEC, 0x3A, 0xDB, 0x85, 0x1D, 0xFA, - 0x63, 0x09, 0x43, 0x66, 0xC4, 0x64, 0xC3, 0xD2, 0xEF, 0x1C, 0x18, 0x47, - 0x32, 0x15, 0xD8, 0x08, 0xDD, 0x43, 0x3B, 0x37, 0x24, 0xC2, 0xBA, 0x16, - 0x12, 0xA1, 0x4D, 0x43, 0x2A, 0x65, 0xC4, 0x51, 0x50, 0x94, 0x00, 0x02, - 0x13, 0x3A, 0xE4, 0xDD, 0x71, 0xDF, 0xF8, 0x9E, 0x10, 0x31, 0x4E, 0x55, - 0x81, 0xAC, 0x77, 0xD6, 0x5F, 0x11, 0x19, 0x9B, 0x04, 0x35, 0x56, 0xF1, - 0xD7, 0xA3, 0xC7, 0x6B, 0x3C, 0x11, 0x18, 0x3B, 0x59, 0x24, 0xA5, 0x09, - 0xF2, 0x8F, 0xE6, 0xED, 0x97, 0xF1, 0xFB, 0xFA, 0x9E, 0xBA, 0xBF, 0x2C, - 0x1E, 0x15, 0x3C, 0x6E, 0x86, 0xE3, 0x45, 0x70, 0xEA, 0xE9, 0x6F, 0xB1, - 0x86, 0x0E, 0x5E, 0x0A, 0x5A, 0x3E, 0x2A, 0xB3, 0x77, 0x1F, 0xE7, 0x1C, - 0x4E, 0x3D, 0x06, 0xFA, 0x29, 0x65, 0xDC, 0xB9, 0x99, 0xE7, 0x1D, 0x0F, - 0x80, 0x3E, 0x89, 0xD6, 0x52, 0x66, 0xC8, 0x25, 0x2E, 0x4C, 0xC9, 0x78, - 0x9C, 0x10, 0xB3, 0x6A, 0xC6, 0x15, 0x0E, 0xBA, 0x94, 0xE2, 0xEA, 0x78, - 0xA6, 0xFC, 0x3C, 0x53, 0x1E, 0x0A, 0x2D, 0xF4, 0xF2, 0xF7, 0x4E, 0xA7, - 0x36, 0x1D, 0x2B, 0x3D, 0x19, 0x39, 0x26, 0x0F, 0x19, 0xC2, 0x79, 0x60, - 0x52, 0x23, 0xA7, 0x08, 0xF7, 0x13, 0x12, 0xB6, 0xEB, 0xAD, 0xFE, 0x6E, - 0xEA, 0xC3, 0x1F, 0x66, 0xE3, 0xBC, 0x45, 0x95, 0xA6, 0x7B, 0xC8, 0x83, - 0xB1, 0x7F, 0x37, 0xD1, 0x01, 0x8C, 0xFF, 0x28, 0xC3, 0x32, 0xDD, 0xEF, - 0xBE, 0x6C, 0x5A, 0xA5, 0x65, 0x58, 0x21, 0x85, 0x68, 0xAB, 0x97, 0x02, - 0xEE, 0xCE, 0xA5, 0x0F, 0xDB, 0x2F, 0x95, 0x3B, 0x2A, 0xEF, 0x7D, 0xAD, - 0x5B, 0x6E, 0x2F, 0x84, 0x15, 0x21, 0xB6, 0x28, 0x29, 0x07, 0x61, 0x70, - 0xEC, 0xDD, 0x47, 0x75, 0x61, 0x9F, 0x15, 0x10, 0x13, 0xCC, 0xA8, 0x30, - 0xEB, 0x61, 0xBD, 0x96, 0x03, 0x34, 0xFE, 0x1E, 0xAA, 0x03, 0x63, 0xCF, - 0xB5, 0x73, 0x5C, 0x90, 0x4C, 0x70, 0xA2, 0x39, 0xD5, 0x9E, 0x9E, 0x0B, - 0xCB, 0xAA, 0xDE, 0x14, 0xEE, 0xCC, 0x86, 0xBC, 0x60, 0x62, 0x2C, 0xA7, - 0x9C, 0xAB, 0x5C, 0xAB, 0xB2, 0xF3, 0x84, 0x6E, 0x64, 0x8B, 0x1E, 0xAF, - 0x19, 0xBD, 0xF0, 0xCA, 0xA0, 0x23, 0x69, 0xB9, 0x65, 0x5A, 0xBB, 0x50, - 0x40, 0x68, 0x5A, 0x32, 0x3C, 0x2A, 0xB4, 0xB3, 0x31, 0x9E, 0xE9, 0xD5, - 0xC0, 0x21, 0xB8, 0xF7, 0x9B, 0x54, 0x0B, 0x19, 0x87, 0x5F, 0xA0, 0x99, - 0x95, 0xF7, 0x99, 0x7E, 0x62, 0x3D, 0x7D, 0xA8, 0xF8, 0x37, 0x88, 0x9A, - 0x97, 0xE3, 0x2D, 0x77, 0x11, 0xED, 0x93, 0x5F, 0x16, 0x68, 0x12, 0x81, - 0x0E, 0x35, 0x88, 0x29, 0xC7, 0xE6, 0x1F, 0xD6, 0x96, 0xDE, 0xDF, 0xA1, - 0x78, 0x58, 0xBA, 0x99, 0x57, 0xF5, 0x84, 0xA5, 0x1B, 0x22, 0x72, 0x63, - 0x9B, 0x83, 0xC3, 0xFF, 0x1A, 0xC2, 0x46, 0x96, 0xCD, 0xB3, 0x0A, 0xEB, - 0x53, 0x2E, 0x30, 0x54, 0x8F, 0xD9, 0x48, 0xE4, 0x6D, 0xBC, 0x31, 0x28, - 0x58, 0xEB, 0xF2, 0xEF, 0x34, 0xC6, 0xFF, 0xEA, 0xFE, 0x28, 0xED, 0x61, - 0xEE, 0x7C, 0x3C, 0x73, 0x5D, 0x4A, 0x14, 0xD9, 0xE8, 0x64, 0xB7, 0xE3, - 0x42, 0x10, 0x5D, 0x14, 0x20, 0x3E, 0x13, 0xE0, 0x45, 0xEE, 0xE2, 0xB6, - 0xA3, 0xAA, 0xAB, 0xEA, 0xDB, 0x6C, 0x4F, 0x15, 0xFA, 0xCB, 0x4F, 0xD0, - 0xC7, 0x42, 0xF4, 0x42, 0xEF, 0x6A, 0xBB, 0xB5, 0x65, 0x4F, 0x3B, 0x1D, - 0x41, 0xCD, 0x21, 0x05, 0xD8, 0x1E, 0x79, 0x9E, 0x86, 0x85, 0x4D, 0xC7, - 0xE4, 0x4B, 0x47, 0x6A, 0x3D, 0x81, 0x62, 0x50, 0xCF, 0x62, 0xA1, 0xF2, - 0x5B, 0x8D, 0x26, 0x46, 0xFC, 0x88, 0x83, 0xA0, 0xC1, 0xC7, 0xB6, 0xA3, - 0x7F, 0x15, 0x24, 0xC3, 0x69, 0xCB, 0x74, 0x92, 0x47, 0x84, 0x8A, 0x0B, - 0x56, 0x92, 0xB2, 0x85, 0x09, 0x5B, 0xBF, 0x00, 0xAD, 0x19, 0x48, 0x9D, - 0x14, 0x62, 0xB1, 0x74, 0x23, 0x82, 0x0D, 0x00, 0x58, 0x42, 0x8D, 0x2A, - 0x0C, 0x55, 0xF5, 0xEA, 0x1D, 0xAD, 0xF4, 0x3E, 0x23, 0x3F, 0x70, 0x61, - 0x33, 0x72, 0xF0, 0x92, 0x8D, 0x93, 0x7E, 0x41, 0xD6, 0x5F, 0xEC, 0xF1, - 0x6C, 0x22, 0x3B, 0xDB, 0x7C, 0xDE, 0x37, 0x59, 0xCB, 0xEE, 0x74, 0x60, - 0x40, 0x85, 0xF2, 0xA7, 0xCE, 0x77, 0x32, 0x6E, 0xA6, 0x07, 0x80, 0x84, - 0x19, 0xF8, 0x50, 0x9E, 0xE8, 0xEF, 0xD8, 0x55, 0x61, 0xD9, 0x97, 0x35, - 0xA9, 0x69, 0xA7, 0xAA, 0xC5, 0x0C, 0x06, 0xC2, 0x5A, 0x04, 0xAB, 0xFC, - 0x80, 0x0B, 0xCA, 0xDC, 0x9E, 0x44, 0x7A, 0x2E, 0xC3, 0x45, 0x34, 0x84, - 0xFD, 0xD5, 0x67, 0x05, 0x0E, 0x1E, 0x9E, 0xC9, 0xDB, 0x73, 0xDB, 0xD3, - 0x10, 0x55, 0x88, 0xCD, 0x67, 0x5F, 0xDA, 0x79, 0xE3, 0x67, 0x43, 0x40, - 0xC5, 0xC4, 0x34, 0x65, 0x71, 0x3E, 0x38, 0xD8, 0x3D, 0x28, 0xF8, 0x9E, - 0xF1, 0x6D, 0xFF, 0x20, 0x15, 0x3E, 0x21, 0xE7, 0x8F, 0xB0, 0x3D, 0x4A, - 0xE6, 0xE3, 0x9F, 0x2B, 0xDB, 0x83, 0xAD, 0xF7, 0xE9, 0x3D, 0x5A, 0x68, - 0x94, 0x81, 0x40, 0xF7, 0xF6, 0x4C, 0x26, 0x1C, 0x94, 0x69, 0x29, 0x34, - 0x41, 0x15, 0x20, 0xF7, 0x76, 0x02, 0xD4, 0xF7, 0xBC, 0xF4, 0x6B, 0x2E, - 0xD4, 0xA1, 0x00, 0x68, 0xD4, 0x08, 0x24, 0x71, 0x33, 0x20, 0xF4, 0x6A, - 0x43, 0xB7, 0xD4, 0xB7, 0x50, 0x00, 0x61, 0xAF, 0x1E, 0x39, 0xF6, 0x2E, - 0x97, 0x24, 0x45, 0x46, -}; - -alignas(16) const unsigned char kRandenRoundKeys[kKeyBytes] = { - 0x44, 0x73, 0x70, 0x03, 0x2E, 0x8A, 0x19, 0x13, 0xD3, 0x08, 0xA3, 0x85, - 0x88, 0x6A, 0x3F, 0x24, 0x89, 0x6C, 0x4E, 0xEC, 0x98, 0xFA, 0x2E, 0x08, - 0xD0, 0x31, 0x9F, 0x29, 0x22, 0x38, 0x09, 0xA4, 0x6C, 0x0C, 0xE9, 0x34, - 0xCF, 0x66, 0x54, 0xBE, 0x77, 0x13, 0xD0, 0x38, 0xE6, 0x21, 0x28, 0x45, - 0x17, 0x09, 0x47, 0xB5, 0xB5, 0xD5, 0x84, 0x3F, 0xDD, 0x50, 0x7C, 0xC9, - 0xB7, 0x29, 0xAC, 0xC0, 0xAC, 0xB5, 0xDF, 0x98, 0xA6, 0x0B, 0x31, 0xD1, - 0x1B, 0xFB, 0x79, 0x89, 0xD9, 0xD5, 0x16, 0x92, 0x96, 0x7E, 0x26, 0x6A, - 0xED, 0xAF, 0xE1, 0xB8, 0xB7, 0xDF, 0x1A, 0xD0, 0xDB, 0x72, 0xFD, 0x2F, - 0xF7, 0x6C, 0x91, 0xB3, 0x47, 0x99, 0xA1, 0x24, 0x99, 0x7F, 0x2C, 0xF1, - 0x45, 0x90, 0x7C, 0xBA, 0x69, 0x4E, 0x57, 0x71, 0xD8, 0x20, 0x69, 0x63, - 0x16, 0xFC, 0x8E, 0x85, 0xE2, 0xF2, 0x01, 0x08, 0x58, 0xB6, 0x8E, 0x72, - 0x8F, 0x74, 0x95, 0x0D, 0x7E, 0x3D, 0x93, 0xF4, 0xA3, 0xFE, 0x58, 0xA4, - 0xB5, 0x59, 0x5A, 0xC2, 0x1D, 0xA4, 0x54, 0x7B, 0xEE, 0x4A, 0x15, 0x82, - 0x58, 0xCD, 0x8B, 0x71, 0xF0, 0x85, 0x60, 0x28, 0x23, 0xB0, 0xD1, 0xC5, - 0x13, 0x60, 0xF2, 0x2A, 0x39, 0xD5, 0x30, 0x9C, 0x0E, 0x18, 0x3A, 0x60, - 0xB0, 0xDC, 0x79, 0x8E, 0xEF, 0x38, 0xDB, 0xB8, 0x18, 0x79, 0x41, 0xCA, - 0x27, 0x4B, 0x31, 0xBD, 0xC1, 0x77, 0x15, 0xD7, 0x3E, 0x8A, 0x1E, 0xB0, - 0x8B, 0x0E, 0x9E, 0x6C, 0x94, 0xAB, 0x55, 0xAA, 0xF3, 0x25, 0x55, 0xE6, - 0x60, 0x5C, 0x60, 0x55, 0xDA, 0x2F, 0xAF, 0x78, 0xB6, 0x10, 0xAB, 0x2A, - 0x6A, 0x39, 0xCA, 0x55, 0x40, 0x14, 0xE8, 0x63, 0x62, 0x98, 0x48, 0x57, - 0x93, 0xE9, 0x72, 0x7C, 0xAF, 0x86, 0x54, 0xA1, 0xCE, 0xE8, 0x41, 0x11, - 0x34, 0x5C, 0xCC, 0xB4, 0xF6, 0x31, 0x18, 0x74, 0x5D, 0xC5, 0xA9, 0x2B, - 0x2A, 0xBC, 0x6F, 0x63, 0x11, 0x14, 0xEE, 0xB3, 0x5C, 0xCF, 0x24, 0x6C, - 0x33, 0xBA, 0xD6, 0xAF, 0x1E, 0x93, 0x87, 0x9B, 0x16, 0x3E, 0x5C, 0xCE, - 0xAF, 0xB9, 0x4B, 0x6B, 0x98, 0x48, 0x8F, 0x3B, 0x77, 0x86, 0x95, 0x28, - 0x81, 0x53, 0x32, 0x7A, 0x91, 0xA9, 0x21, 0xFB, 0xCC, 0x09, 0xD8, 0x61, - 0x93, 0x21, 0x28, 0x66, 0x1B, 0xE8, 0xBF, 0xC4, 0xB1, 0x75, 0x85, 0xE9, - 0x5D, 0x5D, 0x84, 0xEF, 0x32, 0x80, 0xEC, 0x5D, 0x60, 0xAC, 0x7C, 0x48, - 0xC5, 0xAC, 0x96, 0xD3, 0x81, 0x3E, 0x89, 0x23, 0x88, 0x1B, 0x65, 0xEB, - 0x02, 0x23, 0x26, 0xDC, 0x04, 0x20, 0x84, 0xA4, 0x82, 0x44, 0x0B, 0x2E, - 0x39, 0x42, 0xF4, 0x83, 0xF3, 0x6F, 0x6D, 0x0F, 0x9A, 0x6C, 0xE9, 0xF6, - 0x42, 0x68, 0xC6, 0x21, 0x5E, 0x9B, 0x1F, 0x9E, 0x4A, 0xF0, 0xC8, 0x69, - 0x68, 0x2F, 0x54, 0xD8, 0xD2, 0xA0, 0x51, 0x6A, 0xF0, 0x88, 0xD3, 0xAB, - 0x61, 0x9C, 0x0C, 0x67, 0xE4, 0x3B, 0x7A, 0x13, 0x6C, 0x0B, 0xEF, 0x6E, - 0xA3, 0x33, 0x51, 0xAB, 0x28, 0xA7, 0x0F, 0x96, 0x76, 0x01, 0xAF, 0x39, - 0x1D, 0x65, 0xF1, 0xA1, 0x98, 0x2A, 0xFB, 0x7E, 0x50, 0xF0, 0x3B, 0xBA, - 0xB4, 0x9F, 0x6F, 0x45, 0x19, 0x86, 0xEE, 0x8C, 0x88, 0x0E, 0x43, 0x82, - 0x3E, 0x59, 0xCA, 0x66, 0x73, 0x20, 0xC1, 0x85, 0xD8, 0x75, 0x6F, 0xE0, - 0xBE, 0x5E, 0x8B, 0x3B, 0xC3, 0xA5, 0x84, 0x7D, 0x06, 0x77, 0x3F, 0x36, - 0x62, 0xAA, 0xD3, 0x4E, 0xA6, 0x6A, 0xC1, 0x56, 0x9F, 0x44, 0x1A, 0x40, - 0x48, 0x12, 0x0A, 0xD0, 0x24, 0xD7, 0xD0, 0x37, 0x3D, 0x02, 0x9B, 0x42, - 0x72, 0xDF, 0xFE, 0x1B, 0x7B, 0x1B, 0x99, 0x80, 0xC9, 0x72, 0x53, 0x07, - 0x9B, 0xC0, 0xF1, 0x49, 0xD3, 0xEA, 0x0F, 0xDB, 0x3B, 0x4C, 0x79, 0xB6, - 0x1A, 0x50, 0xFE, 0xE3, 0xF7, 0xDE, 0xE8, 0xF6, 0xD8, 0x79, 0xD4, 0x25, - 0xC4, 0x60, 0x9F, 0x40, 0xB6, 0x4F, 0xA9, 0xC1, 0xBA, 0x06, 0xC0, 0x04, - 0xBD, 0xE0, 0x6C, 0x97, 0xB5, 0x53, 0x6C, 0x3E, 0xAF, 0x6F, 0xFB, 0x68, - 0x63, 0x24, 0x6A, 0x19, 0xC2, 0x9E, 0x5C, 0x5E, 0x2C, 0x95, 0x30, 0x9B, - 0x1F, 0x51, 0xFC, 0x6D, 0x6F, 0xEC, 0x52, 0x3B, 0xEB, 0xB2, 0x39, 0x13, - 0xFD, 0x4A, 0x33, 0xDE, 0x04, 0xD0, 0xE3, 0xBE, 0x09, 0xBD, 0x5E, 0xAF, - 0x44, 0x45, 0x81, 0xCC, 0x0F, 0x74, 0xC8, 0x45, 0x57, 0xA8, 0xCB, 0xC0, - 0xB3, 0x4B, 0x2E, 0x19, 0x07, 0x28, 0x0F, 0x66, 0x0A, 0x32, 0x60, 0x1A, - 0xBD, 0xC0, 0x79, 0x55, 0xDB, 0xFB, 0xD3, 0xB9, 0x39, 0x5F, 0x0B, 0xD2, - 0xCC, 0xA3, 0x1F, 0xFB, 0xFE, 0x25, 0x9F, 0x67, 0x79, 0x72, 0x2C, 0x40, - 0xC6, 0x00, 0xA1, 0xD6, 0x15, 0x6B, 0x61, 0xFD, 0xDF, 0x16, 0x75, 0x3C, - 0xF8, 0x22, 0x32, 0xDB, 0xF8, 0xE9, 0xA5, 0x8E, 0x60, 0x87, 0x23, 0xFD, - 0xFA, 0xB5, 0x3D, 0x32, 0xAB, 0x52, 0x05, 0xAD, 0xC8, 0x1E, 0x50, 0x2F, - 0xA0, 0x8C, 0x6F, 0xCA, 0xBB, 0x57, 0x5C, 0x9E, 0x82, 0xDF, 0x00, 0x3E, - 0x48, 0x7B, 0x31, 0x53, 0xC3, 0xFF, 0x7E, 0x28, 0xF6, 0xA8, 0x42, 0xD5, - 0xDB, 0x69, 0x17, 0xDF, 0x2E, 0x56, 0x87, 0x1A, 0xC8, 0x58, 0xCA, 0xBB, - 0xB0, 0x27, 0x5B, 0x69, 0x73, 0x55, 0x4F, 0x8C, 0xC6, 0x32, 0x67, 0xAC, - 0xB8, 0x83, 0x21, 0xFD, 0x98, 0x3D, 0xFA, 0x10, 0xA0, 0x11, 0xF0, 0xB8, - 0x5D, 0xA3, 0xFF, 0xE1, 0x65, 0x45, 0xF8, 0xB6, 0x79, 0xE4, 0x53, 0x9A, - 0x5B, 0xD3, 0xD1, 0x2D, 0x6C, 0xB5, 0xFC, 0x4A, 0x33, 0x7E, 0xCB, 0xA4, - 0xDA, 0xF2, 0xDD, 0xE1, 0x90, 0x97, 0xFB, 0x4B, 0xBC, 0x49, 0x8E, 0xD2, - 0x01, 0x4C, 0x77, 0x36, 0xDA, 0xCA, 0x20, 0xEF, 0xE8, 0xC6, 0xE4, 0xCE, - 0x41, 0x13, 0xFB, 0x62, 0x98, 0x91, 0x90, 0xAE, 0x4D, 0xDA, 0xDB, 0x95, - 0xB4, 0x1F, 0xF1, 0x2B, 0xFE, 0x9E, 0x7E, 0xD0, 0xE0, 0x25, 0xC7, 0xAF, - 0xD0, 0xD1, 0x8E, 0xD0, 0xA0, 0xD5, 0x93, 0x6B, 0x71, 0x8E, 0xAD, 0xEA, - 0x64, 0x2B, 0x12, 0xF2, 0xFB, 0xE2, 0xF6, 0x8F, 0xB7, 0x94, 0x75, 0x8E, - 0x2F, 0x5B, 0x3C, 0x8E, 0x1C, 0xC3, 0x8F, 0x68, 0xA0, 0x5E, 0xAD, 0x4F, - 0x1C, 0xF0, 0x0D, 0x90, 0x12, 0xB8, 0x88, 0x88, 0x77, 0x17, 0x0E, 0xBE, - 0x18, 0x22, 0x2F, 0x2F, 0xAD, 0xC1, 0xA8, 0xB3, 0x91, 0xF1, 0xCF, 0xD1, - 0xE8, 0x74, 0x6F, 0xB5, 0x0F, 0xCC, 0xA0, 0xE5, 0xA1, 0x1F, 0x02, 0x8B, - 0xFE, 0x2D, 0x75, 0xEA, 0xB7, 0xE0, 0x13, 0xFD, 0xE0, 0x4F, 0xA8, 0xB4, - 0x99, 0xE2, 0x89, 0xCE, 0xD6, 0xF3, 0xAC, 0x18, 0x05, 0x77, 0x95, 0x80, - 0x66, 0xA2, 0x5F, 0x16, 0xD9, 0xA8, 0xAD, 0xD2, 0x81, 0x3B, 0xC4, 0x7C, - 0x86, 0xFA, 0xB5, 0x77, 0x65, 0x20, 0xAD, 0xE6, 0x77, 0x14, 0x1A, 0x21, - 0x14, 0x73, 0xCC, 0x93, 0xA0, 0x89, 0x3E, 0x7B, 0x0C, 0xAF, 0xCD, 0xEB, - 0xCF, 0x35, 0x9D, 0xFB, 0xF5, 0x42, 0x54, 0xC7, 0x5E, 0xB3, 0x71, 0x20, - 0x2D, 0x0E, 0x25, 0x00, 0x49, 0x7E, 0x1E, 0xAE, 0xD3, 0x1B, 0x41, 0xD6, - 0x1E, 0xB9, 0x09, 0xF0, 0x9B, 0x36, 0x64, 0x24, 0xAF, 0xE0, 0xB8, 0x57, - 0xBB, 0x00, 0x68, 0x22, 0x7F, 0x53, 0x5A, 0xD9, 0x89, 0x43, 0xC1, 0x78, - 0xAA, 0xA6, 0xDF, 0x59, 0x1D, 0x91, 0x63, 0x55, 0xA9, 0xCF, 0x95, 0x62, - 0x76, 0x03, 0x26, 0x83, 0xC5, 0xB9, 0xE5, 0x02, 0xA2, 0x5B, 0x7D, 0x20, - 0x4A, 0xA9, 0x14, 0x7B, 0xCA, 0x2D, 0x47, 0xB3, 0x41, 0x4A, 0x73, 0x4E, - 0x68, 0x19, 0xC8, 0x11, 0xE4, 0xC6, 0x9B, 0xBC, 0x3F, 0x57, 0x0F, 0xD6, - 0x15, 0x29, 0x53, 0x9A, 0x52, 0x00, 0x51, 0x1B, 0x1F, 0xE9, 0x1B, 0x57, - 0xB5, 0x6F, 0xBA, 0x08, 0x00, 0x74, 0xE6, 0x81, 0x76, 0xA4, 0x60, 0x2B, - 0xB6, 0xF9, 0xB9, 0xE7, 0x21, 0x65, 0x63, 0xB6, 0x15, 0xD9, 0x0D, 0x2A, - 0x6B, 0xEC, 0x96, 0xF2, 0xA1, 0x8F, 0x9F, 0xA9, 0x5D, 0x2D, 0xB0, 0x53, - 0x64, 0x56, 0x85, 0xC5, 0x2E, 0x05, 0x34, 0xFF, 0x44, 0x29, 0xB3, 0xB5, - 0xE9, 0x70, 0x7A, 0x4B, 0x6A, 0x07, 0x85, 0x6E, 0x99, 0x47, 0xBA, 0x08, - 0x7D, 0xDF, 0xA7, 0x49, 0xB0, 0xA6, 0x6E, 0xAD, 0x23, 0x26, 0x19, 0xC4, - 0x2E, 0x09, 0x75, 0xDB, 0xFF, 0x18, 0x9A, 0x69, 0x71, 0x8C, 0xAA, 0xEC, - 0x66, 0xB2, 0xED, 0x8F, 0xB8, 0x60, 0xEE, 0x9C, 0x29, 0x4C, 0x09, 0x75, - 0xA5, 0x02, 0x36, 0x19, 0xE1, 0x9E, 0xB1, 0xC2, 0x6C, 0x52, 0x64, 0x56, - 0x65, 0x9D, 0x42, 0x5B, 0x9A, 0x98, 0x54, 0x3F, 0x3E, 0x3A, 0x18, 0xE4, - 0x40, 0x13, 0x59, 0xA0, 0xF5, 0x30, 0xE8, 0xEF, 0x07, 0x9C, 0xD2, 0xA1, - 0xD6, 0x3F, 0xF7, 0x99, 0xD6, 0xE4, 0x8F, 0x6B, 0x26, 0xEB, 0x70, 0x84, - 0x86, 0x20, 0xDD, 0x4C, 0xC1, 0x5D, 0x25, 0xF0, 0xE6, 0x38, 0x2D, 0x4D, - 0xC9, 0xEF, 0xBA, 0x3E, 0x3F, 0x6B, 0x68, 0x09, 0x5E, 0xCC, 0x1E, 0x02, - 0xC6, 0xE9, 0x82, 0x63, 0x86, 0xE2, 0xA0, 0x52, 0x84, 0x35, 0x7F, 0x68, - 0xA1, 0x70, 0x6A, 0x6B, 0x14, 0x18, 0x97, 0x3C, 0x5C, 0xAE, 0xDE, 0x7F, - 0x1C, 0x84, 0x07, 0x3E, 0x37, 0x07, 0x50, 0xAA, 0x05, 0x53, 0x9C, 0xB7, - 0x0D, 0x0C, 0x50, 0xF0, 0x37, 0xDA, 0x3A, 0xB0, 0xB8, 0xF2, 0x16, 0x57, - 0xEC, 0x44, 0x7D, 0x8E, 0xB2, 0x74, 0xB5, 0x3C, 0x1A, 0xF5, 0x0C, 0xAE, - 0xFF, 0xB3, 0x00, 0x02, 0x04, 0x1F, 0x1C, 0xF0, 0xF6, 0x2F, 0xA9, 0x7C, - 0xF9, 0x13, 0x91, 0xD1, 0xBD, 0x21, 0x09, 0xDC, 0x58, 0x7A, 0x83, 0x25, - 0xDC, 0xDA, 0xC2, 0x37, 0x81, 0xE5, 0xE5, 0x3A, 0x01, 0x47, 0xF5, 0x22, - 0x73, 0x47, 0x32, 0x94, 0x0E, 0x03, 0xD0, 0x0F, 0x46, 0x61, 0x44, 0xA9, - 0xA7, 0xDD, 0xF3, 0x9A, 0x34, 0x76, 0xB5, 0xC8, 0x2F, 0x0E, 0xEA, 0x3B, - 0x99, 0xCD, 0x38, 0xE2, 0x41, 0x1E, 0x75, 0xA4, 0x3E, 0xC7, 0xC8, 0xEC, - 0x08, 0xB9, 0x6D, 0x4F, 0x38, 0x8B, 0x54, 0x4E, 0x31, 0xB3, 0x3E, 0x18, - 0xA1, 0xBB, 0x80, 0x32, 0x79, 0x7C, 0x97, 0x24, 0x90, 0x12, 0xB8, 0x2C, - 0xBF, 0x04, 0x0A, 0xF6, 0x03, 0x0D, 0x42, 0x6F, 0x10, 0x08, 0x93, 0xD9, - 0x1F, 0x77, 0x9A, 0xDE, 0xAF, 0x89, 0xAF, 0xBC, 0x72, 0xB0, 0x79, 0x56, - 0x24, 0x71, 0x6B, 0x2E, 0x1F, 0x72, 0x12, 0x55, 0x2E, 0x3F, 0xCF, 0xDC, - 0x12, 0xAE, 0x8B, 0xB3, 0x17, 0xDA, 0x08, 0x74, 0x18, 0x47, 0x58, 0x7A, - 0x87, 0xCD, 0x84, 0x9F, 0xE6, 0xDD, 0x1A, 0x50, 0xFA, 0x1D, 0x85, 0xDB, - 0x3A, 0xEC, 0x7A, 0xEC, 0x8C, 0x7D, 0x4B, 0xE9, 0xBC, 0x9A, 0x9F, 0xBC, - 0x08, 0xD8, 0x15, 0x32, 0x47, 0x18, 0x1C, 0xEF, 0xD2, 0xC3, 0x64, 0xC4, - 0x66, 0x43, 0x09, 0x63, 0x51, 0xC4, 0x65, 0x2A, 0x43, 0x4D, 0xA1, 0x12, - 0x16, 0xBA, 0xC2, 0x24, 0x37, 0x3B, 0x43, 0xDD, 0x55, 0x4E, 0x31, 0x10, - 0x9E, 0xF8, 0xDF, 0x71, 0xDD, 0xE4, 0x3A, 0x13, 0x02, 0x00, 0x94, 0x50, - 0x6B, 0xC7, 0xA3, 0xD7, 0xF1, 0x56, 0x35, 0x04, 0x9B, 0x19, 0x11, 0x5F, - 0xD6, 0x77, 0xAC, 0x81, 0xFA, 0xFB, 0xF1, 0x97, 0xED, 0xE6, 0x8F, 0xF2, - 0x09, 0xA5, 0x24, 0x59, 0x3B, 0x18, 0x11, 0x3C, 0xB1, 0x6F, 0xE9, 0xEA, - 0x70, 0x45, 0xE3, 0x86, 0x6E, 0x3C, 0x15, 0x1E, 0x2C, 0xBF, 0xBA, 0x9E, - 0xFA, 0x06, 0x3D, 0x4E, 0x1C, 0xE7, 0x1F, 0x77, 0xB3, 0x2A, 0x3E, 0x5A, - 0x0A, 0x5E, 0x0E, 0x86, 0x25, 0xC8, 0x66, 0x52, 0xD6, 0x89, 0x3E, 0x80, - 0x0F, 0x1D, 0xE7, 0x99, 0xB9, 0xDC, 0x65, 0x29, 0x78, 0xEA, 0xE2, 0x94, - 0xBA, 0x0E, 0x15, 0xC6, 0x6A, 0xB3, 0x10, 0x9C, 0x78, 0xC9, 0x4C, 0x2E, - 0x3D, 0x2B, 0x1D, 0x36, 0xA7, 0x4E, 0xF7, 0xF2, 0xF4, 0x2D, 0x0A, 0x1E, - 0x53, 0x3C, 0xFC, 0xA6, 0xB6, 0x12, 0x13, 0xF7, 0x08, 0xA7, 0x23, 0x52, - 0x60, 0x79, 0xC2, 0x19, 0x0F, 0x26, 0x39, 0x19, 0x83, 0xC8, 0x7B, 0xA6, - 0x95, 0x45, 0xBC, 0xE3, 0x66, 0x1F, 0xC3, 0xEA, 0x6E, 0xFE, 0xAD, 0xEB, - 0xA5, 0x5A, 0x6C, 0xBE, 0xEF, 0xDD, 0x32, 0xC3, 0x28, 0xFF, 0x8C, 0x01, - 0xD1, 0x37, 0x7F, 0xB1, 0x3B, 0x95, 0x2F, 0xDB, 0x0F, 0xA5, 0xCE, 0xEE, - 0x02, 0x97, 0xAB, 0x68, 0x85, 0x21, 0x58, 0x65, 0x70, 0x61, 0x07, 0x29, - 0x28, 0xB6, 0x21, 0x15, 0x84, 0x2F, 0x6E, 0x5B, 0xAD, 0x7D, 0xEF, 0x2A, - 0x96, 0xBD, 0x61, 0xEB, 0x30, 0xA8, 0xCC, 0x13, 0x10, 0x15, 0x9F, 0x61, - 0x75, 0x47, 0xDD, 0xEC, 0x39, 0xA2, 0x70, 0x4C, 0x90, 0x5C, 0x73, 0xB5, - 0xCF, 0x63, 0x03, 0xAA, 0x1E, 0xFE, 0x34, 0x03, 0xA7, 0x2C, 0x62, 0x60, - 0xBC, 0x86, 0xCC, 0xEE, 0x14, 0xDE, 0xAA, 0xCB, 0x0B, 0x9E, 0x9E, 0xD5, - 0xCA, 0xF0, 0xBD, 0x19, 0xAF, 0x1E, 0x8B, 0x64, 0x6E, 0x84, 0xF3, 0xB2, - 0xAB, 0x5C, 0xAB, 0x9C, 0xB3, 0xB4, 0x2A, 0x3C, 0x32, 0x5A, 0x68, 0x40, - 0x50, 0xBB, 0x5A, 0x65, 0xB9, 0x69, 0x23, 0xA0, 0x99, 0xA0, 0x5F, 0x87, - 0x19, 0x0B, 0x54, 0x9B, 0xF7, 0xB8, 0x21, 0xC0, 0xD5, 0xE9, 0x9E, 0x31, - 0x77, 0x2D, 0xE3, 0x97, 0x9A, 0x88, 0x37, 0xF8, 0xA8, 0x7D, 0x3D, 0x62, - 0x7E, 0x99, 0xF7, 0x95, 0xD6, 0x1F, 0xE6, 0xC7, 0x29, 0x88, 0x35, 0x0E, - 0x81, 0x12, 0x68, 0x16, 0x5F, 0x93, 0xED, 0x11, 0x63, 0x72, 0x22, 0x1B, - 0xA5, 0x84, 0xF5, 0x57, 0x99, 0xBA, 0x58, 0x78, 0xA1, 0xDF, 0xDE, 0x96, - 0x54, 0x30, 0x2E, 0x53, 0xEB, 0x0A, 0xB3, 0xCD, 0x96, 0x46, 0xC2, 0x1A, - 0xFF, 0xC3, 0x83, 0x9B, 0xEA, 0xFF, 0xC6, 0x34, 0xEF, 0xF2, 0xEB, 0x58, - 0x28, 0x31, 0xBC, 0x6D, 0xE4, 0x48, 0xD9, 0x8F, 0xE3, 0xB7, 0x64, 0xE8, - 0xD9, 0x14, 0x4A, 0x5D, 0x73, 0x3C, 0x7C, 0xEE, 0x61, 0xED, 0x28, 0xFE, - 0xEA, 0xAB, 0xAA, 0xA3, 0xB6, 0xE2, 0xEE, 0x45, 0xE0, 0x13, 0x3E, 0x20, - 0x14, 0x5D, 0x10, 0x42, 0xB5, 0xBB, 0x6A, 0xEF, 0x42, 0xF4, 0x42, 0xC7, - 0xD0, 0x4F, 0xCB, 0xFA, 0x15, 0x4F, 0x6C, 0xDB, 0xC7, 0x4D, 0x85, 0x86, - 0x9E, 0x79, 0x1E, 0xD8, 0x05, 0x21, 0xCD, 0x41, 0x1D, 0x3B, 0x4F, 0x65, - 0x46, 0x26, 0x8D, 0x5B, 0xF2, 0xA1, 0x62, 0xCF, 0x50, 0x62, 0x81, 0x3D, - 0x6A, 0x47, 0x4B, 0xE4, 0x92, 0x74, 0xCB, 0x69, 0xC3, 0x24, 0x15, 0x7F, - 0xA3, 0xB6, 0xC7, 0xC1, 0xA0, 0x83, 0x88, 0xFC, 0x9D, 0x48, 0x19, 0xAD, - 0x00, 0xBF, 0x5B, 0x09, 0x85, 0xB2, 0x92, 0x56, 0x0B, 0x8A, 0x84, 0x47, - 0xEA, 0xF5, 0x55, 0x0C, 0x2A, 0x8D, 0x42, 0x58, 0x00, 0x0D, 0x82, 0x23, - 0x74, 0xB1, 0x62, 0x14, 0x41, 0x7E, 0x93, 0x8D, 0x92, 0xF0, 0x72, 0x33, - 0x61, 0x70, 0x3F, 0x23, 0x3E, 0xF4, 0xAD, 0x1D, 0x60, 0x74, 0xEE, 0xCB, - 0x59, 0x37, 0xDE, 0x7C, 0xDB, 0x3B, 0x22, 0x6C, 0xF1, 0xEC, 0x5F, 0xD6, - 0x9E, 0x50, 0xF8, 0x19, 0x84, 0x80, 0x07, 0xA6, 0x6E, 0x32, 0x77, 0xCE, - 0xA7, 0xF2, 0x85, 0x40, 0xC2, 0x06, 0x0C, 0xC5, 0xAA, 0xA7, 0x69, 0xA9, - 0x35, 0x97, 0xD9, 0x61, 0x55, 0xD8, 0xEF, 0xE8, 0x84, 0x34, 0x45, 0xC3, - 0x2E, 0x7A, 0x44, 0x9E, 0xDC, 0xCA, 0x0B, 0x80, 0xFC, 0xAB, 0x04, 0x5A, - 0xCD, 0x88, 0x55, 0x10, 0xD3, 0xDB, 0x73, 0xDB, 0xC9, 0x9E, 0x1E, 0x0E, - 0x05, 0x67, 0xD5, 0xFD, 0xD8, 0x38, 0x3E, 0x71, 0x65, 0x34, 0xC4, 0xC5, - 0x40, 0x43, 0x67, 0xE3, 0x79, 0xDA, 0x5F, 0x67, 0x4A, 0x3D, 0xB0, 0x8F, - 0xE7, 0x21, 0x3E, 0x15, 0x20, 0xFF, 0x6D, 0xF1, 0x9E, 0xF8, 0x28, 0x3D, - 0xF7, 0x40, 0x81, 0x94, 0x68, 0x5A, 0x3D, 0xE9, 0xF7, 0xAD, 0x83, 0xDB, - 0x2B, 0x9F, 0xE3, 0xE6, 0xF7, 0xD4, 0x02, 0x76, 0xF7, 0x20, 0x15, 0x41, - 0x34, 0x29, 0x69, 0x94, 0x1C, 0x26, 0x4C, 0xF6, 0x6A, 0xF4, 0x20, 0x33, - 0x71, 0x24, 0x08, 0xD4, 0x68, 0x00, 0xA1, 0xD4, 0x2E, 0x6B, 0xF4, 0xBC, - 0x46, 0x45, 0x24, 0x97, 0x2E, 0xF6, 0x39, 0x1E, 0xAF, 0x61, 0x00, 0x50, - 0xB7, 0xD4, 0xB7, 0x43, -}; - -} // namespace random_internal -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2017 The Abseil Authors. +// +// 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 +// +// https://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 "absl/random/internal/randen_traits.h" + +// This file contains only the round keys for randen. +// +// "Nothing up my sleeve" numbers from the first hex digits of Pi, obtained +// from http://hexpi.sourceforge.net/. The array was generated by following +// Python script: + +/* +python >tmp.cc << EOF +"""Generates Randen round keys array from pi-hex.62500.txt file.""" +import binascii + +KEYS = 17 * 8 + +def chunks(l, n): + """Yield successive n-sized chunks from l.""" + for i in range(0, len(l), n): + yield l[i:i + n] + +def pairwise(t): + """Transforms sequence into sequence of pairs.""" + it = iter(t) + return zip(it,it) + +def digits_from_pi(): + """Reads digits from hexpi.sourceforge.net file.""" + with open("pi-hex.62500.txt") as file: + return file.read() + +def digits_from_urandom(): + """Reads digits from /dev/urandom.""" + with open("/dev/urandom") as file: + return binascii.hexlify(file.read(KEYS * 16)) + +def print_row(b) + print(" 0x{0}, 0x{1}, 0x{2}, 0x{3}, 0x{4}, 0x{5}, 0x{6}, 0x{7}, 0x{8}, 0x{9}, +0x{10}, 0x{11}, 0x{12}, 0x{13}, 0x{14}, 0x{15},".format(*b)) + + +digits = digits_from_pi() +#digits = digits_from_urandom() + +print("namespace {") +print("static constexpr size_t kKeyBytes = {0};\n".format(KEYS * 16)) +print("}") + +print("alignas(16) const unsigned char kRandenRoundKeysBE[kKeyBytes] = {") + +for i, u16 in zip(range(KEYS), chunks(digits, 32)): + b = list(chunks(u16, 2)) + print_row(b) + +print("};") + +print("alignas(16) const unsigned char kRandenRoundKeys[kKeyBytes] = {") + +for i, u16 in zip(range(KEYS), chunks(digits, 32)): + b = list(chunks(u16, 2)) + b.reverse() + print_row(b) + +print("};") + +EOF + +*/ + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace random_internal { +namespace { +static constexpr size_t kKeyBytes = 2176; +} + +alignas(16) const unsigned char kRandenRoundKeysBE[kKeyBytes] = { + 0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, 0x13, 0x19, 0x8A, 0x2E, + 0x03, 0x70, 0x73, 0x44, 0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, + 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89, 0x45, 0x28, 0x21, 0xE6, + 0x38, 0xD0, 0x13, 0x77, 0xBE, 0x54, 0x66, 0xCF, 0x34, 0xE9, 0x0C, 0x6C, + 0xC0, 0xAC, 0x29, 0xB7, 0xC9, 0x7C, 0x50, 0xDD, 0x3F, 0x84, 0xD5, 0xB5, + 0xB5, 0x47, 0x09, 0x17, 0x92, 0x16, 0xD5, 0xD9, 0x89, 0x79, 0xFB, 0x1B, + 0xD1, 0x31, 0x0B, 0xA6, 0x98, 0xDF, 0xB5, 0xAC, 0x2F, 0xFD, 0x72, 0xDB, + 0xD0, 0x1A, 0xDF, 0xB7, 0xB8, 0xE1, 0xAF, 0xED, 0x6A, 0x26, 0x7E, 0x96, + 0xBA, 0x7C, 0x90, 0x45, 0xF1, 0x2C, 0x7F, 0x99, 0x24, 0xA1, 0x99, 0x47, + 0xB3, 0x91, 0x6C, 0xF7, 0x08, 0x01, 0xF2, 0xE2, 0x85, 0x8E, 0xFC, 0x16, + 0x63, 0x69, 0x20, 0xD8, 0x71, 0x57, 0x4E, 0x69, 0xA4, 0x58, 0xFE, 0xA3, + 0xF4, 0x93, 0x3D, 0x7E, 0x0D, 0x95, 0x74, 0x8F, 0x72, 0x8E, 0xB6, 0x58, + 0x71, 0x8B, 0xCD, 0x58, 0x82, 0x15, 0x4A, 0xEE, 0x7B, 0x54, 0xA4, 0x1D, + 0xC2, 0x5A, 0x59, 0xB5, 0x9C, 0x30, 0xD5, 0x39, 0x2A, 0xF2, 0x60, 0x13, + 0xC5, 0xD1, 0xB0, 0x23, 0x28, 0x60, 0x85, 0xF0, 0xCA, 0x41, 0x79, 0x18, + 0xB8, 0xDB, 0x38, 0xEF, 0x8E, 0x79, 0xDC, 0xB0, 0x60, 0x3A, 0x18, 0x0E, + 0x6C, 0x9E, 0x0E, 0x8B, 0xB0, 0x1E, 0x8A, 0x3E, 0xD7, 0x15, 0x77, 0xC1, + 0xBD, 0x31, 0x4B, 0x27, 0x78, 0xAF, 0x2F, 0xDA, 0x55, 0x60, 0x5C, 0x60, + 0xE6, 0x55, 0x25, 0xF3, 0xAA, 0x55, 0xAB, 0x94, 0x57, 0x48, 0x98, 0x62, + 0x63, 0xE8, 0x14, 0x40, 0x55, 0xCA, 0x39, 0x6A, 0x2A, 0xAB, 0x10, 0xB6, + 0xB4, 0xCC, 0x5C, 0x34, 0x11, 0x41, 0xE8, 0xCE, 0xA1, 0x54, 0x86, 0xAF, + 0x7C, 0x72, 0xE9, 0x93, 0xB3, 0xEE, 0x14, 0x11, 0x63, 0x6F, 0xBC, 0x2A, + 0x2B, 0xA9, 0xC5, 0x5D, 0x74, 0x18, 0x31, 0xF6, 0xCE, 0x5C, 0x3E, 0x16, + 0x9B, 0x87, 0x93, 0x1E, 0xAF, 0xD6, 0xBA, 0x33, 0x6C, 0x24, 0xCF, 0x5C, + 0x7A, 0x32, 0x53, 0x81, 0x28, 0x95, 0x86, 0x77, 0x3B, 0x8F, 0x48, 0x98, + 0x6B, 0x4B, 0xB9, 0xAF, 0xC4, 0xBF, 0xE8, 0x1B, 0x66, 0x28, 0x21, 0x93, + 0x61, 0xD8, 0x09, 0xCC, 0xFB, 0x21, 0xA9, 0x91, 0x48, 0x7C, 0xAC, 0x60, + 0x5D, 0xEC, 0x80, 0x32, 0xEF, 0x84, 0x5D, 0x5D, 0xE9, 0x85, 0x75, 0xB1, + 0xDC, 0x26, 0x23, 0x02, 0xEB, 0x65, 0x1B, 0x88, 0x23, 0x89, 0x3E, 0x81, + 0xD3, 0x96, 0xAC, 0xC5, 0x0F, 0x6D, 0x6F, 0xF3, 0x83, 0xF4, 0x42, 0x39, + 0x2E, 0x0B, 0x44, 0x82, 0xA4, 0x84, 0x20, 0x04, 0x69, 0xC8, 0xF0, 0x4A, + 0x9E, 0x1F, 0x9B, 0x5E, 0x21, 0xC6, 0x68, 0x42, 0xF6, 0xE9, 0x6C, 0x9A, + 0x67, 0x0C, 0x9C, 0x61, 0xAB, 0xD3, 0x88, 0xF0, 0x6A, 0x51, 0xA0, 0xD2, + 0xD8, 0x54, 0x2F, 0x68, 0x96, 0x0F, 0xA7, 0x28, 0xAB, 0x51, 0x33, 0xA3, + 0x6E, 0xEF, 0x0B, 0x6C, 0x13, 0x7A, 0x3B, 0xE4, 0xBA, 0x3B, 0xF0, 0x50, + 0x7E, 0xFB, 0x2A, 0x98, 0xA1, 0xF1, 0x65, 0x1D, 0x39, 0xAF, 0x01, 0x76, + 0x66, 0xCA, 0x59, 0x3E, 0x82, 0x43, 0x0E, 0x88, 0x8C, 0xEE, 0x86, 0x19, + 0x45, 0x6F, 0x9F, 0xB4, 0x7D, 0x84, 0xA5, 0xC3, 0x3B, 0x8B, 0x5E, 0xBE, + 0xE0, 0x6F, 0x75, 0xD8, 0x85, 0xC1, 0x20, 0x73, 0x40, 0x1A, 0x44, 0x9F, + 0x56, 0xC1, 0x6A, 0xA6, 0x4E, 0xD3, 0xAA, 0x62, 0x36, 0x3F, 0x77, 0x06, + 0x1B, 0xFE, 0xDF, 0x72, 0x42, 0x9B, 0x02, 0x3D, 0x37, 0xD0, 0xD7, 0x24, + 0xD0, 0x0A, 0x12, 0x48, 0xDB, 0x0F, 0xEA, 0xD3, 0x49, 0xF1, 0xC0, 0x9B, + 0x07, 0x53, 0x72, 0xC9, 0x80, 0x99, 0x1B, 0x7B, 0x25, 0xD4, 0x79, 0xD8, + 0xF6, 0xE8, 0xDE, 0xF7, 0xE3, 0xFE, 0x50, 0x1A, 0xB6, 0x79, 0x4C, 0x3B, + 0x97, 0x6C, 0xE0, 0xBD, 0x04, 0xC0, 0x06, 0xBA, 0xC1, 0xA9, 0x4F, 0xB6, + 0x40, 0x9F, 0x60, 0xC4, 0x5E, 0x5C, 0x9E, 0xC2, 0x19, 0x6A, 0x24, 0x63, + 0x68, 0xFB, 0x6F, 0xAF, 0x3E, 0x6C, 0x53, 0xB5, 0x13, 0x39, 0xB2, 0xEB, + 0x3B, 0x52, 0xEC, 0x6F, 0x6D, 0xFC, 0x51, 0x1F, 0x9B, 0x30, 0x95, 0x2C, + 0xCC, 0x81, 0x45, 0x44, 0xAF, 0x5E, 0xBD, 0x09, 0xBE, 0xE3, 0xD0, 0x04, + 0xDE, 0x33, 0x4A, 0xFD, 0x66, 0x0F, 0x28, 0x07, 0x19, 0x2E, 0x4B, 0xB3, + 0xC0, 0xCB, 0xA8, 0x57, 0x45, 0xC8, 0x74, 0x0F, 0xD2, 0x0B, 0x5F, 0x39, + 0xB9, 0xD3, 0xFB, 0xDB, 0x55, 0x79, 0xC0, 0xBD, 0x1A, 0x60, 0x32, 0x0A, + 0xD6, 0xA1, 0x00, 0xC6, 0x40, 0x2C, 0x72, 0x79, 0x67, 0x9F, 0x25, 0xFE, + 0xFB, 0x1F, 0xA3, 0xCC, 0x8E, 0xA5, 0xE9, 0xF8, 0xDB, 0x32, 0x22, 0xF8, + 0x3C, 0x75, 0x16, 0xDF, 0xFD, 0x61, 0x6B, 0x15, 0x2F, 0x50, 0x1E, 0xC8, + 0xAD, 0x05, 0x52, 0xAB, 0x32, 0x3D, 0xB5, 0xFA, 0xFD, 0x23, 0x87, 0x60, + 0x53, 0x31, 0x7B, 0x48, 0x3E, 0x00, 0xDF, 0x82, 0x9E, 0x5C, 0x57, 0xBB, + 0xCA, 0x6F, 0x8C, 0xA0, 0x1A, 0x87, 0x56, 0x2E, 0xDF, 0x17, 0x69, 0xDB, + 0xD5, 0x42, 0xA8, 0xF6, 0x28, 0x7E, 0xFF, 0xC3, 0xAC, 0x67, 0x32, 0xC6, + 0x8C, 0x4F, 0x55, 0x73, 0x69, 0x5B, 0x27, 0xB0, 0xBB, 0xCA, 0x58, 0xC8, + 0xE1, 0xFF, 0xA3, 0x5D, 0xB8, 0xF0, 0x11, 0xA0, 0x10, 0xFA, 0x3D, 0x98, + 0xFD, 0x21, 0x83, 0xB8, 0x4A, 0xFC, 0xB5, 0x6C, 0x2D, 0xD1, 0xD3, 0x5B, + 0x9A, 0x53, 0xE4, 0x79, 0xB6, 0xF8, 0x45, 0x65, 0xD2, 0x8E, 0x49, 0xBC, + 0x4B, 0xFB, 0x97, 0x90, 0xE1, 0xDD, 0xF2, 0xDA, 0xA4, 0xCB, 0x7E, 0x33, + 0x62, 0xFB, 0x13, 0x41, 0xCE, 0xE4, 0xC6, 0xE8, 0xEF, 0x20, 0xCA, 0xDA, + 0x36, 0x77, 0x4C, 0x01, 0xD0, 0x7E, 0x9E, 0xFE, 0x2B, 0xF1, 0x1F, 0xB4, + 0x95, 0xDB, 0xDA, 0x4D, 0xAE, 0x90, 0x91, 0x98, 0xEA, 0xAD, 0x8E, 0x71, + 0x6B, 0x93, 0xD5, 0xA0, 0xD0, 0x8E, 0xD1, 0xD0, 0xAF, 0xC7, 0x25, 0xE0, + 0x8E, 0x3C, 0x5B, 0x2F, 0x8E, 0x75, 0x94, 0xB7, 0x8F, 0xF6, 0xE2, 0xFB, + 0xF2, 0x12, 0x2B, 0x64, 0x88, 0x88, 0xB8, 0x12, 0x90, 0x0D, 0xF0, 0x1C, + 0x4F, 0xAD, 0x5E, 0xA0, 0x68, 0x8F, 0xC3, 0x1C, 0xD1, 0xCF, 0xF1, 0x91, + 0xB3, 0xA8, 0xC1, 0xAD, 0x2F, 0x2F, 0x22, 0x18, 0xBE, 0x0E, 0x17, 0x77, + 0xEA, 0x75, 0x2D, 0xFE, 0x8B, 0x02, 0x1F, 0xA1, 0xE5, 0xA0, 0xCC, 0x0F, + 0xB5, 0x6F, 0x74, 0xE8, 0x18, 0xAC, 0xF3, 0xD6, 0xCE, 0x89, 0xE2, 0x99, + 0xB4, 0xA8, 0x4F, 0xE0, 0xFD, 0x13, 0xE0, 0xB7, 0x7C, 0xC4, 0x3B, 0x81, + 0xD2, 0xAD, 0xA8, 0xD9, 0x16, 0x5F, 0xA2, 0x66, 0x80, 0x95, 0x77, 0x05, + 0x93, 0xCC, 0x73, 0x14, 0x21, 0x1A, 0x14, 0x77, 0xE6, 0xAD, 0x20, 0x65, + 0x77, 0xB5, 0xFA, 0x86, 0xC7, 0x54, 0x42, 0xF5, 0xFB, 0x9D, 0x35, 0xCF, + 0xEB, 0xCD, 0xAF, 0x0C, 0x7B, 0x3E, 0x89, 0xA0, 0xD6, 0x41, 0x1B, 0xD3, + 0xAE, 0x1E, 0x7E, 0x49, 0x00, 0x25, 0x0E, 0x2D, 0x20, 0x71, 0xB3, 0x5E, + 0x22, 0x68, 0x00, 0xBB, 0x57, 0xB8, 0xE0, 0xAF, 0x24, 0x64, 0x36, 0x9B, + 0xF0, 0x09, 0xB9, 0x1E, 0x55, 0x63, 0x91, 0x1D, 0x59, 0xDF, 0xA6, 0xAA, + 0x78, 0xC1, 0x43, 0x89, 0xD9, 0x5A, 0x53, 0x7F, 0x20, 0x7D, 0x5B, 0xA2, + 0x02, 0xE5, 0xB9, 0xC5, 0x83, 0x26, 0x03, 0x76, 0x62, 0x95, 0xCF, 0xA9, + 0x11, 0xC8, 0x19, 0x68, 0x4E, 0x73, 0x4A, 0x41, 0xB3, 0x47, 0x2D, 0xCA, + 0x7B, 0x14, 0xA9, 0x4A, 0x1B, 0x51, 0x00, 0x52, 0x9A, 0x53, 0x29, 0x15, + 0xD6, 0x0F, 0x57, 0x3F, 0xBC, 0x9B, 0xC6, 0xE4, 0x2B, 0x60, 0xA4, 0x76, + 0x81, 0xE6, 0x74, 0x00, 0x08, 0xBA, 0x6F, 0xB5, 0x57, 0x1B, 0xE9, 0x1F, + 0xF2, 0x96, 0xEC, 0x6B, 0x2A, 0x0D, 0xD9, 0x15, 0xB6, 0x63, 0x65, 0x21, + 0xE7, 0xB9, 0xF9, 0xB6, 0xFF, 0x34, 0x05, 0x2E, 0xC5, 0x85, 0x56, 0x64, + 0x53, 0xB0, 0x2D, 0x5D, 0xA9, 0x9F, 0x8F, 0xA1, 0x08, 0xBA, 0x47, 0x99, + 0x6E, 0x85, 0x07, 0x6A, 0x4B, 0x7A, 0x70, 0xE9, 0xB5, 0xB3, 0x29, 0x44, + 0xDB, 0x75, 0x09, 0x2E, 0xC4, 0x19, 0x26, 0x23, 0xAD, 0x6E, 0xA6, 0xB0, + 0x49, 0xA7, 0xDF, 0x7D, 0x9C, 0xEE, 0x60, 0xB8, 0x8F, 0xED, 0xB2, 0x66, + 0xEC, 0xAA, 0x8C, 0x71, 0x69, 0x9A, 0x18, 0xFF, 0x56, 0x64, 0x52, 0x6C, + 0xC2, 0xB1, 0x9E, 0xE1, 0x19, 0x36, 0x02, 0xA5, 0x75, 0x09, 0x4C, 0x29, + 0xA0, 0x59, 0x13, 0x40, 0xE4, 0x18, 0x3A, 0x3E, 0x3F, 0x54, 0x98, 0x9A, + 0x5B, 0x42, 0x9D, 0x65, 0x6B, 0x8F, 0xE4, 0xD6, 0x99, 0xF7, 0x3F, 0xD6, + 0xA1, 0xD2, 0x9C, 0x07, 0xEF, 0xE8, 0x30, 0xF5, 0x4D, 0x2D, 0x38, 0xE6, + 0xF0, 0x25, 0x5D, 0xC1, 0x4C, 0xDD, 0x20, 0x86, 0x84, 0x70, 0xEB, 0x26, + 0x63, 0x82, 0xE9, 0xC6, 0x02, 0x1E, 0xCC, 0x5E, 0x09, 0x68, 0x6B, 0x3F, + 0x3E, 0xBA, 0xEF, 0xC9, 0x3C, 0x97, 0x18, 0x14, 0x6B, 0x6A, 0x70, 0xA1, + 0x68, 0x7F, 0x35, 0x84, 0x52, 0xA0, 0xE2, 0x86, 0xB7, 0x9C, 0x53, 0x05, + 0xAA, 0x50, 0x07, 0x37, 0x3E, 0x07, 0x84, 0x1C, 0x7F, 0xDE, 0xAE, 0x5C, + 0x8E, 0x7D, 0x44, 0xEC, 0x57, 0x16, 0xF2, 0xB8, 0xB0, 0x3A, 0xDA, 0x37, + 0xF0, 0x50, 0x0C, 0x0D, 0xF0, 0x1C, 0x1F, 0x04, 0x02, 0x00, 0xB3, 0xFF, + 0xAE, 0x0C, 0xF5, 0x1A, 0x3C, 0xB5, 0x74, 0xB2, 0x25, 0x83, 0x7A, 0x58, + 0xDC, 0x09, 0x21, 0xBD, 0xD1, 0x91, 0x13, 0xF9, 0x7C, 0xA9, 0x2F, 0xF6, + 0x94, 0x32, 0x47, 0x73, 0x22, 0xF5, 0x47, 0x01, 0x3A, 0xE5, 0xE5, 0x81, + 0x37, 0xC2, 0xDA, 0xDC, 0xC8, 0xB5, 0x76, 0x34, 0x9A, 0xF3, 0xDD, 0xA7, + 0xA9, 0x44, 0x61, 0x46, 0x0F, 0xD0, 0x03, 0x0E, 0xEC, 0xC8, 0xC7, 0x3E, + 0xA4, 0x75, 0x1E, 0x41, 0xE2, 0x38, 0xCD, 0x99, 0x3B, 0xEA, 0x0E, 0x2F, + 0x32, 0x80, 0xBB, 0xA1, 0x18, 0x3E, 0xB3, 0x31, 0x4E, 0x54, 0x8B, 0x38, + 0x4F, 0x6D, 0xB9, 0x08, 0x6F, 0x42, 0x0D, 0x03, 0xF6, 0x0A, 0x04, 0xBF, + 0x2C, 0xB8, 0x12, 0x90, 0x24, 0x97, 0x7C, 0x79, 0x56, 0x79, 0xB0, 0x72, + 0xBC, 0xAF, 0x89, 0xAF, 0xDE, 0x9A, 0x77, 0x1F, 0xD9, 0x93, 0x08, 0x10, + 0xB3, 0x8B, 0xAE, 0x12, 0xDC, 0xCF, 0x3F, 0x2E, 0x55, 0x12, 0x72, 0x1F, + 0x2E, 0x6B, 0x71, 0x24, 0x50, 0x1A, 0xDD, 0xE6, 0x9F, 0x84, 0xCD, 0x87, + 0x7A, 0x58, 0x47, 0x18, 0x74, 0x08, 0xDA, 0x17, 0xBC, 0x9F, 0x9A, 0xBC, + 0xE9, 0x4B, 0x7D, 0x8C, 0xEC, 0x7A, 0xEC, 0x3A, 0xDB, 0x85, 0x1D, 0xFA, + 0x63, 0x09, 0x43, 0x66, 0xC4, 0x64, 0xC3, 0xD2, 0xEF, 0x1C, 0x18, 0x47, + 0x32, 0x15, 0xD8, 0x08, 0xDD, 0x43, 0x3B, 0x37, 0x24, 0xC2, 0xBA, 0x16, + 0x12, 0xA1, 0x4D, 0x43, 0x2A, 0x65, 0xC4, 0x51, 0x50, 0x94, 0x00, 0x02, + 0x13, 0x3A, 0xE4, 0xDD, 0x71, 0xDF, 0xF8, 0x9E, 0x10, 0x31, 0x4E, 0x55, + 0x81, 0xAC, 0x77, 0xD6, 0x5F, 0x11, 0x19, 0x9B, 0x04, 0x35, 0x56, 0xF1, + 0xD7, 0xA3, 0xC7, 0x6B, 0x3C, 0x11, 0x18, 0x3B, 0x59, 0x24, 0xA5, 0x09, + 0xF2, 0x8F, 0xE6, 0xED, 0x97, 0xF1, 0xFB, 0xFA, 0x9E, 0xBA, 0xBF, 0x2C, + 0x1E, 0x15, 0x3C, 0x6E, 0x86, 0xE3, 0x45, 0x70, 0xEA, 0xE9, 0x6F, 0xB1, + 0x86, 0x0E, 0x5E, 0x0A, 0x5A, 0x3E, 0x2A, 0xB3, 0x77, 0x1F, 0xE7, 0x1C, + 0x4E, 0x3D, 0x06, 0xFA, 0x29, 0x65, 0xDC, 0xB9, 0x99, 0xE7, 0x1D, 0x0F, + 0x80, 0x3E, 0x89, 0xD6, 0x52, 0x66, 0xC8, 0x25, 0x2E, 0x4C, 0xC9, 0x78, + 0x9C, 0x10, 0xB3, 0x6A, 0xC6, 0x15, 0x0E, 0xBA, 0x94, 0xE2, 0xEA, 0x78, + 0xA6, 0xFC, 0x3C, 0x53, 0x1E, 0x0A, 0x2D, 0xF4, 0xF2, 0xF7, 0x4E, 0xA7, + 0x36, 0x1D, 0x2B, 0x3D, 0x19, 0x39, 0x26, 0x0F, 0x19, 0xC2, 0x79, 0x60, + 0x52, 0x23, 0xA7, 0x08, 0xF7, 0x13, 0x12, 0xB6, 0xEB, 0xAD, 0xFE, 0x6E, + 0xEA, 0xC3, 0x1F, 0x66, 0xE3, 0xBC, 0x45, 0x95, 0xA6, 0x7B, 0xC8, 0x83, + 0xB1, 0x7F, 0x37, 0xD1, 0x01, 0x8C, 0xFF, 0x28, 0xC3, 0x32, 0xDD, 0xEF, + 0xBE, 0x6C, 0x5A, 0xA5, 0x65, 0x58, 0x21, 0x85, 0x68, 0xAB, 0x97, 0x02, + 0xEE, 0xCE, 0xA5, 0x0F, 0xDB, 0x2F, 0x95, 0x3B, 0x2A, 0xEF, 0x7D, 0xAD, + 0x5B, 0x6E, 0x2F, 0x84, 0x15, 0x21, 0xB6, 0x28, 0x29, 0x07, 0x61, 0x70, + 0xEC, 0xDD, 0x47, 0x75, 0x61, 0x9F, 0x15, 0x10, 0x13, 0xCC, 0xA8, 0x30, + 0xEB, 0x61, 0xBD, 0x96, 0x03, 0x34, 0xFE, 0x1E, 0xAA, 0x03, 0x63, 0xCF, + 0xB5, 0x73, 0x5C, 0x90, 0x4C, 0x70, 0xA2, 0x39, 0xD5, 0x9E, 0x9E, 0x0B, + 0xCB, 0xAA, 0xDE, 0x14, 0xEE, 0xCC, 0x86, 0xBC, 0x60, 0x62, 0x2C, 0xA7, + 0x9C, 0xAB, 0x5C, 0xAB, 0xB2, 0xF3, 0x84, 0x6E, 0x64, 0x8B, 0x1E, 0xAF, + 0x19, 0xBD, 0xF0, 0xCA, 0xA0, 0x23, 0x69, 0xB9, 0x65, 0x5A, 0xBB, 0x50, + 0x40, 0x68, 0x5A, 0x32, 0x3C, 0x2A, 0xB4, 0xB3, 0x31, 0x9E, 0xE9, 0xD5, + 0xC0, 0x21, 0xB8, 0xF7, 0x9B, 0x54, 0x0B, 0x19, 0x87, 0x5F, 0xA0, 0x99, + 0x95, 0xF7, 0x99, 0x7E, 0x62, 0x3D, 0x7D, 0xA8, 0xF8, 0x37, 0x88, 0x9A, + 0x97, 0xE3, 0x2D, 0x77, 0x11, 0xED, 0x93, 0x5F, 0x16, 0x68, 0x12, 0x81, + 0x0E, 0x35, 0x88, 0x29, 0xC7, 0xE6, 0x1F, 0xD6, 0x96, 0xDE, 0xDF, 0xA1, + 0x78, 0x58, 0xBA, 0x99, 0x57, 0xF5, 0x84, 0xA5, 0x1B, 0x22, 0x72, 0x63, + 0x9B, 0x83, 0xC3, 0xFF, 0x1A, 0xC2, 0x46, 0x96, 0xCD, 0xB3, 0x0A, 0xEB, + 0x53, 0x2E, 0x30, 0x54, 0x8F, 0xD9, 0x48, 0xE4, 0x6D, 0xBC, 0x31, 0x28, + 0x58, 0xEB, 0xF2, 0xEF, 0x34, 0xC6, 0xFF, 0xEA, 0xFE, 0x28, 0xED, 0x61, + 0xEE, 0x7C, 0x3C, 0x73, 0x5D, 0x4A, 0x14, 0xD9, 0xE8, 0x64, 0xB7, 0xE3, + 0x42, 0x10, 0x5D, 0x14, 0x20, 0x3E, 0x13, 0xE0, 0x45, 0xEE, 0xE2, 0xB6, + 0xA3, 0xAA, 0xAB, 0xEA, 0xDB, 0x6C, 0x4F, 0x15, 0xFA, 0xCB, 0x4F, 0xD0, + 0xC7, 0x42, 0xF4, 0x42, 0xEF, 0x6A, 0xBB, 0xB5, 0x65, 0x4F, 0x3B, 0x1D, + 0x41, 0xCD, 0x21, 0x05, 0xD8, 0x1E, 0x79, 0x9E, 0x86, 0x85, 0x4D, 0xC7, + 0xE4, 0x4B, 0x47, 0x6A, 0x3D, 0x81, 0x62, 0x50, 0xCF, 0x62, 0xA1, 0xF2, + 0x5B, 0x8D, 0x26, 0x46, 0xFC, 0x88, 0x83, 0xA0, 0xC1, 0xC7, 0xB6, 0xA3, + 0x7F, 0x15, 0x24, 0xC3, 0x69, 0xCB, 0x74, 0x92, 0x47, 0x84, 0x8A, 0x0B, + 0x56, 0x92, 0xB2, 0x85, 0x09, 0x5B, 0xBF, 0x00, 0xAD, 0x19, 0x48, 0x9D, + 0x14, 0x62, 0xB1, 0x74, 0x23, 0x82, 0x0D, 0x00, 0x58, 0x42, 0x8D, 0x2A, + 0x0C, 0x55, 0xF5, 0xEA, 0x1D, 0xAD, 0xF4, 0x3E, 0x23, 0x3F, 0x70, 0x61, + 0x33, 0x72, 0xF0, 0x92, 0x8D, 0x93, 0x7E, 0x41, 0xD6, 0x5F, 0xEC, 0xF1, + 0x6C, 0x22, 0x3B, 0xDB, 0x7C, 0xDE, 0x37, 0x59, 0xCB, 0xEE, 0x74, 0x60, + 0x40, 0x85, 0xF2, 0xA7, 0xCE, 0x77, 0x32, 0x6E, 0xA6, 0x07, 0x80, 0x84, + 0x19, 0xF8, 0x50, 0x9E, 0xE8, 0xEF, 0xD8, 0x55, 0x61, 0xD9, 0x97, 0x35, + 0xA9, 0x69, 0xA7, 0xAA, 0xC5, 0x0C, 0x06, 0xC2, 0x5A, 0x04, 0xAB, 0xFC, + 0x80, 0x0B, 0xCA, 0xDC, 0x9E, 0x44, 0x7A, 0x2E, 0xC3, 0x45, 0x34, 0x84, + 0xFD, 0xD5, 0x67, 0x05, 0x0E, 0x1E, 0x9E, 0xC9, 0xDB, 0x73, 0xDB, 0xD3, + 0x10, 0x55, 0x88, 0xCD, 0x67, 0x5F, 0xDA, 0x79, 0xE3, 0x67, 0x43, 0x40, + 0xC5, 0xC4, 0x34, 0x65, 0x71, 0x3E, 0x38, 0xD8, 0x3D, 0x28, 0xF8, 0x9E, + 0xF1, 0x6D, 0xFF, 0x20, 0x15, 0x3E, 0x21, 0xE7, 0x8F, 0xB0, 0x3D, 0x4A, + 0xE6, 0xE3, 0x9F, 0x2B, 0xDB, 0x83, 0xAD, 0xF7, 0xE9, 0x3D, 0x5A, 0x68, + 0x94, 0x81, 0x40, 0xF7, 0xF6, 0x4C, 0x26, 0x1C, 0x94, 0x69, 0x29, 0x34, + 0x41, 0x15, 0x20, 0xF7, 0x76, 0x02, 0xD4, 0xF7, 0xBC, 0xF4, 0x6B, 0x2E, + 0xD4, 0xA1, 0x00, 0x68, 0xD4, 0x08, 0x24, 0x71, 0x33, 0x20, 0xF4, 0x6A, + 0x43, 0xB7, 0xD4, 0xB7, 0x50, 0x00, 0x61, 0xAF, 0x1E, 0x39, 0xF6, 0x2E, + 0x97, 0x24, 0x45, 0x46, +}; + +alignas(16) const unsigned char kRandenRoundKeys[kKeyBytes] = { + 0x44, 0x73, 0x70, 0x03, 0x2E, 0x8A, 0x19, 0x13, 0xD3, 0x08, 0xA3, 0x85, + 0x88, 0x6A, 0x3F, 0x24, 0x89, 0x6C, 0x4E, 0xEC, 0x98, 0xFA, 0x2E, 0x08, + 0xD0, 0x31, 0x9F, 0x29, 0x22, 0x38, 0x09, 0xA4, 0x6C, 0x0C, 0xE9, 0x34, + 0xCF, 0x66, 0x54, 0xBE, 0x77, 0x13, 0xD0, 0x38, 0xE6, 0x21, 0x28, 0x45, + 0x17, 0x09, 0x47, 0xB5, 0xB5, 0xD5, 0x84, 0x3F, 0xDD, 0x50, 0x7C, 0xC9, + 0xB7, 0x29, 0xAC, 0xC0, 0xAC, 0xB5, 0xDF, 0x98, 0xA6, 0x0B, 0x31, 0xD1, + 0x1B, 0xFB, 0x79, 0x89, 0xD9, 0xD5, 0x16, 0x92, 0x96, 0x7E, 0x26, 0x6A, + 0xED, 0xAF, 0xE1, 0xB8, 0xB7, 0xDF, 0x1A, 0xD0, 0xDB, 0x72, 0xFD, 0x2F, + 0xF7, 0x6C, 0x91, 0xB3, 0x47, 0x99, 0xA1, 0x24, 0x99, 0x7F, 0x2C, 0xF1, + 0x45, 0x90, 0x7C, 0xBA, 0x69, 0x4E, 0x57, 0x71, 0xD8, 0x20, 0x69, 0x63, + 0x16, 0xFC, 0x8E, 0x85, 0xE2, 0xF2, 0x01, 0x08, 0x58, 0xB6, 0x8E, 0x72, + 0x8F, 0x74, 0x95, 0x0D, 0x7E, 0x3D, 0x93, 0xF4, 0xA3, 0xFE, 0x58, 0xA4, + 0xB5, 0x59, 0x5A, 0xC2, 0x1D, 0xA4, 0x54, 0x7B, 0xEE, 0x4A, 0x15, 0x82, + 0x58, 0xCD, 0x8B, 0x71, 0xF0, 0x85, 0x60, 0x28, 0x23, 0xB0, 0xD1, 0xC5, + 0x13, 0x60, 0xF2, 0x2A, 0x39, 0xD5, 0x30, 0x9C, 0x0E, 0x18, 0x3A, 0x60, + 0xB0, 0xDC, 0x79, 0x8E, 0xEF, 0x38, 0xDB, 0xB8, 0x18, 0x79, 0x41, 0xCA, + 0x27, 0x4B, 0x31, 0xBD, 0xC1, 0x77, 0x15, 0xD7, 0x3E, 0x8A, 0x1E, 0xB0, + 0x8B, 0x0E, 0x9E, 0x6C, 0x94, 0xAB, 0x55, 0xAA, 0xF3, 0x25, 0x55, 0xE6, + 0x60, 0x5C, 0x60, 0x55, 0xDA, 0x2F, 0xAF, 0x78, 0xB6, 0x10, 0xAB, 0x2A, + 0x6A, 0x39, 0xCA, 0x55, 0x40, 0x14, 0xE8, 0x63, 0x62, 0x98, 0x48, 0x57, + 0x93, 0xE9, 0x72, 0x7C, 0xAF, 0x86, 0x54, 0xA1, 0xCE, 0xE8, 0x41, 0x11, + 0x34, 0x5C, 0xCC, 0xB4, 0xF6, 0x31, 0x18, 0x74, 0x5D, 0xC5, 0xA9, 0x2B, + 0x2A, 0xBC, 0x6F, 0x63, 0x11, 0x14, 0xEE, 0xB3, 0x5C, 0xCF, 0x24, 0x6C, + 0x33, 0xBA, 0xD6, 0xAF, 0x1E, 0x93, 0x87, 0x9B, 0x16, 0x3E, 0x5C, 0xCE, + 0xAF, 0xB9, 0x4B, 0x6B, 0x98, 0x48, 0x8F, 0x3B, 0x77, 0x86, 0x95, 0x28, + 0x81, 0x53, 0x32, 0x7A, 0x91, 0xA9, 0x21, 0xFB, 0xCC, 0x09, 0xD8, 0x61, + 0x93, 0x21, 0x28, 0x66, 0x1B, 0xE8, 0xBF, 0xC4, 0xB1, 0x75, 0x85, 0xE9, + 0x5D, 0x5D, 0x84, 0xEF, 0x32, 0x80, 0xEC, 0x5D, 0x60, 0xAC, 0x7C, 0x48, + 0xC5, 0xAC, 0x96, 0xD3, 0x81, 0x3E, 0x89, 0x23, 0x88, 0x1B, 0x65, 0xEB, + 0x02, 0x23, 0x26, 0xDC, 0x04, 0x20, 0x84, 0xA4, 0x82, 0x44, 0x0B, 0x2E, + 0x39, 0x42, 0xF4, 0x83, 0xF3, 0x6F, 0x6D, 0x0F, 0x9A, 0x6C, 0xE9, 0xF6, + 0x42, 0x68, 0xC6, 0x21, 0x5E, 0x9B, 0x1F, 0x9E, 0x4A, 0xF0, 0xC8, 0x69, + 0x68, 0x2F, 0x54, 0xD8, 0xD2, 0xA0, 0x51, 0x6A, 0xF0, 0x88, 0xD3, 0xAB, + 0x61, 0x9C, 0x0C, 0x67, 0xE4, 0x3B, 0x7A, 0x13, 0x6C, 0x0B, 0xEF, 0x6E, + 0xA3, 0x33, 0x51, 0xAB, 0x28, 0xA7, 0x0F, 0x96, 0x76, 0x01, 0xAF, 0x39, + 0x1D, 0x65, 0xF1, 0xA1, 0x98, 0x2A, 0xFB, 0x7E, 0x50, 0xF0, 0x3B, 0xBA, + 0xB4, 0x9F, 0x6F, 0x45, 0x19, 0x86, 0xEE, 0x8C, 0x88, 0x0E, 0x43, 0x82, + 0x3E, 0x59, 0xCA, 0x66, 0x73, 0x20, 0xC1, 0x85, 0xD8, 0x75, 0x6F, 0xE0, + 0xBE, 0x5E, 0x8B, 0x3B, 0xC3, 0xA5, 0x84, 0x7D, 0x06, 0x77, 0x3F, 0x36, + 0x62, 0xAA, 0xD3, 0x4E, 0xA6, 0x6A, 0xC1, 0x56, 0x9F, 0x44, 0x1A, 0x40, + 0x48, 0x12, 0x0A, 0xD0, 0x24, 0xD7, 0xD0, 0x37, 0x3D, 0x02, 0x9B, 0x42, + 0x72, 0xDF, 0xFE, 0x1B, 0x7B, 0x1B, 0x99, 0x80, 0xC9, 0x72, 0x53, 0x07, + 0x9B, 0xC0, 0xF1, 0x49, 0xD3, 0xEA, 0x0F, 0xDB, 0x3B, 0x4C, 0x79, 0xB6, + 0x1A, 0x50, 0xFE, 0xE3, 0xF7, 0xDE, 0xE8, 0xF6, 0xD8, 0x79, 0xD4, 0x25, + 0xC4, 0x60, 0x9F, 0x40, 0xB6, 0x4F, 0xA9, 0xC1, 0xBA, 0x06, 0xC0, 0x04, + 0xBD, 0xE0, 0x6C, 0x97, 0xB5, 0x53, 0x6C, 0x3E, 0xAF, 0x6F, 0xFB, 0x68, + 0x63, 0x24, 0x6A, 0x19, 0xC2, 0x9E, 0x5C, 0x5E, 0x2C, 0x95, 0x30, 0x9B, + 0x1F, 0x51, 0xFC, 0x6D, 0x6F, 0xEC, 0x52, 0x3B, 0xEB, 0xB2, 0x39, 0x13, + 0xFD, 0x4A, 0x33, 0xDE, 0x04, 0xD0, 0xE3, 0xBE, 0x09, 0xBD, 0x5E, 0xAF, + 0x44, 0x45, 0x81, 0xCC, 0x0F, 0x74, 0xC8, 0x45, 0x57, 0xA8, 0xCB, 0xC0, + 0xB3, 0x4B, 0x2E, 0x19, 0x07, 0x28, 0x0F, 0x66, 0x0A, 0x32, 0x60, 0x1A, + 0xBD, 0xC0, 0x79, 0x55, 0xDB, 0xFB, 0xD3, 0xB9, 0x39, 0x5F, 0x0B, 0xD2, + 0xCC, 0xA3, 0x1F, 0xFB, 0xFE, 0x25, 0x9F, 0x67, 0x79, 0x72, 0x2C, 0x40, + 0xC6, 0x00, 0xA1, 0xD6, 0x15, 0x6B, 0x61, 0xFD, 0xDF, 0x16, 0x75, 0x3C, + 0xF8, 0x22, 0x32, 0xDB, 0xF8, 0xE9, 0xA5, 0x8E, 0x60, 0x87, 0x23, 0xFD, + 0xFA, 0xB5, 0x3D, 0x32, 0xAB, 0x52, 0x05, 0xAD, 0xC8, 0x1E, 0x50, 0x2F, + 0xA0, 0x8C, 0x6F, 0xCA, 0xBB, 0x57, 0x5C, 0x9E, 0x82, 0xDF, 0x00, 0x3E, + 0x48, 0x7B, 0x31, 0x53, 0xC3, 0xFF, 0x7E, 0x28, 0xF6, 0xA8, 0x42, 0xD5, + 0xDB, 0x69, 0x17, 0xDF, 0x2E, 0x56, 0x87, 0x1A, 0xC8, 0x58, 0xCA, 0xBB, + 0xB0, 0x27, 0x5B, 0x69, 0x73, 0x55, 0x4F, 0x8C, 0xC6, 0x32, 0x67, 0xAC, + 0xB8, 0x83, 0x21, 0xFD, 0x98, 0x3D, 0xFA, 0x10, 0xA0, 0x11, 0xF0, 0xB8, + 0x5D, 0xA3, 0xFF, 0xE1, 0x65, 0x45, 0xF8, 0xB6, 0x79, 0xE4, 0x53, 0x9A, + 0x5B, 0xD3, 0xD1, 0x2D, 0x6C, 0xB5, 0xFC, 0x4A, 0x33, 0x7E, 0xCB, 0xA4, + 0xDA, 0xF2, 0xDD, 0xE1, 0x90, 0x97, 0xFB, 0x4B, 0xBC, 0x49, 0x8E, 0xD2, + 0x01, 0x4C, 0x77, 0x36, 0xDA, 0xCA, 0x20, 0xEF, 0xE8, 0xC6, 0xE4, 0xCE, + 0x41, 0x13, 0xFB, 0x62, 0x98, 0x91, 0x90, 0xAE, 0x4D, 0xDA, 0xDB, 0x95, + 0xB4, 0x1F, 0xF1, 0x2B, 0xFE, 0x9E, 0x7E, 0xD0, 0xE0, 0x25, 0xC7, 0xAF, + 0xD0, 0xD1, 0x8E, 0xD0, 0xA0, 0xD5, 0x93, 0x6B, 0x71, 0x8E, 0xAD, 0xEA, + 0x64, 0x2B, 0x12, 0xF2, 0xFB, 0xE2, 0xF6, 0x8F, 0xB7, 0x94, 0x75, 0x8E, + 0x2F, 0x5B, 0x3C, 0x8E, 0x1C, 0xC3, 0x8F, 0x68, 0xA0, 0x5E, 0xAD, 0x4F, + 0x1C, 0xF0, 0x0D, 0x90, 0x12, 0xB8, 0x88, 0x88, 0x77, 0x17, 0x0E, 0xBE, + 0x18, 0x22, 0x2F, 0x2F, 0xAD, 0xC1, 0xA8, 0xB3, 0x91, 0xF1, 0xCF, 0xD1, + 0xE8, 0x74, 0x6F, 0xB5, 0x0F, 0xCC, 0xA0, 0xE5, 0xA1, 0x1F, 0x02, 0x8B, + 0xFE, 0x2D, 0x75, 0xEA, 0xB7, 0xE0, 0x13, 0xFD, 0xE0, 0x4F, 0xA8, 0xB4, + 0x99, 0xE2, 0x89, 0xCE, 0xD6, 0xF3, 0xAC, 0x18, 0x05, 0x77, 0x95, 0x80, + 0x66, 0xA2, 0x5F, 0x16, 0xD9, 0xA8, 0xAD, 0xD2, 0x81, 0x3B, 0xC4, 0x7C, + 0x86, 0xFA, 0xB5, 0x77, 0x65, 0x20, 0xAD, 0xE6, 0x77, 0x14, 0x1A, 0x21, + 0x14, 0x73, 0xCC, 0x93, 0xA0, 0x89, 0x3E, 0x7B, 0x0C, 0xAF, 0xCD, 0xEB, + 0xCF, 0x35, 0x9D, 0xFB, 0xF5, 0x42, 0x54, 0xC7, 0x5E, 0xB3, 0x71, 0x20, + 0x2D, 0x0E, 0x25, 0x00, 0x49, 0x7E, 0x1E, 0xAE, 0xD3, 0x1B, 0x41, 0xD6, + 0x1E, 0xB9, 0x09, 0xF0, 0x9B, 0x36, 0x64, 0x24, 0xAF, 0xE0, 0xB8, 0x57, + 0xBB, 0x00, 0x68, 0x22, 0x7F, 0x53, 0x5A, 0xD9, 0x89, 0x43, 0xC1, 0x78, + 0xAA, 0xA6, 0xDF, 0x59, 0x1D, 0x91, 0x63, 0x55, 0xA9, 0xCF, 0x95, 0x62, + 0x76, 0x03, 0x26, 0x83, 0xC5, 0xB9, 0xE5, 0x02, 0xA2, 0x5B, 0x7D, 0x20, + 0x4A, 0xA9, 0x14, 0x7B, 0xCA, 0x2D, 0x47, 0xB3, 0x41, 0x4A, 0x73, 0x4E, + 0x68, 0x19, 0xC8, 0x11, 0xE4, 0xC6, 0x9B, 0xBC, 0x3F, 0x57, 0x0F, 0xD6, + 0x15, 0x29, 0x53, 0x9A, 0x52, 0x00, 0x51, 0x1B, 0x1F, 0xE9, 0x1B, 0x57, + 0xB5, 0x6F, 0xBA, 0x08, 0x00, 0x74, 0xE6, 0x81, 0x76, 0xA4, 0x60, 0x2B, + 0xB6, 0xF9, 0xB9, 0xE7, 0x21, 0x65, 0x63, 0xB6, 0x15, 0xD9, 0x0D, 0x2A, + 0x6B, 0xEC, 0x96, 0xF2, 0xA1, 0x8F, 0x9F, 0xA9, 0x5D, 0x2D, 0xB0, 0x53, + 0x64, 0x56, 0x85, 0xC5, 0x2E, 0x05, 0x34, 0xFF, 0x44, 0x29, 0xB3, 0xB5, + 0xE9, 0x70, 0x7A, 0x4B, 0x6A, 0x07, 0x85, 0x6E, 0x99, 0x47, 0xBA, 0x08, + 0x7D, 0xDF, 0xA7, 0x49, 0xB0, 0xA6, 0x6E, 0xAD, 0x23, 0x26, 0x19, 0xC4, + 0x2E, 0x09, 0x75, 0xDB, 0xFF, 0x18, 0x9A, 0x69, 0x71, 0x8C, 0xAA, 0xEC, + 0x66, 0xB2, 0xED, 0x8F, 0xB8, 0x60, 0xEE, 0x9C, 0x29, 0x4C, 0x09, 0x75, + 0xA5, 0x02, 0x36, 0x19, 0xE1, 0x9E, 0xB1, 0xC2, 0x6C, 0x52, 0x64, 0x56, + 0x65, 0x9D, 0x42, 0x5B, 0x9A, 0x98, 0x54, 0x3F, 0x3E, 0x3A, 0x18, 0xE4, + 0x40, 0x13, 0x59, 0xA0, 0xF5, 0x30, 0xE8, 0xEF, 0x07, 0x9C, 0xD2, 0xA1, + 0xD6, 0x3F, 0xF7, 0x99, 0xD6, 0xE4, 0x8F, 0x6B, 0x26, 0xEB, 0x70, 0x84, + 0x86, 0x20, 0xDD, 0x4C, 0xC1, 0x5D, 0x25, 0xF0, 0xE6, 0x38, 0x2D, 0x4D, + 0xC9, 0xEF, 0xBA, 0x3E, 0x3F, 0x6B, 0x68, 0x09, 0x5E, 0xCC, 0x1E, 0x02, + 0xC6, 0xE9, 0x82, 0x63, 0x86, 0xE2, 0xA0, 0x52, 0x84, 0x35, 0x7F, 0x68, + 0xA1, 0x70, 0x6A, 0x6B, 0x14, 0x18, 0x97, 0x3C, 0x5C, 0xAE, 0xDE, 0x7F, + 0x1C, 0x84, 0x07, 0x3E, 0x37, 0x07, 0x50, 0xAA, 0x05, 0x53, 0x9C, 0xB7, + 0x0D, 0x0C, 0x50, 0xF0, 0x37, 0xDA, 0x3A, 0xB0, 0xB8, 0xF2, 0x16, 0x57, + 0xEC, 0x44, 0x7D, 0x8E, 0xB2, 0x74, 0xB5, 0x3C, 0x1A, 0xF5, 0x0C, 0xAE, + 0xFF, 0xB3, 0x00, 0x02, 0x04, 0x1F, 0x1C, 0xF0, 0xF6, 0x2F, 0xA9, 0x7C, + 0xF9, 0x13, 0x91, 0xD1, 0xBD, 0x21, 0x09, 0xDC, 0x58, 0x7A, 0x83, 0x25, + 0xDC, 0xDA, 0xC2, 0x37, 0x81, 0xE5, 0xE5, 0x3A, 0x01, 0x47, 0xF5, 0x22, + 0x73, 0x47, 0x32, 0x94, 0x0E, 0x03, 0xD0, 0x0F, 0x46, 0x61, 0x44, 0xA9, + 0xA7, 0xDD, 0xF3, 0x9A, 0x34, 0x76, 0xB5, 0xC8, 0x2F, 0x0E, 0xEA, 0x3B, + 0x99, 0xCD, 0x38, 0xE2, 0x41, 0x1E, 0x75, 0xA4, 0x3E, 0xC7, 0xC8, 0xEC, + 0x08, 0xB9, 0x6D, 0x4F, 0x38, 0x8B, 0x54, 0x4E, 0x31, 0xB3, 0x3E, 0x18, + 0xA1, 0xBB, 0x80, 0x32, 0x79, 0x7C, 0x97, 0x24, 0x90, 0x12, 0xB8, 0x2C, + 0xBF, 0x04, 0x0A, 0xF6, 0x03, 0x0D, 0x42, 0x6F, 0x10, 0x08, 0x93, 0xD9, + 0x1F, 0x77, 0x9A, 0xDE, 0xAF, 0x89, 0xAF, 0xBC, 0x72, 0xB0, 0x79, 0x56, + 0x24, 0x71, 0x6B, 0x2E, 0x1F, 0x72, 0x12, 0x55, 0x2E, 0x3F, 0xCF, 0xDC, + 0x12, 0xAE, 0x8B, 0xB3, 0x17, 0xDA, 0x08, 0x74, 0x18, 0x47, 0x58, 0x7A, + 0x87, 0xCD, 0x84, 0x9F, 0xE6, 0xDD, 0x1A, 0x50, 0xFA, 0x1D, 0x85, 0xDB, + 0x3A, 0xEC, 0x7A, 0xEC, 0x8C, 0x7D, 0x4B, 0xE9, 0xBC, 0x9A, 0x9F, 0xBC, + 0x08, 0xD8, 0x15, 0x32, 0x47, 0x18, 0x1C, 0xEF, 0xD2, 0xC3, 0x64, 0xC4, + 0x66, 0x43, 0x09, 0x63, 0x51, 0xC4, 0x65, 0x2A, 0x43, 0x4D, 0xA1, 0x12, + 0x16, 0xBA, 0xC2, 0x24, 0x37, 0x3B, 0x43, 0xDD, 0x55, 0x4E, 0x31, 0x10, + 0x9E, 0xF8, 0xDF, 0x71, 0xDD, 0xE4, 0x3A, 0x13, 0x02, 0x00, 0x94, 0x50, + 0x6B, 0xC7, 0xA3, 0xD7, 0xF1, 0x56, 0x35, 0x04, 0x9B, 0x19, 0x11, 0x5F, + 0xD6, 0x77, 0xAC, 0x81, 0xFA, 0xFB, 0xF1, 0x97, 0xED, 0xE6, 0x8F, 0xF2, + 0x09, 0xA5, 0x24, 0x59, 0x3B, 0x18, 0x11, 0x3C, 0xB1, 0x6F, 0xE9, 0xEA, + 0x70, 0x45, 0xE3, 0x86, 0x6E, 0x3C, 0x15, 0x1E, 0x2C, 0xBF, 0xBA, 0x9E, + 0xFA, 0x06, 0x3D, 0x4E, 0x1C, 0xE7, 0x1F, 0x77, 0xB3, 0x2A, 0x3E, 0x5A, + 0x0A, 0x5E, 0x0E, 0x86, 0x25, 0xC8, 0x66, 0x52, 0xD6, 0x89, 0x3E, 0x80, + 0x0F, 0x1D, 0xE7, 0x99, 0xB9, 0xDC, 0x65, 0x29, 0x78, 0xEA, 0xE2, 0x94, + 0xBA, 0x0E, 0x15, 0xC6, 0x6A, 0xB3, 0x10, 0x9C, 0x78, 0xC9, 0x4C, 0x2E, + 0x3D, 0x2B, 0x1D, 0x36, 0xA7, 0x4E, 0xF7, 0xF2, 0xF4, 0x2D, 0x0A, 0x1E, + 0x53, 0x3C, 0xFC, 0xA6, 0xB6, 0x12, 0x13, 0xF7, 0x08, 0xA7, 0x23, 0x52, + 0x60, 0x79, 0xC2, 0x19, 0x0F, 0x26, 0x39, 0x19, 0x83, 0xC8, 0x7B, 0xA6, + 0x95, 0x45, 0xBC, 0xE3, 0x66, 0x1F, 0xC3, 0xEA, 0x6E, 0xFE, 0xAD, 0xEB, + 0xA5, 0x5A, 0x6C, 0xBE, 0xEF, 0xDD, 0x32, 0xC3, 0x28, 0xFF, 0x8C, 0x01, + 0xD1, 0x37, 0x7F, 0xB1, 0x3B, 0x95, 0x2F, 0xDB, 0x0F, 0xA5, 0xCE, 0xEE, + 0x02, 0x97, 0xAB, 0x68, 0x85, 0x21, 0x58, 0x65, 0x70, 0x61, 0x07, 0x29, + 0x28, 0xB6, 0x21, 0x15, 0x84, 0x2F, 0x6E, 0x5B, 0xAD, 0x7D, 0xEF, 0x2A, + 0x96, 0xBD, 0x61, 0xEB, 0x30, 0xA8, 0xCC, 0x13, 0x10, 0x15, 0x9F, 0x61, + 0x75, 0x47, 0xDD, 0xEC, 0x39, 0xA2, 0x70, 0x4C, 0x90, 0x5C, 0x73, 0xB5, + 0xCF, 0x63, 0x03, 0xAA, 0x1E, 0xFE, 0x34, 0x03, 0xA7, 0x2C, 0x62, 0x60, + 0xBC, 0x86, 0xCC, 0xEE, 0x14, 0xDE, 0xAA, 0xCB, 0x0B, 0x9E, 0x9E, 0xD5, + 0xCA, 0xF0, 0xBD, 0x19, 0xAF, 0x1E, 0x8B, 0x64, 0x6E, 0x84, 0xF3, 0xB2, + 0xAB, 0x5C, 0xAB, 0x9C, 0xB3, 0xB4, 0x2A, 0x3C, 0x32, 0x5A, 0x68, 0x40, + 0x50, 0xBB, 0x5A, 0x65, 0xB9, 0x69, 0x23, 0xA0, 0x99, 0xA0, 0x5F, 0x87, + 0x19, 0x0B, 0x54, 0x9B, 0xF7, 0xB8, 0x21, 0xC0, 0xD5, 0xE9, 0x9E, 0x31, + 0x77, 0x2D, 0xE3, 0x97, 0x9A, 0x88, 0x37, 0xF8, 0xA8, 0x7D, 0x3D, 0x62, + 0x7E, 0x99, 0xF7, 0x95, 0xD6, 0x1F, 0xE6, 0xC7, 0x29, 0x88, 0x35, 0x0E, + 0x81, 0x12, 0x68, 0x16, 0x5F, 0x93, 0xED, 0x11, 0x63, 0x72, 0x22, 0x1B, + 0xA5, 0x84, 0xF5, 0x57, 0x99, 0xBA, 0x58, 0x78, 0xA1, 0xDF, 0xDE, 0x96, + 0x54, 0x30, 0x2E, 0x53, 0xEB, 0x0A, 0xB3, 0xCD, 0x96, 0x46, 0xC2, 0x1A, + 0xFF, 0xC3, 0x83, 0x9B, 0xEA, 0xFF, 0xC6, 0x34, 0xEF, 0xF2, 0xEB, 0x58, + 0x28, 0x31, 0xBC, 0x6D, 0xE4, 0x48, 0xD9, 0x8F, 0xE3, 0xB7, 0x64, 0xE8, + 0xD9, 0x14, 0x4A, 0x5D, 0x73, 0x3C, 0x7C, 0xEE, 0x61, 0xED, 0x28, 0xFE, + 0xEA, 0xAB, 0xAA, 0xA3, 0xB6, 0xE2, 0xEE, 0x45, 0xE0, 0x13, 0x3E, 0x20, + 0x14, 0x5D, 0x10, 0x42, 0xB5, 0xBB, 0x6A, 0xEF, 0x42, 0xF4, 0x42, 0xC7, + 0xD0, 0x4F, 0xCB, 0xFA, 0x15, 0x4F, 0x6C, 0xDB, 0xC7, 0x4D, 0x85, 0x86, + 0x9E, 0x79, 0x1E, 0xD8, 0x05, 0x21, 0xCD, 0x41, 0x1D, 0x3B, 0x4F, 0x65, + 0x46, 0x26, 0x8D, 0x5B, 0xF2, 0xA1, 0x62, 0xCF, 0x50, 0x62, 0x81, 0x3D, + 0x6A, 0x47, 0x4B, 0xE4, 0x92, 0x74, 0xCB, 0x69, 0xC3, 0x24, 0x15, 0x7F, + 0xA3, 0xB6, 0xC7, 0xC1, 0xA0, 0x83, 0x88, 0xFC, 0x9D, 0x48, 0x19, 0xAD, + 0x00, 0xBF, 0x5B, 0x09, 0x85, 0xB2, 0x92, 0x56, 0x0B, 0x8A, 0x84, 0x47, + 0xEA, 0xF5, 0x55, 0x0C, 0x2A, 0x8D, 0x42, 0x58, 0x00, 0x0D, 0x82, 0x23, + 0x74, 0xB1, 0x62, 0x14, 0x41, 0x7E, 0x93, 0x8D, 0x92, 0xF0, 0x72, 0x33, + 0x61, 0x70, 0x3F, 0x23, 0x3E, 0xF4, 0xAD, 0x1D, 0x60, 0x74, 0xEE, 0xCB, + 0x59, 0x37, 0xDE, 0x7C, 0xDB, 0x3B, 0x22, 0x6C, 0xF1, 0xEC, 0x5F, 0xD6, + 0x9E, 0x50, 0xF8, 0x19, 0x84, 0x80, 0x07, 0xA6, 0x6E, 0x32, 0x77, 0xCE, + 0xA7, 0xF2, 0x85, 0x40, 0xC2, 0x06, 0x0C, 0xC5, 0xAA, 0xA7, 0x69, 0xA9, + 0x35, 0x97, 0xD9, 0x61, 0x55, 0xD8, 0xEF, 0xE8, 0x84, 0x34, 0x45, 0xC3, + 0x2E, 0x7A, 0x44, 0x9E, 0xDC, 0xCA, 0x0B, 0x80, 0xFC, 0xAB, 0x04, 0x5A, + 0xCD, 0x88, 0x55, 0x10, 0xD3, 0xDB, 0x73, 0xDB, 0xC9, 0x9E, 0x1E, 0x0E, + 0x05, 0x67, 0xD5, 0xFD, 0xD8, 0x38, 0x3E, 0x71, 0x65, 0x34, 0xC4, 0xC5, + 0x40, 0x43, 0x67, 0xE3, 0x79, 0xDA, 0x5F, 0x67, 0x4A, 0x3D, 0xB0, 0x8F, + 0xE7, 0x21, 0x3E, 0x15, 0x20, 0xFF, 0x6D, 0xF1, 0x9E, 0xF8, 0x28, 0x3D, + 0xF7, 0x40, 0x81, 0x94, 0x68, 0x5A, 0x3D, 0xE9, 0xF7, 0xAD, 0x83, 0xDB, + 0x2B, 0x9F, 0xE3, 0xE6, 0xF7, 0xD4, 0x02, 0x76, 0xF7, 0x20, 0x15, 0x41, + 0x34, 0x29, 0x69, 0x94, 0x1C, 0x26, 0x4C, 0xF6, 0x6A, 0xF4, 0x20, 0x33, + 0x71, 0x24, 0x08, 0xD4, 0x68, 0x00, 0xA1, 0xD4, 0x2E, 0x6B, 0xF4, 0xBC, + 0x46, 0x45, 0x24, 0x97, 0x2E, 0xF6, 0x39, 0x1E, 0xAF, 0x61, 0x00, 0x50, + 0xB7, 0xD4, 0xB7, 0x43, +}; + +} // namespace random_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys/ya.make index 36eb10009e..a231749d39 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys/ya.make @@ -1,29 +1,29 @@ -# Generated by devtools/yamaker. - -LIBRARY() - +# Generated by devtools/yamaker. + +LIBRARY() + WITHOUT_LICENSE_TEXTS() -OWNER(g:cpp-contrib) - -LICENSE(Apache-2.0) - -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DNOMINMAX -) - -SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal) - -SRCS( - randen_round_keys.cc -) - -END() +OWNER(g:cpp-contrib) + +LICENSE(Apache-2.0) + +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DNOMINMAX +) + +SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal) + +SRCS( + randen_round_keys.cc +) + +END() diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc index 9bfd2a4092..ec035a210c 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc @@ -18,11 +18,11 @@ #include <cstdint> #include <cstring> -#include "absl/base/attributes.h" +#include "absl/base/attributes.h" #include "absl/base/internal/endian.h" #include "absl/numeric/int128.h" #include "absl/random/internal/platform.h" -#include "absl/random/internal/randen_traits.h" +#include "absl/random/internal/randen_traits.h" #if ABSL_HAVE_ATTRIBUTE(always_inline) || \ (defined(__GNUC__) && !defined(__clang__)) @@ -231,19 +231,19 @@ constexpr uint32_t te3[256] = { // Software implementation of the Vector128 class, using uint32_t // as an underlying vector register. -struct alignas(16) Vector128 { +struct alignas(16) Vector128 { uint32_t s[4]; }; inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 -Vector128Load(const void* from) { +Vector128Load(const void* from) { Vector128 result; std::memcpy(result.s, from, sizeof(Vector128)); return result; } inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Vector128Store( - const Vector128& v, void* to) { + const Vector128& v, void* to) { std::memcpy(to, v.s, sizeof(Vector128)); } @@ -253,22 +253,22 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 AesRound(const Vector128& state, const Vector128& round_key) { Vector128 result; #ifdef ABSL_IS_LITTLE_ENDIAN - result.s[0] = round_key.s[0] ^ // + result.s[0] = round_key.s[0] ^ // te0[uint8_t(state.s[0])] ^ // te1[uint8_t(state.s[1] >> 8)] ^ // te2[uint8_t(state.s[2] >> 16)] ^ // te3[uint8_t(state.s[3] >> 24)]; - result.s[1] = round_key.s[1] ^ // + result.s[1] = round_key.s[1] ^ // te0[uint8_t(state.s[1])] ^ // te1[uint8_t(state.s[2] >> 8)] ^ // te2[uint8_t(state.s[3] >> 16)] ^ // te3[uint8_t(state.s[0] >> 24)]; - result.s[2] = round_key.s[2] ^ // + result.s[2] = round_key.s[2] ^ // te0[uint8_t(state.s[2])] ^ // te1[uint8_t(state.s[3] >> 8)] ^ // te2[uint8_t(state.s[0] >> 16)] ^ // te3[uint8_t(state.s[1] >> 24)]; - result.s[3] = round_key.s[3] ^ // + result.s[3] = round_key.s[3] ^ // te0[uint8_t(state.s[3])] ^ // te1[uint8_t(state.s[0] >> 8)] ^ // te2[uint8_t(state.s[1] >> 16)] ^ // @@ -298,28 +298,28 @@ AesRound(const Vector128& state, const Vector128& round_key) { return result; } -using ::absl::random_internal::RandenTraits; +using ::absl::random_internal::RandenTraits; // The improved Feistel block shuffle function for 16 blocks. inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle( absl::uint128* state) { - static_assert(RandenTraits::kFeistelBlocks == 16, + static_assert(RandenTraits::kFeistelBlocks == 16, "Feistel block shuffle only works for 16 blocks."); - constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = { - 7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12}; + constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = { + 7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12}; // The fully unrolled loop without the memcpy improves the speed by about - // 30% over the equivalent: -#if 0 + // 30% over the equivalent: +#if 0 absl::uint128 source[RandenTraits::kFeistelBlocks]; - std::memcpy(source, state, sizeof(source)); - for (size_t i = 0; i < RandenTraits::kFeistelBlocks; i++) { + std::memcpy(source, state, sizeof(source)); + for (size_t i = 0; i < RandenTraits::kFeistelBlocks; i++) { const absl::uint128 v0 = source[shuffle[i]]; - state[i] = v0; + state[i] = v0; } - return; -#endif + return; +#endif const absl::uint128 v0 = state[shuffle[0]]; const absl::uint128 v1 = state[shuffle[1]]; @@ -363,21 +363,21 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle( inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE const absl::uint128* FeistelRound(absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT state, const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) { - for (size_t branch = 0; branch < RandenTraits::kFeistelBlocks; branch += 4) { - const Vector128 s0 = Vector128Load(state + branch); - const Vector128 s1 = Vector128Load(state + branch + 1); + for (size_t branch = 0; branch < RandenTraits::kFeistelBlocks; branch += 4) { + const Vector128 s0 = Vector128Load(state + branch); + const Vector128 s1 = Vector128Load(state + branch + 1); const Vector128 f0 = AesRound(s0, Vector128Load(keys)); keys++; const Vector128 o1 = AesRound(f0, s1); - Vector128Store(o1, state + branch + 1); + Vector128Store(o1, state + branch + 1); // Manually unroll this loop once. about 10% better than not unrolled. - const Vector128 s2 = Vector128Load(state + branch + 2); - const Vector128 s3 = Vector128Load(state + branch + 3); + const Vector128 s2 = Vector128Load(state + branch + 2); + const Vector128 s3 = Vector128Load(state + branch + 3); const Vector128 f2 = AesRound(s2, Vector128Load(keys)); keys++; const Vector128 o3 = AesRound(f2, s3); - Vector128Store(o3, state + branch + 3); + Vector128Store(o3, state + branch + 3); } return keys; } @@ -389,8 +389,8 @@ FeistelRound(absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT state, inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Permute( absl::uint128* state, const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) { - for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) { - keys = FeistelRound(state, keys); + for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) { + keys = FeistelRound(state, keys); BlockShuffle(state); } } @@ -415,41 +415,41 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void SwapEndian( } // namespace namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { const void* RandenSlow::GetKeys() { // Round keys for one AES per Feistel round and branch. // The canonical implementation uses first digits of Pi. #ifdef ABSL_IS_LITTLE_ENDIAN - return kRandenRoundKeys; + return kRandenRoundKeys; #else return kRandenRoundKeysBE; #endif } void RandenSlow::Absorb(const void* seed_void, void* state_void) { - auto* state = - reinterpret_cast<uint64_t * ABSL_RANDOM_INTERNAL_RESTRICT>(state_void); - const auto* seed = - reinterpret_cast<const uint64_t * ABSL_RANDOM_INTERNAL_RESTRICT>( - seed_void); - - constexpr size_t kCapacityBlocks = - RandenTraits::kCapacityBytes / sizeof(uint64_t); - static_assert( - kCapacityBlocks * sizeof(uint64_t) == RandenTraits::kCapacityBytes, - "Not i*V"); - - for (size_t i = kCapacityBlocks; - i < RandenTraits::kStateBytes / sizeof(uint64_t); ++i) { + auto* state = + reinterpret_cast<uint64_t * ABSL_RANDOM_INTERNAL_RESTRICT>(state_void); + const auto* seed = + reinterpret_cast<const uint64_t * ABSL_RANDOM_INTERNAL_RESTRICT>( + seed_void); + + constexpr size_t kCapacityBlocks = + RandenTraits::kCapacityBytes / sizeof(uint64_t); + static_assert( + kCapacityBlocks * sizeof(uint64_t) == RandenTraits::kCapacityBytes, + "Not i*V"); + + for (size_t i = kCapacityBlocks; + i < RandenTraits::kStateBytes / sizeof(uint64_t); ++i) { state[i] ^= seed[i - kCapacityBlocks]; } } -void RandenSlow::Generate(const void* keys_void, void* state_void) { +void RandenSlow::Generate(const void* keys_void, void* state_void) { static_assert(RandenTraits::kCapacityBytes == sizeof(absl::uint128), - "Capacity mismatch"); + "Capacity mismatch"); auto* state = reinterpret_cast<absl::uint128*>(state_void); const auto* keys = reinterpret_cast<const absl::uint128*>(keys_void); @@ -458,7 +458,7 @@ void RandenSlow::Generate(const void* keys_void, void* state_void) { SwapEndian(state); - Permute(state, keys); + Permute(state, keys); SwapEndian(state); @@ -467,5 +467,5 @@ void RandenSlow::Generate(const void* keys_void, void* state_void) { } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.h index 532c3a8991..768e961ccc 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.h @@ -17,10 +17,10 @@ #include <cstddef> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // RANDen = RANDom generator or beetroots in Swiss High German. @@ -34,7 +34,7 @@ class RandenSlow { }; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow/ya.make index af124ae798..5d3c5aa4a2 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow/ya.make @@ -8,10 +8,10 @@ OWNER(g:cpp-contrib) LICENSE(Apache-2.0) -PEERDIR( - contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys -) - +PEERDIR( + contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys +) + ADDINCL( GLOBAL contrib/restricted/abseil-cpp ) @@ -20,10 +20,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_traits.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen_traits.h index 120022c9fb..3cd6593cc0 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_traits.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_traits.h @@ -22,35 +22,35 @@ #include <cstddef> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // RANDen = RANDom generator or beetroots in Swiss High German. // 'Strong' (well-distributed, unpredictable, backtracking-resistant) random // generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32. // -// High-level summary: -// 1) Reverie (see "A Robust and Sponge-Like PRNG with Improved Efficiency") is -// a sponge-like random generator that requires a cryptographic permutation. -// It improves upon "Provably Robust Sponge-Based PRNGs and KDFs" by -// achieving backtracking resistance with only one Permute() per buffer. -// -// 2) "Simpira v2: A Family of Efficient Permutations Using the AES Round -// Function" constructs up to 1024-bit permutations using an improved -// Generalized Feistel network with 2-round AES-128 functions. This Feistel -// block shuffle achieves diffusion faster and is less vulnerable to -// sliced-biclique attacks than the Type-2 cyclic shuffle. -// -// 3) "Improving the Generalized Feistel" and "New criterion for diffusion -// property" extends the same kind of improved Feistel block shuffle to 16 -// branches, which enables a 2048-bit permutation. -// -// Combine these three ideas and also change Simpira's subround keys from -// structured/low-entropy counters to digits of Pi (or other random source). - +// High-level summary: +// 1) Reverie (see "A Robust and Sponge-Like PRNG with Improved Efficiency") is +// a sponge-like random generator that requires a cryptographic permutation. +// It improves upon "Provably Robust Sponge-Based PRNGs and KDFs" by +// achieving backtracking resistance with only one Permute() per buffer. +// +// 2) "Simpira v2: A Family of Efficient Permutations Using the AES Round +// Function" constructs up to 1024-bit permutations using an improved +// Generalized Feistel network with 2-round AES-128 functions. This Feistel +// block shuffle achieves diffusion faster and is less vulnerable to +// sliced-biclique attacks than the Type-2 cyclic shuffle. +// +// 3) "Improving the Generalized Feistel" and "New criterion for diffusion +// property" extends the same kind of improved Feistel block shuffle to 16 +// branches, which enables a 2048-bit permutation. +// +// Combine these three ideas and also change Simpira's subround keys from +// structured/low-entropy counters to digits of Pi (or other random source). + // RandenTraits contains the basic algorithm traits, such as the size of the // state, seed, sponge, etc. struct RandenTraits { @@ -64,25 +64,25 @@ struct RandenTraits { // Size of the default seed consumed by the sponge. static constexpr size_t kSeedBytes = kStateBytes - kCapacityBytes; - // Assuming 128-bit blocks, the number of blocks in the state. + // Assuming 128-bit blocks, the number of blocks in the state. // Largest size for which security proofs are known. static constexpr size_t kFeistelBlocks = 16; // Ensures SPRP security and two full subblock diffusions. // Must be > 4 * log2(kFeistelBlocks). static constexpr size_t kFeistelRounds = 16 + 1; - - // Size of the key. A 128-bit key block is used for every-other - // feistel block (Type-2 generalized Feistel network) in each round. - static constexpr size_t kKeyBytes = 16 * kFeistelRounds * kFeistelBlocks / 2; + + // Size of the key. A 128-bit key block is used for every-other + // feistel block (Type-2 generalized Feistel network) in each round. + static constexpr size_t kKeyBytes = 16 * kFeistelRounds * kFeistelBlocks / 2; }; -// Randen key arrays. In randen_round_keys.cc -extern const unsigned char kRandenRoundKeys[RandenTraits::kKeyBytes]; -extern const unsigned char kRandenRoundKeysBE[RandenTraits::kKeyBytes]; - +// Randen key arrays. In randen_round_keys.cc +extern const unsigned char kRandenRoundKeys[RandenTraits::kKeyBytes]; +extern const unsigned char kRandenRoundKeysBE[RandenTraits::kKeyBytes]; + } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/salted_seed_seq.h b/contrib/restricted/abseil-cpp/absl/random/internal/salted_seed_seq.h index 5953a090f8..0cafe0e937 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/salted_seed_seq.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/salted_seed_seq.h @@ -30,7 +30,7 @@ #include "absl/types/span.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // This class conforms to the C++ Standard "Seed Sequence" concept @@ -161,7 +161,7 @@ SaltedSeedSeq<typename std::decay<SSeq>::type> MakeSaltedSeedSeq(SSeq&& seq) { } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc index c03cad8502..d89072c774 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc +++ b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc @@ -46,9 +46,9 @@ #define ABSL_RANDOM_USE_BCRYPT 1 #pragma comment(lib, "bcrypt.lib") -#elif defined(__Fuchsia__) -#include <zircon/syscalls.h> - +#elif defined(__Fuchsia__) +#include <zircon/syscalls.h> + #endif #if defined(__GLIBC__) && \ @@ -74,7 +74,7 @@ #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { namespace { @@ -124,15 +124,15 @@ bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) { return true; } -#elif defined(__Fuchsia__) - -bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) { - auto buffer = reinterpret_cast<uint8_t*>(values.data()); - size_t buffer_size = sizeof(uint32_t) * values.size(); - zx_cprng_draw(buffer, buffer_size); - return true; -} - +#elif defined(__Fuchsia__) + +bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) { + auto buffer = reinterpret_cast<uint8_t*>(values.data()); + size_t buffer_size = sizeof(uint32_t) * values.size(); + zx_cprng_draw(buffer, buffer_size); + return true; +} + #else #if defined(ABSL_RANDOM_USE_GET_ENTROPY) @@ -263,5 +263,5 @@ absl::optional<uint32_t> GetSaltMaterial() { } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.h b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.h index 4be10e9256..c8a2cc7106 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.h @@ -27,7 +27,7 @@ #include "absl/types/span.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // Returns the number of 32-bit blocks needed to contain the given number of @@ -98,7 +98,7 @@ void MixIntoSeedMaterial(absl::Span<const uint32_t> sequence, absl::optional<uint32_t> GetSaltMaterial(); } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make index 65618b087d..2090a8101c 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make @@ -28,10 +28,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/sequence_urbg.h b/contrib/restricted/abseil-cpp/absl/random/internal/sequence_urbg.h index bc96a12cd2..92ae380b12 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/sequence_urbg.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/sequence_urbg.h @@ -21,10 +21,10 @@ #include <type_traits> #include <vector> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // `sequence_urbg` is a simple random number generator which meets the @@ -54,7 +54,7 @@ class sequence_urbg { }; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_SEQUENCE_URBG_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/traits.h b/contrib/restricted/abseil-cpp/absl/random/internal/traits.h index 75772bd9ab..920ba18f04 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/traits.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/traits.h @@ -22,7 +22,7 @@ #include "absl/base/config.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // random_internal::is_widening_convertible<A, B> @@ -95,7 +95,7 @@ struct make_unsigned_bits { }; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_TRAITS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h b/contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h index 1243bc1c62..f4e7eeaca4 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h @@ -19,13 +19,13 @@ #include <limits> #include <type_traits> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/meta/type_traits.h" -#include "absl/random/internal/traits.h" +#include "absl/random/internal/traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN - +ABSL_NAMESPACE_BEGIN + template <typename IntType> class uniform_int_distribution; @@ -61,26 +61,26 @@ struct IntervalOpenOpenTag : public random_internal::TagTypeCompare<IntervalOpenOpenTag> {}; namespace random_internal { - -// In the absence of an explicitly provided return-type, the template -// "uniform_inferred_return_t<A, B>" is used to derive a suitable type, based on -// the data-types of the endpoint-arguments {A lo, B hi}. -// -// Given endpoints {A lo, B hi}, one of {A, B} will be chosen as the -// return-type, if one type can be implicitly converted into the other, in a -// lossless way. The template "is_widening_convertible" implements the -// compile-time logic for deciding if such a conversion is possible. -// -// If no such conversion between {A, B} exists, then the overload for -// absl::Uniform() will be discarded, and the call will be ill-formed. -// Return-type for absl::Uniform() when the return-type is inferred. -template <typename A, typename B> -using uniform_inferred_return_t = - absl::enable_if_t<absl::disjunction<is_widening_convertible<A, B>, - is_widening_convertible<B, A>>::value, - typename std::conditional< - is_widening_convertible<A, B>::value, B, A>::type>; - + +// In the absence of an explicitly provided return-type, the template +// "uniform_inferred_return_t<A, B>" is used to derive a suitable type, based on +// the data-types of the endpoint-arguments {A lo, B hi}. +// +// Given endpoints {A lo, B hi}, one of {A, B} will be chosen as the +// return-type, if one type can be implicitly converted into the other, in a +// lossless way. The template "is_widening_convertible" implements the +// compile-time logic for deciding if such a conversion is possible. +// +// If no such conversion between {A, B} exists, then the overload for +// absl::Uniform() will be discarded, and the call will be ill-formed. +// Return-type for absl::Uniform() when the return-type is inferred. +template <typename A, typename B> +using uniform_inferred_return_t = + absl::enable_if_t<absl::disjunction<is_widening_convertible<A, B>, + is_widening_convertible<B, A>>::value, + typename std::conditional< + is_widening_convertible<A, B>::value, B, A>::type>; + // The functions // uniform_lower_bound(tag, a, b) // and @@ -105,7 +105,7 @@ typename absl::enable_if_t< std::is_same<Tag, IntervalOpenOpenTag>>>::value, IntType> uniform_lower_bound(Tag, IntType a, IntType) { - return a < (std::numeric_limits<IntType>::max)() ? (a + 1) : a; + return a < (std::numeric_limits<IntType>::max)() ? (a + 1) : a; } template <typename FloatType, typename Tag> @@ -136,7 +136,7 @@ typename absl::enable_if_t< std::is_same<Tag, IntervalOpenOpenTag>>>::value, IntType> uniform_upper_bound(Tag, IntType, IntType b) { - return b > (std::numeric_limits<IntType>::min)() ? (b - 1) : b; + return b > (std::numeric_limits<IntType>::min)() ? (b - 1) : b; } template <typename FloatType, typename Tag> @@ -172,53 +172,53 @@ uniform_upper_bound(Tag, FloatType, FloatType b) { return std::nextafter(b, (std::numeric_limits<FloatType>::max)()); } -// Returns whether the bounds are valid for the underlying distribution. -// Inputs must have already been resolved via uniform_*_bound calls. -// -// The c++ standard constraints in [rand.dist.uni.int] are listed as: -// requires: lo <= hi. -// -// In the uniform_int_distrubtion, {lo, hi} are closed, closed. Thus: -// [0, 0] is legal. -// [0, 0) is not legal, but [0, 1) is, which translates to [0, 0]. -// (0, 1) is not legal, but (0, 2) is, which translates to [1, 1]. -// (0, 0] is not legal, but (0, 1] is, which translates to [1, 1]. -// -// The c++ standard constraints in [rand.dist.uni.real] are listed as: -// requires: lo <= hi. -// requires: (hi - lo) <= numeric_limits<T>::max() -// -// In the uniform_real_distribution, {lo, hi} are closed, open, Thus: -// [0, 0] is legal, which is [0, 0+epsilon). -// [0, 0) is legal. -// (0, 0) is not legal, but (0-epsilon, 0+epsilon) is. -// (0, 0] is not legal, but (0, 0+epsilon] is. -// -template <typename FloatType> -absl::enable_if_t<std::is_floating_point<FloatType>::value, bool> -is_uniform_range_valid(FloatType a, FloatType b) { - return a <= b && std::isfinite(b - a); -} - -template <typename IntType> -absl::enable_if_t<std::is_integral<IntType>::value, bool> -is_uniform_range_valid(IntType a, IntType b) { - return a <= b; -} - -// UniformDistribution selects either absl::uniform_int_distribution -// or absl::uniform_real_distribution depending on the NumType parameter. +// Returns whether the bounds are valid for the underlying distribution. +// Inputs must have already been resolved via uniform_*_bound calls. +// +// The c++ standard constraints in [rand.dist.uni.int] are listed as: +// requires: lo <= hi. +// +// In the uniform_int_distrubtion, {lo, hi} are closed, closed. Thus: +// [0, 0] is legal. +// [0, 0) is not legal, but [0, 1) is, which translates to [0, 0]. +// (0, 1) is not legal, but (0, 2) is, which translates to [1, 1]. +// (0, 0] is not legal, but (0, 1] is, which translates to [1, 1]. +// +// The c++ standard constraints in [rand.dist.uni.real] are listed as: +// requires: lo <= hi. +// requires: (hi - lo) <= numeric_limits<T>::max() +// +// In the uniform_real_distribution, {lo, hi} are closed, open, Thus: +// [0, 0] is legal, which is [0, 0+epsilon). +// [0, 0) is legal. +// (0, 0) is not legal, but (0-epsilon, 0+epsilon) is. +// (0, 0] is not legal, but (0, 0+epsilon] is. +// +template <typename FloatType> +absl::enable_if_t<std::is_floating_point<FloatType>::value, bool> +is_uniform_range_valid(FloatType a, FloatType b) { + return a <= b && std::isfinite(b - a); +} + +template <typename IntType> +absl::enable_if_t<std::is_integral<IntType>::value, bool> +is_uniform_range_valid(IntType a, IntType b) { + return a <= b; +} + +// UniformDistribution selects either absl::uniform_int_distribution +// or absl::uniform_real_distribution depending on the NumType parameter. template <typename NumType> using UniformDistribution = typename std::conditional<std::is_integral<NumType>::value, absl::uniform_int_distribution<NumType>, absl::uniform_real_distribution<NumType>>::type; -// UniformDistributionWrapper is used as the underlying distribution type -// by the absl::Uniform template function. It selects the proper Abseil -// uniform distribution and provides constructor overloads that match the -// expected parameter order as well as adjusting distribtuion bounds based -// on the tag. +// UniformDistributionWrapper is used as the underlying distribution type +// by the absl::Uniform template function. It selects the proper Abseil +// uniform distribution and provides constructor overloads that match the +// expected parameter order as well as adjusting distribtuion bounds based +// on the tag. template <typename NumType> struct UniformDistributionWrapper : public UniformDistribution<NumType> { template <typename TagType> @@ -238,7 +238,7 @@ struct UniformDistributionWrapper : public UniformDistribution<NumType> { }; } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h b/contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h index b6e6c4b6aa..a86a3c461b 100644 --- a/contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h +++ b/contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h @@ -31,16 +31,16 @@ #include "absl/random/internal/traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace random_internal { // Helper object to multiply two 64-bit values to a 128-bit value. // MultiplyU64ToU128 multiplies two 64-bit values to a 128-bit value. // If an intrinsic is available, it is used, otherwise use native 32-bit // multiplies to construct the result. -inline absl::uint128 MultiplyU64ToU128(uint64_t a, uint64_t b) { +inline absl::uint128 MultiplyU64ToU128(uint64_t a, uint64_t b) { #if defined(ABSL_HAVE_INTRINSIC_INT128) - return absl::uint128(static_cast<__uint128_t>(a) * b); + return absl::uint128(static_cast<__uint128_t>(a) * b); #elif defined(ABSL_INTERNAL_USE_UMUL128) // uint64_t * uint64_t => uint128 multiply using imul intrinsic on MSVC. uint64_t high = 0; @@ -93,19 +93,19 @@ struct wide_multiply { template <> struct wide_multiply<uint64_t> { using input_type = uint64_t; - using result_type = absl::uint128; + using result_type = absl::uint128; static result_type multiply(uint64_t a, uint64_t b) { return MultiplyU64ToU128(a, b); } - static uint64_t hi(result_type r) { return absl::Uint128High64(r); } - static uint64_t lo(result_type r) { return absl::Uint128Low64(r); } + static uint64_t hi(result_type r) { return absl::Uint128High64(r); } + static uint64_t lo(result_type r) { return absl::Uint128Low64(r); } }; #endif } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h b/contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h index 43e101169c..35946055e8 100644 --- a/contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h +++ b/contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h @@ -31,7 +31,7 @@ #include "absl/random/uniform_int_distribution.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // log_uniform_int_distribution: // @@ -251,7 +251,7 @@ std::basic_istream<CharT, Traits>& operator>>( return is; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_LOG_UNIFORM_INT_DISTRIBUTION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/mock_distributions.h b/contrib/restricted/abseil-cpp/absl/random/mock_distributions.h index 764ab370ab..0788b68636 100644 --- a/contrib/restricted/abseil-cpp/absl/random/mock_distributions.h +++ b/contrib/restricted/abseil-cpp/absl/random/mock_distributions.h @@ -1,266 +1,266 @@ -// Copyright 2018 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// File: mock_distributions.h -// ----------------------------------------------------------------------------- -// -// This file contains mock distribution functions for use alongside an -// `absl::MockingBitGen` object within the Googletest testing framework. Such -// mocks are useful to provide deterministic values as return values within -// (otherwise random) Abseil distribution functions. -// -// The return type of each function is a mock expectation object which -// is used to set the match result. -// -// More information about the Googletest testing framework is available at -// https://github.com/google/googletest -// -// EXPECT_CALL and ON_CALL need to be made within the same DLL component as -// the call to absl::Uniform and related methods, otherwise mocking will fail -// since the underlying implementation creates a type-specific pointer which -// will be distinct across different DLL boundaries. -// -// Example: -// -// absl::MockingBitGen mock; -// EXPECT_CALL(absl::MockUniform<int>(), Call(mock, 1, 1000)) -// .WillRepeatedly(testing::ReturnRoundRobin({20, 40})); -// -// EXPECT_EQ(absl::Uniform<int>(gen, 1, 1000), 20); -// EXPECT_EQ(absl::Uniform<int>(gen, 1, 1000), 40); -// EXPECT_EQ(absl::Uniform<int>(gen, 1, 1000), 20); -// EXPECT_EQ(absl::Uniform<int>(gen, 1, 1000), 40); - -#ifndef ABSL_RANDOM_MOCK_DISTRIBUTIONS_H_ -#define ABSL_RANDOM_MOCK_DISTRIBUTIONS_H_ - -#include <limits> -#include <type_traits> -#include <utility> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/meta/type_traits.h" -#include "absl/random/distributions.h" -#include "absl/random/internal/mock_overload_set.h" -#include "absl/random/mocking_bit_gen.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -// ----------------------------------------------------------------------------- -// absl::MockUniform -// ----------------------------------------------------------------------------- -// -// Matches calls to absl::Uniform. -// -// `absl::MockUniform` is a class template used in conjunction with Googletest's -// `ON_CALL()` and `EXPECT_CALL()` macros. To use it, default-construct an -// instance of it inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the -// same way one would define mocks on a Googletest `MockFunction()`. -// -// Example: -// -// absl::MockingBitGen mock; -// EXPECT_CALL(absl::MockUniform<uint32_t>(), Call(mock)) -// .WillOnce(Return(123456)); -// auto x = absl::Uniform<uint32_t>(mock); -// assert(x == 123456) -// -template <typename R> -using MockUniform = random_internal::MockOverloadSet< - random_internal::UniformDistributionWrapper<R>, - R(IntervalClosedOpenTag, MockingBitGen&, R, R), - R(IntervalClosedClosedTag, MockingBitGen&, R, R), - R(IntervalOpenOpenTag, MockingBitGen&, R, R), - R(IntervalOpenClosedTag, MockingBitGen&, R, R), R(MockingBitGen&, R, R), - R(MockingBitGen&)>; - -// ----------------------------------------------------------------------------- -// absl::MockBernoulli -// ----------------------------------------------------------------------------- -// -// Matches calls to absl::Bernoulli. -// -// `absl::MockBernoulli` is a class used in conjunction with Googletest's -// `ON_CALL()` and `EXPECT_CALL()` macros. To use it, default-construct an -// instance of it inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the -// same way one would define mocks on a Googletest `MockFunction()`. -// -// Example: -// -// absl::MockingBitGen mock; -// EXPECT_CALL(absl::MockBernoulli(), Call(mock, testing::_)) -// .WillOnce(Return(false)); -// assert(absl::Bernoulli(mock, 0.5) == false); -// -using MockBernoulli = - random_internal::MockOverloadSet<absl::bernoulli_distribution, - bool(MockingBitGen&, double)>; - -// ----------------------------------------------------------------------------- -// absl::MockBeta -// ----------------------------------------------------------------------------- -// -// Matches calls to absl::Beta. -// -// `absl::MockBeta` is a class used in conjunction with Googletest's `ON_CALL()` -// and `EXPECT_CALL()` macros. To use it, default-construct an instance of it -// inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the same way one -// would define mocks on a Googletest `MockFunction()`. -// -// Example: -// -// absl::MockingBitGen mock; -// EXPECT_CALL(absl::MockBeta(), Call(mock, 3.0, 2.0)) -// .WillOnce(Return(0.567)); -// auto x = absl::Beta<double>(mock, 3.0, 2.0); -// assert(x == 0.567); -// -template <typename RealType> -using MockBeta = - random_internal::MockOverloadSet<absl::beta_distribution<RealType>, - RealType(MockingBitGen&, RealType, - RealType)>; - -// ----------------------------------------------------------------------------- -// absl::MockExponential -// ----------------------------------------------------------------------------- -// -// Matches calls to absl::Exponential. -// -// `absl::MockExponential` is a class template used in conjunction with -// Googletest's `ON_CALL()` and `EXPECT_CALL()` macros. To use it, -// default-construct an instance of it inside `ON_CALL()` or `EXPECT_CALL()`, -// and use `Call(...)` the same way one would define mocks on a -// Googletest `MockFunction()`. -// -// Example: -// -// absl::MockingBitGen mock; -// EXPECT_CALL(absl::MockExponential<double>(), Call(mock, 0.5)) -// .WillOnce(Return(12.3456789)); -// auto x = absl::Exponential<double>(mock, 0.5); -// assert(x == 12.3456789) -// -template <typename RealType> -using MockExponential = - random_internal::MockOverloadSet<absl::exponential_distribution<RealType>, - RealType(MockingBitGen&, RealType)>; - -// ----------------------------------------------------------------------------- -// absl::MockGaussian -// ----------------------------------------------------------------------------- -// -// Matches calls to absl::Gaussian. -// -// `absl::MockGaussian` is a class template used in conjunction with -// Googletest's `ON_CALL()` and `EXPECT_CALL()` macros. To use it, -// default-construct an instance of it inside `ON_CALL()` or `EXPECT_CALL()`, -// and use `Call(...)` the same way one would define mocks on a -// Googletest `MockFunction()`. -// -// Example: -// -// absl::MockingBitGen mock; -// EXPECT_CALL(absl::MockGaussian<double>(), Call(mock, 16.3, 3.3)) -// .WillOnce(Return(12.3456789)); -// auto x = absl::Gaussian<double>(mock, 16.3, 3.3); -// assert(x == 12.3456789) -// -template <typename RealType> -using MockGaussian = - random_internal::MockOverloadSet<absl::gaussian_distribution<RealType>, - RealType(MockingBitGen&, RealType, - RealType)>; - -// ----------------------------------------------------------------------------- -// absl::MockLogUniform -// ----------------------------------------------------------------------------- -// -// Matches calls to absl::LogUniform. -// -// `absl::MockLogUniform` is a class template used in conjunction with -// Googletest's `ON_CALL()` and `EXPECT_CALL()` macros. To use it, -// default-construct an instance of it inside `ON_CALL()` or `EXPECT_CALL()`, -// and use `Call(...)` the same way one would define mocks on a -// Googletest `MockFunction()`. -// -// Example: -// -// absl::MockingBitGen mock; -// EXPECT_CALL(absl::MockLogUniform<int>(), Call(mock, 10, 10000, 10)) -// .WillOnce(Return(1221)); -// auto x = absl::LogUniform<int>(mock, 10, 10000, 10); -// assert(x == 1221) -// -template <typename IntType> -using MockLogUniform = random_internal::MockOverloadSet< - absl::log_uniform_int_distribution<IntType>, - IntType(MockingBitGen&, IntType, IntType, IntType)>; - -// ----------------------------------------------------------------------------- -// absl::MockPoisson -// ----------------------------------------------------------------------------- -// -// Matches calls to absl::Poisson. -// -// `absl::MockPoisson` is a class template used in conjunction with Googletest's -// `ON_CALL()` and `EXPECT_CALL()` macros. To use it, default-construct an -// instance of it inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the -// same way one would define mocks on a Googletest `MockFunction()`. -// -// Example: -// -// absl::MockingBitGen mock; -// EXPECT_CALL(absl::MockPoisson<int>(), Call(mock, 2.0)) -// .WillOnce(Return(1221)); -// auto x = absl::Poisson<int>(mock, 2.0); -// assert(x == 1221) -// -template <typename IntType> -using MockPoisson = - random_internal::MockOverloadSet<absl::poisson_distribution<IntType>, - IntType(MockingBitGen&, double)>; - -// ----------------------------------------------------------------------------- -// absl::MockZipf -// ----------------------------------------------------------------------------- -// -// Matches calls to absl::Zipf. -// -// `absl::MockZipf` is a class template used in conjunction with Googletest's -// `ON_CALL()` and `EXPECT_CALL()` macros. To use it, default-construct an -// instance of it inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the -// same way one would define mocks on a Googletest `MockFunction()`. -// -// Example: -// -// absl::MockingBitGen mock; -// EXPECT_CALL(absl::MockZipf<int>(), Call(mock, 1000000, 2.0, 1.0)) -// .WillOnce(Return(1221)); -// auto x = absl::Zipf<int>(mock, 1000000, 2.0, 1.0); -// assert(x == 1221) -// -template <typename IntType> -using MockZipf = - random_internal::MockOverloadSet<absl::zipf_distribution<IntType>, - IntType(MockingBitGen&, IntType, double, - double)>; - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_MOCK_DISTRIBUTIONS_H_ +// Copyright 2018 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// File: mock_distributions.h +// ----------------------------------------------------------------------------- +// +// This file contains mock distribution functions for use alongside an +// `absl::MockingBitGen` object within the Googletest testing framework. Such +// mocks are useful to provide deterministic values as return values within +// (otherwise random) Abseil distribution functions. +// +// The return type of each function is a mock expectation object which +// is used to set the match result. +// +// More information about the Googletest testing framework is available at +// https://github.com/google/googletest +// +// EXPECT_CALL and ON_CALL need to be made within the same DLL component as +// the call to absl::Uniform and related methods, otherwise mocking will fail +// since the underlying implementation creates a type-specific pointer which +// will be distinct across different DLL boundaries. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockUniform<int>(), Call(mock, 1, 1000)) +// .WillRepeatedly(testing::ReturnRoundRobin({20, 40})); +// +// EXPECT_EQ(absl::Uniform<int>(gen, 1, 1000), 20); +// EXPECT_EQ(absl::Uniform<int>(gen, 1, 1000), 40); +// EXPECT_EQ(absl::Uniform<int>(gen, 1, 1000), 20); +// EXPECT_EQ(absl::Uniform<int>(gen, 1, 1000), 40); + +#ifndef ABSL_RANDOM_MOCK_DISTRIBUTIONS_H_ +#define ABSL_RANDOM_MOCK_DISTRIBUTIONS_H_ + +#include <limits> +#include <type_traits> +#include <utility> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/meta/type_traits.h" +#include "absl/random/distributions.h" +#include "absl/random/internal/mock_overload_set.h" +#include "absl/random/mocking_bit_gen.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +// ----------------------------------------------------------------------------- +// absl::MockUniform +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Uniform. +// +// `absl::MockUniform` is a class template used in conjunction with Googletest's +// `ON_CALL()` and `EXPECT_CALL()` macros. To use it, default-construct an +// instance of it inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the +// same way one would define mocks on a Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockUniform<uint32_t>(), Call(mock)) +// .WillOnce(Return(123456)); +// auto x = absl::Uniform<uint32_t>(mock); +// assert(x == 123456) +// +template <typename R> +using MockUniform = random_internal::MockOverloadSet< + random_internal::UniformDistributionWrapper<R>, + R(IntervalClosedOpenTag, MockingBitGen&, R, R), + R(IntervalClosedClosedTag, MockingBitGen&, R, R), + R(IntervalOpenOpenTag, MockingBitGen&, R, R), + R(IntervalOpenClosedTag, MockingBitGen&, R, R), R(MockingBitGen&, R, R), + R(MockingBitGen&)>; + +// ----------------------------------------------------------------------------- +// absl::MockBernoulli +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Bernoulli. +// +// `absl::MockBernoulli` is a class used in conjunction with Googletest's +// `ON_CALL()` and `EXPECT_CALL()` macros. To use it, default-construct an +// instance of it inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the +// same way one would define mocks on a Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockBernoulli(), Call(mock, testing::_)) +// .WillOnce(Return(false)); +// assert(absl::Bernoulli(mock, 0.5) == false); +// +using MockBernoulli = + random_internal::MockOverloadSet<absl::bernoulli_distribution, + bool(MockingBitGen&, double)>; + +// ----------------------------------------------------------------------------- +// absl::MockBeta +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Beta. +// +// `absl::MockBeta` is a class used in conjunction with Googletest's `ON_CALL()` +// and `EXPECT_CALL()` macros. To use it, default-construct an instance of it +// inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the same way one +// would define mocks on a Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockBeta(), Call(mock, 3.0, 2.0)) +// .WillOnce(Return(0.567)); +// auto x = absl::Beta<double>(mock, 3.0, 2.0); +// assert(x == 0.567); +// +template <typename RealType> +using MockBeta = + random_internal::MockOverloadSet<absl::beta_distribution<RealType>, + RealType(MockingBitGen&, RealType, + RealType)>; + +// ----------------------------------------------------------------------------- +// absl::MockExponential +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Exponential. +// +// `absl::MockExponential` is a class template used in conjunction with +// Googletest's `ON_CALL()` and `EXPECT_CALL()` macros. To use it, +// default-construct an instance of it inside `ON_CALL()` or `EXPECT_CALL()`, +// and use `Call(...)` the same way one would define mocks on a +// Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockExponential<double>(), Call(mock, 0.5)) +// .WillOnce(Return(12.3456789)); +// auto x = absl::Exponential<double>(mock, 0.5); +// assert(x == 12.3456789) +// +template <typename RealType> +using MockExponential = + random_internal::MockOverloadSet<absl::exponential_distribution<RealType>, + RealType(MockingBitGen&, RealType)>; + +// ----------------------------------------------------------------------------- +// absl::MockGaussian +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Gaussian. +// +// `absl::MockGaussian` is a class template used in conjunction with +// Googletest's `ON_CALL()` and `EXPECT_CALL()` macros. To use it, +// default-construct an instance of it inside `ON_CALL()` or `EXPECT_CALL()`, +// and use `Call(...)` the same way one would define mocks on a +// Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockGaussian<double>(), Call(mock, 16.3, 3.3)) +// .WillOnce(Return(12.3456789)); +// auto x = absl::Gaussian<double>(mock, 16.3, 3.3); +// assert(x == 12.3456789) +// +template <typename RealType> +using MockGaussian = + random_internal::MockOverloadSet<absl::gaussian_distribution<RealType>, + RealType(MockingBitGen&, RealType, + RealType)>; + +// ----------------------------------------------------------------------------- +// absl::MockLogUniform +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::LogUniform. +// +// `absl::MockLogUniform` is a class template used in conjunction with +// Googletest's `ON_CALL()` and `EXPECT_CALL()` macros. To use it, +// default-construct an instance of it inside `ON_CALL()` or `EXPECT_CALL()`, +// and use `Call(...)` the same way one would define mocks on a +// Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockLogUniform<int>(), Call(mock, 10, 10000, 10)) +// .WillOnce(Return(1221)); +// auto x = absl::LogUniform<int>(mock, 10, 10000, 10); +// assert(x == 1221) +// +template <typename IntType> +using MockLogUniform = random_internal::MockOverloadSet< + absl::log_uniform_int_distribution<IntType>, + IntType(MockingBitGen&, IntType, IntType, IntType)>; + +// ----------------------------------------------------------------------------- +// absl::MockPoisson +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Poisson. +// +// `absl::MockPoisson` is a class template used in conjunction with Googletest's +// `ON_CALL()` and `EXPECT_CALL()` macros. To use it, default-construct an +// instance of it inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the +// same way one would define mocks on a Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockPoisson<int>(), Call(mock, 2.0)) +// .WillOnce(Return(1221)); +// auto x = absl::Poisson<int>(mock, 2.0); +// assert(x == 1221) +// +template <typename IntType> +using MockPoisson = + random_internal::MockOverloadSet<absl::poisson_distribution<IntType>, + IntType(MockingBitGen&, double)>; + +// ----------------------------------------------------------------------------- +// absl::MockZipf +// ----------------------------------------------------------------------------- +// +// Matches calls to absl::Zipf. +// +// `absl::MockZipf` is a class template used in conjunction with Googletest's +// `ON_CALL()` and `EXPECT_CALL()` macros. To use it, default-construct an +// instance of it inside `ON_CALL()` or `EXPECT_CALL()`, and use `Call(...)` the +// same way one would define mocks on a Googletest `MockFunction()`. +// +// Example: +// +// absl::MockingBitGen mock; +// EXPECT_CALL(absl::MockZipf<int>(), Call(mock, 1000000, 2.0, 1.0)) +// .WillOnce(Return(1221)); +// auto x = absl::Zipf<int>(mock, 1000000, 2.0, 1.0); +// assert(x == 1221) +// +template <typename IntType> +using MockZipf = + random_internal::MockOverloadSet<absl::zipf_distribution<IntType>, + IntType(MockingBitGen&, IntType, double, + double)>; + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_RANDOM_MOCK_DISTRIBUTIONS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/mocking_bit_gen.h b/contrib/restricted/abseil-cpp/absl/random/mocking_bit_gen.h index 7b2b80eb35..b7a43a756f 100644 --- a/contrib/restricted/abseil-cpp/absl/random/mocking_bit_gen.h +++ b/contrib/restricted/abseil-cpp/absl/random/mocking_bit_gen.h @@ -1,142 +1,142 @@ -// Copyright 2018 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// mocking_bit_gen.h -// ----------------------------------------------------------------------------- -// -// This file includes an `absl::MockingBitGen` class to use as a mock within the -// Googletest testing framework. Such a mock is useful to provide deterministic -// values as return values within (otherwise random) Abseil distribution -// functions. Such determinism within a mock is useful within testing frameworks -// to test otherwise indeterminate APIs. -// -// More information about the Googletest testing framework is available at -// https://github.com/google/googletest - -#ifndef ABSL_RANDOM_MOCKING_BIT_GEN_H_ -#define ABSL_RANDOM_MOCKING_BIT_GEN_H_ - -#include <iterator> -#include <limits> -#include <memory> -#include <tuple> -#include <type_traits> -#include <utility> - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/base/internal/fast_type_id.h" -#include "absl/container/flat_hash_map.h" -#include "absl/meta/type_traits.h" -#include "absl/random/distributions.h" -#include "absl/random/internal/distribution_caller.h" -#include "absl/random/random.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_join.h" -#include "absl/types/span.h" -#include "absl/types/variant.h" -#include "absl/utility/utility.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -namespace random_internal { -template <typename> -struct DistributionCaller; -class MockHelpers; - -} // namespace random_internal -class BitGenRef; - -// MockingBitGen -// -// `absl::MockingBitGen` is a mock Uniform Random Bit Generator (URBG) class -// which can act in place of an `absl::BitGen` URBG within tests using the -// Googletest testing framework. -// -// Usage: -// -// Use an `absl::MockingBitGen` along with a mock distribution object (within -// mock_distributions.h) inside Googletest constructs such as ON_CALL(), -// EXPECT_TRUE(), etc. to produce deterministic results conforming to the -// distribution's API contract. -// -// Example: -// -// // Mock a call to an `absl::Bernoulli` distribution using Googletest -// absl::MockingBitGen bitgen; -// -// ON_CALL(absl::MockBernoulli(), Call(bitgen, 0.5)) -// .WillByDefault(testing::Return(true)); -// EXPECT_TRUE(absl::Bernoulli(bitgen, 0.5)); -// -// // Mock a call to an `absl::Uniform` distribution within Googletest -// absl::MockingBitGen bitgen; -// -// ON_CALL(absl::MockUniform<int>(), Call(bitgen, testing::_, testing::_)) -// .WillByDefault([] (int low, int high) { -// return (low + high) / 2; -// }); -// -// EXPECT_EQ(absl::Uniform<int>(gen, 0, 10), 5); -// EXPECT_EQ(absl::Uniform<int>(gen, 30, 40), 35); -// -// At this time, only mock distributions supplied within the Abseil random -// library are officially supported. -// -// EXPECT_CALL and ON_CALL need to be made within the same DLL component as -// the call to absl::Uniform and related methods, otherwise mocking will fail -// since the underlying implementation creates a type-specific pointer which -// will be distinct across different DLL boundaries. -// -class MockingBitGen { - public: - MockingBitGen() = default; +// Copyright 2018 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// mocking_bit_gen.h +// ----------------------------------------------------------------------------- +// +// This file includes an `absl::MockingBitGen` class to use as a mock within the +// Googletest testing framework. Such a mock is useful to provide deterministic +// values as return values within (otherwise random) Abseil distribution +// functions. Such determinism within a mock is useful within testing frameworks +// to test otherwise indeterminate APIs. +// +// More information about the Googletest testing framework is available at +// https://github.com/google/googletest + +#ifndef ABSL_RANDOM_MOCKING_BIT_GEN_H_ +#define ABSL_RANDOM_MOCKING_BIT_GEN_H_ + +#include <iterator> +#include <limits> +#include <memory> +#include <tuple> +#include <type_traits> +#include <utility> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/base/internal/fast_type_id.h" +#include "absl/container/flat_hash_map.h" +#include "absl/meta/type_traits.h" +#include "absl/random/distributions.h" +#include "absl/random/internal/distribution_caller.h" +#include "absl/random/random.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_join.h" +#include "absl/types/span.h" +#include "absl/types/variant.h" +#include "absl/utility/utility.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +namespace random_internal { +template <typename> +struct DistributionCaller; +class MockHelpers; + +} // namespace random_internal +class BitGenRef; + +// MockingBitGen +// +// `absl::MockingBitGen` is a mock Uniform Random Bit Generator (URBG) class +// which can act in place of an `absl::BitGen` URBG within tests using the +// Googletest testing framework. +// +// Usage: +// +// Use an `absl::MockingBitGen` along with a mock distribution object (within +// mock_distributions.h) inside Googletest constructs such as ON_CALL(), +// EXPECT_TRUE(), etc. to produce deterministic results conforming to the +// distribution's API contract. +// +// Example: +// +// // Mock a call to an `absl::Bernoulli` distribution using Googletest +// absl::MockingBitGen bitgen; +// +// ON_CALL(absl::MockBernoulli(), Call(bitgen, 0.5)) +// .WillByDefault(testing::Return(true)); +// EXPECT_TRUE(absl::Bernoulli(bitgen, 0.5)); +// +// // Mock a call to an `absl::Uniform` distribution within Googletest +// absl::MockingBitGen bitgen; +// +// ON_CALL(absl::MockUniform<int>(), Call(bitgen, testing::_, testing::_)) +// .WillByDefault([] (int low, int high) { +// return (low + high) / 2; +// }); +// +// EXPECT_EQ(absl::Uniform<int>(gen, 0, 10), 5); +// EXPECT_EQ(absl::Uniform<int>(gen, 30, 40), 35); +// +// At this time, only mock distributions supplied within the Abseil random +// library are officially supported. +// +// EXPECT_CALL and ON_CALL need to be made within the same DLL component as +// the call to absl::Uniform and related methods, otherwise mocking will fail +// since the underlying implementation creates a type-specific pointer which +// will be distinct across different DLL boundaries. +// +class MockingBitGen { + public: + MockingBitGen() = default; ~MockingBitGen() = default; - - // URBG interface - using result_type = absl::BitGen::result_type; - - static constexpr result_type(min)() { return (absl::BitGen::min)(); } - static constexpr result_type(max)() { return (absl::BitGen::max)(); } - result_type operator()() { return gen_(); } - - private: - // GetMockFnType returns the testing::MockFunction for a result and tuple. - // This method only exists for type deduction and is otherwise unimplemented. - template <typename ResultT, typename... Args> - static auto GetMockFnType(ResultT, std::tuple<Args...>) - -> ::testing::MockFunction<ResultT(Args...)>; - - // MockFnCaller is a helper method for use with absl::apply to - // apply an ArgTupleT to a compatible MockFunction. - // NOTE: MockFnCaller is essentially equivalent to the lambda: - // [fn](auto... args) { return fn->Call(std::move(args)...)} - // however that fails to build on some supported platforms. + + // URBG interface + using result_type = absl::BitGen::result_type; + + static constexpr result_type(min)() { return (absl::BitGen::min)(); } + static constexpr result_type(max)() { return (absl::BitGen::max)(); } + result_type operator()() { return gen_(); } + + private: + // GetMockFnType returns the testing::MockFunction for a result and tuple. + // This method only exists for type deduction and is otherwise unimplemented. + template <typename ResultT, typename... Args> + static auto GetMockFnType(ResultT, std::tuple<Args...>) + -> ::testing::MockFunction<ResultT(Args...)>; + + // MockFnCaller is a helper method for use with absl::apply to + // apply an ArgTupleT to a compatible MockFunction. + // NOTE: MockFnCaller is essentially equivalent to the lambda: + // [fn](auto... args) { return fn->Call(std::move(args)...)} + // however that fails to build on some supported platforms. template <typename MockFnType, typename ResultT, typename Tuple> - struct MockFnCaller; + struct MockFnCaller; - // specialization for std::tuple. + // specialization for std::tuple. template <typename MockFnType, typename ResultT, typename... Args> struct MockFnCaller<MockFnType, ResultT, std::tuple<Args...>> { - MockFnType* fn; - inline ResultT operator()(Args... args) { - return fn->Call(std::move(args)...); - } - }; - + MockFnType* fn; + inline ResultT operator()(Args... args) { + return fn->Call(std::move(args)...); + } + }; + // FunctionHolder owns a particular ::testing::MockFunction associated with // a mocked type signature, and implement the type-erased Apply call, which // applies type-erased arguments to the mock. @@ -165,20 +165,20 @@ class MockingBitGen { MockFnType mock_fn_; }; - // MockingBitGen::RegisterMock - // - // RegisterMock<ResultT, ArgTupleT>(FastTypeIdType) is the main extension - // point for extending the MockingBitGen framework. It provides a mechanism to - // install a mock expectation for a function like ResultT(Args...) keyed by - // type_idex onto the MockingBitGen context. The key is that the type_index - // used to register must match the type index used to call the mock. - // - // The returned MockFunction<...> type can be used to setup additional - // distribution parameters of the expectation. + // MockingBitGen::RegisterMock + // + // RegisterMock<ResultT, ArgTupleT>(FastTypeIdType) is the main extension + // point for extending the MockingBitGen framework. It provides a mechanism to + // install a mock expectation for a function like ResultT(Args...) keyed by + // type_idex onto the MockingBitGen context. The key is that the type_index + // used to register must match the type index used to call the mock. + // + // The returned MockFunction<...> type can be used to setup additional + // distribution parameters of the expectation. template <typename ResultT, typename ArgTupleT, typename SelfT> auto RegisterMock(SelfT&, base_internal::FastTypeIdType type) - -> decltype(GetMockFnType(std::declval<ResultT>(), - std::declval<ArgTupleT>()))& { + -> decltype(GetMockFnType(std::declval<ResultT>(), + std::declval<ArgTupleT>()))& { using MockFnType = decltype(GetMockFnType(std::declval<ResultT>(), std::declval<ArgTupleT>())); @@ -195,46 +195,46 @@ class MockingBitGen { ::testing::StrictMock<MockFnType>, MockFnType>>>; using ImplT = FunctionHolderImpl<WrappedFnType, ResultT, ArgTupleT>; - auto& mock = mocks_[type]; + auto& mock = mocks_[type]; if (!mock) { mock = absl::make_unique<ImplT>(); - } + } return static_cast<ImplT*>(mock.get())->mock_fn_; - } - - // MockingBitGen::InvokeMock - // - // InvokeMock(FastTypeIdType, args, result) is the entrypoint for invoking - // mocks registered on MockingBitGen. - // - // When no mocks are registered on the provided FastTypeIdType, returns false. - // Otherwise attempts to invoke the mock function ResultT(Args...) that - // was previously registered via the type_index. - // Requires tuple_args to point to a ArgTupleT, which is a std::tuple<Args...> - // used to invoke the mock function. - // Requires result to point to a ResultT, which is the result of the call. - inline bool InvokeMock(base_internal::FastTypeIdType type, void* args_tuple, - void* result) { - // Trigger a mock, if there exists one that matches `param`. - auto it = mocks_.find(type); - if (it == mocks_.end()) return false; + } + + // MockingBitGen::InvokeMock + // + // InvokeMock(FastTypeIdType, args, result) is the entrypoint for invoking + // mocks registered on MockingBitGen. + // + // When no mocks are registered on the provided FastTypeIdType, returns false. + // Otherwise attempts to invoke the mock function ResultT(Args...) that + // was previously registered via the type_index. + // Requires tuple_args to point to a ArgTupleT, which is a std::tuple<Args...> + // used to invoke the mock function. + // Requires result to point to a ResultT, which is the result of the call. + inline bool InvokeMock(base_internal::FastTypeIdType type, void* args_tuple, + void* result) { + // Trigger a mock, if there exists one that matches `param`. + auto it = mocks_.find(type); + if (it == mocks_.end()) return false; it->second->Apply(args_tuple, result); - return true; - } - + return true; + } + absl::flat_hash_map<base_internal::FastTypeIdType, std::unique_ptr<FunctionHolder>> mocks_; - absl::BitGen gen_; - - template <typename> - friend struct ::absl::random_internal::DistributionCaller; // for InvokeMock - friend class ::absl::BitGenRef; // for InvokeMock - friend class ::absl::random_internal::MockHelpers; // for RegisterMock, - // InvokeMock -}; - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_RANDOM_MOCKING_BIT_GEN_H_ + absl::BitGen gen_; + + template <typename> + friend struct ::absl::random_internal::DistributionCaller; // for InvokeMock + friend class ::absl::BitGenRef; // for InvokeMock + friend class ::absl::random_internal::MockHelpers; // for RegisterMock, + // InvokeMock +}; + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_RANDOM_MOCKING_BIT_GEN_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h b/contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h index cb5f5d5d0f..ae2747e142 100644 --- a/contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h +++ b/contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h @@ -28,7 +28,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // absl::poisson_distribution: // Generates discrete variates conforming to a Poisson distribution. @@ -252,7 +252,7 @@ std::basic_istream<CharT, Traits>& operator>>( return is; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_POISSON_DISTRIBUTION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/random.h b/contrib/restricted/abseil-cpp/absl/random/random.h index 71b6309288..ad0b5d0912 100644 --- a/contrib/restricted/abseil-cpp/absl/random/random.h +++ b/contrib/restricted/abseil-cpp/absl/random/random.h @@ -41,7 +41,7 @@ #include "absl/random/seed_sequences.h" // IWYU pragma: export namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // absl::BitGen @@ -109,7 +109,7 @@ ABSL_NAMESPACE_BEGIN // absl::BitGen::max() // -// Returns the largest possible value from this bit generator. +// Returns the largest possible value from this bit generator. // absl::BitGen::discard(num) // @@ -183,7 +183,7 @@ using InsecureBitGen = // discards the intermediate results. // --------------------------------------------------------------------------- -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_RANDOM_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc index fdcb54a86c..afa028f805 100644 --- a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc +++ b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc @@ -19,7 +19,7 @@ #include "absl/base/config.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN static constexpr const char kExceptionMessage[] = "Failed generating seed-material for URBG."; @@ -42,5 +42,5 @@ void ThrowSeedGenException() { } } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.h b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.h index 5353900564..970b07e848 100644 --- a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.h +++ b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.h @@ -28,10 +28,10 @@ #include <exception> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN //------------------------------------------------------------------------------ // SeedGenException @@ -49,7 +49,7 @@ namespace random_internal { [[noreturn]] void ThrowSeedGenException(); } // namespace random_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_SEED_GEN_EXCEPTION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception/ya.make b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception/ya.make index 6d9b4a7b19..ca8ca01eed 100644 --- a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception/ya.make @@ -16,10 +16,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/random) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_sequences.cc b/contrib/restricted/abseil-cpp/absl/random/seed_sequences.cc index 426eafd3c8..b6eb1cecfc 100644 --- a/contrib/restricted/abseil-cpp/absl/random/seed_sequences.cc +++ b/contrib/restricted/abseil-cpp/absl/random/seed_sequences.cc @@ -17,7 +17,7 @@ #include "absl/random/internal/pool_urbg.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN SeedSeq MakeSeedSeq() { SeedSeq::result_type seed_material[8]; @@ -25,5 +25,5 @@ SeedSeq MakeSeedSeq() { return SeedSeq(std::begin(seed_material), std::end(seed_material)); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_sequences.h b/contrib/restricted/abseil-cpp/absl/random/seed_sequences.h index ff1340cc8e..1fe6889947 100644 --- a/contrib/restricted/abseil-cpp/absl/random/seed_sequences.h +++ b/contrib/restricted/abseil-cpp/absl/random/seed_sequences.h @@ -34,7 +34,7 @@ #include "absl/types/span.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // absl::SeedSeq @@ -104,7 +104,7 @@ SeedSeq CreateSeedSeqFrom(URBG* urbg) { // SeedSeq MakeSeedSeq(); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_SEED_SEQUENCES_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make b/contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make index 49cb3ff19c..20e16a11f6 100644 --- a/contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make +++ b/contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make @@ -19,7 +19,7 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/random/internal/randen contrib/restricted/abseil-cpp/absl/random/internal/randen_detect contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes - contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys + contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys contrib/restricted/abseil-cpp/absl/random/internal/randen_slow contrib/restricted/abseil-cpp/absl/random/internal/seed_material contrib/restricted/abseil-cpp/absl/random/seed_gen_exception @@ -36,10 +36,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/random) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h b/contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h index c1f54ccebc..32fa9e263c 100644 --- a/contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h +++ b/contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h @@ -40,7 +40,7 @@ #include "absl/random/internal/wide_multiply.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // absl::uniform_int_distribution<T> // @@ -269,7 +269,7 @@ uniform_int_distribution<IntType>::Generate( return helper::hi(product); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_UNIFORM_INT_DISTRIBUTION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h b/contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h index 5ba17b2341..5f97f55d58 100644 --- a/contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h +++ b/contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h @@ -45,7 +45,7 @@ #include "absl/random/internal/iostream_state_saver.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // absl::uniform_real_distribution<T> // @@ -196,7 +196,7 @@ std::basic_istream<CharT, Traits>& operator>>( } return is; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_UNIFORM_REAL_DISTRIBUTION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h b/contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h index 22ebc756cf..4d81795af8 100644 --- a/contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h +++ b/contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h @@ -26,7 +26,7 @@ #include "absl/random/uniform_real_distribution.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // absl::zipf_distribution produces random integer-values in the range [0, k], // distributed according to the discrete probability function: @@ -265,7 +265,7 @@ std::basic_istream<CharT, Traits>& operator>>( return is; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_ZIPF_DISTRIBUTION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h b/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h index ac12940a6d..ac92ebb949 100644 --- a/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h +++ b/contrib/restricted/abseil-cpp/absl/status/internal/status_internal.h @@ -1,52 +1,52 @@ -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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. -#ifndef ABSL_STATUS_INTERNAL_STATUS_INTERNAL_H_ -#define ABSL_STATUS_INTERNAL_STATUS_INTERNAL_H_ - -#include <string> - -#include "absl/container/inlined_vector.h" -#include "absl/strings/cord.h" - +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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. +#ifndef ABSL_STATUS_INTERNAL_STATUS_INTERNAL_H_ +#define ABSL_STATUS_INTERNAL_STATUS_INTERNAL_H_ + +#include <string> + +#include "absl/container/inlined_vector.h" +#include "absl/strings/cord.h" + #ifndef SWIG // Disabled for SWIG as it doesn't parse attributes correctly. -namespace absl { -ABSL_NAMESPACE_BEGIN +namespace absl { +ABSL_NAMESPACE_BEGIN // Returned Status objects may not be ignored. Codesearch doesn't handle ifdefs // as part of a class definitions (b/6995610), so we use a forward declaration. class ABSL_MUST_USE_RESULT Status; ABSL_NAMESPACE_END } // namespace absl #endif // !SWIG - + namespace absl { ABSL_NAMESPACE_BEGIN -enum class StatusCode : int; - -namespace status_internal { - -// Container for status payloads. -struct Payload { - std::string type_url; - absl::Cord payload; -}; - -using Payloads = absl::InlinedVector<Payload, 1>; - -// Reference-counted representation of Status data. -struct StatusRep { +enum class StatusCode : int; + +namespace status_internal { + +// Container for status payloads. +struct Payload { + std::string type_url; + absl::Cord payload; +}; + +using Payloads = absl::InlinedVector<Payload, 1>; + +// Reference-counted representation of Status data. +struct StatusRep { StatusRep(absl::StatusCode code_arg, absl::string_view message_arg, std::unique_ptr<status_internal::Payloads> payloads_arg) : ref(int32_t{1}), @@ -54,16 +54,16 @@ struct StatusRep { message(message_arg), payloads(std::move(payloads_arg)) {} - std::atomic<int32_t> ref; - absl::StatusCode code; - std::string message; - std::unique_ptr<status_internal::Payloads> payloads; -}; - -absl::StatusCode MapToLocalCode(int value); -} // namespace status_internal - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STATUS_INTERNAL_STATUS_INTERNAL_H_ + std::atomic<int32_t> ref; + absl::StatusCode code; + std::string message; + std::unique_ptr<status_internal::Payloads> payloads; +}; + +absl::StatusCode MapToLocalCode(int value); +} // namespace status_internal + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STATUS_INTERNAL_STATUS_INTERNAL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/status/internal/statusor_internal.h b/contrib/restricted/abseil-cpp/absl/status/internal/statusor_internal.h index eaac2c0b14..092e086184 100644 --- a/contrib/restricted/abseil-cpp/absl/status/internal/statusor_internal.h +++ b/contrib/restricted/abseil-cpp/absl/status/internal/statusor_internal.h @@ -1,396 +1,396 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. -#ifndef ABSL_STATUS_INTERNAL_STATUSOR_INTERNAL_H_ -#define ABSL_STATUS_INTERNAL_STATUSOR_INTERNAL_H_ - -#include <type_traits> -#include <utility> - +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. +#ifndef ABSL_STATUS_INTERNAL_STATUSOR_INTERNAL_H_ +#define ABSL_STATUS_INTERNAL_STATUSOR_INTERNAL_H_ + +#include <type_traits> +#include <utility> + #include "absl/base/attributes.h" -#include "absl/meta/type_traits.h" -#include "absl/status/status.h" -#include "absl/utility/utility.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -template <typename T> -class ABSL_MUST_USE_RESULT StatusOr; - -namespace internal_statusor { - -// Detects whether `U` has conversion operator to `StatusOr<T>`, i.e. `operator -// StatusOr<T>()`. -template <typename T, typename U, typename = void> -struct HasConversionOperatorToStatusOr : std::false_type {}; - -template <typename T, typename U> -void test(char (*)[sizeof(std::declval<U>().operator absl::StatusOr<T>())]); - -template <typename T, typename U> -struct HasConversionOperatorToStatusOr<T, U, decltype(test<T, U>(0))> - : std::true_type {}; - -// Detects whether `T` is constructible or convertible from `StatusOr<U>`. -template <typename T, typename U> -using IsConstructibleOrConvertibleFromStatusOr = - absl::disjunction<std::is_constructible<T, StatusOr<U>&>, - std::is_constructible<T, const StatusOr<U>&>, - std::is_constructible<T, StatusOr<U>&&>, - std::is_constructible<T, const StatusOr<U>&&>, - std::is_convertible<StatusOr<U>&, T>, - std::is_convertible<const StatusOr<U>&, T>, - std::is_convertible<StatusOr<U>&&, T>, - std::is_convertible<const StatusOr<U>&&, T>>; - -// Detects whether `T` is constructible or convertible or assignable from -// `StatusOr<U>`. -template <typename T, typename U> -using IsConstructibleOrConvertibleOrAssignableFromStatusOr = - absl::disjunction<IsConstructibleOrConvertibleFromStatusOr<T, U>, - std::is_assignable<T&, StatusOr<U>&>, - std::is_assignable<T&, const StatusOr<U>&>, - std::is_assignable<T&, StatusOr<U>&&>, - std::is_assignable<T&, const StatusOr<U>&&>>; - -// Detects whether direct initializing `StatusOr<T>` from `U` is ambiguous, i.e. -// when `U` is `StatusOr<V>` and `T` is constructible or convertible from `V`. -template <typename T, typename U> -struct IsDirectInitializationAmbiguous - : public absl::conditional_t< - std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>, - U>::value, - std::false_type, - IsDirectInitializationAmbiguous< - T, absl::remove_cv_t<absl::remove_reference_t<U>>>> {}; - -template <typename T, typename V> -struct IsDirectInitializationAmbiguous<T, absl::StatusOr<V>> - : public IsConstructibleOrConvertibleFromStatusOr<T, V> {}; - -// Checks against the constraints of the direction initialization, i.e. when -// `StatusOr<T>::StatusOr(U&&)` should participate in overload resolution. -template <typename T, typename U> -using IsDirectInitializationValid = absl::disjunction< - // Short circuits if T is basically U. - std::is_same<T, absl::remove_cv_t<absl::remove_reference_t<U>>>, - absl::negation<absl::disjunction< - std::is_same<absl::StatusOr<T>, - absl::remove_cv_t<absl::remove_reference_t<U>>>, - std::is_same<absl::Status, - absl::remove_cv_t<absl::remove_reference_t<U>>>, - std::is_same<absl::in_place_t, - absl::remove_cv_t<absl::remove_reference_t<U>>>, - IsDirectInitializationAmbiguous<T, U>>>>; - -// This trait detects whether `StatusOr<T>::operator=(U&&)` is ambiguous, which -// is equivalent to whether all the following conditions are met: -// 1. `U` is `StatusOr<V>`. -// 2. `T` is constructible and assignable from `V`. -// 3. `T` is constructible and assignable from `U` (i.e. `StatusOr<V>`). -// For example, the following code is considered ambiguous: -// (`T` is `bool`, `U` is `StatusOr<bool>`, `V` is `bool`) -// StatusOr<bool> s1 = true; // s1.ok() && s1.ValueOrDie() == true -// StatusOr<bool> s2 = false; // s2.ok() && s2.ValueOrDie() == false -// s1 = s2; // ambiguous, `s1 = s2.ValueOrDie()` or `s1 = bool(s2)`? -template <typename T, typename U> -struct IsForwardingAssignmentAmbiguous - : public absl::conditional_t< - std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>, - U>::value, - std::false_type, - IsForwardingAssignmentAmbiguous< - T, absl::remove_cv_t<absl::remove_reference_t<U>>>> {}; - -template <typename T, typename U> -struct IsForwardingAssignmentAmbiguous<T, absl::StatusOr<U>> - : public IsConstructibleOrConvertibleOrAssignableFromStatusOr<T, U> {}; - -// Checks against the constraints of the forwarding assignment, i.e. whether -// `StatusOr<T>::operator(U&&)` should participate in overload resolution. -template <typename T, typename U> -using IsForwardingAssignmentValid = absl::disjunction< - // Short circuits if T is basically U. - std::is_same<T, absl::remove_cv_t<absl::remove_reference_t<U>>>, - absl::negation<absl::disjunction< - std::is_same<absl::StatusOr<T>, - absl::remove_cv_t<absl::remove_reference_t<U>>>, - std::is_same<absl::Status, - absl::remove_cv_t<absl::remove_reference_t<U>>>, - std::is_same<absl::in_place_t, - absl::remove_cv_t<absl::remove_reference_t<U>>>, - IsForwardingAssignmentAmbiguous<T, U>>>>; - -class Helper { - public: - // Move type-agnostic error handling to the .cc. - static void HandleInvalidStatusCtorArg(Status*); +#include "absl/meta/type_traits.h" +#include "absl/status/status.h" +#include "absl/utility/utility.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +template <typename T> +class ABSL_MUST_USE_RESULT StatusOr; + +namespace internal_statusor { + +// Detects whether `U` has conversion operator to `StatusOr<T>`, i.e. `operator +// StatusOr<T>()`. +template <typename T, typename U, typename = void> +struct HasConversionOperatorToStatusOr : std::false_type {}; + +template <typename T, typename U> +void test(char (*)[sizeof(std::declval<U>().operator absl::StatusOr<T>())]); + +template <typename T, typename U> +struct HasConversionOperatorToStatusOr<T, U, decltype(test<T, U>(0))> + : std::true_type {}; + +// Detects whether `T` is constructible or convertible from `StatusOr<U>`. +template <typename T, typename U> +using IsConstructibleOrConvertibleFromStatusOr = + absl::disjunction<std::is_constructible<T, StatusOr<U>&>, + std::is_constructible<T, const StatusOr<U>&>, + std::is_constructible<T, StatusOr<U>&&>, + std::is_constructible<T, const StatusOr<U>&&>, + std::is_convertible<StatusOr<U>&, T>, + std::is_convertible<const StatusOr<U>&, T>, + std::is_convertible<StatusOr<U>&&, T>, + std::is_convertible<const StatusOr<U>&&, T>>; + +// Detects whether `T` is constructible or convertible or assignable from +// `StatusOr<U>`. +template <typename T, typename U> +using IsConstructibleOrConvertibleOrAssignableFromStatusOr = + absl::disjunction<IsConstructibleOrConvertibleFromStatusOr<T, U>, + std::is_assignable<T&, StatusOr<U>&>, + std::is_assignable<T&, const StatusOr<U>&>, + std::is_assignable<T&, StatusOr<U>&&>, + std::is_assignable<T&, const StatusOr<U>&&>>; + +// Detects whether direct initializing `StatusOr<T>` from `U` is ambiguous, i.e. +// when `U` is `StatusOr<V>` and `T` is constructible or convertible from `V`. +template <typename T, typename U> +struct IsDirectInitializationAmbiguous + : public absl::conditional_t< + std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>, + U>::value, + std::false_type, + IsDirectInitializationAmbiguous< + T, absl::remove_cv_t<absl::remove_reference_t<U>>>> {}; + +template <typename T, typename V> +struct IsDirectInitializationAmbiguous<T, absl::StatusOr<V>> + : public IsConstructibleOrConvertibleFromStatusOr<T, V> {}; + +// Checks against the constraints of the direction initialization, i.e. when +// `StatusOr<T>::StatusOr(U&&)` should participate in overload resolution. +template <typename T, typename U> +using IsDirectInitializationValid = absl::disjunction< + // Short circuits if T is basically U. + std::is_same<T, absl::remove_cv_t<absl::remove_reference_t<U>>>, + absl::negation<absl::disjunction< + std::is_same<absl::StatusOr<T>, + absl::remove_cv_t<absl::remove_reference_t<U>>>, + std::is_same<absl::Status, + absl::remove_cv_t<absl::remove_reference_t<U>>>, + std::is_same<absl::in_place_t, + absl::remove_cv_t<absl::remove_reference_t<U>>>, + IsDirectInitializationAmbiguous<T, U>>>>; + +// This trait detects whether `StatusOr<T>::operator=(U&&)` is ambiguous, which +// is equivalent to whether all the following conditions are met: +// 1. `U` is `StatusOr<V>`. +// 2. `T` is constructible and assignable from `V`. +// 3. `T` is constructible and assignable from `U` (i.e. `StatusOr<V>`). +// For example, the following code is considered ambiguous: +// (`T` is `bool`, `U` is `StatusOr<bool>`, `V` is `bool`) +// StatusOr<bool> s1 = true; // s1.ok() && s1.ValueOrDie() == true +// StatusOr<bool> s2 = false; // s2.ok() && s2.ValueOrDie() == false +// s1 = s2; // ambiguous, `s1 = s2.ValueOrDie()` or `s1 = bool(s2)`? +template <typename T, typename U> +struct IsForwardingAssignmentAmbiguous + : public absl::conditional_t< + std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>, + U>::value, + std::false_type, + IsForwardingAssignmentAmbiguous< + T, absl::remove_cv_t<absl::remove_reference_t<U>>>> {}; + +template <typename T, typename U> +struct IsForwardingAssignmentAmbiguous<T, absl::StatusOr<U>> + : public IsConstructibleOrConvertibleOrAssignableFromStatusOr<T, U> {}; + +// Checks against the constraints of the forwarding assignment, i.e. whether +// `StatusOr<T>::operator(U&&)` should participate in overload resolution. +template <typename T, typename U> +using IsForwardingAssignmentValid = absl::disjunction< + // Short circuits if T is basically U. + std::is_same<T, absl::remove_cv_t<absl::remove_reference_t<U>>>, + absl::negation<absl::disjunction< + std::is_same<absl::StatusOr<T>, + absl::remove_cv_t<absl::remove_reference_t<U>>>, + std::is_same<absl::Status, + absl::remove_cv_t<absl::remove_reference_t<U>>>, + std::is_same<absl::in_place_t, + absl::remove_cv_t<absl::remove_reference_t<U>>>, + IsForwardingAssignmentAmbiguous<T, U>>>>; + +class Helper { + public: + // Move type-agnostic error handling to the .cc. + static void HandleInvalidStatusCtorArg(Status*); ABSL_ATTRIBUTE_NORETURN static void Crash(const absl::Status& status); -}; - -// Construct an instance of T in `p` through placement new, passing Args... to -// the constructor. -// This abstraction is here mostly for the gcc performance fix. -template <typename T, typename... Args> +}; + +// Construct an instance of T in `p` through placement new, passing Args... to +// the constructor. +// This abstraction is here mostly for the gcc performance fix. +template <typename T, typename... Args> ABSL_ATTRIBUTE_NONNULL(1) void PlacementNew(void* p, Args&&... args) { - new (p) T(std::forward<Args>(args)...); -} - -// Helper base class to hold the data and all operations. -// We move all this to a base class to allow mixing with the appropriate -// TraitsBase specialization. -template <typename T> -class StatusOrData { - template <typename U> - friend class StatusOrData; - - public: - StatusOrData() = delete; - - StatusOrData(const StatusOrData& other) { - if (other.ok()) { - MakeValue(other.data_); - MakeStatus(); - } else { - MakeStatus(other.status_); - } - } - - StatusOrData(StatusOrData&& other) noexcept { - if (other.ok()) { - MakeValue(std::move(other.data_)); - MakeStatus(); - } else { - MakeStatus(std::move(other.status_)); - } - } - - template <typename U> - explicit StatusOrData(const StatusOrData<U>& other) { - if (other.ok()) { - MakeValue(other.data_); - MakeStatus(); - } else { - MakeStatus(other.status_); - } - } - - template <typename U> - explicit StatusOrData(StatusOrData<U>&& other) { - if (other.ok()) { - MakeValue(std::move(other.data_)); - MakeStatus(); - } else { - MakeStatus(std::move(other.status_)); - } - } - - template <typename... Args> - explicit StatusOrData(absl::in_place_t, Args&&... args) - : data_(std::forward<Args>(args)...) { - MakeStatus(); - } - - explicit StatusOrData(const T& value) : data_(value) { - MakeStatus(); - } - explicit StatusOrData(T&& value) : data_(std::move(value)) { - MakeStatus(); - } - - template <typename U, - absl::enable_if_t<std::is_constructible<absl::Status, U&&>::value, - int> = 0> - explicit StatusOrData(U&& v) : status_(std::forward<U>(v)) { - EnsureNotOk(); - } - - StatusOrData& operator=(const StatusOrData& other) { - if (this == &other) return *this; - if (other.ok()) - Assign(other.data_); - else - AssignStatus(other.status_); - return *this; - } - - StatusOrData& operator=(StatusOrData&& other) { - if (this == &other) return *this; - if (other.ok()) - Assign(std::move(other.data_)); - else - AssignStatus(std::move(other.status_)); - return *this; - } - - ~StatusOrData() { - if (ok()) { - status_.~Status(); - data_.~T(); - } else { - status_.~Status(); - } - } - - template <typename U> - void Assign(U&& value) { - if (ok()) { - data_ = std::forward<U>(value); - } else { - MakeValue(std::forward<U>(value)); - status_ = OkStatus(); - } - } - - template <typename U> - void AssignStatus(U&& v) { - Clear(); - status_ = static_cast<absl::Status>(std::forward<U>(v)); - EnsureNotOk(); - } - - bool ok() const { return status_.ok(); } - - protected: - // status_ will always be active after the constructor. - // We make it a union to be able to initialize exactly how we need without - // waste. - // Eg. in the copy constructor we use the default constructor of Status in - // the ok() path to avoid an extra Ref call. - union { - Status status_; - }; - - // data_ is active iff status_.ok()==true - struct Dummy {}; - union { - // When T is const, we need some non-const object we can cast to void* for - // the placement new. dummy_ is that object. - Dummy dummy_; - T data_; - }; - - void Clear() { - if (ok()) data_.~T(); - } - - void EnsureOk() const { - if (ABSL_PREDICT_FALSE(!ok())) Helper::Crash(status_); - } - - void EnsureNotOk() { - if (ABSL_PREDICT_FALSE(ok())) Helper::HandleInvalidStatusCtorArg(&status_); - } - - // Construct the value (ie. data_) through placement new with the passed - // argument. - template <typename... Arg> - void MakeValue(Arg&&... arg) { - internal_statusor::PlacementNew<T>(&dummy_, std::forward<Arg>(arg)...); - } - - // Construct the status (ie. status_) through placement new with the passed - // argument. - template <typename... Args> - void MakeStatus(Args&&... args) { - internal_statusor::PlacementNew<Status>(&status_, - std::forward<Args>(args)...); - } -}; - -// Helper base classes to allow implicitly deleted constructors and assignment -// operators in `StatusOr`. For example, `CopyCtorBase` will explicitly delete -// the copy constructor when T is not copy constructible and `StatusOr` will -// inherit that behavior implicitly. -template <typename T, bool = std::is_copy_constructible<T>::value> -struct CopyCtorBase { - CopyCtorBase() = default; - CopyCtorBase(const CopyCtorBase&) = default; - CopyCtorBase(CopyCtorBase&&) = default; - CopyCtorBase& operator=(const CopyCtorBase&) = default; - CopyCtorBase& operator=(CopyCtorBase&&) = default; -}; - -template <typename T> -struct CopyCtorBase<T, false> { - CopyCtorBase() = default; - CopyCtorBase(const CopyCtorBase&) = delete; - CopyCtorBase(CopyCtorBase&&) = default; - CopyCtorBase& operator=(const CopyCtorBase&) = default; - CopyCtorBase& operator=(CopyCtorBase&&) = default; -}; - -template <typename T, bool = std::is_move_constructible<T>::value> -struct MoveCtorBase { - MoveCtorBase() = default; - MoveCtorBase(const MoveCtorBase&) = default; - MoveCtorBase(MoveCtorBase&&) = default; - MoveCtorBase& operator=(const MoveCtorBase&) = default; - MoveCtorBase& operator=(MoveCtorBase&&) = default; -}; - -template <typename T> -struct MoveCtorBase<T, false> { - MoveCtorBase() = default; - MoveCtorBase(const MoveCtorBase&) = default; - MoveCtorBase(MoveCtorBase&&) = delete; - MoveCtorBase& operator=(const MoveCtorBase&) = default; - MoveCtorBase& operator=(MoveCtorBase&&) = default; -}; - -template <typename T, bool = std::is_copy_constructible<T>::value&& - std::is_copy_assignable<T>::value> -struct CopyAssignBase { - CopyAssignBase() = default; - CopyAssignBase(const CopyAssignBase&) = default; - CopyAssignBase(CopyAssignBase&&) = default; - CopyAssignBase& operator=(const CopyAssignBase&) = default; - CopyAssignBase& operator=(CopyAssignBase&&) = default; -}; - -template <typename T> -struct CopyAssignBase<T, false> { - CopyAssignBase() = default; - CopyAssignBase(const CopyAssignBase&) = default; - CopyAssignBase(CopyAssignBase&&) = default; - CopyAssignBase& operator=(const CopyAssignBase&) = delete; - CopyAssignBase& operator=(CopyAssignBase&&) = default; -}; - -template <typename T, bool = std::is_move_constructible<T>::value&& - std::is_move_assignable<T>::value> -struct MoveAssignBase { - MoveAssignBase() = default; - MoveAssignBase(const MoveAssignBase&) = default; - MoveAssignBase(MoveAssignBase&&) = default; - MoveAssignBase& operator=(const MoveAssignBase&) = default; - MoveAssignBase& operator=(MoveAssignBase&&) = default; -}; - -template <typename T> -struct MoveAssignBase<T, false> { - MoveAssignBase() = default; - MoveAssignBase(const MoveAssignBase&) = default; - MoveAssignBase(MoveAssignBase&&) = default; - MoveAssignBase& operator=(const MoveAssignBase&) = default; - MoveAssignBase& operator=(MoveAssignBase&&) = delete; -}; - -ABSL_ATTRIBUTE_NORETURN void ThrowBadStatusOrAccess(absl::Status status); - -} // namespace internal_statusor -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STATUS_INTERNAL_STATUSOR_INTERNAL_H_ + new (p) T(std::forward<Args>(args)...); +} + +// Helper base class to hold the data and all operations. +// We move all this to a base class to allow mixing with the appropriate +// TraitsBase specialization. +template <typename T> +class StatusOrData { + template <typename U> + friend class StatusOrData; + + public: + StatusOrData() = delete; + + StatusOrData(const StatusOrData& other) { + if (other.ok()) { + MakeValue(other.data_); + MakeStatus(); + } else { + MakeStatus(other.status_); + } + } + + StatusOrData(StatusOrData&& other) noexcept { + if (other.ok()) { + MakeValue(std::move(other.data_)); + MakeStatus(); + } else { + MakeStatus(std::move(other.status_)); + } + } + + template <typename U> + explicit StatusOrData(const StatusOrData<U>& other) { + if (other.ok()) { + MakeValue(other.data_); + MakeStatus(); + } else { + MakeStatus(other.status_); + } + } + + template <typename U> + explicit StatusOrData(StatusOrData<U>&& other) { + if (other.ok()) { + MakeValue(std::move(other.data_)); + MakeStatus(); + } else { + MakeStatus(std::move(other.status_)); + } + } + + template <typename... Args> + explicit StatusOrData(absl::in_place_t, Args&&... args) + : data_(std::forward<Args>(args)...) { + MakeStatus(); + } + + explicit StatusOrData(const T& value) : data_(value) { + MakeStatus(); + } + explicit StatusOrData(T&& value) : data_(std::move(value)) { + MakeStatus(); + } + + template <typename U, + absl::enable_if_t<std::is_constructible<absl::Status, U&&>::value, + int> = 0> + explicit StatusOrData(U&& v) : status_(std::forward<U>(v)) { + EnsureNotOk(); + } + + StatusOrData& operator=(const StatusOrData& other) { + if (this == &other) return *this; + if (other.ok()) + Assign(other.data_); + else + AssignStatus(other.status_); + return *this; + } + + StatusOrData& operator=(StatusOrData&& other) { + if (this == &other) return *this; + if (other.ok()) + Assign(std::move(other.data_)); + else + AssignStatus(std::move(other.status_)); + return *this; + } + + ~StatusOrData() { + if (ok()) { + status_.~Status(); + data_.~T(); + } else { + status_.~Status(); + } + } + + template <typename U> + void Assign(U&& value) { + if (ok()) { + data_ = std::forward<U>(value); + } else { + MakeValue(std::forward<U>(value)); + status_ = OkStatus(); + } + } + + template <typename U> + void AssignStatus(U&& v) { + Clear(); + status_ = static_cast<absl::Status>(std::forward<U>(v)); + EnsureNotOk(); + } + + bool ok() const { return status_.ok(); } + + protected: + // status_ will always be active after the constructor. + // We make it a union to be able to initialize exactly how we need without + // waste. + // Eg. in the copy constructor we use the default constructor of Status in + // the ok() path to avoid an extra Ref call. + union { + Status status_; + }; + + // data_ is active iff status_.ok()==true + struct Dummy {}; + union { + // When T is const, we need some non-const object we can cast to void* for + // the placement new. dummy_ is that object. + Dummy dummy_; + T data_; + }; + + void Clear() { + if (ok()) data_.~T(); + } + + void EnsureOk() const { + if (ABSL_PREDICT_FALSE(!ok())) Helper::Crash(status_); + } + + void EnsureNotOk() { + if (ABSL_PREDICT_FALSE(ok())) Helper::HandleInvalidStatusCtorArg(&status_); + } + + // Construct the value (ie. data_) through placement new with the passed + // argument. + template <typename... Arg> + void MakeValue(Arg&&... arg) { + internal_statusor::PlacementNew<T>(&dummy_, std::forward<Arg>(arg)...); + } + + // Construct the status (ie. status_) through placement new with the passed + // argument. + template <typename... Args> + void MakeStatus(Args&&... args) { + internal_statusor::PlacementNew<Status>(&status_, + std::forward<Args>(args)...); + } +}; + +// Helper base classes to allow implicitly deleted constructors and assignment +// operators in `StatusOr`. For example, `CopyCtorBase` will explicitly delete +// the copy constructor when T is not copy constructible and `StatusOr` will +// inherit that behavior implicitly. +template <typename T, bool = std::is_copy_constructible<T>::value> +struct CopyCtorBase { + CopyCtorBase() = default; + CopyCtorBase(const CopyCtorBase&) = default; + CopyCtorBase(CopyCtorBase&&) = default; + CopyCtorBase& operator=(const CopyCtorBase&) = default; + CopyCtorBase& operator=(CopyCtorBase&&) = default; +}; + +template <typename T> +struct CopyCtorBase<T, false> { + CopyCtorBase() = default; + CopyCtorBase(const CopyCtorBase&) = delete; + CopyCtorBase(CopyCtorBase&&) = default; + CopyCtorBase& operator=(const CopyCtorBase&) = default; + CopyCtorBase& operator=(CopyCtorBase&&) = default; +}; + +template <typename T, bool = std::is_move_constructible<T>::value> +struct MoveCtorBase { + MoveCtorBase() = default; + MoveCtorBase(const MoveCtorBase&) = default; + MoveCtorBase(MoveCtorBase&&) = default; + MoveCtorBase& operator=(const MoveCtorBase&) = default; + MoveCtorBase& operator=(MoveCtorBase&&) = default; +}; + +template <typename T> +struct MoveCtorBase<T, false> { + MoveCtorBase() = default; + MoveCtorBase(const MoveCtorBase&) = default; + MoveCtorBase(MoveCtorBase&&) = delete; + MoveCtorBase& operator=(const MoveCtorBase&) = default; + MoveCtorBase& operator=(MoveCtorBase&&) = default; +}; + +template <typename T, bool = std::is_copy_constructible<T>::value&& + std::is_copy_assignable<T>::value> +struct CopyAssignBase { + CopyAssignBase() = default; + CopyAssignBase(const CopyAssignBase&) = default; + CopyAssignBase(CopyAssignBase&&) = default; + CopyAssignBase& operator=(const CopyAssignBase&) = default; + CopyAssignBase& operator=(CopyAssignBase&&) = default; +}; + +template <typename T> +struct CopyAssignBase<T, false> { + CopyAssignBase() = default; + CopyAssignBase(const CopyAssignBase&) = default; + CopyAssignBase(CopyAssignBase&&) = default; + CopyAssignBase& operator=(const CopyAssignBase&) = delete; + CopyAssignBase& operator=(CopyAssignBase&&) = default; +}; + +template <typename T, bool = std::is_move_constructible<T>::value&& + std::is_move_assignable<T>::value> +struct MoveAssignBase { + MoveAssignBase() = default; + MoveAssignBase(const MoveAssignBase&) = default; + MoveAssignBase(MoveAssignBase&&) = default; + MoveAssignBase& operator=(const MoveAssignBase&) = default; + MoveAssignBase& operator=(MoveAssignBase&&) = default; +}; + +template <typename T> +struct MoveAssignBase<T, false> { + MoveAssignBase() = default; + MoveAssignBase(const MoveAssignBase&) = default; + MoveAssignBase(MoveAssignBase&&) = default; + MoveAssignBase& operator=(const MoveAssignBase&) = default; + MoveAssignBase& operator=(MoveAssignBase&&) = delete; +}; + +ABSL_ATTRIBUTE_NORETURN void ThrowBadStatusOrAccess(absl::Status status); + +} // namespace internal_statusor +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STATUS_INTERNAL_STATUSOR_INTERNAL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/status/status.cc b/contrib/restricted/abseil-cpp/absl/status/status.cc index bcf3413e5f..927ba5b92a 100644 --- a/contrib/restricted/abseil-cpp/absl/status/status.cc +++ b/contrib/restricted/abseil-cpp/absl/status/status.cc @@ -1,292 +1,292 @@ -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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 "absl/status/status.h" - -#include <cassert> - -#include "absl/base/internal/raw_logging.h" -#include "absl/debugging/stacktrace.h" -#include "absl/debugging/symbolize.h" -#include "absl/status/status_payload_printer.h" -#include "absl/strings/escaping.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" -#include "absl/strings/str_split.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -std::string StatusCodeToString(StatusCode code) { - switch (code) { - case StatusCode::kOk: - return "OK"; - case StatusCode::kCancelled: - return "CANCELLED"; - case StatusCode::kUnknown: - return "UNKNOWN"; - case StatusCode::kInvalidArgument: - return "INVALID_ARGUMENT"; - case StatusCode::kDeadlineExceeded: - return "DEADLINE_EXCEEDED"; - case StatusCode::kNotFound: - return "NOT_FOUND"; - case StatusCode::kAlreadyExists: - return "ALREADY_EXISTS"; - case StatusCode::kPermissionDenied: - return "PERMISSION_DENIED"; - case StatusCode::kUnauthenticated: - return "UNAUTHENTICATED"; - case StatusCode::kResourceExhausted: - return "RESOURCE_EXHAUSTED"; - case StatusCode::kFailedPrecondition: - return "FAILED_PRECONDITION"; - case StatusCode::kAborted: - return "ABORTED"; - case StatusCode::kOutOfRange: - return "OUT_OF_RANGE"; - case StatusCode::kUnimplemented: - return "UNIMPLEMENTED"; - case StatusCode::kInternal: - return "INTERNAL"; - case StatusCode::kUnavailable: - return "UNAVAILABLE"; - case StatusCode::kDataLoss: - return "DATA_LOSS"; - default: - return ""; - } -} - -std::ostream& operator<<(std::ostream& os, StatusCode code) { - return os << StatusCodeToString(code); -} - -namespace status_internal { - -static int FindPayloadIndexByUrl(const Payloads* payloads, - absl::string_view type_url) { - if (payloads == nullptr) return -1; - - for (size_t i = 0; i < payloads->size(); ++i) { - if ((*payloads)[i].type_url == type_url) return i; - } - - return -1; -} - -// Convert canonical code to a value known to this binary. -absl::StatusCode MapToLocalCode(int value) { - absl::StatusCode code = static_cast<absl::StatusCode>(value); - switch (code) { - case absl::StatusCode::kOk: - case absl::StatusCode::kCancelled: - case absl::StatusCode::kUnknown: - case absl::StatusCode::kInvalidArgument: - case absl::StatusCode::kDeadlineExceeded: - case absl::StatusCode::kNotFound: - case absl::StatusCode::kAlreadyExists: - case absl::StatusCode::kPermissionDenied: - case absl::StatusCode::kResourceExhausted: - case absl::StatusCode::kFailedPrecondition: - case absl::StatusCode::kAborted: - case absl::StatusCode::kOutOfRange: - case absl::StatusCode::kUnimplemented: - case absl::StatusCode::kInternal: - case absl::StatusCode::kUnavailable: - case absl::StatusCode::kDataLoss: - case absl::StatusCode::kUnauthenticated: - return code; - default: - return absl::StatusCode::kUnknown; - } -} -} // namespace status_internal - -absl::optional<absl::Cord> Status::GetPayload( - absl::string_view type_url) const { - const auto* payloads = GetPayloads(); - int index = status_internal::FindPayloadIndexByUrl(payloads, type_url); - if (index != -1) return (*payloads)[index].payload; - - return absl::nullopt; -} - -void Status::SetPayload(absl::string_view type_url, absl::Cord payload) { - if (ok()) return; - - PrepareToModify(); - - status_internal::StatusRep* rep = RepToPointer(rep_); - if (!rep->payloads) { - rep->payloads = absl::make_unique<status_internal::Payloads>(); - } - - int index = - status_internal::FindPayloadIndexByUrl(rep->payloads.get(), type_url); - if (index != -1) { - (*rep->payloads)[index].payload = std::move(payload); - return; - } - - rep->payloads->push_back({std::string(type_url), std::move(payload)}); -} - -bool Status::ErasePayload(absl::string_view type_url) { - int index = status_internal::FindPayloadIndexByUrl(GetPayloads(), type_url); - if (index != -1) { - PrepareToModify(); - GetPayloads()->erase(GetPayloads()->begin() + index); - if (GetPayloads()->empty() && message().empty()) { - // Special case: If this can be represented inlined, it MUST be - // inlined (EqualsSlow depends on this behavior). - StatusCode c = static_cast<StatusCode>(raw_code()); - Unref(rep_); - rep_ = CodeToInlinedRep(c); - } - return true; - } - - return false; -} - -void Status::ForEachPayload( +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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 "absl/status/status.h" + +#include <cassert> + +#include "absl/base/internal/raw_logging.h" +#include "absl/debugging/stacktrace.h" +#include "absl/debugging/symbolize.h" +#include "absl/status/status_payload_printer.h" +#include "absl/strings/escaping.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" +#include "absl/strings/str_split.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +std::string StatusCodeToString(StatusCode code) { + switch (code) { + case StatusCode::kOk: + return "OK"; + case StatusCode::kCancelled: + return "CANCELLED"; + case StatusCode::kUnknown: + return "UNKNOWN"; + case StatusCode::kInvalidArgument: + return "INVALID_ARGUMENT"; + case StatusCode::kDeadlineExceeded: + return "DEADLINE_EXCEEDED"; + case StatusCode::kNotFound: + return "NOT_FOUND"; + case StatusCode::kAlreadyExists: + return "ALREADY_EXISTS"; + case StatusCode::kPermissionDenied: + return "PERMISSION_DENIED"; + case StatusCode::kUnauthenticated: + return "UNAUTHENTICATED"; + case StatusCode::kResourceExhausted: + return "RESOURCE_EXHAUSTED"; + case StatusCode::kFailedPrecondition: + return "FAILED_PRECONDITION"; + case StatusCode::kAborted: + return "ABORTED"; + case StatusCode::kOutOfRange: + return "OUT_OF_RANGE"; + case StatusCode::kUnimplemented: + return "UNIMPLEMENTED"; + case StatusCode::kInternal: + return "INTERNAL"; + case StatusCode::kUnavailable: + return "UNAVAILABLE"; + case StatusCode::kDataLoss: + return "DATA_LOSS"; + default: + return ""; + } +} + +std::ostream& operator<<(std::ostream& os, StatusCode code) { + return os << StatusCodeToString(code); +} + +namespace status_internal { + +static int FindPayloadIndexByUrl(const Payloads* payloads, + absl::string_view type_url) { + if (payloads == nullptr) return -1; + + for (size_t i = 0; i < payloads->size(); ++i) { + if ((*payloads)[i].type_url == type_url) return i; + } + + return -1; +} + +// Convert canonical code to a value known to this binary. +absl::StatusCode MapToLocalCode(int value) { + absl::StatusCode code = static_cast<absl::StatusCode>(value); + switch (code) { + case absl::StatusCode::kOk: + case absl::StatusCode::kCancelled: + case absl::StatusCode::kUnknown: + case absl::StatusCode::kInvalidArgument: + case absl::StatusCode::kDeadlineExceeded: + case absl::StatusCode::kNotFound: + case absl::StatusCode::kAlreadyExists: + case absl::StatusCode::kPermissionDenied: + case absl::StatusCode::kResourceExhausted: + case absl::StatusCode::kFailedPrecondition: + case absl::StatusCode::kAborted: + case absl::StatusCode::kOutOfRange: + case absl::StatusCode::kUnimplemented: + case absl::StatusCode::kInternal: + case absl::StatusCode::kUnavailable: + case absl::StatusCode::kDataLoss: + case absl::StatusCode::kUnauthenticated: + return code; + default: + return absl::StatusCode::kUnknown; + } +} +} // namespace status_internal + +absl::optional<absl::Cord> Status::GetPayload( + absl::string_view type_url) const { + const auto* payloads = GetPayloads(); + int index = status_internal::FindPayloadIndexByUrl(payloads, type_url); + if (index != -1) return (*payloads)[index].payload; + + return absl::nullopt; +} + +void Status::SetPayload(absl::string_view type_url, absl::Cord payload) { + if (ok()) return; + + PrepareToModify(); + + status_internal::StatusRep* rep = RepToPointer(rep_); + if (!rep->payloads) { + rep->payloads = absl::make_unique<status_internal::Payloads>(); + } + + int index = + status_internal::FindPayloadIndexByUrl(rep->payloads.get(), type_url); + if (index != -1) { + (*rep->payloads)[index].payload = std::move(payload); + return; + } + + rep->payloads->push_back({std::string(type_url), std::move(payload)}); +} + +bool Status::ErasePayload(absl::string_view type_url) { + int index = status_internal::FindPayloadIndexByUrl(GetPayloads(), type_url); + if (index != -1) { + PrepareToModify(); + GetPayloads()->erase(GetPayloads()->begin() + index); + if (GetPayloads()->empty() && message().empty()) { + // Special case: If this can be represented inlined, it MUST be + // inlined (EqualsSlow depends on this behavior). + StatusCode c = static_cast<StatusCode>(raw_code()); + Unref(rep_); + rep_ = CodeToInlinedRep(c); + } + return true; + } + + return false; +} + +void Status::ForEachPayload( absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor) - const { - if (auto* payloads = GetPayloads()) { - bool in_reverse = - payloads->size() > 1 && reinterpret_cast<uintptr_t>(payloads) % 13 > 6; - - for (size_t index = 0; index < payloads->size(); ++index) { - const auto& elem = - (*payloads)[in_reverse ? payloads->size() - 1 - index : index]; - -#ifdef NDEBUG - visitor(elem.type_url, elem.payload); -#else - // In debug mode invalidate the type url to prevent users from relying on - // this string lifetime. - - // NOLINTNEXTLINE intentional extra conversion to force temporary. - visitor(std::string(elem.type_url), elem.payload); -#endif // NDEBUG - } - } -} - -const std::string* Status::EmptyString() { - static std::string* empty_string = new std::string(); - return empty_string; -} - -constexpr const char Status::kMovedFromString[]; - -const std::string* Status::MovedFromString() { - static std::string* moved_from_string = new std::string(kMovedFromString); - return moved_from_string; -} - -void Status::UnrefNonInlined(uintptr_t rep) { - status_internal::StatusRep* r = RepToPointer(rep); - // Fast path: if ref==1, there is no need for a RefCountDec (since - // this is the only reference and therefore no other thread is - // allowed to be mucking with r). - if (r->ref.load(std::memory_order_acquire) == 1 || - r->ref.fetch_sub(1, std::memory_order_acq_rel) - 1 == 0) { - delete r; - } -} - -Status::Status(absl::StatusCode code, absl::string_view msg) - : rep_(CodeToInlinedRep(code)) { - if (code != absl::StatusCode::kOk && !msg.empty()) { + const { + if (auto* payloads = GetPayloads()) { + bool in_reverse = + payloads->size() > 1 && reinterpret_cast<uintptr_t>(payloads) % 13 > 6; + + for (size_t index = 0; index < payloads->size(); ++index) { + const auto& elem = + (*payloads)[in_reverse ? payloads->size() - 1 - index : index]; + +#ifdef NDEBUG + visitor(elem.type_url, elem.payload); +#else + // In debug mode invalidate the type url to prevent users from relying on + // this string lifetime. + + // NOLINTNEXTLINE intentional extra conversion to force temporary. + visitor(std::string(elem.type_url), elem.payload); +#endif // NDEBUG + } + } +} + +const std::string* Status::EmptyString() { + static std::string* empty_string = new std::string(); + return empty_string; +} + +constexpr const char Status::kMovedFromString[]; + +const std::string* Status::MovedFromString() { + static std::string* moved_from_string = new std::string(kMovedFromString); + return moved_from_string; +} + +void Status::UnrefNonInlined(uintptr_t rep) { + status_internal::StatusRep* r = RepToPointer(rep); + // Fast path: if ref==1, there is no need for a RefCountDec (since + // this is the only reference and therefore no other thread is + // allowed to be mucking with r). + if (r->ref.load(std::memory_order_acquire) == 1 || + r->ref.fetch_sub(1, std::memory_order_acq_rel) - 1 == 0) { + delete r; + } +} + +Status::Status(absl::StatusCode code, absl::string_view msg) + : rep_(CodeToInlinedRep(code)) { + if (code != absl::StatusCode::kOk && !msg.empty()) { rep_ = PointerToRep(new status_internal::StatusRep(code, msg, nullptr)); - } -} - -int Status::raw_code() const { - if (IsInlined(rep_)) { - return static_cast<int>(InlinedRepToCode(rep_)); - } - status_internal::StatusRep* rep = RepToPointer(rep_); - return static_cast<int>(rep->code); -} - -absl::StatusCode Status::code() const { - return status_internal::MapToLocalCode(raw_code()); -} - -void Status::PrepareToModify() { - ABSL_RAW_CHECK(!ok(), "PrepareToModify shouldn't be called on OK status."); - if (IsInlined(rep_)) { + } +} + +int Status::raw_code() const { + if (IsInlined(rep_)) { + return static_cast<int>(InlinedRepToCode(rep_)); + } + status_internal::StatusRep* rep = RepToPointer(rep_); + return static_cast<int>(rep->code); +} + +absl::StatusCode Status::code() const { + return status_internal::MapToLocalCode(raw_code()); +} + +void Status::PrepareToModify() { + ABSL_RAW_CHECK(!ok(), "PrepareToModify shouldn't be called on OK status."); + if (IsInlined(rep_)) { rep_ = PointerToRep(new status_internal::StatusRep( static_cast<absl::StatusCode>(raw_code()), absl::string_view(), nullptr)); - return; - } - - uintptr_t rep_i = rep_; - status_internal::StatusRep* rep = RepToPointer(rep_); - if (rep->ref.load(std::memory_order_acquire) != 1) { - std::unique_ptr<status_internal::Payloads> payloads; - if (rep->payloads) { - payloads = absl::make_unique<status_internal::Payloads>(*rep->payloads); - } + return; + } + + uintptr_t rep_i = rep_; + status_internal::StatusRep* rep = RepToPointer(rep_); + if (rep->ref.load(std::memory_order_acquire) != 1) { + std::unique_ptr<status_internal::Payloads> payloads; + if (rep->payloads) { + payloads = absl::make_unique<status_internal::Payloads>(*rep->payloads); + } status_internal::StatusRep* const new_rep = new status_internal::StatusRep( rep->code, message(), std::move(payloads)); rep_ = PointerToRep(new_rep); - UnrefNonInlined(rep_i); - } -} - -bool Status::EqualsSlow(const absl::Status& a, const absl::Status& b) { - if (IsInlined(a.rep_) != IsInlined(b.rep_)) return false; - if (a.message() != b.message()) return false; - if (a.raw_code() != b.raw_code()) return false; - if (a.GetPayloads() == b.GetPayloads()) return true; - - const status_internal::Payloads no_payloads; - const status_internal::Payloads* larger_payloads = - a.GetPayloads() ? a.GetPayloads() : &no_payloads; - const status_internal::Payloads* smaller_payloads = - b.GetPayloads() ? b.GetPayloads() : &no_payloads; - if (larger_payloads->size() < smaller_payloads->size()) { - std::swap(larger_payloads, smaller_payloads); - } - if ((larger_payloads->size() - smaller_payloads->size()) > 1) return false; - // Payloads can be ordered differently, so we can't just compare payload - // vectors. - for (const auto& payload : *larger_payloads) { - - bool found = false; - for (const auto& other_payload : *smaller_payloads) { - if (payload.type_url == other_payload.type_url) { - if (payload.payload != other_payload.payload) { - return false; - } - found = true; - break; - } - } - if (!found) return false; - } - return true; -} - + UnrefNonInlined(rep_i); + } +} + +bool Status::EqualsSlow(const absl::Status& a, const absl::Status& b) { + if (IsInlined(a.rep_) != IsInlined(b.rep_)) return false; + if (a.message() != b.message()) return false; + if (a.raw_code() != b.raw_code()) return false; + if (a.GetPayloads() == b.GetPayloads()) return true; + + const status_internal::Payloads no_payloads; + const status_internal::Payloads* larger_payloads = + a.GetPayloads() ? a.GetPayloads() : &no_payloads; + const status_internal::Payloads* smaller_payloads = + b.GetPayloads() ? b.GetPayloads() : &no_payloads; + if (larger_payloads->size() < smaller_payloads->size()) { + std::swap(larger_payloads, smaller_payloads); + } + if ((larger_payloads->size() - smaller_payloads->size()) > 1) return false; + // Payloads can be ordered differently, so we can't just compare payload + // vectors. + for (const auto& payload : *larger_payloads) { + + bool found = false; + for (const auto& other_payload : *smaller_payloads) { + if (payload.type_url == other_payload.type_url) { + if (payload.payload != other_payload.payload) { + return false; + } + found = true; + break; + } + } + if (!found) return false; + } + return true; +} + std::string Status::ToStringSlow(StatusToStringMode mode) const { - std::string text; - absl::StrAppend(&text, absl::StatusCodeToString(code()), ": ", message()); - + std::string text; + absl::StrAppend(&text, absl::StatusCodeToString(code()), ": ", message()); + const bool with_payload = (mode & StatusToStringMode::kWithPayload) == StatusToStringMode::kWithPayload; @@ -304,141 +304,141 @@ std::string Status::ToStringSlow(StatusToStringMode mode) const { }); } - return text; -} - -std::ostream& operator<<(std::ostream& os, const Status& x) { + return text; +} + +std::ostream& operator<<(std::ostream& os, const Status& x) { os << x.ToString(StatusToStringMode::kWithEverything); - return os; -} - -Status AbortedError(absl::string_view message) { - return Status(absl::StatusCode::kAborted, message); -} - -Status AlreadyExistsError(absl::string_view message) { - return Status(absl::StatusCode::kAlreadyExists, message); -} - -Status CancelledError(absl::string_view message) { - return Status(absl::StatusCode::kCancelled, message); -} - -Status DataLossError(absl::string_view message) { - return Status(absl::StatusCode::kDataLoss, message); -} - -Status DeadlineExceededError(absl::string_view message) { - return Status(absl::StatusCode::kDeadlineExceeded, message); -} - -Status FailedPreconditionError(absl::string_view message) { - return Status(absl::StatusCode::kFailedPrecondition, message); -} - -Status InternalError(absl::string_view message) { - return Status(absl::StatusCode::kInternal, message); -} - -Status InvalidArgumentError(absl::string_view message) { - return Status(absl::StatusCode::kInvalidArgument, message); -} - -Status NotFoundError(absl::string_view message) { - return Status(absl::StatusCode::kNotFound, message); -} - -Status OutOfRangeError(absl::string_view message) { - return Status(absl::StatusCode::kOutOfRange, message); -} - -Status PermissionDeniedError(absl::string_view message) { - return Status(absl::StatusCode::kPermissionDenied, message); -} - -Status ResourceExhaustedError(absl::string_view message) { - return Status(absl::StatusCode::kResourceExhausted, message); -} - -Status UnauthenticatedError(absl::string_view message) { - return Status(absl::StatusCode::kUnauthenticated, message); -} - -Status UnavailableError(absl::string_view message) { - return Status(absl::StatusCode::kUnavailable, message); -} - -Status UnimplementedError(absl::string_view message) { - return Status(absl::StatusCode::kUnimplemented, message); -} - -Status UnknownError(absl::string_view message) { - return Status(absl::StatusCode::kUnknown, message); -} - -bool IsAborted(const Status& status) { - return status.code() == absl::StatusCode::kAborted; -} - -bool IsAlreadyExists(const Status& status) { - return status.code() == absl::StatusCode::kAlreadyExists; -} - -bool IsCancelled(const Status& status) { - return status.code() == absl::StatusCode::kCancelled; -} - -bool IsDataLoss(const Status& status) { - return status.code() == absl::StatusCode::kDataLoss; -} - -bool IsDeadlineExceeded(const Status& status) { - return status.code() == absl::StatusCode::kDeadlineExceeded; -} - -bool IsFailedPrecondition(const Status& status) { - return status.code() == absl::StatusCode::kFailedPrecondition; -} - -bool IsInternal(const Status& status) { - return status.code() == absl::StatusCode::kInternal; -} - -bool IsInvalidArgument(const Status& status) { - return status.code() == absl::StatusCode::kInvalidArgument; -} - -bool IsNotFound(const Status& status) { - return status.code() == absl::StatusCode::kNotFound; -} - -bool IsOutOfRange(const Status& status) { - return status.code() == absl::StatusCode::kOutOfRange; -} - -bool IsPermissionDenied(const Status& status) { - return status.code() == absl::StatusCode::kPermissionDenied; -} - -bool IsResourceExhausted(const Status& status) { - return status.code() == absl::StatusCode::kResourceExhausted; -} - -bool IsUnauthenticated(const Status& status) { - return status.code() == absl::StatusCode::kUnauthenticated; -} - -bool IsUnavailable(const Status& status) { - return status.code() == absl::StatusCode::kUnavailable; -} - -bool IsUnimplemented(const Status& status) { - return status.code() == absl::StatusCode::kUnimplemented; -} - -bool IsUnknown(const Status& status) { - return status.code() == absl::StatusCode::kUnknown; -} - -ABSL_NAMESPACE_END -} // namespace absl + return os; +} + +Status AbortedError(absl::string_view message) { + return Status(absl::StatusCode::kAborted, message); +} + +Status AlreadyExistsError(absl::string_view message) { + return Status(absl::StatusCode::kAlreadyExists, message); +} + +Status CancelledError(absl::string_view message) { + return Status(absl::StatusCode::kCancelled, message); +} + +Status DataLossError(absl::string_view message) { + return Status(absl::StatusCode::kDataLoss, message); +} + +Status DeadlineExceededError(absl::string_view message) { + return Status(absl::StatusCode::kDeadlineExceeded, message); +} + +Status FailedPreconditionError(absl::string_view message) { + return Status(absl::StatusCode::kFailedPrecondition, message); +} + +Status InternalError(absl::string_view message) { + return Status(absl::StatusCode::kInternal, message); +} + +Status InvalidArgumentError(absl::string_view message) { + return Status(absl::StatusCode::kInvalidArgument, message); +} + +Status NotFoundError(absl::string_view message) { + return Status(absl::StatusCode::kNotFound, message); +} + +Status OutOfRangeError(absl::string_view message) { + return Status(absl::StatusCode::kOutOfRange, message); +} + +Status PermissionDeniedError(absl::string_view message) { + return Status(absl::StatusCode::kPermissionDenied, message); +} + +Status ResourceExhaustedError(absl::string_view message) { + return Status(absl::StatusCode::kResourceExhausted, message); +} + +Status UnauthenticatedError(absl::string_view message) { + return Status(absl::StatusCode::kUnauthenticated, message); +} + +Status UnavailableError(absl::string_view message) { + return Status(absl::StatusCode::kUnavailable, message); +} + +Status UnimplementedError(absl::string_view message) { + return Status(absl::StatusCode::kUnimplemented, message); +} + +Status UnknownError(absl::string_view message) { + return Status(absl::StatusCode::kUnknown, message); +} + +bool IsAborted(const Status& status) { + return status.code() == absl::StatusCode::kAborted; +} + +bool IsAlreadyExists(const Status& status) { + return status.code() == absl::StatusCode::kAlreadyExists; +} + +bool IsCancelled(const Status& status) { + return status.code() == absl::StatusCode::kCancelled; +} + +bool IsDataLoss(const Status& status) { + return status.code() == absl::StatusCode::kDataLoss; +} + +bool IsDeadlineExceeded(const Status& status) { + return status.code() == absl::StatusCode::kDeadlineExceeded; +} + +bool IsFailedPrecondition(const Status& status) { + return status.code() == absl::StatusCode::kFailedPrecondition; +} + +bool IsInternal(const Status& status) { + return status.code() == absl::StatusCode::kInternal; +} + +bool IsInvalidArgument(const Status& status) { + return status.code() == absl::StatusCode::kInvalidArgument; +} + +bool IsNotFound(const Status& status) { + return status.code() == absl::StatusCode::kNotFound; +} + +bool IsOutOfRange(const Status& status) { + return status.code() == absl::StatusCode::kOutOfRange; +} + +bool IsPermissionDenied(const Status& status) { + return status.code() == absl::StatusCode::kPermissionDenied; +} + +bool IsResourceExhausted(const Status& status) { + return status.code() == absl::StatusCode::kResourceExhausted; +} + +bool IsUnauthenticated(const Status& status) { + return status.code() == absl::StatusCode::kUnauthenticated; +} + +bool IsUnavailable(const Status& status) { + return status.code() == absl::StatusCode::kUnavailable; +} + +bool IsUnimplemented(const Status& status) { + return status.code() == absl::StatusCode::kUnimplemented; +} + +bool IsUnknown(const Status& status) { + return status.code() == absl::StatusCode::kUnknown; +} + +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/status/status.h b/contrib/restricted/abseil-cpp/absl/status/status.h index 39071e5f4a..3d1d137e07 100644 --- a/contrib/restricted/abseil-cpp/absl/status/status.h +++ b/contrib/restricted/abseil-cpp/absl/status/status.h @@ -1,287 +1,287 @@ -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// File: status.h -// ----------------------------------------------------------------------------- -// -// This header file defines the Abseil `status` library, consisting of: -// -// * An `absl::Status` class for holding error handling information -// * A set of canonical `absl::StatusCode` error codes, and associated -// utilities for generating and propagating status codes. -// * A set of helper functions for creating status codes and checking their -// values -// -// Within Google, `absl::Status` is the primary mechanism for gracefully -// handling errors across API boundaries (and in particular across RPC -// boundaries). Some of these errors may be recoverable, but others may not. -// Most functions that can produce a recoverable error should be designed to -// return an `absl::Status` (or `absl::StatusOr`). -// -// Example: -// -// absl::Status myFunction(absl::string_view fname, ...) { -// ... -// // encounter error -// if (error condition) { -// return absl::InvalidArgumentError("bad mode"); -// } -// // else, return OK -// return absl::OkStatus(); -// } -// -// An `absl::Status` is designed to either return "OK" or one of a number of -// different error codes, corresponding to typical error conditions. -// In almost all cases, when using `absl::Status` you should use the canonical -// error codes (of type `absl::StatusCode`) enumerated in this header file. -// These canonical codes are understood across the codebase and will be -// accepted across all API and RPC boundaries. -#ifndef ABSL_STATUS_STATUS_H_ -#define ABSL_STATUS_STATUS_H_ - -#include <iostream> -#include <string> - -#include "absl/container/inlined_vector.h" +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// File: status.h +// ----------------------------------------------------------------------------- +// +// This header file defines the Abseil `status` library, consisting of: +// +// * An `absl::Status` class for holding error handling information +// * A set of canonical `absl::StatusCode` error codes, and associated +// utilities for generating and propagating status codes. +// * A set of helper functions for creating status codes and checking their +// values +// +// Within Google, `absl::Status` is the primary mechanism for gracefully +// handling errors across API boundaries (and in particular across RPC +// boundaries). Some of these errors may be recoverable, but others may not. +// Most functions that can produce a recoverable error should be designed to +// return an `absl::Status` (or `absl::StatusOr`). +// +// Example: +// +// absl::Status myFunction(absl::string_view fname, ...) { +// ... +// // encounter error +// if (error condition) { +// return absl::InvalidArgumentError("bad mode"); +// } +// // else, return OK +// return absl::OkStatus(); +// } +// +// An `absl::Status` is designed to either return "OK" or one of a number of +// different error codes, corresponding to typical error conditions. +// In almost all cases, when using `absl::Status` you should use the canonical +// error codes (of type `absl::StatusCode`) enumerated in this header file. +// These canonical codes are understood across the codebase and will be +// accepted across all API and RPC boundaries. +#ifndef ABSL_STATUS_STATUS_H_ +#define ABSL_STATUS_STATUS_H_ + +#include <iostream> +#include <string> + +#include "absl/container/inlined_vector.h" #include "absl/functional/function_ref.h" -#include "absl/status/internal/status_internal.h" -#include "absl/strings/cord.h" +#include "absl/status/internal/status_internal.h" +#include "absl/strings/cord.h" #include "absl/strings/string_view.h" -#include "absl/types/optional.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -// absl::StatusCode -// -// An `absl::StatusCode` is an enumerated type indicating either no error ("OK") -// or an error condition. In most cases, an `absl::Status` indicates a -// recoverable error, and the purpose of signalling an error is to indicate what -// action to take in response to that error. These error codes map to the proto -// RPC error codes indicated in https://cloud.google.com/apis/design/errors. -// -// The errors listed below are the canonical errors associated with -// `absl::Status` and are used throughout the codebase. As a result, these -// error codes are somewhat generic. -// -// In general, try to return the most specific error that applies if more than -// one error may pertain. For example, prefer `kOutOfRange` over -// `kFailedPrecondition` if both codes apply. Similarly prefer `kNotFound` or -// `kAlreadyExists` over `kFailedPrecondition`. -// +#include "absl/types/optional.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +// absl::StatusCode +// +// An `absl::StatusCode` is an enumerated type indicating either no error ("OK") +// or an error condition. In most cases, an `absl::Status` indicates a +// recoverable error, and the purpose of signalling an error is to indicate what +// action to take in response to that error. These error codes map to the proto +// RPC error codes indicated in https://cloud.google.com/apis/design/errors. +// +// The errors listed below are the canonical errors associated with +// `absl::Status` and are used throughout the codebase. As a result, these +// error codes are somewhat generic. +// +// In general, try to return the most specific error that applies if more than +// one error may pertain. For example, prefer `kOutOfRange` over +// `kFailedPrecondition` if both codes apply. Similarly prefer `kNotFound` or +// `kAlreadyExists` over `kFailedPrecondition`. +// // Because these errors may cross RPC boundaries, these codes are tied to the -// `google.rpc.Code` definitions within -// https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto -// The string value of these RPC codes is denoted within each enum below. -// -// If your error handling code requires more context, you can attach payloads -// to your status. See `absl::Status::SetPayload()` and -// `absl::Status::GetPayload()` below. -enum class StatusCode : int { - // StatusCode::kOk - // - // kOK (gRPC code "OK") does not indicate an error; this value is returned on - // success. It is typical to check for this value before proceeding on any - // given call across an API or RPC boundary. To check this value, use the - // `absl::Status::ok()` member function rather than inspecting the raw code. - kOk = 0, - - // StatusCode::kCancelled - // - // kCancelled (gRPC code "CANCELLED") indicates the operation was cancelled, - // typically by the caller. - kCancelled = 1, - - // StatusCode::kUnknown - // - // kUnknown (gRPC code "UNKNOWN") indicates an unknown error occurred. In - // general, more specific errors should be raised, if possible. Errors raised - // by APIs that do not return enough error information may be converted to - // this error. - kUnknown = 2, - - // StatusCode::kInvalidArgument - // - // kInvalidArgument (gRPC code "INVALID_ARGUMENT") indicates the caller +// `google.rpc.Code` definitions within +// https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto +// The string value of these RPC codes is denoted within each enum below. +// +// If your error handling code requires more context, you can attach payloads +// to your status. See `absl::Status::SetPayload()` and +// `absl::Status::GetPayload()` below. +enum class StatusCode : int { + // StatusCode::kOk + // + // kOK (gRPC code "OK") does not indicate an error; this value is returned on + // success. It is typical to check for this value before proceeding on any + // given call across an API or RPC boundary. To check this value, use the + // `absl::Status::ok()` member function rather than inspecting the raw code. + kOk = 0, + + // StatusCode::kCancelled + // + // kCancelled (gRPC code "CANCELLED") indicates the operation was cancelled, + // typically by the caller. + kCancelled = 1, + + // StatusCode::kUnknown + // + // kUnknown (gRPC code "UNKNOWN") indicates an unknown error occurred. In + // general, more specific errors should be raised, if possible. Errors raised + // by APIs that do not return enough error information may be converted to + // this error. + kUnknown = 2, + + // StatusCode::kInvalidArgument + // + // kInvalidArgument (gRPC code "INVALID_ARGUMENT") indicates the caller // specified an invalid argument, such as a malformed filename. Note that use // of such errors should be narrowly limited to indicate the invalid nature of // the arguments themselves. Errors with validly formed arguments that may // cause errors with the state of the receiving system should be denoted with - // `kFailedPrecondition` instead. - kInvalidArgument = 3, - - // StatusCode::kDeadlineExceeded - // - // kDeadlineExceeded (gRPC code "DEADLINE_EXCEEDED") indicates a deadline - // expired before the operation could complete. For operations that may change - // state within a system, this error may be returned even if the operation has - // completed successfully. For example, a successful response from a server - // could have been delayed long enough for the deadline to expire. - kDeadlineExceeded = 4, - - // StatusCode::kNotFound - // - // kNotFound (gRPC code "NOT_FOUND") indicates some requested entity (such as - // a file or directory) was not found. - // - // `kNotFound` is useful if a request should be denied for an entire class of - // users, such as during a gradual feature rollout or undocumented allow list. + // `kFailedPrecondition` instead. + kInvalidArgument = 3, + + // StatusCode::kDeadlineExceeded + // + // kDeadlineExceeded (gRPC code "DEADLINE_EXCEEDED") indicates a deadline + // expired before the operation could complete. For operations that may change + // state within a system, this error may be returned even if the operation has + // completed successfully. For example, a successful response from a server + // could have been delayed long enough for the deadline to expire. + kDeadlineExceeded = 4, + + // StatusCode::kNotFound + // + // kNotFound (gRPC code "NOT_FOUND") indicates some requested entity (such as + // a file or directory) was not found. + // + // `kNotFound` is useful if a request should be denied for an entire class of + // users, such as during a gradual feature rollout or undocumented allow list. // If a request should be denied for specific sets of users, such as through // user-based access control, use `kPermissionDenied` instead. - kNotFound = 5, - - // StatusCode::kAlreadyExists - // + kNotFound = 5, + + // StatusCode::kAlreadyExists + // // kAlreadyExists (gRPC code "ALREADY_EXISTS") indicates that the entity a // caller attempted to create (such as a file or directory) is already // present. - kAlreadyExists = 6, - - // StatusCode::kPermissionDenied - // - // kPermissionDenied (gRPC code "PERMISSION_DENIED") indicates that the caller - // does not have permission to execute the specified operation. Note that this - // error is different than an error due to an *un*authenticated user. This - // error code does not imply the request is valid or the requested entity - // exists or satisfies any other pre-conditions. - // - // `kPermissionDenied` must not be used for rejections caused by exhausting - // some resource. Instead, use `kResourceExhausted` for those errors. - // `kPermissionDenied` must not be used if the caller cannot be identified. - // Instead, use `kUnauthenticated` for those errors. - kPermissionDenied = 7, - - // StatusCode::kResourceExhausted - // - // kResourceExhausted (gRPC code "RESOURCE_EXHAUSTED") indicates some resource - // has been exhausted, perhaps a per-user quota, or perhaps the entire file - // system is out of space. - kResourceExhausted = 8, - - // StatusCode::kFailedPrecondition - // - // kFailedPrecondition (gRPC code "FAILED_PRECONDITION") indicates that the - // operation was rejected because the system is not in a state required for - // the operation's execution. For example, a directory to be deleted may be - // non-empty, an "rmdir" operation is applied to a non-directory, etc. - // - // Some guidelines that may help a service implementer in deciding between - // `kFailedPrecondition`, `kAborted`, and `kUnavailable`: - // - // (a) Use `kUnavailable` if the client can retry just the failing call. - // (b) Use `kAborted` if the client should retry at a higher transaction - // level (such as when a client-specified test-and-set fails, indicating - // the client should restart a read-modify-write sequence). - // (c) Use `kFailedPrecondition` if the client should not retry until + kAlreadyExists = 6, + + // StatusCode::kPermissionDenied + // + // kPermissionDenied (gRPC code "PERMISSION_DENIED") indicates that the caller + // does not have permission to execute the specified operation. Note that this + // error is different than an error due to an *un*authenticated user. This + // error code does not imply the request is valid or the requested entity + // exists or satisfies any other pre-conditions. + // + // `kPermissionDenied` must not be used for rejections caused by exhausting + // some resource. Instead, use `kResourceExhausted` for those errors. + // `kPermissionDenied` must not be used if the caller cannot be identified. + // Instead, use `kUnauthenticated` for those errors. + kPermissionDenied = 7, + + // StatusCode::kResourceExhausted + // + // kResourceExhausted (gRPC code "RESOURCE_EXHAUSTED") indicates some resource + // has been exhausted, perhaps a per-user quota, or perhaps the entire file + // system is out of space. + kResourceExhausted = 8, + + // StatusCode::kFailedPrecondition + // + // kFailedPrecondition (gRPC code "FAILED_PRECONDITION") indicates that the + // operation was rejected because the system is not in a state required for + // the operation's execution. For example, a directory to be deleted may be + // non-empty, an "rmdir" operation is applied to a non-directory, etc. + // + // Some guidelines that may help a service implementer in deciding between + // `kFailedPrecondition`, `kAborted`, and `kUnavailable`: + // + // (a) Use `kUnavailable` if the client can retry just the failing call. + // (b) Use `kAborted` if the client should retry at a higher transaction + // level (such as when a client-specified test-and-set fails, indicating + // the client should restart a read-modify-write sequence). + // (c) Use `kFailedPrecondition` if the client should not retry until // the system state has been explicitly fixed. For example, if a "rmdir" - // fails because the directory is non-empty, `kFailedPrecondition` - // should be returned since the client should not retry unless - // the files are deleted from the directory. - kFailedPrecondition = 9, - - // StatusCode::kAborted - // - // kAborted (gRPC code "ABORTED") indicates the operation was aborted, - // typically due to a concurrency issue such as a sequencer check failure or a - // failed transaction. - // - // See the guidelines above for deciding between `kFailedPrecondition`, - // `kAborted`, and `kUnavailable`. - kAborted = 10, - - // StatusCode::kOutOfRange - // - // kOutOfRange (gRPC code "OUT_OF_RANGE") indicates the operation was - // attempted past the valid range, such as seeking or reading past an - // end-of-file. - // - // Unlike `kInvalidArgument`, this error indicates a problem that may - // be fixed if the system state changes. For example, a 32-bit file - // system will generate `kInvalidArgument` if asked to read at an - // offset that is not in the range [0,2^32-1], but it will generate - // `kOutOfRange` if asked to read from an offset past the current - // file size. - // - // There is a fair bit of overlap between `kFailedPrecondition` and - // `kOutOfRange`. We recommend using `kOutOfRange` (the more specific - // error) when it applies so that callers who are iterating through - // a space can easily look for an `kOutOfRange` error to detect when - // they are done. - kOutOfRange = 11, - - // StatusCode::kUnimplemented - // - // kUnimplemented (gRPC code "UNIMPLEMENTED") indicates the operation is not - // implemented or supported in this service. In this case, the operation - // should not be re-attempted. - kUnimplemented = 12, - - // StatusCode::kInternal - // - // kInternal (gRPC code "INTERNAL") indicates an internal error has occurred - // and some invariants expected by the underlying system have not been - // satisfied. This error code is reserved for serious errors. - kInternal = 13, - - // StatusCode::kUnavailable - // - // kUnavailable (gRPC code "UNAVAILABLE") indicates the service is currently - // unavailable and that this is most likely a transient condition. An error - // such as this can be corrected by retrying with a backoff scheme. Note that - // it is not always safe to retry non-idempotent operations. - // - // See the guidelines above for deciding between `kFailedPrecondition`, - // `kAborted`, and `kUnavailable`. - kUnavailable = 14, - - // StatusCode::kDataLoss - // - // kDataLoss (gRPC code "DATA_LOSS") indicates that unrecoverable data loss or - // corruption has occurred. As this error is serious, proper alerting should - // be attached to errors such as this. - kDataLoss = 15, - - // StatusCode::kUnauthenticated - // - // kUnauthenticated (gRPC code "UNAUTHENTICATED") indicates that the request - // does not have valid authentication credentials for the operation. Correct - // the authentication and try again. - kUnauthenticated = 16, - - // StatusCode::DoNotUseReservedForFutureExpansionUseDefaultInSwitchInstead_ - // - // NOTE: this error code entry should not be used and you should not rely on - // its value, which may change. - // - // The purpose of this enumerated value is to force people who handle status - // codes with `switch()` statements to *not* simply enumerate all possible - // values, but instead provide a "default:" case. Providing such a default - // case ensures that code will compile when new codes are added. - kDoNotUseReservedForFutureExpansionUseDefaultInSwitchInstead_ = 20 -}; - -// StatusCodeToString() -// -// Returns the name for the status code, or "" if it is an unknown value. -std::string StatusCodeToString(StatusCode code); - -// operator<< -// -// Streams StatusCodeToString(code) to `os`. -std::ostream& operator<<(std::ostream& os, StatusCode code); - + // fails because the directory is non-empty, `kFailedPrecondition` + // should be returned since the client should not retry unless + // the files are deleted from the directory. + kFailedPrecondition = 9, + + // StatusCode::kAborted + // + // kAborted (gRPC code "ABORTED") indicates the operation was aborted, + // typically due to a concurrency issue such as a sequencer check failure or a + // failed transaction. + // + // See the guidelines above for deciding between `kFailedPrecondition`, + // `kAborted`, and `kUnavailable`. + kAborted = 10, + + // StatusCode::kOutOfRange + // + // kOutOfRange (gRPC code "OUT_OF_RANGE") indicates the operation was + // attempted past the valid range, such as seeking or reading past an + // end-of-file. + // + // Unlike `kInvalidArgument`, this error indicates a problem that may + // be fixed if the system state changes. For example, a 32-bit file + // system will generate `kInvalidArgument` if asked to read at an + // offset that is not in the range [0,2^32-1], but it will generate + // `kOutOfRange` if asked to read from an offset past the current + // file size. + // + // There is a fair bit of overlap between `kFailedPrecondition` and + // `kOutOfRange`. We recommend using `kOutOfRange` (the more specific + // error) when it applies so that callers who are iterating through + // a space can easily look for an `kOutOfRange` error to detect when + // they are done. + kOutOfRange = 11, + + // StatusCode::kUnimplemented + // + // kUnimplemented (gRPC code "UNIMPLEMENTED") indicates the operation is not + // implemented or supported in this service. In this case, the operation + // should not be re-attempted. + kUnimplemented = 12, + + // StatusCode::kInternal + // + // kInternal (gRPC code "INTERNAL") indicates an internal error has occurred + // and some invariants expected by the underlying system have not been + // satisfied. This error code is reserved for serious errors. + kInternal = 13, + + // StatusCode::kUnavailable + // + // kUnavailable (gRPC code "UNAVAILABLE") indicates the service is currently + // unavailable and that this is most likely a transient condition. An error + // such as this can be corrected by retrying with a backoff scheme. Note that + // it is not always safe to retry non-idempotent operations. + // + // See the guidelines above for deciding between `kFailedPrecondition`, + // `kAborted`, and `kUnavailable`. + kUnavailable = 14, + + // StatusCode::kDataLoss + // + // kDataLoss (gRPC code "DATA_LOSS") indicates that unrecoverable data loss or + // corruption has occurred. As this error is serious, proper alerting should + // be attached to errors such as this. + kDataLoss = 15, + + // StatusCode::kUnauthenticated + // + // kUnauthenticated (gRPC code "UNAUTHENTICATED") indicates that the request + // does not have valid authentication credentials for the operation. Correct + // the authentication and try again. + kUnauthenticated = 16, + + // StatusCode::DoNotUseReservedForFutureExpansionUseDefaultInSwitchInstead_ + // + // NOTE: this error code entry should not be used and you should not rely on + // its value, which may change. + // + // The purpose of this enumerated value is to force people who handle status + // codes with `switch()` statements to *not* simply enumerate all possible + // values, but instead provide a "default:" case. Providing such a default + // case ensures that code will compile when new codes are added. + kDoNotUseReservedForFutureExpansionUseDefaultInSwitchInstead_ = 20 +}; + +// StatusCodeToString() +// +// Returns the name for the status code, or "" if it is an unknown value. +std::string StatusCodeToString(StatusCode code); + +// operator<< +// +// Streams StatusCodeToString(code) to `os`. +std::ostream& operator<<(std::ostream& os, StatusCode code); + // absl::StatusToStringMode // // An `absl::StatusToStringMode` is an enumerated type indicating how @@ -335,548 +335,548 @@ inline StatusToStringMode& operator^=(StatusToStringMode& lhs, return lhs; } -// absl::Status -// -// The `absl::Status` class is generally used to gracefully handle errors -// across API boundaries (and in particular across RPC boundaries). Some of -// these errors may be recoverable, but others may not. Most -// functions which can produce a recoverable error should be designed to return -// either an `absl::Status` (or the similar `absl::StatusOr<T>`, which holds -// either an object of type `T` or an error). -// -// API developers should construct their functions to return `absl::OkStatus()` -// upon success, or an `absl::StatusCode` upon another type of error (e.g -// an `absl::StatusCode::kInvalidArgument` error). The API provides convenience +// absl::Status +// +// The `absl::Status` class is generally used to gracefully handle errors +// across API boundaries (and in particular across RPC boundaries). Some of +// these errors may be recoverable, but others may not. Most +// functions which can produce a recoverable error should be designed to return +// either an `absl::Status` (or the similar `absl::StatusOr<T>`, which holds +// either an object of type `T` or an error). +// +// API developers should construct their functions to return `absl::OkStatus()` +// upon success, or an `absl::StatusCode` upon another type of error (e.g +// an `absl::StatusCode::kInvalidArgument` error). The API provides convenience // functions to construct each status code. -// -// Example: -// -// absl::Status myFunction(absl::string_view fname, ...) { -// ... -// // encounter error -// if (error condition) { -// // Construct an absl::StatusCode::kInvalidArgument error -// return absl::InvalidArgumentError("bad mode"); -// } -// // else, return OK -// return absl::OkStatus(); -// } -// -// Users handling status error codes should prefer checking for an OK status -// using the `ok()` member function. Handling multiple error codes may justify -// use of switch statement, but only check for error codes you know how to -// handle; do not try to exhaustively match against all canonical error codes. -// Errors that cannot be handled should be logged and/or propagated for higher -// levels to deal with. If you do use a switch statement, make sure that you -// also provide a `default:` switch case, so that code does not break as other -// canonical codes are added to the API. -// -// Example: -// -// absl::Status result = DoSomething(); -// if (!result.ok()) { -// LOG(ERROR) << result; -// } -// -// // Provide a default if switching on multiple error codes -// switch (result.code()) { -// // The user hasn't authenticated. Ask them to reauth -// case absl::StatusCode::kUnauthenticated: -// DoReAuth(); -// break; -// // The user does not have permission. Log an error. -// case absl::StatusCode::kPermissionDenied: -// LOG(ERROR) << result; -// break; -// // Propagate the error otherwise. -// default: -// return true; -// } -// -// An `absl::Status` can optionally include a payload with more information -// about the error. Typically, this payload serves one of several purposes: -// -// * It may provide more fine-grained semantic information about the error to -// facilitate actionable remedies. -// * It may provide human-readable contexual information that is more -// appropriate to display to an end user. -// -// Example: -// -// absl::Status result = DoSomething(); -// // Inform user to retry after 30 seconds -// // See more error details in googleapis/google/rpc/error_details.proto -// if (absl::IsResourceExhausted(result)) { -// google::rpc::RetryInfo info; -// info.retry_delay().seconds() = 30; -// // Payloads require a unique key (a URL to ensure no collisions with -// // other payloads), and an `absl::Cord` to hold the encoded data. -// absl::string_view url = "type.googleapis.com/google.rpc.RetryInfo"; -// result.SetPayload(url, info.SerializeAsCord()); -// return result; -// } -// +// +// Example: +// +// absl::Status myFunction(absl::string_view fname, ...) { +// ... +// // encounter error +// if (error condition) { +// // Construct an absl::StatusCode::kInvalidArgument error +// return absl::InvalidArgumentError("bad mode"); +// } +// // else, return OK +// return absl::OkStatus(); +// } +// +// Users handling status error codes should prefer checking for an OK status +// using the `ok()` member function. Handling multiple error codes may justify +// use of switch statement, but only check for error codes you know how to +// handle; do not try to exhaustively match against all canonical error codes. +// Errors that cannot be handled should be logged and/or propagated for higher +// levels to deal with. If you do use a switch statement, make sure that you +// also provide a `default:` switch case, so that code does not break as other +// canonical codes are added to the API. +// +// Example: +// +// absl::Status result = DoSomething(); +// if (!result.ok()) { +// LOG(ERROR) << result; +// } +// +// // Provide a default if switching on multiple error codes +// switch (result.code()) { +// // The user hasn't authenticated. Ask them to reauth +// case absl::StatusCode::kUnauthenticated: +// DoReAuth(); +// break; +// // The user does not have permission. Log an error. +// case absl::StatusCode::kPermissionDenied: +// LOG(ERROR) << result; +// break; +// // Propagate the error otherwise. +// default: +// return true; +// } +// +// An `absl::Status` can optionally include a payload with more information +// about the error. Typically, this payload serves one of several purposes: +// +// * It may provide more fine-grained semantic information about the error to +// facilitate actionable remedies. +// * It may provide human-readable contexual information that is more +// appropriate to display to an end user. +// +// Example: +// +// absl::Status result = DoSomething(); +// // Inform user to retry after 30 seconds +// // See more error details in googleapis/google/rpc/error_details.proto +// if (absl::IsResourceExhausted(result)) { +// google::rpc::RetryInfo info; +// info.retry_delay().seconds() = 30; +// // Payloads require a unique key (a URL to ensure no collisions with +// // other payloads), and an `absl::Cord` to hold the encoded data. +// absl::string_view url = "type.googleapis.com/google.rpc.RetryInfo"; +// result.SetPayload(url, info.SerializeAsCord()); +// return result; +// } +// // For documentation see https://abseil.io/docs/cpp/guides/status. // // Returned Status objects may not be ignored. status_internal.h has a forward // declaration of the form // class ABSL_MUST_USE_RESULT Status; class Status final { - public: - // Constructors - - // This default constructor creates an OK status with no message or payload. - // Avoid this constructor and prefer explicit construction of an OK status - // with `absl::OkStatus()`. - Status(); - - // Creates a status in the canonical error space with the specified + public: + // Constructors + + // This default constructor creates an OK status with no message or payload. + // Avoid this constructor and prefer explicit construction of an OK status + // with `absl::OkStatus()`. + Status(); + + // Creates a status in the canonical error space with the specified // `absl::StatusCode` and error message. If `code == absl::StatusCode::kOk`, // NOLINT - // `msg` is ignored and an object identical to an OK status is constructed. - // + // `msg` is ignored and an object identical to an OK status is constructed. + // // The `msg` string must be in UTF-8. The implementation may complain (e.g., // NOLINT - // by printing a warning) if it is not. - Status(absl::StatusCode code, absl::string_view msg); - - Status(const Status&); - Status& operator=(const Status& x); - - // Move operators - - // The moved-from state is valid but unspecified. - Status(Status&&) noexcept; - Status& operator=(Status&&); - - ~Status(); - - // Status::Update() - // - // Updates the existing status with `new_status` provided that `this->ok()`. - // If the existing status already contains a non-OK error, this update has no - // effect and preserves the current data. Note that this behavior may change - // in the future to augment a current non-ok status with additional - // information about `new_status`. - // - // `Update()` provides a convenient way of keeping track of the first error - // encountered. - // - // Example: - // // Instead of "if (overall_status.ok()) overall_status = new_status" - // overall_status.Update(new_status); - // - void Update(const Status& new_status); - void Update(Status&& new_status); - - // Status::ok() - // - // Returns `true` if `this->ok()`. Prefer checking for an OK status using this - // member function. - ABSL_MUST_USE_RESULT bool ok() const; - - // Status::code() - // - // Returns the canonical error code of type `absl::StatusCode` of this status. - absl::StatusCode code() const; - - // Status::raw_code() - // - // Returns a raw (canonical) error code corresponding to the enum value of - // `google.rpc.Code` definitions within - // https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto. - // These values could be out of the range of canonical `absl::StatusCode` - // enum values. - // - // NOTE: This function should only be called when converting to an associated - // wire format. Use `Status::code()` for error handling. - int raw_code() const; - - // Status::message() - // - // Returns the error message associated with this error code, if available. - // Note that this message rarely describes the error code. It is not unusual - // for the error message to be the empty string. As a result, prefer + // by printing a warning) if it is not. + Status(absl::StatusCode code, absl::string_view msg); + + Status(const Status&); + Status& operator=(const Status& x); + + // Move operators + + // The moved-from state is valid but unspecified. + Status(Status&&) noexcept; + Status& operator=(Status&&); + + ~Status(); + + // Status::Update() + // + // Updates the existing status with `new_status` provided that `this->ok()`. + // If the existing status already contains a non-OK error, this update has no + // effect and preserves the current data. Note that this behavior may change + // in the future to augment a current non-ok status with additional + // information about `new_status`. + // + // `Update()` provides a convenient way of keeping track of the first error + // encountered. + // + // Example: + // // Instead of "if (overall_status.ok()) overall_status = new_status" + // overall_status.Update(new_status); + // + void Update(const Status& new_status); + void Update(Status&& new_status); + + // Status::ok() + // + // Returns `true` if `this->ok()`. Prefer checking for an OK status using this + // member function. + ABSL_MUST_USE_RESULT bool ok() const; + + // Status::code() + // + // Returns the canonical error code of type `absl::StatusCode` of this status. + absl::StatusCode code() const; + + // Status::raw_code() + // + // Returns a raw (canonical) error code corresponding to the enum value of + // `google.rpc.Code` definitions within + // https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto. + // These values could be out of the range of canonical `absl::StatusCode` + // enum values. + // + // NOTE: This function should only be called when converting to an associated + // wire format. Use `Status::code()` for error handling. + int raw_code() const; + + // Status::message() + // + // Returns the error message associated with this error code, if available. + // Note that this message rarely describes the error code. It is not unusual + // for the error message to be the empty string. As a result, prefer // `operator<<` or `Status::ToString()` for debug logging. - absl::string_view message() const; - - friend bool operator==(const Status&, const Status&); - friend bool operator!=(const Status&, const Status&); - - // Status::ToString() - // + absl::string_view message() const; + + friend bool operator==(const Status&, const Status&); + friend bool operator!=(const Status&, const Status&); + + // Status::ToString() + // // Returns a string based on the `mode`. By default, it returns combination of // the error code name, the message and any associated payload messages. This // string is designed simply to be human readable and its exact format should // not be load bearing. Do not depend on the exact format of the result of // `ToString()` which is subject to change. - // - // The printed code name and the message are generally substrings of the - // result, and the payloads to be printed use the status payload printer - // mechanism (which is internal). + // + // The printed code name and the message are generally substrings of the + // result, and the payloads to be printed use the status payload printer + // mechanism (which is internal). std::string ToString( StatusToStringMode mode = StatusToStringMode::kDefault) const; - - // Status::IgnoreError() - // - // Ignores any errors. This method does nothing except potentially suppress - // complaints from any tools that are checking that errors are not dropped on - // the floor. - void IgnoreError() const; - - // swap() - // - // Swap the contents of one status with another. - friend void swap(Status& a, Status& b); - - //---------------------------------------------------------------------------- - // Payload Management APIs - //---------------------------------------------------------------------------- - - // A payload may be attached to a status to provide additional context to an - // error that may not be satisifed by an existing `absl::StatusCode`. - // Typically, this payload serves one of several purposes: - // - // * It may provide more fine-grained semantic information about the error - // to facilitate actionable remedies. - // * It may provide human-readable contexual information that is more - // appropriate to display to an end user. - // - // A payload consists of a [key,value] pair, where the key is a string - // referring to a unique "type URL" and the value is an object of type - // `absl::Cord` to hold the contextual data. - // - // The "type URL" should be unique and follow the format of a URL - // (https://en.wikipedia.org/wiki/URL) and, ideally, provide some - // documentation or schema on how to interpret its associated data. For - // example, the default type URL for a protobuf message type is - // "type.googleapis.com/packagename.messagename". Other custom wire formats - // should define the format of type URL in a similar practice so as to - // minimize the chance of conflict between type URLs. - // Users should ensure that the type URL can be mapped to a concrete - // C++ type if they want to deserialize the payload and read it effectively. - // - // To attach a payload to a status object, call `Status::SetPayload()`, - // passing it the type URL and an `absl::Cord` of associated data. Similarly, - // to extract the payload from a status, call `Status::GetPayload()`. You - // may attach multiple payloads (with differing type URLs) to any given - // status object, provided that the status is currently exhibiting an error - // code (i.e. is not OK). - - // Status::GetPayload() - // - // Gets the payload of a status given its unique `type_url` key, if present. - absl::optional<absl::Cord> GetPayload(absl::string_view type_url) const; - - // Status::SetPayload() - // - // Sets the payload for a non-ok status using a `type_url` key, overwriting - // any existing payload for that `type_url`. - // - // NOTE: This function does nothing if the Status is ok. - void SetPayload(absl::string_view type_url, absl::Cord payload); - - // Status::ErasePayload() - // - // Erases the payload corresponding to the `type_url` key. Returns `true` if - // the payload was present. - bool ErasePayload(absl::string_view type_url); - - // Status::ForEachPayload() - // - // Iterates over the stored payloads and calls the - // `visitor(type_key, payload)` callable for each one. - // - // NOTE: The order of calls to `visitor()` is not specified and may change at - // any time. - // - // NOTE: Any mutation on the same 'absl::Status' object during visitation is - // forbidden and could result in undefined behavior. - void ForEachPayload( + + // Status::IgnoreError() + // + // Ignores any errors. This method does nothing except potentially suppress + // complaints from any tools that are checking that errors are not dropped on + // the floor. + void IgnoreError() const; + + // swap() + // + // Swap the contents of one status with another. + friend void swap(Status& a, Status& b); + + //---------------------------------------------------------------------------- + // Payload Management APIs + //---------------------------------------------------------------------------- + + // A payload may be attached to a status to provide additional context to an + // error that may not be satisifed by an existing `absl::StatusCode`. + // Typically, this payload serves one of several purposes: + // + // * It may provide more fine-grained semantic information about the error + // to facilitate actionable remedies. + // * It may provide human-readable contexual information that is more + // appropriate to display to an end user. + // + // A payload consists of a [key,value] pair, where the key is a string + // referring to a unique "type URL" and the value is an object of type + // `absl::Cord` to hold the contextual data. + // + // The "type URL" should be unique and follow the format of a URL + // (https://en.wikipedia.org/wiki/URL) and, ideally, provide some + // documentation or schema on how to interpret its associated data. For + // example, the default type URL for a protobuf message type is + // "type.googleapis.com/packagename.messagename". Other custom wire formats + // should define the format of type URL in a similar practice so as to + // minimize the chance of conflict between type URLs. + // Users should ensure that the type URL can be mapped to a concrete + // C++ type if they want to deserialize the payload and read it effectively. + // + // To attach a payload to a status object, call `Status::SetPayload()`, + // passing it the type URL and an `absl::Cord` of associated data. Similarly, + // to extract the payload from a status, call `Status::GetPayload()`. You + // may attach multiple payloads (with differing type URLs) to any given + // status object, provided that the status is currently exhibiting an error + // code (i.e. is not OK). + + // Status::GetPayload() + // + // Gets the payload of a status given its unique `type_url` key, if present. + absl::optional<absl::Cord> GetPayload(absl::string_view type_url) const; + + // Status::SetPayload() + // + // Sets the payload for a non-ok status using a `type_url` key, overwriting + // any existing payload for that `type_url`. + // + // NOTE: This function does nothing if the Status is ok. + void SetPayload(absl::string_view type_url, absl::Cord payload); + + // Status::ErasePayload() + // + // Erases the payload corresponding to the `type_url` key. Returns `true` if + // the payload was present. + bool ErasePayload(absl::string_view type_url); + + // Status::ForEachPayload() + // + // Iterates over the stored payloads and calls the + // `visitor(type_key, payload)` callable for each one. + // + // NOTE: The order of calls to `visitor()` is not specified and may change at + // any time. + // + // NOTE: Any mutation on the same 'absl::Status' object during visitation is + // forbidden and could result in undefined behavior. + void ForEachPayload( absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor) - const; - - private: - friend Status CancelledError(); - - // Creates a status in the canonical error space with the specified - // code, and an empty error message. - explicit Status(absl::StatusCode code); - - static void UnrefNonInlined(uintptr_t rep); - static void Ref(uintptr_t rep); - static void Unref(uintptr_t rep); - - // REQUIRES: !ok() - // Ensures rep_ is not shared with any other Status. - void PrepareToModify(); - - const status_internal::Payloads* GetPayloads() const; - status_internal::Payloads* GetPayloads(); - - // Takes ownership of payload. + const; + + private: + friend Status CancelledError(); + + // Creates a status in the canonical error space with the specified + // code, and an empty error message. + explicit Status(absl::StatusCode code); + + static void UnrefNonInlined(uintptr_t rep); + static void Ref(uintptr_t rep); + static void Unref(uintptr_t rep); + + // REQUIRES: !ok() + // Ensures rep_ is not shared with any other Status. + void PrepareToModify(); + + const status_internal::Payloads* GetPayloads() const; + status_internal::Payloads* GetPayloads(); + + // Takes ownership of payload. static uintptr_t NewRep( absl::StatusCode code, absl::string_view msg, std::unique_ptr<status_internal::Payloads> payload); - static bool EqualsSlow(const absl::Status& a, const absl::Status& b); - - // MSVC 14.0 limitation requires the const. - static constexpr const char kMovedFromString[] = - "Status accessed after move."; - - static const std::string* EmptyString(); - static const std::string* MovedFromString(); - - // Returns whether rep contains an inlined representation. - // See rep_ for details. - static bool IsInlined(uintptr_t rep); - - // Indicates whether this Status was the rhs of a move operation. See rep_ - // for details. - static bool IsMovedFrom(uintptr_t rep); - static uintptr_t MovedFromRep(); - - // Convert between error::Code and the inlined uintptr_t representation used - // by rep_. See rep_ for details. - static uintptr_t CodeToInlinedRep(absl::StatusCode code); - static absl::StatusCode InlinedRepToCode(uintptr_t rep); - - // Converts between StatusRep* and the external uintptr_t representation used - // by rep_. See rep_ for details. - static uintptr_t PointerToRep(status_internal::StatusRep* r); - static status_internal::StatusRep* RepToPointer(uintptr_t r); - + static bool EqualsSlow(const absl::Status& a, const absl::Status& b); + + // MSVC 14.0 limitation requires the const. + static constexpr const char kMovedFromString[] = + "Status accessed after move."; + + static const std::string* EmptyString(); + static const std::string* MovedFromString(); + + // Returns whether rep contains an inlined representation. + // See rep_ for details. + static bool IsInlined(uintptr_t rep); + + // Indicates whether this Status was the rhs of a move operation. See rep_ + // for details. + static bool IsMovedFrom(uintptr_t rep); + static uintptr_t MovedFromRep(); + + // Convert between error::Code and the inlined uintptr_t representation used + // by rep_. See rep_ for details. + static uintptr_t CodeToInlinedRep(absl::StatusCode code); + static absl::StatusCode InlinedRepToCode(uintptr_t rep); + + // Converts between StatusRep* and the external uintptr_t representation used + // by rep_. See rep_ for details. + static uintptr_t PointerToRep(status_internal::StatusRep* r); + static status_internal::StatusRep* RepToPointer(uintptr_t r); + std::string ToStringSlow(StatusToStringMode mode) const; - - // Status supports two different representations. - // - When the low bit is off it is an inlined representation. - // It uses the canonical error space, no message or payload. - // The error code is (rep_ >> 2). - // The (rep_ & 2) bit is the "moved from" indicator, used in IsMovedFrom(). - // - When the low bit is on it is an external representation. - // In this case all the data comes from a heap allocated Rep object. - // (rep_ - 1) is a status_internal::StatusRep* pointer to that structure. - uintptr_t rep_; -}; - -// OkStatus() -// -// Returns an OK status, equivalent to a default constructed instance. Prefer -// usage of `absl::OkStatus()` when constructing such an OK status. -Status OkStatus(); - -// operator<<() -// -// Prints a human-readable representation of `x` to `os`. -std::ostream& operator<<(std::ostream& os, const Status& x); - -// IsAborted() -// IsAlreadyExists() -// IsCancelled() -// IsDataLoss() -// IsDeadlineExceeded() -// IsFailedPrecondition() -// IsInternal() -// IsInvalidArgument() -// IsNotFound() -// IsOutOfRange() -// IsPermissionDenied() -// IsResourceExhausted() -// IsUnauthenticated() -// IsUnavailable() -// IsUnimplemented() -// IsUnknown() -// -// These convenience functions return `true` if a given status matches the -// `absl::StatusCode` error code of its associated function. -ABSL_MUST_USE_RESULT bool IsAborted(const Status& status); -ABSL_MUST_USE_RESULT bool IsAlreadyExists(const Status& status); -ABSL_MUST_USE_RESULT bool IsCancelled(const Status& status); -ABSL_MUST_USE_RESULT bool IsDataLoss(const Status& status); -ABSL_MUST_USE_RESULT bool IsDeadlineExceeded(const Status& status); -ABSL_MUST_USE_RESULT bool IsFailedPrecondition(const Status& status); -ABSL_MUST_USE_RESULT bool IsInternal(const Status& status); -ABSL_MUST_USE_RESULT bool IsInvalidArgument(const Status& status); -ABSL_MUST_USE_RESULT bool IsNotFound(const Status& status); -ABSL_MUST_USE_RESULT bool IsOutOfRange(const Status& status); -ABSL_MUST_USE_RESULT bool IsPermissionDenied(const Status& status); -ABSL_MUST_USE_RESULT bool IsResourceExhausted(const Status& status); -ABSL_MUST_USE_RESULT bool IsUnauthenticated(const Status& status); -ABSL_MUST_USE_RESULT bool IsUnavailable(const Status& status); -ABSL_MUST_USE_RESULT bool IsUnimplemented(const Status& status); -ABSL_MUST_USE_RESULT bool IsUnknown(const Status& status); - -// AbortedError() -// AlreadyExistsError() -// CancelledError() -// DataLossError() -// DeadlineExceededError() -// FailedPreconditionError() -// InternalError() -// InvalidArgumentError() -// NotFoundError() -// OutOfRangeError() -// PermissionDeniedError() -// ResourceExhaustedError() -// UnauthenticatedError() -// UnavailableError() -// UnimplementedError() -// UnknownError() -// -// These convenience functions create an `absl::Status` object with an error -// code as indicated by the associated function name, using the error message -// passed in `message`. -Status AbortedError(absl::string_view message); -Status AlreadyExistsError(absl::string_view message); -Status CancelledError(absl::string_view message); -Status DataLossError(absl::string_view message); -Status DeadlineExceededError(absl::string_view message); -Status FailedPreconditionError(absl::string_view message); -Status InternalError(absl::string_view message); -Status InvalidArgumentError(absl::string_view message); -Status NotFoundError(absl::string_view message); -Status OutOfRangeError(absl::string_view message); -Status PermissionDeniedError(absl::string_view message); -Status ResourceExhaustedError(absl::string_view message); -Status UnauthenticatedError(absl::string_view message); -Status UnavailableError(absl::string_view message); -Status UnimplementedError(absl::string_view message); -Status UnknownError(absl::string_view message); - -//------------------------------------------------------------------------------ -// Implementation details follow -//------------------------------------------------------------------------------ - -inline Status::Status() : rep_(CodeToInlinedRep(absl::StatusCode::kOk)) {} - -inline Status::Status(absl::StatusCode code) : rep_(CodeToInlinedRep(code)) {} - -inline Status::Status(const Status& x) : rep_(x.rep_) { Ref(rep_); } - -inline Status& Status::operator=(const Status& x) { - uintptr_t old_rep = rep_; - if (x.rep_ != old_rep) { - Ref(x.rep_); - rep_ = x.rep_; - Unref(old_rep); - } - return *this; -} - -inline Status::Status(Status&& x) noexcept : rep_(x.rep_) { - x.rep_ = MovedFromRep(); -} - -inline Status& Status::operator=(Status&& x) { - uintptr_t old_rep = rep_; + + // Status supports two different representations. + // - When the low bit is off it is an inlined representation. + // It uses the canonical error space, no message or payload. + // The error code is (rep_ >> 2). + // The (rep_ & 2) bit is the "moved from" indicator, used in IsMovedFrom(). + // - When the low bit is on it is an external representation. + // In this case all the data comes from a heap allocated Rep object. + // (rep_ - 1) is a status_internal::StatusRep* pointer to that structure. + uintptr_t rep_; +}; + +// OkStatus() +// +// Returns an OK status, equivalent to a default constructed instance. Prefer +// usage of `absl::OkStatus()` when constructing such an OK status. +Status OkStatus(); + +// operator<<() +// +// Prints a human-readable representation of `x` to `os`. +std::ostream& operator<<(std::ostream& os, const Status& x); + +// IsAborted() +// IsAlreadyExists() +// IsCancelled() +// IsDataLoss() +// IsDeadlineExceeded() +// IsFailedPrecondition() +// IsInternal() +// IsInvalidArgument() +// IsNotFound() +// IsOutOfRange() +// IsPermissionDenied() +// IsResourceExhausted() +// IsUnauthenticated() +// IsUnavailable() +// IsUnimplemented() +// IsUnknown() +// +// These convenience functions return `true` if a given status matches the +// `absl::StatusCode` error code of its associated function. +ABSL_MUST_USE_RESULT bool IsAborted(const Status& status); +ABSL_MUST_USE_RESULT bool IsAlreadyExists(const Status& status); +ABSL_MUST_USE_RESULT bool IsCancelled(const Status& status); +ABSL_MUST_USE_RESULT bool IsDataLoss(const Status& status); +ABSL_MUST_USE_RESULT bool IsDeadlineExceeded(const Status& status); +ABSL_MUST_USE_RESULT bool IsFailedPrecondition(const Status& status); +ABSL_MUST_USE_RESULT bool IsInternal(const Status& status); +ABSL_MUST_USE_RESULT bool IsInvalidArgument(const Status& status); +ABSL_MUST_USE_RESULT bool IsNotFound(const Status& status); +ABSL_MUST_USE_RESULT bool IsOutOfRange(const Status& status); +ABSL_MUST_USE_RESULT bool IsPermissionDenied(const Status& status); +ABSL_MUST_USE_RESULT bool IsResourceExhausted(const Status& status); +ABSL_MUST_USE_RESULT bool IsUnauthenticated(const Status& status); +ABSL_MUST_USE_RESULT bool IsUnavailable(const Status& status); +ABSL_MUST_USE_RESULT bool IsUnimplemented(const Status& status); +ABSL_MUST_USE_RESULT bool IsUnknown(const Status& status); + +// AbortedError() +// AlreadyExistsError() +// CancelledError() +// DataLossError() +// DeadlineExceededError() +// FailedPreconditionError() +// InternalError() +// InvalidArgumentError() +// NotFoundError() +// OutOfRangeError() +// PermissionDeniedError() +// ResourceExhaustedError() +// UnauthenticatedError() +// UnavailableError() +// UnimplementedError() +// UnknownError() +// +// These convenience functions create an `absl::Status` object with an error +// code as indicated by the associated function name, using the error message +// passed in `message`. +Status AbortedError(absl::string_view message); +Status AlreadyExistsError(absl::string_view message); +Status CancelledError(absl::string_view message); +Status DataLossError(absl::string_view message); +Status DeadlineExceededError(absl::string_view message); +Status FailedPreconditionError(absl::string_view message); +Status InternalError(absl::string_view message); +Status InvalidArgumentError(absl::string_view message); +Status NotFoundError(absl::string_view message); +Status OutOfRangeError(absl::string_view message); +Status PermissionDeniedError(absl::string_view message); +Status ResourceExhaustedError(absl::string_view message); +Status UnauthenticatedError(absl::string_view message); +Status UnavailableError(absl::string_view message); +Status UnimplementedError(absl::string_view message); +Status UnknownError(absl::string_view message); + +//------------------------------------------------------------------------------ +// Implementation details follow +//------------------------------------------------------------------------------ + +inline Status::Status() : rep_(CodeToInlinedRep(absl::StatusCode::kOk)) {} + +inline Status::Status(absl::StatusCode code) : rep_(CodeToInlinedRep(code)) {} + +inline Status::Status(const Status& x) : rep_(x.rep_) { Ref(rep_); } + +inline Status& Status::operator=(const Status& x) { + uintptr_t old_rep = rep_; + if (x.rep_ != old_rep) { + Ref(x.rep_); + rep_ = x.rep_; + Unref(old_rep); + } + return *this; +} + +inline Status::Status(Status&& x) noexcept : rep_(x.rep_) { + x.rep_ = MovedFromRep(); +} + +inline Status& Status::operator=(Status&& x) { + uintptr_t old_rep = rep_; if (x.rep_ != old_rep) { rep_ = x.rep_; x.rep_ = MovedFromRep(); Unref(old_rep); } - return *this; -} - -inline void Status::Update(const Status& new_status) { - if (ok()) { - *this = new_status; - } -} - -inline void Status::Update(Status&& new_status) { - if (ok()) { - *this = std::move(new_status); - } -} - -inline Status::~Status() { Unref(rep_); } - -inline bool Status::ok() const { - return rep_ == CodeToInlinedRep(absl::StatusCode::kOk); -} - -inline absl::string_view Status::message() const { - return !IsInlined(rep_) - ? RepToPointer(rep_)->message - : (IsMovedFrom(rep_) ? absl::string_view(kMovedFromString) - : absl::string_view()); -} - -inline bool operator==(const Status& lhs, const Status& rhs) { - return lhs.rep_ == rhs.rep_ || Status::EqualsSlow(lhs, rhs); -} - -inline bool operator!=(const Status& lhs, const Status& rhs) { - return !(lhs == rhs); -} - + return *this; +} + +inline void Status::Update(const Status& new_status) { + if (ok()) { + *this = new_status; + } +} + +inline void Status::Update(Status&& new_status) { + if (ok()) { + *this = std::move(new_status); + } +} + +inline Status::~Status() { Unref(rep_); } + +inline bool Status::ok() const { + return rep_ == CodeToInlinedRep(absl::StatusCode::kOk); +} + +inline absl::string_view Status::message() const { + return !IsInlined(rep_) + ? RepToPointer(rep_)->message + : (IsMovedFrom(rep_) ? absl::string_view(kMovedFromString) + : absl::string_view()); +} + +inline bool operator==(const Status& lhs, const Status& rhs) { + return lhs.rep_ == rhs.rep_ || Status::EqualsSlow(lhs, rhs); +} + +inline bool operator!=(const Status& lhs, const Status& rhs) { + return !(lhs == rhs); +} + inline std::string Status::ToString(StatusToStringMode mode) const { return ok() ? "OK" : ToStringSlow(mode); -} - -inline void Status::IgnoreError() const { - // no-op -} - -inline void swap(absl::Status& a, absl::Status& b) { - using std::swap; - swap(a.rep_, b.rep_); -} - -inline const status_internal::Payloads* Status::GetPayloads() const { - return IsInlined(rep_) ? nullptr : RepToPointer(rep_)->payloads.get(); -} - -inline status_internal::Payloads* Status::GetPayloads() { - return IsInlined(rep_) ? nullptr : RepToPointer(rep_)->payloads.get(); -} - -inline bool Status::IsInlined(uintptr_t rep) { return (rep & 1) == 0; } - -inline bool Status::IsMovedFrom(uintptr_t rep) { - return IsInlined(rep) && (rep & 2) != 0; -} - -inline uintptr_t Status::MovedFromRep() { - return CodeToInlinedRep(absl::StatusCode::kInternal) | 2; -} - -inline uintptr_t Status::CodeToInlinedRep(absl::StatusCode code) { - return static_cast<uintptr_t>(code) << 2; -} - -inline absl::StatusCode Status::InlinedRepToCode(uintptr_t rep) { - assert(IsInlined(rep)); - return static_cast<absl::StatusCode>(rep >> 2); -} - -inline status_internal::StatusRep* Status::RepToPointer(uintptr_t rep) { - assert(!IsInlined(rep)); - return reinterpret_cast<status_internal::StatusRep*>(rep - 1); -} - -inline uintptr_t Status::PointerToRep(status_internal::StatusRep* rep) { - return reinterpret_cast<uintptr_t>(rep) + 1; -} - -inline void Status::Ref(uintptr_t rep) { - if (!IsInlined(rep)) { - RepToPointer(rep)->ref.fetch_add(1, std::memory_order_relaxed); - } -} - -inline void Status::Unref(uintptr_t rep) { - if (!IsInlined(rep)) { - UnrefNonInlined(rep); - } -} - -inline Status OkStatus() { return Status(); } - -// Creates a `Status` object with the `absl::StatusCode::kCancelled` error code -// and an empty message. It is provided only for efficiency, given that -// message-less kCancelled errors are common in the infrastructure. -inline Status CancelledError() { return Status(absl::StatusCode::kCancelled); } - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STATUS_STATUS_H_ +} + +inline void Status::IgnoreError() const { + // no-op +} + +inline void swap(absl::Status& a, absl::Status& b) { + using std::swap; + swap(a.rep_, b.rep_); +} + +inline const status_internal::Payloads* Status::GetPayloads() const { + return IsInlined(rep_) ? nullptr : RepToPointer(rep_)->payloads.get(); +} + +inline status_internal::Payloads* Status::GetPayloads() { + return IsInlined(rep_) ? nullptr : RepToPointer(rep_)->payloads.get(); +} + +inline bool Status::IsInlined(uintptr_t rep) { return (rep & 1) == 0; } + +inline bool Status::IsMovedFrom(uintptr_t rep) { + return IsInlined(rep) && (rep & 2) != 0; +} + +inline uintptr_t Status::MovedFromRep() { + return CodeToInlinedRep(absl::StatusCode::kInternal) | 2; +} + +inline uintptr_t Status::CodeToInlinedRep(absl::StatusCode code) { + return static_cast<uintptr_t>(code) << 2; +} + +inline absl::StatusCode Status::InlinedRepToCode(uintptr_t rep) { + assert(IsInlined(rep)); + return static_cast<absl::StatusCode>(rep >> 2); +} + +inline status_internal::StatusRep* Status::RepToPointer(uintptr_t rep) { + assert(!IsInlined(rep)); + return reinterpret_cast<status_internal::StatusRep*>(rep - 1); +} + +inline uintptr_t Status::PointerToRep(status_internal::StatusRep* rep) { + return reinterpret_cast<uintptr_t>(rep) + 1; +} + +inline void Status::Ref(uintptr_t rep) { + if (!IsInlined(rep)) { + RepToPointer(rep)->ref.fetch_add(1, std::memory_order_relaxed); + } +} + +inline void Status::Unref(uintptr_t rep) { + if (!IsInlined(rep)) { + UnrefNonInlined(rep); + } +} + +inline Status OkStatus() { return Status(); } + +// Creates a `Status` object with the `absl::StatusCode::kCancelled` error code +// and an empty message. It is provided only for efficiency, given that +// message-less kCancelled errors are common in the infrastructure. +inline Status CancelledError() { return Status(absl::StatusCode::kCancelled); } + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STATUS_STATUS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.cc b/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.cc index a47aea11c2..e908cbf316 100644 --- a/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.cc +++ b/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.cc @@ -1,38 +1,38 @@ -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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 "absl/status/status_payload_printer.h" - -#include <atomic> - -#include "absl/base/attributes.h" -#include "absl/base/internal/atomic_hook.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace status_internal { - -ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES -static absl::base_internal::AtomicHook<StatusPayloadPrinter> storage; - -void SetStatusPayloadPrinter(StatusPayloadPrinter printer) { - storage.Store(printer); -} - -StatusPayloadPrinter GetStatusPayloadPrinter() { - return storage.Load(); -} - -} // namespace status_internal -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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 "absl/status/status_payload_printer.h" + +#include <atomic> + +#include "absl/base/attributes.h" +#include "absl/base/internal/atomic_hook.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace status_internal { + +ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES +static absl::base_internal::AtomicHook<StatusPayloadPrinter> storage; + +void SetStatusPayloadPrinter(StatusPayloadPrinter printer) { + storage.Store(printer); +} + +StatusPayloadPrinter GetStatusPayloadPrinter() { + return storage.Load(); +} + +} // namespace status_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.h b/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.h index 5e0937f67d..2f5e0ea7d7 100644 --- a/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.h +++ b/contrib/restricted/abseil-cpp/absl/status/status_payload_printer.h @@ -1,51 +1,51 @@ -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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. -#ifndef ABSL_STATUS_STATUS_PAYLOAD_PRINTER_H_ -#define ABSL_STATUS_STATUS_PAYLOAD_PRINTER_H_ - -#include <string> - -#include "absl/strings/cord.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace status_internal { - -// By default, `Status::ToString` and `operator<<(Status)` print a payload by -// dumping the type URL and the raw bytes. To help debugging, we provide an -// extension point, which is a global printer function that can be set by users -// to specify how to print payloads. The function takes the type URL and the -// payload as input, and should return a valid human-readable string on success -// or `absl::nullopt` on failure (in which case it falls back to the default -// approach of printing the raw bytes). -// NOTE: This is an internal API and the design is subject to change in the -// future in a non-backward-compatible way. Since it's only meant for debugging -// purpose, you should not rely on it in any critical logic. -using StatusPayloadPrinter = absl::optional<std::string> (*)(absl::string_view, - const absl::Cord&); - -// Sets the global payload printer. Only one printer should be set per process. -// If multiple printers are set, it's undefined which one will be used. -void SetStatusPayloadPrinter(StatusPayloadPrinter); - -// Returns the global payload printer if previously set, otherwise `nullptr`. -StatusPayloadPrinter GetStatusPayloadPrinter(); - -} // namespace status_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STATUS_STATUS_PAYLOAD_PRINTER_H_ +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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. +#ifndef ABSL_STATUS_STATUS_PAYLOAD_PRINTER_H_ +#define ABSL_STATUS_STATUS_PAYLOAD_PRINTER_H_ + +#include <string> + +#include "absl/strings/cord.h" +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace status_internal { + +// By default, `Status::ToString` and `operator<<(Status)` print a payload by +// dumping the type URL and the raw bytes. To help debugging, we provide an +// extension point, which is a global printer function that can be set by users +// to specify how to print payloads. The function takes the type URL and the +// payload as input, and should return a valid human-readable string on success +// or `absl::nullopt` on failure (in which case it falls back to the default +// approach of printing the raw bytes). +// NOTE: This is an internal API and the design is subject to change in the +// future in a non-backward-compatible way. Since it's only meant for debugging +// purpose, you should not rely on it in any critical logic. +using StatusPayloadPrinter = absl::optional<std::string> (*)(absl::string_view, + const absl::Cord&); + +// Sets the global payload printer. Only one printer should be set per process. +// If multiple printers are set, it's undefined which one will be used. +void SetStatusPayloadPrinter(StatusPayloadPrinter); + +// Returns the global payload printer if previously set, otherwise `nullptr`. +StatusPayloadPrinter GetStatusPayloadPrinter(); + +} // namespace status_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STATUS_STATUS_PAYLOAD_PRINTER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/status/statusor.cc b/contrib/restricted/abseil-cpp/absl/status/statusor.cc index 96642b340f..c2a5b063c9 100644 --- a/contrib/restricted/abseil-cpp/absl/status/statusor.cc +++ b/contrib/restricted/abseil-cpp/absl/status/statusor.cc @@ -1,32 +1,32 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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 "absl/status/statusor.h" - -#include <cstdlib> -#include <utility> - +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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 "absl/status/statusor.h" + +#include <cstdlib> +#include <utility> + #include "absl/base/call_once.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/status/status.h" -#include "absl/strings/str_cat.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -BadStatusOrAccess::BadStatusOrAccess(absl::Status status) - : status_(std::move(status)) {} - +#include "absl/base/internal/raw_logging.h" +#include "absl/status/status.h" +#include "absl/strings/str_cat.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +BadStatusOrAccess::BadStatusOrAccess(absl::Status status) + : status_(std::move(status)) {} + BadStatusOrAccess::BadStatusOrAccess(const BadStatusOrAccess& other) : status_(other.status_) {} @@ -52,52 +52,52 @@ BadStatusOrAccess& BadStatusOrAccess::operator=(BadStatusOrAccess&& other) { BadStatusOrAccess::BadStatusOrAccess(BadStatusOrAccess&& other) : status_(std::move(other.status_)) {} -const char* BadStatusOrAccess::what() const noexcept { +const char* BadStatusOrAccess::what() const noexcept { InitWhat(); return what_.c_str(); -} - -const absl::Status& BadStatusOrAccess::status() const { return status_; } - +} + +const absl::Status& BadStatusOrAccess::status() const { return status_; } + void BadStatusOrAccess::InitWhat() const { absl::call_once(init_what_, [this] { what_ = absl::StrCat("Bad StatusOr access: ", status_.ToString()); }); } -namespace internal_statusor { - -void Helper::HandleInvalidStatusCtorArg(absl::Status* status) { - const char* kMessage = - "An OK status is not a valid constructor argument to StatusOr<T>"; -#ifdef NDEBUG - ABSL_INTERNAL_LOG(ERROR, kMessage); -#else - ABSL_INTERNAL_LOG(FATAL, kMessage); -#endif - // In optimized builds, we will fall back to InternalError. - *status = absl::InternalError(kMessage); -} - -void Helper::Crash(const absl::Status& status) { - ABSL_INTERNAL_LOG( - FATAL, - absl::StrCat("Attempting to fetch value instead of handling error ", - status.ToString())); -} - -void ThrowBadStatusOrAccess(absl::Status status) { -#ifdef ABSL_HAVE_EXCEPTIONS - throw absl::BadStatusOrAccess(std::move(status)); -#else - ABSL_INTERNAL_LOG( - FATAL, - absl::StrCat("Attempting to fetch value instead of handling error ", - status.ToString())); - std::abort(); -#endif -} - -} // namespace internal_statusor -ABSL_NAMESPACE_END -} // namespace absl +namespace internal_statusor { + +void Helper::HandleInvalidStatusCtorArg(absl::Status* status) { + const char* kMessage = + "An OK status is not a valid constructor argument to StatusOr<T>"; +#ifdef NDEBUG + ABSL_INTERNAL_LOG(ERROR, kMessage); +#else + ABSL_INTERNAL_LOG(FATAL, kMessage); +#endif + // In optimized builds, we will fall back to InternalError. + *status = absl::InternalError(kMessage); +} + +void Helper::Crash(const absl::Status& status) { + ABSL_INTERNAL_LOG( + FATAL, + absl::StrCat("Attempting to fetch value instead of handling error ", + status.ToString())); +} + +void ThrowBadStatusOrAccess(absl::Status status) { +#ifdef ABSL_HAVE_EXCEPTIONS + throw absl::BadStatusOrAccess(std::move(status)); +#else + ABSL_INTERNAL_LOG( + FATAL, + absl::StrCat("Attempting to fetch value instead of handling error ", + status.ToString())); + std::abort(); +#endif +} + +} // namespace internal_statusor +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/status/statusor.h b/contrib/restricted/abseil-cpp/absl/status/statusor.h index c051fbb3aa..817a0a59a3 100644 --- a/contrib/restricted/abseil-cpp/absl/status/statusor.h +++ b/contrib/restricted/abseil-cpp/absl/status/statusor.h @@ -1,770 +1,770 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// File: statusor.h -// ----------------------------------------------------------------------------- -// -// An `absl::StatusOr<T>` represents a union of an `absl::Status` object -// and an object of type `T`. The `absl::StatusOr<T>` will either contain an -// object of type `T` (indicating a successful operation), or an error (of type -// `absl::Status`) explaining why such a value is not present. -// -// In general, check the success of an operation returning an -// `absl::StatusOr<T>` like you would an `absl::Status` by using the `ok()` -// member function. -// -// Example: -// -// StatusOr<Foo> result = Calculation(); -// if (result.ok()) { -// result->DoSomethingCool(); -// } else { -// LOG(ERROR) << result.status(); -// } -#ifndef ABSL_STATUS_STATUSOR_H_ -#define ABSL_STATUS_STATUSOR_H_ - -#include <exception> -#include <initializer_list> -#include <new> -#include <string> -#include <type_traits> -#include <utility> - -#include "absl/base/attributes.h" +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// File: statusor.h +// ----------------------------------------------------------------------------- +// +// An `absl::StatusOr<T>` represents a union of an `absl::Status` object +// and an object of type `T`. The `absl::StatusOr<T>` will either contain an +// object of type `T` (indicating a successful operation), or an error (of type +// `absl::Status`) explaining why such a value is not present. +// +// In general, check the success of an operation returning an +// `absl::StatusOr<T>` like you would an `absl::Status` by using the `ok()` +// member function. +// +// Example: +// +// StatusOr<Foo> result = Calculation(); +// if (result.ok()) { +// result->DoSomethingCool(); +// } else { +// LOG(ERROR) << result.status(); +// } +#ifndef ABSL_STATUS_STATUSOR_H_ +#define ABSL_STATUS_STATUSOR_H_ + +#include <exception> +#include <initializer_list> +#include <new> +#include <string> +#include <type_traits> +#include <utility> + +#include "absl/base/attributes.h" #include "absl/base/call_once.h" -#include "absl/meta/type_traits.h" -#include "absl/status/internal/statusor_internal.h" -#include "absl/status/status.h" -#include "absl/types/variant.h" -#include "absl/utility/utility.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -// BadStatusOrAccess -// -// This class defines the type of object to throw (if exceptions are enabled), -// when accessing the value of an `absl::StatusOr<T>` object that does not -// contain a value. This behavior is analogous to that of -// `std::bad_optional_access` in the case of accessing an invalid -// `std::optional` value. -// -// Example: -// -// try { -// absl::StatusOr<int> v = FetchInt(); -// DoWork(v.value()); // Accessing value() when not "OK" may throw -// } catch (absl::BadStatusOrAccess& ex) { -// LOG(ERROR) << ex.status(); -// } -class BadStatusOrAccess : public std::exception { - public: - explicit BadStatusOrAccess(absl::Status status); +#include "absl/meta/type_traits.h" +#include "absl/status/internal/statusor_internal.h" +#include "absl/status/status.h" +#include "absl/types/variant.h" +#include "absl/utility/utility.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +// BadStatusOrAccess +// +// This class defines the type of object to throw (if exceptions are enabled), +// when accessing the value of an `absl::StatusOr<T>` object that does not +// contain a value. This behavior is analogous to that of +// `std::bad_optional_access` in the case of accessing an invalid +// `std::optional` value. +// +// Example: +// +// try { +// absl::StatusOr<int> v = FetchInt(); +// DoWork(v.value()); // Accessing value() when not "OK" may throw +// } catch (absl::BadStatusOrAccess& ex) { +// LOG(ERROR) << ex.status(); +// } +class BadStatusOrAccess : public std::exception { + public: + explicit BadStatusOrAccess(absl::Status status); ~BadStatusOrAccess() override = default; - + BadStatusOrAccess(const BadStatusOrAccess& other); BadStatusOrAccess& operator=(const BadStatusOrAccess& other); BadStatusOrAccess(BadStatusOrAccess&& other); BadStatusOrAccess& operator=(BadStatusOrAccess&& other); - // BadStatusOrAccess::what() - // - // Returns the associated explanatory string of the `absl::StatusOr<T>` + // BadStatusOrAccess::what() + // + // Returns the associated explanatory string of the `absl::StatusOr<T>` // object's error code. This function contains information about the failing // status, but its exact formatting may change and should not be depended on. - // - // The pointer of this string is guaranteed to be valid until any non-const - // function is invoked on the exception object. - const char* what() const noexcept override; - - // BadStatusOrAccess::status() - // - // Returns the associated `absl::Status` of the `absl::StatusOr<T>` object's - // error. - const absl::Status& status() const; - - private: + // + // The pointer of this string is guaranteed to be valid until any non-const + // function is invoked on the exception object. + const char* what() const noexcept override; + + // BadStatusOrAccess::status() + // + // Returns the associated `absl::Status` of the `absl::StatusOr<T>` object's + // error. + const absl::Status& status() const; + + private: void InitWhat() const; - absl::Status status_; + absl::Status status_; mutable absl::once_flag init_what_; mutable std::string what_; -}; - -// Returned StatusOr objects may not be ignored. -template <typename T> -class ABSL_MUST_USE_RESULT StatusOr; - -// absl::StatusOr<T> -// -// The `absl::StatusOr<T>` class template is a union of an `absl::Status` object -// and an object of type `T`. The `absl::StatusOr<T>` models an object that is -// either a usable object, or an error (of type `absl::Status`) explaining why -// such an object is not present. An `absl::StatusOr<T>` is typically the return -// value of a function which may fail. -// -// An `absl::StatusOr<T>` can never hold an "OK" status (an -// `absl::StatusCode::kOk` value); instead, the presence of an object of type -// `T` indicates success. Instead of checking for a `kOk` value, use the -// `absl::StatusOr<T>::ok()` member function. (It is for this reason, and code -// readability, that using the `ok()` function is preferred for `absl::Status` -// as well.) -// -// Example: -// -// StatusOr<Foo> result = DoBigCalculationThatCouldFail(); -// if (result.ok()) { -// result->DoSomethingCool(); -// } else { -// LOG(ERROR) << result.status(); -// } -// -// Accessing the object held by an `absl::StatusOr<T>` should be performed via -// `operator*` or `operator->`, after a call to `ok()` confirms that the -// `absl::StatusOr<T>` holds an object of type `T`: -// -// Example: -// -// absl::StatusOr<int> i = GetCount(); -// if (i.ok()) { -// updated_total += *i -// } -// -// NOTE: using `absl::StatusOr<T>::value()` when no valid value is present will -// throw an exception if exceptions are enabled or terminate the process when +}; + +// Returned StatusOr objects may not be ignored. +template <typename T> +class ABSL_MUST_USE_RESULT StatusOr; + +// absl::StatusOr<T> +// +// The `absl::StatusOr<T>` class template is a union of an `absl::Status` object +// and an object of type `T`. The `absl::StatusOr<T>` models an object that is +// either a usable object, or an error (of type `absl::Status`) explaining why +// such an object is not present. An `absl::StatusOr<T>` is typically the return +// value of a function which may fail. +// +// An `absl::StatusOr<T>` can never hold an "OK" status (an +// `absl::StatusCode::kOk` value); instead, the presence of an object of type +// `T` indicates success. Instead of checking for a `kOk` value, use the +// `absl::StatusOr<T>::ok()` member function. (It is for this reason, and code +// readability, that using the `ok()` function is preferred for `absl::Status` +// as well.) +// +// Example: +// +// StatusOr<Foo> result = DoBigCalculationThatCouldFail(); +// if (result.ok()) { +// result->DoSomethingCool(); +// } else { +// LOG(ERROR) << result.status(); +// } +// +// Accessing the object held by an `absl::StatusOr<T>` should be performed via +// `operator*` or `operator->`, after a call to `ok()` confirms that the +// `absl::StatusOr<T>` holds an object of type `T`: +// +// Example: +// +// absl::StatusOr<int> i = GetCount(); +// if (i.ok()) { +// updated_total += *i +// } +// +// NOTE: using `absl::StatusOr<T>::value()` when no valid value is present will +// throw an exception if exceptions are enabled or terminate the process when // exceptions are not enabled. -// -// Example: -// -// StatusOr<Foo> result = DoBigCalculationThatCouldFail(); -// const Foo& foo = result.value(); // Crash/exception if no value present -// foo.DoSomethingCool(); -// -// A `absl::StatusOr<T*>` can be constructed from a null pointer like any other -// pointer value, and the result will be that `ok()` returns `true` and -// `value()` returns `nullptr`. Checking the value of pointer in an -// `absl::StatusOr<T>` generally requires a bit more care, to ensure both that a -// value is present and that value is not null: -// -// StatusOr<std::unique_ptr<Foo>> result = FooFactory::MakeNewFoo(arg); -// if (!result.ok()) { -// LOG(ERROR) << result.status(); -// } else if (*result == nullptr) { -// LOG(ERROR) << "Unexpected null pointer"; -// } else { -// (*result)->DoSomethingCool(); -// } -// -// Example factory implementation returning StatusOr<T>: -// -// StatusOr<Foo> FooFactory::MakeFoo(int arg) { -// if (arg <= 0) { -// return absl::Status(absl::StatusCode::kInvalidArgument, -// "Arg must be positive"); -// } -// return Foo(arg); -// } -template <typename T> -class StatusOr : private internal_statusor::StatusOrData<T>, - private internal_statusor::CopyCtorBase<T>, - private internal_statusor::MoveCtorBase<T>, - private internal_statusor::CopyAssignBase<T>, - private internal_statusor::MoveAssignBase<T> { - template <typename U> - friend class StatusOr; - - typedef internal_statusor::StatusOrData<T> Base; - - public: - // StatusOr<T>::value_type - // - // This instance data provides a generic `value_type` member for use within - // generic programming. This usage is analogous to that of - // `optional::value_type` in the case of `std::optional`. - typedef T value_type; - - // Constructors - - // Constructs a new `absl::StatusOr` with an `absl::StatusCode::kUnknown` - // status. This constructor is marked 'explicit' to prevent usages in return - // values such as 'return {};', under the misconception that - // `absl::StatusOr<std::vector<int>>` will be initialized with an empty - // vector, instead of an `absl::StatusCode::kUnknown` error code. - explicit StatusOr(); - - // `StatusOr<T>` is copy constructible if `T` is copy constructible. - StatusOr(const StatusOr&) = default; - // `StatusOr<T>` is copy assignable if `T` is copy constructible and copy - // assignable. - StatusOr& operator=(const StatusOr&) = default; - - // `StatusOr<T>` is move constructible if `T` is move constructible. - StatusOr(StatusOr&&) = default; - // `StatusOr<T>` is moveAssignable if `T` is move constructible and move - // assignable. - StatusOr& operator=(StatusOr&&) = default; - - // Converting Constructors - - // Constructs a new `absl::StatusOr<T>` from an `absl::StatusOr<U>`, when `T` - // is constructible from `U`. To avoid ambiguity, these constructors are - // disabled if `T` is also constructible from `StatusOr<U>.`. This constructor - // is explicit if and only if the corresponding construction of `T` from `U` - // is explicit. (This constructor inherits its explicitness from the - // underlying constructor.) - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_same<T, U>>, - std::is_constructible<T, const U&>, - std::is_convertible<const U&, T>, - absl::negation< - internal_statusor::IsConstructibleOrConvertibleFromStatusOr< - T, U>>>::value, - int> = 0> - StatusOr(const StatusOr<U>& other) // NOLINT - : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {} - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_same<T, U>>, - std::is_constructible<T, const U&>, - absl::negation<std::is_convertible<const U&, T>>, - absl::negation< - internal_statusor::IsConstructibleOrConvertibleFromStatusOr< - T, U>>>::value, - int> = 0> - explicit StatusOr(const StatusOr<U>& other) - : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {} - - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>, - std::is_convertible<U&&, T>, - absl::negation< - internal_statusor::IsConstructibleOrConvertibleFromStatusOr< - T, U>>>::value, - int> = 0> - StatusOr(StatusOr<U>&& other) // NOLINT - : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {} - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>, - absl::negation<std::is_convertible<U&&, T>>, - absl::negation< - internal_statusor::IsConstructibleOrConvertibleFromStatusOr< - T, U>>>::value, - int> = 0> - explicit StatusOr(StatusOr<U>&& other) - : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {} - - // Converting Assignment Operators - - // Creates an `absl::StatusOr<T>` through assignment from an - // `absl::StatusOr<U>` when: - // - // * Both `absl::StatusOr<T>` and `absl::StatusOr<U>` are OK by assigning - // `U` to `T` directly. - // * `absl::StatusOr<T>` is OK and `absl::StatusOr<U>` contains an error - // code by destroying `absl::StatusOr<T>`'s value and assigning from - // `absl::StatusOr<U>' - // * `absl::StatusOr<T>` contains an error code and `absl::StatusOr<U>` is - // OK by directly initializing `T` from `U`. - // * Both `absl::StatusOr<T>` and `absl::StatusOr<U>` contain an error - // code by assigning the `Status` in `absl::StatusOr<U>` to - // `absl::StatusOr<T>` - // - // These overloads only apply if `absl::StatusOr<T>` is constructible and - // assignable from `absl::StatusOr<U>` and `StatusOr<T>` cannot be directly - // assigned from `StatusOr<U>`. - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_same<T, U>>, - std::is_constructible<T, const U&>, - std::is_assignable<T, const U&>, - absl::negation< - internal_statusor:: - IsConstructibleOrConvertibleOrAssignableFromStatusOr< - T, U>>>::value, - int> = 0> - StatusOr& operator=(const StatusOr<U>& other) { - this->Assign(other); - return *this; - } - template < - typename U, - absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>, - std::is_assignable<T, U&&>, - absl::negation< - internal_statusor:: - IsConstructibleOrConvertibleOrAssignableFromStatusOr< - T, U>>>::value, - int> = 0> - StatusOr& operator=(StatusOr<U>&& other) { - this->Assign(std::move(other)); - return *this; - } - - // Constructs a new `absl::StatusOr<T>` with a non-ok status. After calling - // this constructor, `this->ok()` will be `false` and calls to `value()` will - // crash, or produce an exception if exceptions are enabled. - // - // The constructor also takes any type `U` that is convertible to - // `absl::Status`. This constructor is explicit if an only if `U` is not of - // type `absl::Status` and the conversion from `U` to `Status` is explicit. - // - // REQUIRES: !Status(std::forward<U>(v)).ok(). This requirement is DCHECKed. - // In optimized builds, passing absl::OkStatus() here will have the effect - // of passing absl::StatusCode::kInternal as a fallback. - template < - typename U = absl::Status, - absl::enable_if_t< - absl::conjunction< - std::is_convertible<U&&, absl::Status>, - std::is_constructible<absl::Status, U&&>, - absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>, - absl::negation<std::is_same<absl::decay_t<U>, T>>, - absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>, - absl::negation<internal_statusor::HasConversionOperatorToStatusOr< - T, U&&>>>::value, - int> = 0> - StatusOr(U&& v) : Base(std::forward<U>(v)) {} - - template < - typename U = absl::Status, - absl::enable_if_t< - absl::conjunction< - absl::negation<std::is_convertible<U&&, absl::Status>>, - std::is_constructible<absl::Status, U&&>, - absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>, - absl::negation<std::is_same<absl::decay_t<U>, T>>, - absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>, - absl::negation<internal_statusor::HasConversionOperatorToStatusOr< - T, U&&>>>::value, - int> = 0> - explicit StatusOr(U&& v) : Base(std::forward<U>(v)) {} - - template < - typename U = absl::Status, - absl::enable_if_t< - absl::conjunction< - std::is_convertible<U&&, absl::Status>, - std::is_constructible<absl::Status, U&&>, - absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>, - absl::negation<std::is_same<absl::decay_t<U>, T>>, - absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>, - absl::negation<internal_statusor::HasConversionOperatorToStatusOr< - T, U&&>>>::value, - int> = 0> - StatusOr& operator=(U&& v) { - this->AssignStatus(std::forward<U>(v)); - return *this; - } - - // Perfect-forwarding value assignment operator. - - // If `*this` contains a `T` value before the call, the contained value is - // assigned from `std::forward<U>(v)`; Otherwise, it is directly-initialized - // from `std::forward<U>(v)`. - // This function does not participate in overload unless: - // 1. `std::is_constructible_v<T, U>` is true, - // 2. `std::is_assignable_v<T&, U>` is true. - // 3. `std::is_same_v<StatusOr<T>, std::remove_cvref_t<U>>` is false. - // 4. Assigning `U` to `T` is not ambiguous: - // If `U` is `StatusOr<V>` and `T` is constructible and assignable from - // both `StatusOr<V>` and `V`, the assignment is considered bug-prone and - // ambiguous thus will fail to compile. For example: - // StatusOr<bool> s1 = true; // s1.ok() && *s1 == true - // StatusOr<bool> s2 = false; // s2.ok() && *s2 == false - // s1 = s2; // ambiguous, `s1 = *s2` or `s1 = bool(s2)`? - template < - typename U = T, - typename = typename std::enable_if<absl::conjunction< - std::is_constructible<T, U&&>, std::is_assignable<T&, U&&>, - absl::disjunction< - std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>, T>, - absl::conjunction< - absl::negation<std::is_convertible<U&&, absl::Status>>, - absl::negation<internal_statusor:: - HasConversionOperatorToStatusOr<T, U&&>>>>, - internal_statusor::IsForwardingAssignmentValid<T, U&&>>::value>::type> - StatusOr& operator=(U&& v) { - this->Assign(std::forward<U>(v)); - return *this; - } - - // Constructs the inner value `T` in-place using the provided args, using the - // `T(args...)` constructor. - template <typename... Args> - explicit StatusOr(absl::in_place_t, Args&&... args); - template <typename U, typename... Args> - explicit StatusOr(absl::in_place_t, std::initializer_list<U> ilist, - Args&&... args); - - // Constructs the inner value `T` in-place using the provided args, using the - // `T(U)` (direct-initialization) constructor. This constructor is only valid - // if `T` can be constructed from a `U`. Can accept move or copy constructors. - // - // This constructor is explicit if `U` is not convertible to `T`. To avoid +// +// Example: +// +// StatusOr<Foo> result = DoBigCalculationThatCouldFail(); +// const Foo& foo = result.value(); // Crash/exception if no value present +// foo.DoSomethingCool(); +// +// A `absl::StatusOr<T*>` can be constructed from a null pointer like any other +// pointer value, and the result will be that `ok()` returns `true` and +// `value()` returns `nullptr`. Checking the value of pointer in an +// `absl::StatusOr<T>` generally requires a bit more care, to ensure both that a +// value is present and that value is not null: +// +// StatusOr<std::unique_ptr<Foo>> result = FooFactory::MakeNewFoo(arg); +// if (!result.ok()) { +// LOG(ERROR) << result.status(); +// } else if (*result == nullptr) { +// LOG(ERROR) << "Unexpected null pointer"; +// } else { +// (*result)->DoSomethingCool(); +// } +// +// Example factory implementation returning StatusOr<T>: +// +// StatusOr<Foo> FooFactory::MakeFoo(int arg) { +// if (arg <= 0) { +// return absl::Status(absl::StatusCode::kInvalidArgument, +// "Arg must be positive"); +// } +// return Foo(arg); +// } +template <typename T> +class StatusOr : private internal_statusor::StatusOrData<T>, + private internal_statusor::CopyCtorBase<T>, + private internal_statusor::MoveCtorBase<T>, + private internal_statusor::CopyAssignBase<T>, + private internal_statusor::MoveAssignBase<T> { + template <typename U> + friend class StatusOr; + + typedef internal_statusor::StatusOrData<T> Base; + + public: + // StatusOr<T>::value_type + // + // This instance data provides a generic `value_type` member for use within + // generic programming. This usage is analogous to that of + // `optional::value_type` in the case of `std::optional`. + typedef T value_type; + + // Constructors + + // Constructs a new `absl::StatusOr` with an `absl::StatusCode::kUnknown` + // status. This constructor is marked 'explicit' to prevent usages in return + // values such as 'return {};', under the misconception that + // `absl::StatusOr<std::vector<int>>` will be initialized with an empty + // vector, instead of an `absl::StatusCode::kUnknown` error code. + explicit StatusOr(); + + // `StatusOr<T>` is copy constructible if `T` is copy constructible. + StatusOr(const StatusOr&) = default; + // `StatusOr<T>` is copy assignable if `T` is copy constructible and copy + // assignable. + StatusOr& operator=(const StatusOr&) = default; + + // `StatusOr<T>` is move constructible if `T` is move constructible. + StatusOr(StatusOr&&) = default; + // `StatusOr<T>` is moveAssignable if `T` is move constructible and move + // assignable. + StatusOr& operator=(StatusOr&&) = default; + + // Converting Constructors + + // Constructs a new `absl::StatusOr<T>` from an `absl::StatusOr<U>`, when `T` + // is constructible from `U`. To avoid ambiguity, these constructors are + // disabled if `T` is also constructible from `StatusOr<U>.`. This constructor + // is explicit if and only if the corresponding construction of `T` from `U` + // is explicit. (This constructor inherits its explicitness from the + // underlying constructor.) + template < + typename U, + absl::enable_if_t< + absl::conjunction< + absl::negation<std::is_same<T, U>>, + std::is_constructible<T, const U&>, + std::is_convertible<const U&, T>, + absl::negation< + internal_statusor::IsConstructibleOrConvertibleFromStatusOr< + T, U>>>::value, + int> = 0> + StatusOr(const StatusOr<U>& other) // NOLINT + : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {} + template < + typename U, + absl::enable_if_t< + absl::conjunction< + absl::negation<std::is_same<T, U>>, + std::is_constructible<T, const U&>, + absl::negation<std::is_convertible<const U&, T>>, + absl::negation< + internal_statusor::IsConstructibleOrConvertibleFromStatusOr< + T, U>>>::value, + int> = 0> + explicit StatusOr(const StatusOr<U>& other) + : Base(static_cast<const typename StatusOr<U>::Base&>(other)) {} + + template < + typename U, + absl::enable_if_t< + absl::conjunction< + absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>, + std::is_convertible<U&&, T>, + absl::negation< + internal_statusor::IsConstructibleOrConvertibleFromStatusOr< + T, U>>>::value, + int> = 0> + StatusOr(StatusOr<U>&& other) // NOLINT + : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {} + template < + typename U, + absl::enable_if_t< + absl::conjunction< + absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>, + absl::negation<std::is_convertible<U&&, T>>, + absl::negation< + internal_statusor::IsConstructibleOrConvertibleFromStatusOr< + T, U>>>::value, + int> = 0> + explicit StatusOr(StatusOr<U>&& other) + : Base(static_cast<typename StatusOr<U>::Base&&>(other)) {} + + // Converting Assignment Operators + + // Creates an `absl::StatusOr<T>` through assignment from an + // `absl::StatusOr<U>` when: + // + // * Both `absl::StatusOr<T>` and `absl::StatusOr<U>` are OK by assigning + // `U` to `T` directly. + // * `absl::StatusOr<T>` is OK and `absl::StatusOr<U>` contains an error + // code by destroying `absl::StatusOr<T>`'s value and assigning from + // `absl::StatusOr<U>' + // * `absl::StatusOr<T>` contains an error code and `absl::StatusOr<U>` is + // OK by directly initializing `T` from `U`. + // * Both `absl::StatusOr<T>` and `absl::StatusOr<U>` contain an error + // code by assigning the `Status` in `absl::StatusOr<U>` to + // `absl::StatusOr<T>` + // + // These overloads only apply if `absl::StatusOr<T>` is constructible and + // assignable from `absl::StatusOr<U>` and `StatusOr<T>` cannot be directly + // assigned from `StatusOr<U>`. + template < + typename U, + absl::enable_if_t< + absl::conjunction< + absl::negation<std::is_same<T, U>>, + std::is_constructible<T, const U&>, + std::is_assignable<T, const U&>, + absl::negation< + internal_statusor:: + IsConstructibleOrConvertibleOrAssignableFromStatusOr< + T, U>>>::value, + int> = 0> + StatusOr& operator=(const StatusOr<U>& other) { + this->Assign(other); + return *this; + } + template < + typename U, + absl::enable_if_t< + absl::conjunction< + absl::negation<std::is_same<T, U>>, std::is_constructible<T, U&&>, + std::is_assignable<T, U&&>, + absl::negation< + internal_statusor:: + IsConstructibleOrConvertibleOrAssignableFromStatusOr< + T, U>>>::value, + int> = 0> + StatusOr& operator=(StatusOr<U>&& other) { + this->Assign(std::move(other)); + return *this; + } + + // Constructs a new `absl::StatusOr<T>` with a non-ok status. After calling + // this constructor, `this->ok()` will be `false` and calls to `value()` will + // crash, or produce an exception if exceptions are enabled. + // + // The constructor also takes any type `U` that is convertible to + // `absl::Status`. This constructor is explicit if an only if `U` is not of + // type `absl::Status` and the conversion from `U` to `Status` is explicit. + // + // REQUIRES: !Status(std::forward<U>(v)).ok(). This requirement is DCHECKed. + // In optimized builds, passing absl::OkStatus() here will have the effect + // of passing absl::StatusCode::kInternal as a fallback. + template < + typename U = absl::Status, + absl::enable_if_t< + absl::conjunction< + std::is_convertible<U&&, absl::Status>, + std::is_constructible<absl::Status, U&&>, + absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>, + absl::negation<std::is_same<absl::decay_t<U>, T>>, + absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>, + absl::negation<internal_statusor::HasConversionOperatorToStatusOr< + T, U&&>>>::value, + int> = 0> + StatusOr(U&& v) : Base(std::forward<U>(v)) {} + + template < + typename U = absl::Status, + absl::enable_if_t< + absl::conjunction< + absl::negation<std::is_convertible<U&&, absl::Status>>, + std::is_constructible<absl::Status, U&&>, + absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>, + absl::negation<std::is_same<absl::decay_t<U>, T>>, + absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>, + absl::negation<internal_statusor::HasConversionOperatorToStatusOr< + T, U&&>>>::value, + int> = 0> + explicit StatusOr(U&& v) : Base(std::forward<U>(v)) {} + + template < + typename U = absl::Status, + absl::enable_if_t< + absl::conjunction< + std::is_convertible<U&&, absl::Status>, + std::is_constructible<absl::Status, U&&>, + absl::negation<std::is_same<absl::decay_t<U>, absl::StatusOr<T>>>, + absl::negation<std::is_same<absl::decay_t<U>, T>>, + absl::negation<std::is_same<absl::decay_t<U>, absl::in_place_t>>, + absl::negation<internal_statusor::HasConversionOperatorToStatusOr< + T, U&&>>>::value, + int> = 0> + StatusOr& operator=(U&& v) { + this->AssignStatus(std::forward<U>(v)); + return *this; + } + + // Perfect-forwarding value assignment operator. + + // If `*this` contains a `T` value before the call, the contained value is + // assigned from `std::forward<U>(v)`; Otherwise, it is directly-initialized + // from `std::forward<U>(v)`. + // This function does not participate in overload unless: + // 1. `std::is_constructible_v<T, U>` is true, + // 2. `std::is_assignable_v<T&, U>` is true. + // 3. `std::is_same_v<StatusOr<T>, std::remove_cvref_t<U>>` is false. + // 4. Assigning `U` to `T` is not ambiguous: + // If `U` is `StatusOr<V>` and `T` is constructible and assignable from + // both `StatusOr<V>` and `V`, the assignment is considered bug-prone and + // ambiguous thus will fail to compile. For example: + // StatusOr<bool> s1 = true; // s1.ok() && *s1 == true + // StatusOr<bool> s2 = false; // s2.ok() && *s2 == false + // s1 = s2; // ambiguous, `s1 = *s2` or `s1 = bool(s2)`? + template < + typename U = T, + typename = typename std::enable_if<absl::conjunction< + std::is_constructible<T, U&&>, std::is_assignable<T&, U&&>, + absl::disjunction< + std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>, T>, + absl::conjunction< + absl::negation<std::is_convertible<U&&, absl::Status>>, + absl::negation<internal_statusor:: + HasConversionOperatorToStatusOr<T, U&&>>>>, + internal_statusor::IsForwardingAssignmentValid<T, U&&>>::value>::type> + StatusOr& operator=(U&& v) { + this->Assign(std::forward<U>(v)); + return *this; + } + + // Constructs the inner value `T` in-place using the provided args, using the + // `T(args...)` constructor. + template <typename... Args> + explicit StatusOr(absl::in_place_t, Args&&... args); + template <typename U, typename... Args> + explicit StatusOr(absl::in_place_t, std::initializer_list<U> ilist, + Args&&... args); + + // Constructs the inner value `T` in-place using the provided args, using the + // `T(U)` (direct-initialization) constructor. This constructor is only valid + // if `T` can be constructed from a `U`. Can accept move or copy constructors. + // + // This constructor is explicit if `U` is not convertible to `T`. To avoid // ambiguity, this constructor is disabled if `U` is a `StatusOr<J>`, where // `J` is convertible to `T`. - template < - typename U = T, - absl::enable_if_t< - absl::conjunction< - internal_statusor::IsDirectInitializationValid<T, U&&>, - std::is_constructible<T, U&&>, std::is_convertible<U&&, T>, - absl::disjunction< - std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>, - T>, - absl::conjunction< - absl::negation<std::is_convertible<U&&, absl::Status>>, - absl::negation< - internal_statusor::HasConversionOperatorToStatusOr< - T, U&&>>>>>::value, - int> = 0> - StatusOr(U&& u) // NOLINT + template < + typename U = T, + absl::enable_if_t< + absl::conjunction< + internal_statusor::IsDirectInitializationValid<T, U&&>, + std::is_constructible<T, U&&>, std::is_convertible<U&&, T>, + absl::disjunction< + std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>, + T>, + absl::conjunction< + absl::negation<std::is_convertible<U&&, absl::Status>>, + absl::negation< + internal_statusor::HasConversionOperatorToStatusOr< + T, U&&>>>>>::value, + int> = 0> + StatusOr(U&& u) // NOLINT : StatusOr(absl::in_place, std::forward<U>(u)) {} - - template < - typename U = T, - absl::enable_if_t< - absl::conjunction< - internal_statusor::IsDirectInitializationValid<T, U&&>, - absl::disjunction< - std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>, - T>, - absl::conjunction< - absl::negation<std::is_constructible<absl::Status, U&&>>, - absl::negation< - internal_statusor::HasConversionOperatorToStatusOr< - T, U&&>>>>, - std::is_constructible<T, U&&>, - absl::negation<std::is_convertible<U&&, T>>>::value, - int> = 0> - explicit StatusOr(U&& u) // NOLINT + + template < + typename U = T, + absl::enable_if_t< + absl::conjunction< + internal_statusor::IsDirectInitializationValid<T, U&&>, + absl::disjunction< + std::is_same<absl::remove_cv_t<absl::remove_reference_t<U>>, + T>, + absl::conjunction< + absl::negation<std::is_constructible<absl::Status, U&&>>, + absl::negation< + internal_statusor::HasConversionOperatorToStatusOr< + T, U&&>>>>, + std::is_constructible<T, U&&>, + absl::negation<std::is_convertible<U&&, T>>>::value, + int> = 0> + explicit StatusOr(U&& u) // NOLINT : StatusOr(absl::in_place, std::forward<U>(u)) {} - - // StatusOr<T>::ok() - // - // Returns whether or not this `absl::StatusOr<T>` holds a `T` value. This - // member function is analagous to `absl::Status::ok()` and should be used - // similarly to check the status of return values. - // - // Example: - // - // StatusOr<Foo> result = DoBigCalculationThatCouldFail(); - // if (result.ok()) { - // // Handle result - // else { - // // Handle error - // } - ABSL_MUST_USE_RESULT bool ok() const { return this->status_.ok(); } - - // StatusOr<T>::status() - // - // Returns a reference to the current `absl::Status` contained within the - // `absl::StatusOr<T>`. If `absl::StatusOr<T>` contains a `T`, then this - // function returns `absl::OkStatus()`. + + // StatusOr<T>::ok() + // + // Returns whether or not this `absl::StatusOr<T>` holds a `T` value. This + // member function is analagous to `absl::Status::ok()` and should be used + // similarly to check the status of return values. + // + // Example: + // + // StatusOr<Foo> result = DoBigCalculationThatCouldFail(); + // if (result.ok()) { + // // Handle result + // else { + // // Handle error + // } + ABSL_MUST_USE_RESULT bool ok() const { return this->status_.ok(); } + + // StatusOr<T>::status() + // + // Returns a reference to the current `absl::Status` contained within the + // `absl::StatusOr<T>`. If `absl::StatusOr<T>` contains a `T`, then this + // function returns `absl::OkStatus()`. const Status& status() const&; - Status status() &&; - - // StatusOr<T>::value() - // - // Returns a reference to the held value if `this->ok()`. Otherwise, throws - // `absl::BadStatusOrAccess` if exceptions are enabled, or is guaranteed to - // terminate the process if exceptions are disabled. - // - // If you have already checked the status using `this->ok()`, you probably - // want to use `operator*()` or `operator->()` to access the value instead of - // `value`. - // - // Note: for value types that are cheap to copy, prefer simple code: - // - // T value = statusor.value(); - // - // Otherwise, if the value type is expensive to copy, but can be left - // in the StatusOr, simply assign to a reference: - // - // T& value = statusor.value(); // or `const T&` - // - // Otherwise, if the value type supports an efficient move, it can be - // used as follows: - // - // T value = std::move(statusor).value(); - // - // The `std::move` on statusor instead of on the whole expression enables - // warnings about possible uses of the statusor object after the move. + Status status() &&; + + // StatusOr<T>::value() + // + // Returns a reference to the held value if `this->ok()`. Otherwise, throws + // `absl::BadStatusOrAccess` if exceptions are enabled, or is guaranteed to + // terminate the process if exceptions are disabled. + // + // If you have already checked the status using `this->ok()`, you probably + // want to use `operator*()` or `operator->()` to access the value instead of + // `value`. + // + // Note: for value types that are cheap to copy, prefer simple code: + // + // T value = statusor.value(); + // + // Otherwise, if the value type is expensive to copy, but can be left + // in the StatusOr, simply assign to a reference: + // + // T& value = statusor.value(); // or `const T&` + // + // Otherwise, if the value type supports an efficient move, it can be + // used as follows: + // + // T value = std::move(statusor).value(); + // + // The `std::move` on statusor instead of on the whole expression enables + // warnings about possible uses of the statusor object after the move. const T& value() const& ABSL_ATTRIBUTE_LIFETIME_BOUND; T& value() & ABSL_ATTRIBUTE_LIFETIME_BOUND; const T&& value() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND; T&& value() && ABSL_ATTRIBUTE_LIFETIME_BOUND; - - // StatusOr<T>:: operator*() - // - // Returns a reference to the current value. - // - // REQUIRES: `this->ok() == true`, otherwise the behavior is undefined. - // - // Use `this->ok()` to verify that there is a current value within the - // `absl::StatusOr<T>`. Alternatively, see the `value()` member function for a - // similar API that guarantees crashing or throwing an exception if there is - // no current value. + + // StatusOr<T>:: operator*() + // + // Returns a reference to the current value. + // + // REQUIRES: `this->ok() == true`, otherwise the behavior is undefined. + // + // Use `this->ok()` to verify that there is a current value within the + // `absl::StatusOr<T>`. Alternatively, see the `value()` member function for a + // similar API that guarantees crashing or throwing an exception if there is + // no current value. const T& operator*() const& ABSL_ATTRIBUTE_LIFETIME_BOUND; T& operator*() & ABSL_ATTRIBUTE_LIFETIME_BOUND; const T&& operator*() const&& ABSL_ATTRIBUTE_LIFETIME_BOUND; T&& operator*() && ABSL_ATTRIBUTE_LIFETIME_BOUND; - - // StatusOr<T>::operator->() - // - // Returns a pointer to the current value. - // - // REQUIRES: `this->ok() == true`, otherwise the behavior is undefined. - // - // Use `this->ok()` to verify that there is a current value. + + // StatusOr<T>::operator->() + // + // Returns a pointer to the current value. + // + // REQUIRES: `this->ok() == true`, otherwise the behavior is undefined. + // + // Use `this->ok()` to verify that there is a current value. const T* operator->() const ABSL_ATTRIBUTE_LIFETIME_BOUND; T* operator->() ABSL_ATTRIBUTE_LIFETIME_BOUND; - - // StatusOr<T>::value_or() - // + + // StatusOr<T>::value_or() + // // Returns the current value if `this->ok() == true`. Otherwise constructs a - // value using the provided `default_value`. - // - // Unlike `value`, this function returns by value, copying the current value - // if necessary. If the value type supports an efficient move, it can be used - // as follows: - // - // T value = std::move(statusor).value_or(def); - // - // Unlike with `value`, calling `std::move()` on the result of `value_or` will - // still trigger a copy. - template <typename U> - T value_or(U&& default_value) const&; - template <typename U> - T value_or(U&& default_value) &&; - - // StatusOr<T>::IgnoreError() - // - // Ignores any errors. This method does nothing except potentially suppress - // complaints from any tools that are checking that errors are not dropped on - // the floor. - void IgnoreError() const; - - // StatusOr<T>::emplace() - // - // Reconstructs the inner value T in-place using the provided args, using the - // T(args...) constructor. Returns reference to the reconstructed `T`. - template <typename... Args> - T& emplace(Args&&... args) { - if (ok()) { - this->Clear(); - this->MakeValue(std::forward<Args>(args)...); - } else { - this->MakeValue(std::forward<Args>(args)...); - this->status_ = absl::OkStatus(); - } - return this->data_; - } - - template < - typename U, typename... Args, - absl::enable_if_t< - std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value, - int> = 0> - T& emplace(std::initializer_list<U> ilist, Args&&... args) { - if (ok()) { - this->Clear(); - this->MakeValue(ilist, std::forward<Args>(args)...); - } else { - this->MakeValue(ilist, std::forward<Args>(args)...); - this->status_ = absl::OkStatus(); - } - return this->data_; - } - - private: - using internal_statusor::StatusOrData<T>::Assign; - template <typename U> - void Assign(const absl::StatusOr<U>& other); - template <typename U> - void Assign(absl::StatusOr<U>&& other); -}; - -// operator==() -// -// This operator checks the equality of two `absl::StatusOr<T>` objects. -template <typename T> -bool operator==(const StatusOr<T>& lhs, const StatusOr<T>& rhs) { - if (lhs.ok() && rhs.ok()) return *lhs == *rhs; - return lhs.status() == rhs.status(); -} - -// operator!=() -// -// This operator checks the inequality of two `absl::StatusOr<T>` objects. -template <typename T> -bool operator!=(const StatusOr<T>& lhs, const StatusOr<T>& rhs) { - return !(lhs == rhs); -} - -//------------------------------------------------------------------------------ -// Implementation details for StatusOr<T> -//------------------------------------------------------------------------------ - -// TODO(sbenza): avoid the string here completely. -template <typename T> -StatusOr<T>::StatusOr() : Base(Status(absl::StatusCode::kUnknown, "")) {} - -template <typename T> -template <typename U> -inline void StatusOr<T>::Assign(const StatusOr<U>& other) { - if (other.ok()) { - this->Assign(*other); - } else { - this->AssignStatus(other.status()); - } -} - -template <typename T> -template <typename U> -inline void StatusOr<T>::Assign(StatusOr<U>&& other) { - if (other.ok()) { - this->Assign(*std::move(other)); - } else { - this->AssignStatus(std::move(other).status()); - } -} -template <typename T> -template <typename... Args> -StatusOr<T>::StatusOr(absl::in_place_t, Args&&... args) - : Base(absl::in_place, std::forward<Args>(args)...) {} - -template <typename T> -template <typename U, typename... Args> -StatusOr<T>::StatusOr(absl::in_place_t, std::initializer_list<U> ilist, - Args&&... args) - : Base(absl::in_place, ilist, std::forward<Args>(args)...) {} - -template <typename T> + // value using the provided `default_value`. + // + // Unlike `value`, this function returns by value, copying the current value + // if necessary. If the value type supports an efficient move, it can be used + // as follows: + // + // T value = std::move(statusor).value_or(def); + // + // Unlike with `value`, calling `std::move()` on the result of `value_or` will + // still trigger a copy. + template <typename U> + T value_or(U&& default_value) const&; + template <typename U> + T value_or(U&& default_value) &&; + + // StatusOr<T>::IgnoreError() + // + // Ignores any errors. This method does nothing except potentially suppress + // complaints from any tools that are checking that errors are not dropped on + // the floor. + void IgnoreError() const; + + // StatusOr<T>::emplace() + // + // Reconstructs the inner value T in-place using the provided args, using the + // T(args...) constructor. Returns reference to the reconstructed `T`. + template <typename... Args> + T& emplace(Args&&... args) { + if (ok()) { + this->Clear(); + this->MakeValue(std::forward<Args>(args)...); + } else { + this->MakeValue(std::forward<Args>(args)...); + this->status_ = absl::OkStatus(); + } + return this->data_; + } + + template < + typename U, typename... Args, + absl::enable_if_t< + std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value, + int> = 0> + T& emplace(std::initializer_list<U> ilist, Args&&... args) { + if (ok()) { + this->Clear(); + this->MakeValue(ilist, std::forward<Args>(args)...); + } else { + this->MakeValue(ilist, std::forward<Args>(args)...); + this->status_ = absl::OkStatus(); + } + return this->data_; + } + + private: + using internal_statusor::StatusOrData<T>::Assign; + template <typename U> + void Assign(const absl::StatusOr<U>& other); + template <typename U> + void Assign(absl::StatusOr<U>&& other); +}; + +// operator==() +// +// This operator checks the equality of two `absl::StatusOr<T>` objects. +template <typename T> +bool operator==(const StatusOr<T>& lhs, const StatusOr<T>& rhs) { + if (lhs.ok() && rhs.ok()) return *lhs == *rhs; + return lhs.status() == rhs.status(); +} + +// operator!=() +// +// This operator checks the inequality of two `absl::StatusOr<T>` objects. +template <typename T> +bool operator!=(const StatusOr<T>& lhs, const StatusOr<T>& rhs) { + return !(lhs == rhs); +} + +//------------------------------------------------------------------------------ +// Implementation details for StatusOr<T> +//------------------------------------------------------------------------------ + +// TODO(sbenza): avoid the string here completely. +template <typename T> +StatusOr<T>::StatusOr() : Base(Status(absl::StatusCode::kUnknown, "")) {} + +template <typename T> +template <typename U> +inline void StatusOr<T>::Assign(const StatusOr<U>& other) { + if (other.ok()) { + this->Assign(*other); + } else { + this->AssignStatus(other.status()); + } +} + +template <typename T> +template <typename U> +inline void StatusOr<T>::Assign(StatusOr<U>&& other) { + if (other.ok()) { + this->Assign(*std::move(other)); + } else { + this->AssignStatus(std::move(other).status()); + } +} +template <typename T> +template <typename... Args> +StatusOr<T>::StatusOr(absl::in_place_t, Args&&... args) + : Base(absl::in_place, std::forward<Args>(args)...) {} + +template <typename T> +template <typename U, typename... Args> +StatusOr<T>::StatusOr(absl::in_place_t, std::initializer_list<U> ilist, + Args&&... args) + : Base(absl::in_place, ilist, std::forward<Args>(args)...) {} + +template <typename T> const Status& StatusOr<T>::status() const& { return this->status_; } -template <typename T> -Status StatusOr<T>::status() && { - return ok() ? OkStatus() : std::move(this->status_); -} - -template <typename T> -const T& StatusOr<T>::value() const& { - if (!this->ok()) internal_statusor::ThrowBadStatusOrAccess(this->status_); - return this->data_; -} - -template <typename T> -T& StatusOr<T>::value() & { - if (!this->ok()) internal_statusor::ThrowBadStatusOrAccess(this->status_); - return this->data_; -} - -template <typename T> -const T&& StatusOr<T>::value() const&& { - if (!this->ok()) { - internal_statusor::ThrowBadStatusOrAccess(std::move(this->status_)); - } - return std::move(this->data_); -} - -template <typename T> -T&& StatusOr<T>::value() && { - if (!this->ok()) { - internal_statusor::ThrowBadStatusOrAccess(std::move(this->status_)); - } - return std::move(this->data_); -} - -template <typename T> -const T& StatusOr<T>::operator*() const& { - this->EnsureOk(); - return this->data_; -} - -template <typename T> -T& StatusOr<T>::operator*() & { - this->EnsureOk(); - return this->data_; -} - -template <typename T> -const T&& StatusOr<T>::operator*() const&& { - this->EnsureOk(); - return std::move(this->data_); -} - -template <typename T> -T&& StatusOr<T>::operator*() && { - this->EnsureOk(); - return std::move(this->data_); -} - -template <typename T> -const T* StatusOr<T>::operator->() const { - this->EnsureOk(); - return &this->data_; -} - -template <typename T> -T* StatusOr<T>::operator->() { - this->EnsureOk(); - return &this->data_; -} - -template <typename T> -template <typename U> -T StatusOr<T>::value_or(U&& default_value) const& { - if (ok()) { - return this->data_; - } - return std::forward<U>(default_value); -} - -template <typename T> -template <typename U> -T StatusOr<T>::value_or(U&& default_value) && { - if (ok()) { - return std::move(this->data_); - } - return std::forward<U>(default_value); -} - -template <typename T> -void StatusOr<T>::IgnoreError() const { - // no-op -} - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STATUS_STATUSOR_H_ +template <typename T> +Status StatusOr<T>::status() && { + return ok() ? OkStatus() : std::move(this->status_); +} + +template <typename T> +const T& StatusOr<T>::value() const& { + if (!this->ok()) internal_statusor::ThrowBadStatusOrAccess(this->status_); + return this->data_; +} + +template <typename T> +T& StatusOr<T>::value() & { + if (!this->ok()) internal_statusor::ThrowBadStatusOrAccess(this->status_); + return this->data_; +} + +template <typename T> +const T&& StatusOr<T>::value() const&& { + if (!this->ok()) { + internal_statusor::ThrowBadStatusOrAccess(std::move(this->status_)); + } + return std::move(this->data_); +} + +template <typename T> +T&& StatusOr<T>::value() && { + if (!this->ok()) { + internal_statusor::ThrowBadStatusOrAccess(std::move(this->status_)); + } + return std::move(this->data_); +} + +template <typename T> +const T& StatusOr<T>::operator*() const& { + this->EnsureOk(); + return this->data_; +} + +template <typename T> +T& StatusOr<T>::operator*() & { + this->EnsureOk(); + return this->data_; +} + +template <typename T> +const T&& StatusOr<T>::operator*() const&& { + this->EnsureOk(); + return std::move(this->data_); +} + +template <typename T> +T&& StatusOr<T>::operator*() && { + this->EnsureOk(); + return std::move(this->data_); +} + +template <typename T> +const T* StatusOr<T>::operator->() const { + this->EnsureOk(); + return &this->data_; +} + +template <typename T> +T* StatusOr<T>::operator->() { + this->EnsureOk(); + return &this->data_; +} + +template <typename T> +template <typename U> +T StatusOr<T>::value_or(U&& default_value) const& { + if (ok()) { + return this->data_; + } + return std::forward<U>(default_value); +} + +template <typename T> +template <typename U> +T StatusOr<T>::value_or(U&& default_value) && { + if (ok()) { + return std::move(this->data_); + } + return std::forward<U>(default_value); +} + +template <typename T> +void StatusOr<T>::IgnoreError() const { + // no-op +} + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STATUS_STATUSOR_H_ diff --git a/contrib/restricted/abseil-cpp/absl/status/ya.make b/contrib/restricted/abseil-cpp/absl/status/ya.make index 54a88b1ab1..a0b84e6686 100644 --- a/contrib/restricted/abseil-cpp/absl/status/ya.make +++ b/contrib/restricted/abseil-cpp/absl/status/ya.make @@ -1,57 +1,57 @@ -# Generated by devtools/yamaker. - -LIBRARY() - -OWNER(g:cpp-contrib) - -LICENSE(Apache-2.0) - +# Generated by devtools/yamaker. + +LIBRARY() + +OWNER(g:cpp-contrib) + +LICENSE(Apache-2.0) + LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -PEERDIR( - contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc - contrib/restricted/abseil-cpp/absl/base/internal/raw_logging - contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait - contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate - contrib/restricted/abseil-cpp/absl/base/log_severity - contrib/restricted/abseil-cpp/absl/debugging - contrib/restricted/abseil-cpp/absl/debugging/stacktrace - contrib/restricted/abseil-cpp/absl/debugging/symbolize - contrib/restricted/abseil-cpp/absl/demangle - contrib/restricted/abseil-cpp/absl/numeric +PEERDIR( + contrib/restricted/abseil-cpp/absl/base + contrib/restricted/abseil-cpp/absl/base/internal/low_level_alloc + contrib/restricted/abseil-cpp/absl/base/internal/raw_logging + contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait + contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate + contrib/restricted/abseil-cpp/absl/base/log_severity + contrib/restricted/abseil-cpp/absl/debugging + contrib/restricted/abseil-cpp/absl/debugging/stacktrace + contrib/restricted/abseil-cpp/absl/debugging/symbolize + contrib/restricted/abseil-cpp/absl/demangle + contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/profiling/internal/exponential_biased - contrib/restricted/abseil-cpp/absl/strings + contrib/restricted/abseil-cpp/absl/strings contrib/restricted/abseil-cpp/absl/strings/cord contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions contrib/restricted/abseil-cpp/absl/strings/internal/cordz_handle contrib/restricted/abseil-cpp/absl/strings/internal/cordz_info - contrib/restricted/abseil-cpp/absl/strings/internal/str_format + contrib/restricted/abseil-cpp/absl/strings/internal/str_format contrib/restricted/abseil-cpp/absl/synchronization contrib/restricted/abseil-cpp/absl/synchronization/internal contrib/restricted/abseil-cpp/absl/time contrib/restricted/abseil-cpp/absl/time/civil_time contrib/restricted/abseil-cpp/absl/time/time_zone - contrib/restricted/abseil-cpp/absl/types/bad_optional_access -) - -ADDINCL( - GLOBAL contrib/restricted/abseil-cpp -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DNOMINMAX -) - -SRCS( - status.cc - status_payload_printer.cc -) - -END() + contrib/restricted/abseil-cpp/absl/types/bad_optional_access +) + +ADDINCL( + GLOBAL contrib/restricted/abseil-cpp +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DNOMINMAX +) + +SRCS( + status.cc + status_payload_printer.cc +) + +END() diff --git a/contrib/restricted/abseil-cpp/absl/strings/ascii.cc b/contrib/restricted/abseil-cpp/absl/strings/ascii.cc index 93bb03e958..facfb50bc0 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/ascii.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/ascii.cc @@ -15,7 +15,7 @@ #include "absl/strings/ascii.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace ascii_internal { // # Table generated by this Python code (bit 0x02 is currently unused): @@ -57,7 +57,7 @@ namespace ascii_internal { // of these bits is tightly coupled to this implementation, the individual bits // are not named. Note that bitfields for all characters above ASCII 127 are // zero-initialized. -ABSL_DLL const unsigned char kPropertyBits[256] = { +ABSL_DLL const unsigned char kPropertyBits[256] = { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x00 0x40, 0x68, 0x48, 0x48, 0x48, 0x48, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x10 @@ -79,7 +79,7 @@ ABSL_DLL const unsigned char kPropertyBits[256] = { // Array of characters for the ascii_tolower() function. For values 'A' // through 'Z', return the lower-case character; otherwise, return the // identity of the passed character. -ABSL_DLL const char kToLower[256] = { +ABSL_DLL const char kToLower[256] = { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', @@ -117,7 +117,7 @@ ABSL_DLL const char kToLower[256] = { // Array of characters for the ascii_toupper() function. For values 'a' // through 'z', return the upper-case character; otherwise, return the // identity of the passed character. -ABSL_DLL const char kToUpper[256] = { +ABSL_DLL const char kToUpper[256] = { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', @@ -196,5 +196,5 @@ void RemoveExtraAsciiWhitespace(std::string* str) { str->erase(output_it - &(*str)[0]); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/ascii.h b/contrib/restricted/abseil-cpp/absl/strings/ascii.h index b46bc71f35..699c209c9d 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/ascii.h +++ b/contrib/restricted/abseil-cpp/absl/strings/ascii.h @@ -56,21 +56,21 @@ #include <string> #include "absl/base/attributes.h" -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace ascii_internal { // Declaration for an array of bitfields holding character information. -ABSL_DLL extern const unsigned char kPropertyBits[256]; +ABSL_DLL extern const unsigned char kPropertyBits[256]; // Declaration for the array of characters to upper-case characters. -ABSL_DLL extern const char kToUpper[256]; +ABSL_DLL extern const char kToUpper[256]; // Declaration for the array of characters to lower-case characters. -ABSL_DLL extern const char kToLower[256]; +ABSL_DLL extern const char kToLower[256]; } // namespace ascii_internal @@ -236,7 +236,7 @@ inline void StripAsciiWhitespace(std::string* str) { // Removes leading, trailing, and consecutive internal whitespace. void RemoveExtraAsciiWhitespace(std::string*); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_ASCII_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/charconv.cc b/contrib/restricted/abseil-cpp/absl/strings/charconv.cc index fefcfc90a5..870461ce96 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/charconv.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/charconv.cc @@ -57,7 +57,7 @@ // narrower mantissas. namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { template <typename FloatType> @@ -619,10 +619,10 @@ from_chars_result FromCharsImpl(const char* first, const char* last, // Either we failed to parse a hex float after the "0x", or we read // "0xinf" or "0xnan" which we don't want to match. // - // However, a string that begins with "0x" also begins with "0", which + // However, a string that begins with "0x" also begins with "0", which // is normally a valid match for the number zero. So we want these // strings to match zero unless fmt_flags is `scientific`. (This flag - // means an exponent is required, which the string "0" does not have.) + // means an exponent is required, which the string "0" does not have.) if (fmt_flags == chars_format::scientific) { result.ec = std::errc::invalid_argument; } else { @@ -980,5 +980,5 @@ const int16_t kPower10ExponentTable[] = { }; } // namespace -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/charconv.h b/contrib/restricted/abseil-cpp/absl/strings/charconv.h index 7c50981245..be05e34d08 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/charconv.h +++ b/contrib/restricted/abseil-cpp/absl/strings/charconv.h @@ -17,10 +17,10 @@ #include <system_error> // NOLINT(build/c++11) -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // Workalike compatibilty version of std::chars_format from C++17. // @@ -114,7 +114,7 @@ inline chars_format& operator^=(chars_format& lhs, chars_format rhs) { return lhs; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_CHARCONV_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord.cc b/contrib/restricted/abseil-cpp/absl/strings/cord.cc index 854047ca98..a353a9facf 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/cord.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/cord.cc @@ -1,209 +1,209 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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 "absl/strings/cord.h" - -#include <algorithm> -#include <atomic> -#include <cstddef> -#include <cstdio> -#include <cstdlib> -#include <iomanip> -#include <iostream> -#include <limits> -#include <ostream> -#include <sstream> -#include <type_traits> -#include <unordered_set> -#include <vector> - -#include "absl/base/casts.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/base/macros.h" -#include "absl/base/port.h" -#include "absl/container/fixed_array.h" -#include "absl/container/inlined_vector.h" -#include "absl/strings/escaping.h" -#include "absl/strings/internal/cord_internal.h" +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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 "absl/strings/cord.h" + +#include <algorithm> +#include <atomic> +#include <cstddef> +#include <cstdio> +#include <cstdlib> +#include <iomanip> +#include <iostream> +#include <limits> +#include <ostream> +#include <sstream> +#include <type_traits> +#include <unordered_set> +#include <vector> + +#include "absl/base/casts.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/base/macros.h" +#include "absl/base/port.h" +#include "absl/container/fixed_array.h" +#include "absl/container/inlined_vector.h" +#include "absl/strings/escaping.h" +#include "absl/strings/internal/cord_internal.h" #include "absl/strings/internal/cord_rep_btree.h" #include "absl/strings/internal/cord_rep_flat.h" #include "absl/strings/internal/cordz_statistics.h" #include "absl/strings/internal/cordz_update_scope.h" #include "absl/strings/internal/cordz_update_tracker.h" -#include "absl/strings/internal/resize_uninitialized.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" -#include "absl/strings/str_join.h" -#include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -using ::absl::cord_internal::CordRep; +#include "absl/strings/internal/resize_uninitialized.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" +#include "absl/strings/str_join.h" +#include "absl/strings/string_view.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +using ::absl::cord_internal::CordRep; using ::absl::cord_internal::CordRepBtree; -using ::absl::cord_internal::CordRepConcat; -using ::absl::cord_internal::CordRepExternal; +using ::absl::cord_internal::CordRepConcat; +using ::absl::cord_internal::CordRepExternal; using ::absl::cord_internal::CordRepFlat; -using ::absl::cord_internal::CordRepSubstring; +using ::absl::cord_internal::CordRepSubstring; using ::absl::cord_internal::CordzUpdateTracker; using ::absl::cord_internal::InlineData; using ::absl::cord_internal::kMaxFlatLength; using ::absl::cord_internal::kMinFlatLength; - + using ::absl::cord_internal::kInlinedVectorSize; using ::absl::cord_internal::kMaxBytesToCopy; - -constexpr uint64_t Fibonacci(unsigned char n, uint64_t a = 0, uint64_t b = 1) { - return n == 0 ? a : Fibonacci(n - 1, b, a + b); -} - -static_assert(Fibonacci(63) == 6557470319842, - "Fibonacci values computed incorrectly"); - -// Minimum length required for a given depth tree -- a tree is considered -// balanced if -// length(t) >= min_length[depth(t)] -// The root node depth is allowed to become twice as large to reduce rebalancing -// for larger strings (see IsRootBalanced). -static constexpr uint64_t min_length[] = { - Fibonacci(2), Fibonacci(3), Fibonacci(4), Fibonacci(5), - Fibonacci(6), Fibonacci(7), Fibonacci(8), Fibonacci(9), - Fibonacci(10), Fibonacci(11), Fibonacci(12), Fibonacci(13), - Fibonacci(14), Fibonacci(15), Fibonacci(16), Fibonacci(17), - Fibonacci(18), Fibonacci(19), Fibonacci(20), Fibonacci(21), - Fibonacci(22), Fibonacci(23), Fibonacci(24), Fibonacci(25), - Fibonacci(26), Fibonacci(27), Fibonacci(28), Fibonacci(29), - Fibonacci(30), Fibonacci(31), Fibonacci(32), Fibonacci(33), - Fibonacci(34), Fibonacci(35), Fibonacci(36), Fibonacci(37), - Fibonacci(38), Fibonacci(39), Fibonacci(40), Fibonacci(41), - Fibonacci(42), Fibonacci(43), Fibonacci(44), Fibonacci(45), - Fibonacci(46), Fibonacci(47), - 0xffffffffffffffffull, // Avoid overflow -}; - -static const int kMinLengthSize = ABSL_ARRAYSIZE(min_length); - + +constexpr uint64_t Fibonacci(unsigned char n, uint64_t a = 0, uint64_t b = 1) { + return n == 0 ? a : Fibonacci(n - 1, b, a + b); +} + +static_assert(Fibonacci(63) == 6557470319842, + "Fibonacci values computed incorrectly"); + +// Minimum length required for a given depth tree -- a tree is considered +// balanced if +// length(t) >= min_length[depth(t)] +// The root node depth is allowed to become twice as large to reduce rebalancing +// for larger strings (see IsRootBalanced). +static constexpr uint64_t min_length[] = { + Fibonacci(2), Fibonacci(3), Fibonacci(4), Fibonacci(5), + Fibonacci(6), Fibonacci(7), Fibonacci(8), Fibonacci(9), + Fibonacci(10), Fibonacci(11), Fibonacci(12), Fibonacci(13), + Fibonacci(14), Fibonacci(15), Fibonacci(16), Fibonacci(17), + Fibonacci(18), Fibonacci(19), Fibonacci(20), Fibonacci(21), + Fibonacci(22), Fibonacci(23), Fibonacci(24), Fibonacci(25), + Fibonacci(26), Fibonacci(27), Fibonacci(28), Fibonacci(29), + Fibonacci(30), Fibonacci(31), Fibonacci(32), Fibonacci(33), + Fibonacci(34), Fibonacci(35), Fibonacci(36), Fibonacci(37), + Fibonacci(38), Fibonacci(39), Fibonacci(40), Fibonacci(41), + Fibonacci(42), Fibonacci(43), Fibonacci(44), Fibonacci(45), + Fibonacci(46), Fibonacci(47), + 0xffffffffffffffffull, // Avoid overflow +}; + +static const int kMinLengthSize = ABSL_ARRAYSIZE(min_length); + static inline bool btree_enabled() { return cord_internal::cord_btree_enabled.load( std::memory_order_relaxed); } - -static inline bool IsRootBalanced(CordRep* node) { + +static inline bool IsRootBalanced(CordRep* node) { if (!node->IsConcat()) { - return true; - } else if (node->concat()->depth() <= 15) { - return true; - } else if (node->concat()->depth() > kMinLengthSize) { - return false; - } else { - // Allow depth to become twice as large as implied by fibonacci rule to - // reduce rebalancing for larger strings. - return (node->length >= min_length[node->concat()->depth() / 2]); - } -} - -static CordRep* Rebalance(CordRep* node); + return true; + } else if (node->concat()->depth() <= 15) { + return true; + } else if (node->concat()->depth() > kMinLengthSize) { + return false; + } else { + // Allow depth to become twice as large as implied by fibonacci rule to + // reduce rebalancing for larger strings. + return (node->length >= min_length[node->concat()->depth() / 2]); + } +} + +static CordRep* Rebalance(CordRep* node); static void DumpNode(CordRep* rep, bool include_data, std::ostream* os, int indent = 0); -static bool VerifyNode(CordRep* root, CordRep* start_node, - bool full_validation); - -static inline CordRep* VerifyTree(CordRep* node) { - // Verification is expensive, so only do it in debug mode. - // Even in debug mode we normally do only light validation. - // If you are debugging Cord itself, you should define the - // macro EXTRA_CORD_VALIDATION, e.g. by adding - // --copt=-DEXTRA_CORD_VALIDATION to the blaze line. -#ifdef EXTRA_CORD_VALIDATION - assert(node == nullptr || VerifyNode(node, node, /*full_validation=*/true)); -#else // EXTRA_CORD_VALIDATION - assert(node == nullptr || VerifyNode(node, node, /*full_validation=*/false)); -#endif // EXTRA_CORD_VALIDATION - static_cast<void>(&VerifyNode); - - return node; -} - -// Return the depth of a node -static int Depth(const CordRep* rep) { +static bool VerifyNode(CordRep* root, CordRep* start_node, + bool full_validation); + +static inline CordRep* VerifyTree(CordRep* node) { + // Verification is expensive, so only do it in debug mode. + // Even in debug mode we normally do only light validation. + // If you are debugging Cord itself, you should define the + // macro EXTRA_CORD_VALIDATION, e.g. by adding + // --copt=-DEXTRA_CORD_VALIDATION to the blaze line. +#ifdef EXTRA_CORD_VALIDATION + assert(node == nullptr || VerifyNode(node, node, /*full_validation=*/true)); +#else // EXTRA_CORD_VALIDATION + assert(node == nullptr || VerifyNode(node, node, /*full_validation=*/false)); +#endif // EXTRA_CORD_VALIDATION + static_cast<void>(&VerifyNode); + + return node; +} + +// Return the depth of a node +static int Depth(const CordRep* rep) { if (rep->IsConcat()) { - return rep->concat()->depth(); - } else { - return 0; - } -} - -static void SetConcatChildren(CordRepConcat* concat, CordRep* left, - CordRep* right) { - concat->left = left; - concat->right = right; - - concat->length = left->length + right->length; - concat->set_depth(1 + std::max(Depth(left), Depth(right))); -} - -// Create a concatenation of the specified nodes. -// Does not change the refcounts of "left" and "right". -// The returned node has a refcount of 1. -static CordRep* RawConcat(CordRep* left, CordRep* right) { - // Avoid making degenerate concat nodes (one child is empty) + return rep->concat()->depth(); + } else { + return 0; + } +} + +static void SetConcatChildren(CordRepConcat* concat, CordRep* left, + CordRep* right) { + concat->left = left; + concat->right = right; + + concat->length = left->length + right->length; + concat->set_depth(1 + std::max(Depth(left), Depth(right))); +} + +// Create a concatenation of the specified nodes. +// Does not change the refcounts of "left" and "right". +// The returned node has a refcount of 1. +static CordRep* RawConcat(CordRep* left, CordRep* right) { + // Avoid making degenerate concat nodes (one child is empty) if (left == nullptr) return right; if (right == nullptr) return left; if (left->length == 0) { CordRep::Unref(left); - return right; - } + return right; + } if (right->length == 0) { CordRep::Unref(right); - return left; - } - - CordRepConcat* rep = new CordRepConcat(); + return left; + } + + CordRepConcat* rep = new CordRepConcat(); rep->tag = cord_internal::CONCAT; - SetConcatChildren(rep, left, right); - - return rep; -} - -static CordRep* Concat(CordRep* left, CordRep* right) { - CordRep* rep = RawConcat(left, right); - if (rep != nullptr && !IsRootBalanced(rep)) { - rep = Rebalance(rep); - } - return VerifyTree(rep); -} - -// Make a balanced tree out of an array of leaf nodes. -static CordRep* MakeBalancedTree(CordRep** reps, size_t n) { - // Make repeated passes over the array, merging adjacent pairs - // until we are left with just a single node. - while (n > 1) { - size_t dst = 0; - for (size_t src = 0; src < n; src += 2) { - if (src + 1 < n) { - reps[dst] = Concat(reps[src], reps[src + 1]); - } else { - reps[dst] = reps[src]; - } - dst++; - } - n = dst; - } - - return reps[0]; -} - + SetConcatChildren(rep, left, right); + + return rep; +} + +static CordRep* Concat(CordRep* left, CordRep* right) { + CordRep* rep = RawConcat(left, right); + if (rep != nullptr && !IsRootBalanced(rep)) { + rep = Rebalance(rep); + } + return VerifyTree(rep); +} + +// Make a balanced tree out of an array of leaf nodes. +static CordRep* MakeBalancedTree(CordRep** reps, size_t n) { + // Make repeated passes over the array, merging adjacent pairs + // until we are left with just a single node. + while (n > 1) { + size_t dst = 0; + for (size_t src = 0; src < n; src += 2) { + if (src + 1 < n) { + reps[dst] = Concat(reps[src], reps[src + 1]); + } else { + reps[dst] = reps[src]; + } + dst++; + } + n = dst; + } + + return reps[0]; +} + static CordRepFlat* CreateFlat(const char* data, size_t length, size_t alloc_hint) { CordRepFlat* flat = CordRepFlat::New(length + alloc_hint); @@ -217,63 +217,63 @@ static CordRepFlat* CreateFlat(const char* data, size_t length, static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) { if (length <= kMaxFlatLength) { return CreateFlat(data, length, alloc_hint); - } + } CordRepFlat* flat = CreateFlat(data, kMaxFlatLength, 0); data += kMaxFlatLength; length -= kMaxFlatLength; auto* root = CordRepBtree::Create(flat); return CordRepBtree::Append(root, {data, length}, alloc_hint); -} - -// Create a new tree out of the specified array. -// The returned node has a refcount of 1. +} + +// Create a new tree out of the specified array. +// The returned node has a refcount of 1. static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) { - if (length == 0) return nullptr; + if (length == 0) return nullptr; if (btree_enabled()) { return NewBtree(data, length, alloc_hint); } - absl::FixedArray<CordRep*> reps((length - 1) / kMaxFlatLength + 1); - size_t n = 0; - do { - const size_t len = std::min(length, kMaxFlatLength); + absl::FixedArray<CordRep*> reps((length - 1) / kMaxFlatLength + 1); + size_t n = 0; + do { + const size_t len = std::min(length, kMaxFlatLength); CordRepFlat* rep = CordRepFlat::New(len + alloc_hint); - rep->length = len; + rep->length = len; memcpy(rep->Data(), data, len); - reps[n++] = VerifyTree(rep); - data += len; - length -= len; - } while (length != 0); - return MakeBalancedTree(reps.data(), n); -} - -namespace cord_internal { - -void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep) { - assert(!data.empty()); - rep->length = data.size(); - rep->tag = EXTERNAL; - rep->base = data.data(); - VerifyTree(rep); -} - -} // namespace cord_internal - -static CordRep* NewSubstring(CordRep* child, size_t offset, size_t length) { - // Never create empty substring nodes - if (length == 0) { + reps[n++] = VerifyTree(rep); + data += len; + length -= len; + } while (length != 0); + return MakeBalancedTree(reps.data(), n); +} + +namespace cord_internal { + +void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep) { + assert(!data.empty()); + rep->length = data.size(); + rep->tag = EXTERNAL; + rep->base = data.data(); + VerifyTree(rep); +} + +} // namespace cord_internal + +static CordRep* NewSubstring(CordRep* child, size_t offset, size_t length) { + // Never create empty substring nodes + if (length == 0) { CordRep::Unref(child); - return nullptr; - } else { - CordRepSubstring* rep = new CordRepSubstring(); - assert((offset + length) <= child->length); - rep->length = length; + return nullptr; + } else { + CordRepSubstring* rep = new CordRepSubstring(); + assert((offset + length) <= child->length); + rep->length = length; rep->tag = cord_internal::SUBSTRING; - rep->start = offset; - rep->child = child; - return VerifyTree(rep); - } -} - + rep->start = offset; + rep->child = child; + return VerifyTree(rep); + } +} + // Creates a CordRep from the provided string. If the string is large enough, // and not wasteful, we move the string into an external cord rep, preserving // the already allocated string contents. @@ -303,41 +303,41 @@ static CordRep* CordRepFromString(std::string&& src) { return rep; } -// -------------------------------------------------------------------- -// Cord::InlineRep functions - -constexpr unsigned char Cord::InlineRep::kMaxInline; - -inline void Cord::InlineRep::set_data(const char* data, size_t n, - bool nullify_tail) { - static_assert(kMaxInline == 15, "set_data is hard-coded for a length of 15"); - +// -------------------------------------------------------------------- +// Cord::InlineRep functions + +constexpr unsigned char Cord::InlineRep::kMaxInline; + +inline void Cord::InlineRep::set_data(const char* data, size_t n, + bool nullify_tail) { + static_assert(kMaxInline == 15, "set_data is hard-coded for a length of 15"); + cord_internal::SmallMemmove(data_.as_chars(), data, n, nullify_tail); set_inline_size(n); -} - -inline char* Cord::InlineRep::set_data(size_t n) { - assert(n <= kMaxInline); - ResetToEmpty(); +} + +inline char* Cord::InlineRep::set_data(size_t n) { + assert(n <= kMaxInline); + ResetToEmpty(); set_inline_size(n); return data_.as_chars(); -} - -inline void Cord::InlineRep::reduce_size(size_t n) { +} + +inline void Cord::InlineRep::reduce_size(size_t n) { size_t tag = inline_size(); - assert(tag <= kMaxInline); - assert(tag >= n); - tag -= n; + assert(tag <= kMaxInline); + assert(tag >= n); + tag -= n; memset(data_.as_chars() + tag, 0, n); set_inline_size(static_cast<char>(tag)); -} - -inline void Cord::InlineRep::remove_prefix(size_t n) { +} + +inline void Cord::InlineRep::remove_prefix(size_t n) { cord_internal::SmallMemmove(data_.as_chars(), data_.as_chars() + n, inline_size() - n); - reduce_size(n); -} - + reduce_size(n); +} + // Returns `rep` converted into a CordRepBtree. // Directly returns `rep` if `rep` is already a CordRepBtree. static CordRepBtree* ForceBtree(CordRep* rep) { @@ -370,14 +370,14 @@ void Cord::InlineRep::AppendTreeToTree(CordRep* tree, MethodIdentifier method) { } void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) { - if (tree == nullptr) return; + if (tree == nullptr) return; if (data_.is_tree()) { AppendTreeToTree(tree, method); - } else { + } else { AppendTreeToInlined(tree, method); - } -} - + } +} + void Cord::InlineRep::PrependTreeToInlined(CordRep* tree, MethodIdentifier method) { assert(!is_tree()); @@ -405,20 +405,20 @@ void Cord::InlineRep::PrependTreeToTree(CordRep* tree, } void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) { - assert(tree != nullptr); + assert(tree != nullptr); if (data_.is_tree()) { PrependTreeToTree(tree, method); - } else { + } else { PrependTreeToInlined(tree, method); - } -} - -// Searches for a non-full flat node at the rightmost leaf of the tree. If a -// suitable leaf is found, the function will update the length field for all -// nodes to account for the size increase. The append region address will be -// written to region and the actual size increase will be written to size. -static inline bool PrepareAppendRegion(CordRep* root, char** region, - size_t* size, size_t max_length) { + } +} + +// Searches for a non-full flat node at the rightmost leaf of the tree. If a +// suitable leaf is found, the function will update the length field for all +// nodes to account for the size increase. The append region address will be +// written to region and the actual size increase will be written to size. +static inline bool PrepareAppendRegion(CordRep* root, char** region, + size_t* size, size_t max_length) { if (root->IsBtree() && root->refcount.IsMutable()) { Span<char> span = root->btree()->GetAppendBuffer(max_length); if (!span.empty()) { @@ -428,44 +428,44 @@ static inline bool PrepareAppendRegion(CordRep* root, char** region, } } - // Search down the right-hand path for a non-full FLAT node. - CordRep* dst = root; + // Search down the right-hand path for a non-full FLAT node. + CordRep* dst = root; while (dst->IsConcat() && dst->refcount.IsMutable()) { - dst = dst->concat()->right; - } - + dst = dst->concat()->right; + } + if (!dst->IsFlat() || !dst->refcount.IsMutable()) { - *region = nullptr; - *size = 0; - return false; - } - - const size_t in_use = dst->length; + *region = nullptr; + *size = 0; + return false; + } + + const size_t in_use = dst->length; const size_t capacity = dst->flat()->Capacity(); - if (in_use == capacity) { - *region = nullptr; - *size = 0; - return false; - } - - size_t size_increase = std::min(capacity - in_use, max_length); - - // We need to update the length fields for all nodes, including the leaf node. - for (CordRep* rep = root; rep != dst; rep = rep->concat()->right) { - rep->length += size_increase; - } - dst->length += size_increase; - + if (in_use == capacity) { + *region = nullptr; + *size = 0; + return false; + } + + size_t size_increase = std::min(capacity - in_use, max_length); + + // We need to update the length fields for all nodes, including the leaf node. + for (CordRep* rep = root; rep != dst; rep = rep->concat()->right) { + rep->length += size_increase; + } + dst->length += size_increase; + *region = dst->flat()->Data() + in_use; - *size = size_increase; - return true; -} - + *size = size_increase; + return true; +} + template <bool has_length> -void Cord::InlineRep::GetAppendRegion(char** region, size_t* size, +void Cord::InlineRep::GetAppendRegion(char** region, size_t* size, size_t length) { auto constexpr method = CordzUpdateTracker::kGetAppendRegion; - + CordRep* root = tree(); size_t sz = root ? root->length : inline_size(); if (root == nullptr) { @@ -476,21 +476,21 @@ void Cord::InlineRep::GetAppendRegion(char** region, size_t* size, set_inline_size(has_length ? sz + length : kMaxInline); return; } - } - + } + size_t extra = has_length ? length : (std::max)(sz, kMinFlatLength); CordRep* rep = root ? root : MakeFlatWithExtraCapacity(extra); CordzUpdateScope scope(root ? data_.cordz_info() : nullptr, method); if (PrepareAppendRegion(rep, region, size, length)) { CommitTree(root, rep, scope, method); - return; - } - - // Allocate new node. + return; + } + + // Allocate new node. CordRepFlat* new_node = CordRepFlat::New(extra); new_node->length = std::min(new_node->Capacity(), length); *region = new_node->Data(); - *size = new_node->length; + *size = new_node->length; if (btree_enabled()) { rep = CordRepBtree::Append(ForceBtree(rep), new_node); @@ -498,8 +498,8 @@ void Cord::InlineRep::GetAppendRegion(char** region, size_t* size, rep = Concat(rep, new_node); } CommitTree(root, rep, scope, method); -} - +} + // Computes the memory side of the provided edge which must be a valid data edge // for a btrtee, i.e., a FLAT, EXTERNAL or SUBSTRING of a FLAT or EXTERNAL node. static bool RepMemoryUsageDataEdge(const CordRep* rep, @@ -508,11 +508,11 @@ static bool RepMemoryUsageDataEdge(const CordRep* rep, if (ABSL_PREDICT_FALSE(rep->IsSubstring())) { maybe_sub_size = sizeof(cord_internal::CordRepSubstring); rep = rep->substring()->child; - } + } if (rep->IsFlat()) { *total_mem_usage += maybe_sub_size + rep->flat()->AllocatedSize(); return true; - } + } if (rep->IsExternal()) { // We don't know anything about the embedded / bound data, but we can safely // assume it is 'at least' a word / pointer to data. In the future we may @@ -524,15 +524,15 @@ static bool RepMemoryUsageDataEdge(const CordRep* rep, return true; } return false; -} - -// If the rep is a leaf, this will increment the value at total_mem_usage and -// will return true. -static bool RepMemoryUsageLeaf(const CordRep* rep, size_t* total_mem_usage) { +} + +// If the rep is a leaf, this will increment the value at total_mem_usage and +// will return true. +static bool RepMemoryUsageLeaf(const CordRep* rep, size_t* total_mem_usage) { if (rep->IsFlat()) { *total_mem_usage += rep->flat()->AllocatedSize(); - return true; - } + return true; + } if (rep->IsExternal()) { // We don't know anything about the embedded / bound data, but we can safely // assume it is 'at least' a word / pointer to data. In the future we may @@ -540,12 +540,12 @@ static bool RepMemoryUsageLeaf(const CordRep* rep, size_t* total_mem_usage) { // well-known externals, such as a std::string instance. *total_mem_usage += sizeof(cord_internal::CordRepExternalImpl<intptr_t>) + rep->length; - return true; - } - return false; -} - -void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) { + return true; + } + return false; +} + +void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) { assert(&src != this); assert(is_tree() || src.is_tree()); auto constexpr method = CordzUpdateTracker::kAssignCord; @@ -553,7 +553,7 @@ void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) { EmplaceTree(CordRep::Ref(src.as_tree()), src.data_, method); return; } - + CordRep* tree = as_tree(); if (CordRep* src_tree = src.tree()) { // Leave any existing `cordz_info` in place, and let MaybeTrackCord() @@ -563,60 +563,60 @@ void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) { } else { CordzInfo::MaybeUntrackCord(data_.cordz_info()); data_ = src.data_; - } + } CordRep::Unref(tree); -} - +} + void Cord::InlineRep::UnrefTree() { - if (is_tree()) { + if (is_tree()) { CordzInfo::MaybeUntrackCord(data_.cordz_info()); CordRep::Unref(tree()); - } -} - -// -------------------------------------------------------------------- -// Constructors and destructors - + } +} + +// -------------------------------------------------------------------- +// Constructors and destructors + Cord::Cord(absl::string_view src, MethodIdentifier method) : contents_(InlineData::kDefaultInit) { - const size_t n = src.size(); - if (n <= InlineRep::kMaxInline) { + const size_t n = src.size(); + if (n <= InlineRep::kMaxInline) { contents_.set_data(src.data(), n, true); - } else { + } else { CordRep* rep = NewTree(src.data(), n, 0); contents_.EmplaceTree(rep, method); - } -} - -template <typename T, Cord::EnableIfString<T>> + } +} + +template <typename T, Cord::EnableIfString<T>> Cord::Cord(T&& src) : contents_(InlineData::kDefaultInit) { if (src.size() <= InlineRep::kMaxInline) { contents_.set_data(src.data(), src.size(), true); - } else { + } else { CordRep* rep = CordRepFromString(std::forward<T>(src)); contents_.EmplaceTree(rep, CordzUpdateTracker::kConstructorString); - } -} - -template Cord::Cord(std::string&& src); - -// The destruction code is separate so that the compiler can determine -// that it does not need to call the destructor on a moved-from Cord. -void Cord::DestroyCordSlow() { + } +} + +template Cord::Cord(std::string&& src); + +// The destruction code is separate so that the compiler can determine +// that it does not need to call the destructor on a moved-from Cord. +void Cord::DestroyCordSlow() { assert(contents_.is_tree()); CordzInfo::MaybeUntrackCord(contents_.cordz_info()); CordRep::Unref(VerifyTree(contents_.as_tree())); -} - -// -------------------------------------------------------------------- -// Mutators - -void Cord::Clear() { +} + +// -------------------------------------------------------------------- +// Mutators + +void Cord::Clear() { if (CordRep* tree = contents_.clear()) { CordRep::Unref(tree); } -} - +} + Cord& Cord::AssignLargeString(std::string&& src) { auto constexpr method = CordzUpdateTracker::kAssignString; assert(src.size() > kMaxBytesToCopy); @@ -631,21 +631,21 @@ Cord& Cord::AssignLargeString(std::string&& src) { return *this; } -Cord& Cord::operator=(absl::string_view src) { +Cord& Cord::operator=(absl::string_view src) { auto constexpr method = CordzUpdateTracker::kAssignString; - const char* data = src.data(); - size_t length = src.size(); - CordRep* tree = contents_.tree(); - if (length <= InlineRep::kMaxInline) { + const char* data = src.data(); + size_t length = src.size(); + CordRep* tree = contents_.tree(); + if (length <= InlineRep::kMaxInline) { // Embed into this->contents_, which is somewhat subtle: // - MaybeUntrackCord must be called before Unref(tree). // - MaybeUntrackCord must be called before set_data() clobbers cordz_info. // - set_data() must be called before Unref(tree) as it may reference tree. if (tree != nullptr) CordzInfo::MaybeUntrackCord(contents_.cordz_info()); - contents_.set_data(data, length, true); + contents_.set_data(data, length, true); if (tree != nullptr) CordRep::Unref(tree); - return *this; - } + return *this; + } if (tree != nullptr) { CordzUpdateScope scope(contents_.cordz_info(), method); if (tree->IsFlat() && tree->flat()->Capacity() >= length && @@ -658,28 +658,28 @@ Cord& Cord::operator=(absl::string_view src) { } contents_.SetTree(NewTree(data, length, 0), scope); CordRep::Unref(tree); - } else { + } else { contents_.EmplaceTree(NewTree(data, length, 0), method); - } - return *this; -} - -// TODO(sanjay): Move to Cord::InlineRep section of file. For now, -// we keep it here to make diffs easier. + } + return *this; +} + +// TODO(sanjay): Move to Cord::InlineRep section of file. For now, +// we keep it here to make diffs easier. void Cord::InlineRep::AppendArray(absl::string_view src, MethodIdentifier method) { if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. - - size_t appended = 0; + + size_t appended = 0; CordRep* rep = tree(); const CordRep* const root = rep; CordzUpdateScope scope(root ? cordz_info() : nullptr, method); if (root != nullptr) { - char* region; + char* region; if (PrepareAppendRegion(rep, ®ion, &appended, src.size())) { memcpy(region, src.data(), appended); - } - } else { + } + } else { // Try to fit in the inline buffer if possible. size_t inline_length = inline_size(); if (src.size() <= kMaxInline - inline_length) { @@ -697,14 +697,14 @@ void Cord::InlineRep::AppendArray(absl::string_view src, memcpy(rep->flat()->Data(), data_.as_chars(), inline_length); memcpy(rep->flat()->Data() + inline_length, src.data(), appended); rep->length = inline_length + appended; - } - + } + src.remove_prefix(appended); if (src.empty()) { CommitTree(root, rep, scope, method); - return; - } - + return; + } + if (btree_enabled()) { // TODO(b/192061034): keep legacy 10% growth rate: consider other rates. rep = ForceBtree(rep); @@ -727,22 +727,22 @@ void Cord::InlineRep::AppendArray(absl::string_view src, rep = Concat(rep, NewTree(src.data(), src.size(), length - src.size())); } CommitTree(root, rep, scope, method); -} - -inline CordRep* Cord::TakeRep() const& { +} + +inline CordRep* Cord::TakeRep() const& { return CordRep::Ref(contents_.tree()); -} - -inline CordRep* Cord::TakeRep() && { - CordRep* rep = contents_.tree(); - contents_.clear(); - return rep; -} - -template <typename C> -inline void Cord::AppendImpl(C&& src) { +} + +inline CordRep* Cord::TakeRep() && { + CordRep* rep = contents_.tree(); + contents_.clear(); + return rep; +} + +template <typename C> +inline void Cord::AppendImpl(C&& src) { auto constexpr method = CordzUpdateTracker::kAppendCord; - if (empty()) { + if (empty()) { // Since destination is empty, we can avoid allocating a node, if (src.contents_.is_tree()) { // by taking the tree directly @@ -752,75 +752,75 @@ inline void Cord::AppendImpl(C&& src) { // or copying over inline data contents_.data_ = src.contents_.data_; } - return; - } - - // For short cords, it is faster to copy data if there is room in dst. - const size_t src_size = src.contents_.size(); - if (src_size <= kMaxBytesToCopy) { - CordRep* src_tree = src.contents_.tree(); - if (src_tree == nullptr) { - // src has embedded data. + return; + } + + // For short cords, it is faster to copy data if there is room in dst. + const size_t src_size = src.contents_.size(); + if (src_size <= kMaxBytesToCopy) { + CordRep* src_tree = src.contents_.tree(); + if (src_tree == nullptr) { + // src has embedded data. contents_.AppendArray({src.contents_.data(), src_size}, method); - return; - } + return; + } if (src_tree->IsFlat()) { - // src tree just has one flat node. + // src tree just has one flat node. contents_.AppendArray({src_tree->flat()->Data(), src_size}, method); - return; - } - if (&src == this) { - // ChunkIterator below assumes that src is not modified during traversal. - Append(Cord(src)); - return; - } - // TODO(mec): Should we only do this if "dst" has space? - for (absl::string_view chunk : src.Chunks()) { - Append(chunk); - } - return; - } - + return; + } + if (&src == this) { + // ChunkIterator below assumes that src is not modified during traversal. + Append(Cord(src)); + return; + } + // TODO(mec): Should we only do this if "dst" has space? + for (absl::string_view chunk : src.Chunks()) { + Append(chunk); + } + return; + } + // Guaranteed to be a tree (kMaxBytesToCopy > kInlinedSize) CordRep* rep = std::forward<C>(src).TakeRep(); contents_.AppendTree(rep, CordzUpdateTracker::kAppendCord); -} - +} + void Cord::Append(const Cord& src) { AppendImpl(src); } - + void Cord::Append(Cord&& src) { AppendImpl(std::move(src)); } - -template <typename T, Cord::EnableIfString<T>> -void Cord::Append(T&& src) { - if (src.size() <= kMaxBytesToCopy) { - Append(absl::string_view(src)); - } else { + +template <typename T, Cord::EnableIfString<T>> +void Cord::Append(T&& src) { + if (src.size() <= kMaxBytesToCopy) { + Append(absl::string_view(src)); + } else { CordRep* rep = CordRepFromString(std::forward<T>(src)); contents_.AppendTree(rep, CordzUpdateTracker::kAppendString); - } -} - -template void Cord::Append(std::string&& src); - -void Cord::Prepend(const Cord& src) { - CordRep* src_tree = src.contents_.tree(); - if (src_tree != nullptr) { + } +} + +template void Cord::Append(std::string&& src); + +void Cord::Prepend(const Cord& src) { + CordRep* src_tree = src.contents_.tree(); + if (src_tree != nullptr) { CordRep::Ref(src_tree); contents_.PrependTree(src_tree, CordzUpdateTracker::kPrependCord); - return; - } - - // `src` cord is inlined. - absl::string_view src_contents(src.contents_.data(), src.contents_.size()); - return Prepend(src_contents); -} - + return; + } + + // `src` cord is inlined. + absl::string_view src_contents(src.contents_.data(), src.contents_.size()); + return Prepend(src_contents); +} + void Cord::PrependArray(absl::string_view src, MethodIdentifier method) { - if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. + if (src.empty()) return; // memcpy(_, nullptr, 0) is undefined. if (!contents_.is_tree()) { size_t cur_size = contents_.inline_size(); if (cur_size + src.size() <= InlineRep::kMaxInline) { @@ -832,116 +832,116 @@ void Cord::PrependArray(absl::string_view src, MethodIdentifier method) { contents_.set_inline_size(cur_size + src.size()); return; } - } + } CordRep* rep = NewTree(src.data(), src.size(), 0); contents_.PrependTree(rep, method); -} - -template <typename T, Cord::EnableIfString<T>> -inline void Cord::Prepend(T&& src) { - if (src.size() <= kMaxBytesToCopy) { - Prepend(absl::string_view(src)); - } else { +} + +template <typename T, Cord::EnableIfString<T>> +inline void Cord::Prepend(T&& src) { + if (src.size() <= kMaxBytesToCopy) { + Prepend(absl::string_view(src)); + } else { CordRep* rep = CordRepFromString(std::forward<T>(src)); contents_.PrependTree(rep, CordzUpdateTracker::kPrependString); - } -} - -template void Cord::Prepend(std::string&& src); - -static CordRep* RemovePrefixFrom(CordRep* node, size_t n) { - if (n >= node->length) return nullptr; + } +} + +template void Cord::Prepend(std::string&& src); + +static CordRep* RemovePrefixFrom(CordRep* node, size_t n) { + if (n >= node->length) return nullptr; if (n == 0) return CordRep::Ref(node); - absl::InlinedVector<CordRep*, kInlinedVectorSize> rhs_stack; - + absl::InlinedVector<CordRep*, kInlinedVectorSize> rhs_stack; + while (node->IsConcat()) { - assert(n <= node->length); - if (n < node->concat()->left->length) { - // Push right to stack, descend left. - rhs_stack.push_back(node->concat()->right); - node = node->concat()->left; - } else { - // Drop left, descend right. - n -= node->concat()->left->length; - node = node->concat()->right; - } - } - assert(n <= node->length); - - if (n == 0) { + assert(n <= node->length); + if (n < node->concat()->left->length) { + // Push right to stack, descend left. + rhs_stack.push_back(node->concat()->right); + node = node->concat()->left; + } else { + // Drop left, descend right. + n -= node->concat()->left->length; + node = node->concat()->right; + } + } + assert(n <= node->length); + + if (n == 0) { CordRep::Ref(node); - } else { - size_t start = n; - size_t len = node->length - n; + } else { + size_t start = n; + size_t len = node->length - n; if (node->IsSubstring()) { - // Consider in-place update of node, similar to in RemoveSuffixFrom(). - start += node->substring()->start; - node = node->substring()->child; - } + // Consider in-place update of node, similar to in RemoveSuffixFrom(). + start += node->substring()->start; + node = node->substring()->child; + } node = NewSubstring(CordRep::Ref(node), start, len); - } - while (!rhs_stack.empty()) { + } + while (!rhs_stack.empty()) { node = Concat(node, CordRep::Ref(rhs_stack.back())); - rhs_stack.pop_back(); - } - return node; -} - -// RemoveSuffixFrom() is very similar to RemovePrefixFrom(), with the -// exception that removing a suffix has an optimization where a node may be -// edited in place iff that node and all its ancestors have a refcount of 1. -static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) { - if (n >= node->length) return nullptr; + rhs_stack.pop_back(); + } + return node; +} + +// RemoveSuffixFrom() is very similar to RemovePrefixFrom(), with the +// exception that removing a suffix has an optimization where a node may be +// edited in place iff that node and all its ancestors have a refcount of 1. +static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) { + if (n >= node->length) return nullptr; if (n == 0) return CordRep::Ref(node); - absl::InlinedVector<CordRep*, kInlinedVectorSize> lhs_stack; + absl::InlinedVector<CordRep*, kInlinedVectorSize> lhs_stack; bool inplace_ok = node->refcount.IsMutable(); - + while (node->IsConcat()) { - assert(n <= node->length); - if (n < node->concat()->right->length) { - // Push left to stack, descend right. - lhs_stack.push_back(node->concat()->left); - node = node->concat()->right; - } else { - // Drop right, descend left. - n -= node->concat()->right->length; - node = node->concat()->left; - } + assert(n <= node->length); + if (n < node->concat()->right->length) { + // Push left to stack, descend right. + lhs_stack.push_back(node->concat()->left); + node = node->concat()->right; + } else { + // Drop right, descend left. + n -= node->concat()->right->length; + node = node->concat()->left; + } inplace_ok = inplace_ok && node->refcount.IsMutable(); - } - assert(n <= node->length); - - if (n == 0) { + } + assert(n <= node->length); + + if (n == 0) { CordRep::Ref(node); } else if (inplace_ok && !node->IsExternal()) { - // Consider making a new buffer if the current node capacity is much - // larger than the new length. + // Consider making a new buffer if the current node capacity is much + // larger than the new length. CordRep::Ref(node); - node->length -= n; - } else { - size_t start = 0; - size_t len = node->length - n; + node->length -= n; + } else { + size_t start = 0; + size_t len = node->length - n; if (node->IsSubstring()) { - start = node->substring()->start; - node = node->substring()->child; - } + start = node->substring()->start; + node = node->substring()->child; + } node = NewSubstring(CordRep::Ref(node), start, len); - } - while (!lhs_stack.empty()) { + } + while (!lhs_stack.empty()) { node = Concat(CordRep::Ref(lhs_stack.back()), node); - lhs_stack.pop_back(); - } - return node; -} - -void Cord::RemovePrefix(size_t n) { - ABSL_INTERNAL_CHECK(n <= size(), - absl::StrCat("Requested prefix size ", n, - " exceeds Cord's size ", size())); - CordRep* tree = contents_.tree(); - if (tree == nullptr) { - contents_.remove_prefix(n); - } else { + lhs_stack.pop_back(); + } + return node; +} + +void Cord::RemovePrefix(size_t n) { + ABSL_INTERNAL_CHECK(n <= size(), + absl::StrCat("Requested prefix size ", n, + " exceeds Cord's size ", size())); + CordRep* tree = contents_.tree(); + if (tree == nullptr) { + contents_.remove_prefix(n); + } else { auto constexpr method = CordzUpdateTracker::kRemovePrefix; CordzUpdateScope scope(contents_.cordz_info(), method); if (tree->IsBtree()) { @@ -954,17 +954,17 @@ void Cord::RemovePrefix(size_t n) { tree = VerifyTree(newrep); } contents_.SetTreeOrEmpty(tree, scope); - } -} - -void Cord::RemoveSuffix(size_t n) { - ABSL_INTERNAL_CHECK(n <= size(), - absl::StrCat("Requested suffix size ", n, - " exceeds Cord's size ", size())); - CordRep* tree = contents_.tree(); - if (tree == nullptr) { - contents_.reduce_size(n); - } else { + } +} + +void Cord::RemoveSuffix(size_t n) { + ABSL_INTERNAL_CHECK(n <= size(), + absl::StrCat("Requested suffix size ", n, + " exceeds Cord's size ", size())); + CordRep* tree = contents_.tree(); + if (tree == nullptr) { + contents_.reduce_size(n); + } else { auto constexpr method = CordzUpdateTracker::kRemoveSuffix; CordzUpdateScope scope(contents_.cordz_info(), method); if (tree->IsBtree()) { @@ -975,296 +975,296 @@ void Cord::RemoveSuffix(size_t n) { tree = VerifyTree(newrep); } contents_.SetTreeOrEmpty(tree, scope); - } -} - -// Work item for NewSubRange(). -struct SubRange { - SubRange(CordRep* a_node, size_t a_pos, size_t a_n) - : node(a_node), pos(a_pos), n(a_n) {} - CordRep* node; // nullptr means concat last 2 results. - size_t pos; - size_t n; -}; - -static CordRep* NewSubRange(CordRep* node, size_t pos, size_t n) { - absl::InlinedVector<CordRep*, kInlinedVectorSize> results; - absl::InlinedVector<SubRange, kInlinedVectorSize> todo; - todo.push_back(SubRange(node, pos, n)); - do { - const SubRange& sr = todo.back(); - node = sr.node; - pos = sr.pos; - n = sr.n; - todo.pop_back(); - - if (node == nullptr) { - assert(results.size() >= 2); - CordRep* right = results.back(); - results.pop_back(); - CordRep* left = results.back(); - results.pop_back(); - results.push_back(Concat(left, right)); - } else if (pos == 0 && n == node->length) { + } +} + +// Work item for NewSubRange(). +struct SubRange { + SubRange(CordRep* a_node, size_t a_pos, size_t a_n) + : node(a_node), pos(a_pos), n(a_n) {} + CordRep* node; // nullptr means concat last 2 results. + size_t pos; + size_t n; +}; + +static CordRep* NewSubRange(CordRep* node, size_t pos, size_t n) { + absl::InlinedVector<CordRep*, kInlinedVectorSize> results; + absl::InlinedVector<SubRange, kInlinedVectorSize> todo; + todo.push_back(SubRange(node, pos, n)); + do { + const SubRange& sr = todo.back(); + node = sr.node; + pos = sr.pos; + n = sr.n; + todo.pop_back(); + + if (node == nullptr) { + assert(results.size() >= 2); + CordRep* right = results.back(); + results.pop_back(); + CordRep* left = results.back(); + results.pop_back(); + results.push_back(Concat(left, right)); + } else if (pos == 0 && n == node->length) { results.push_back(CordRep::Ref(node)); } else if (!node->IsConcat()) { if (node->IsSubstring()) { - pos += node->substring()->start; - node = node->substring()->child; - } + pos += node->substring()->start; + node = node->substring()->child; + } results.push_back(NewSubstring(CordRep::Ref(node), pos, n)); - } else if (pos + n <= node->concat()->left->length) { - todo.push_back(SubRange(node->concat()->left, pos, n)); - } else if (pos >= node->concat()->left->length) { - pos -= node->concat()->left->length; - todo.push_back(SubRange(node->concat()->right, pos, n)); - } else { - size_t left_n = node->concat()->left->length - pos; - todo.push_back(SubRange(nullptr, 0, 0)); // Concat() - todo.push_back(SubRange(node->concat()->right, 0, n - left_n)); - todo.push_back(SubRange(node->concat()->left, pos, left_n)); - } - } while (!todo.empty()); - assert(results.size() == 1); - return results[0]; -} - -Cord Cord::Subcord(size_t pos, size_t new_size) const { - Cord sub_cord; - size_t length = size(); - if (pos > length) pos = length; - if (new_size > length - pos) new_size = length - pos; + } else if (pos + n <= node->concat()->left->length) { + todo.push_back(SubRange(node->concat()->left, pos, n)); + } else if (pos >= node->concat()->left->length) { + pos -= node->concat()->left->length; + todo.push_back(SubRange(node->concat()->right, pos, n)); + } else { + size_t left_n = node->concat()->left->length - pos; + todo.push_back(SubRange(nullptr, 0, 0)); // Concat() + todo.push_back(SubRange(node->concat()->right, 0, n - left_n)); + todo.push_back(SubRange(node->concat()->left, pos, left_n)); + } + } while (!todo.empty()); + assert(results.size() == 1); + return results[0]; +} + +Cord Cord::Subcord(size_t pos, size_t new_size) const { + Cord sub_cord; + size_t length = size(); + if (pos > length) pos = length; + if (new_size > length - pos) new_size = length - pos; if (new_size == 0) return sub_cord; - CordRep* tree = contents_.tree(); - if (tree == nullptr) { - // sub_cord is newly constructed, no need to re-zero-out the tail of - // contents_ memory. - sub_cord.contents_.set_data(contents_.data() + pos, new_size, false); + CordRep* tree = contents_.tree(); + if (tree == nullptr) { + // sub_cord is newly constructed, no need to re-zero-out the tail of + // contents_ memory. + sub_cord.contents_.set_data(contents_.data() + pos, new_size, false); return sub_cord; } if (new_size <= InlineRep::kMaxInline) { char* dest = sub_cord.contents_.data_.as_chars(); - Cord::ChunkIterator it = chunk_begin(); - it.AdvanceBytes(pos); - size_t remaining_size = new_size; - while (remaining_size > it->size()) { - cord_internal::SmallMemmove(dest, it->data(), it->size()); - remaining_size -= it->size(); - dest += it->size(); - ++it; - } - cord_internal::SmallMemmove(dest, it->data(), remaining_size); + Cord::ChunkIterator it = chunk_begin(); + it.AdvanceBytes(pos); + size_t remaining_size = new_size; + while (remaining_size > it->size()) { + cord_internal::SmallMemmove(dest, it->data(), it->size()); + remaining_size -= it->size(); + dest += it->size(); + ++it; + } + cord_internal::SmallMemmove(dest, it->data(), remaining_size); sub_cord.contents_.set_inline_size(new_size); return sub_cord; } if (tree->IsBtree()) { tree = tree->btree()->SubTree(pos, new_size); - } else { + } else { tree = NewSubRange(tree, pos, new_size); - } + } sub_cord.contents_.EmplaceTree(tree, contents_.data_, CordzUpdateTracker::kSubCord); - return sub_cord; -} - -// -------------------------------------------------------------------- -// Balancing - -class CordForest { - public: - explicit CordForest(size_t length) - : root_length_(length), trees_(kMinLengthSize, nullptr) {} - - void Build(CordRep* cord_root) { - std::vector<CordRep*> pending = {cord_root}; - - while (!pending.empty()) { - CordRep* node = pending.back(); - pending.pop_back(); - CheckNode(node); + return sub_cord; +} + +// -------------------------------------------------------------------- +// Balancing + +class CordForest { + public: + explicit CordForest(size_t length) + : root_length_(length), trees_(kMinLengthSize, nullptr) {} + + void Build(CordRep* cord_root) { + std::vector<CordRep*> pending = {cord_root}; + + while (!pending.empty()) { + CordRep* node = pending.back(); + pending.pop_back(); + CheckNode(node); if (ABSL_PREDICT_FALSE(!node->IsConcat())) { - AddNode(node); - continue; - } - - CordRepConcat* concat_node = node->concat(); - if (concat_node->depth() >= kMinLengthSize || - concat_node->length < min_length[concat_node->depth()]) { - pending.push_back(concat_node->right); - pending.push_back(concat_node->left); - - if (concat_node->refcount.IsOne()) { - concat_node->left = concat_freelist_; - concat_freelist_ = concat_node; - } else { + AddNode(node); + continue; + } + + CordRepConcat* concat_node = node->concat(); + if (concat_node->depth() >= kMinLengthSize || + concat_node->length < min_length[concat_node->depth()]) { + pending.push_back(concat_node->right); + pending.push_back(concat_node->left); + + if (concat_node->refcount.IsOne()) { + concat_node->left = concat_freelist_; + concat_freelist_ = concat_node; + } else { CordRep::Ref(concat_node->right); CordRep::Ref(concat_node->left); CordRep::Unref(concat_node); - } - } else { - AddNode(node); - } - } - } - - CordRep* ConcatNodes() { - CordRep* sum = nullptr; - for (auto* node : trees_) { - if (node == nullptr) continue; - - sum = PrependNode(node, sum); - root_length_ -= node->length; - if (root_length_ == 0) break; - } - ABSL_INTERNAL_CHECK(sum != nullptr, "Failed to locate sum node"); - return VerifyTree(sum); - } - - private: - CordRep* AppendNode(CordRep* node, CordRep* sum) { - return (sum == nullptr) ? node : MakeConcat(sum, node); - } - - CordRep* PrependNode(CordRep* node, CordRep* sum) { - return (sum == nullptr) ? node : MakeConcat(node, sum); - } - - void AddNode(CordRep* node) { - CordRep* sum = nullptr; - - // Collect together everything with which we will merge with node - int i = 0; - for (; node->length > min_length[i + 1]; ++i) { - auto& tree_at_i = trees_[i]; - - if (tree_at_i == nullptr) continue; - sum = PrependNode(tree_at_i, sum); - tree_at_i = nullptr; - } - - sum = AppendNode(node, sum); - - // Insert sum into appropriate place in the forest - for (; sum->length >= min_length[i]; ++i) { - auto& tree_at_i = trees_[i]; - if (tree_at_i == nullptr) continue; - - sum = MakeConcat(tree_at_i, sum); - tree_at_i = nullptr; - } - - // min_length[0] == 1, which means sum->length >= min_length[0] - assert(i > 0); - trees_[i - 1] = sum; - } - - // Make concat node trying to resue existing CordRepConcat nodes we - // already collected in the concat_freelist_. - CordRep* MakeConcat(CordRep* left, CordRep* right) { - if (concat_freelist_ == nullptr) return RawConcat(left, right); - - CordRepConcat* rep = concat_freelist_; - if (concat_freelist_->left == nullptr) { - concat_freelist_ = nullptr; - } else { - concat_freelist_ = concat_freelist_->left->concat(); - } - SetConcatChildren(rep, left, right); - - return rep; - } - - static void CheckNode(CordRep* node) { - ABSL_INTERNAL_CHECK(node->length != 0u, ""); + } + } else { + AddNode(node); + } + } + } + + CordRep* ConcatNodes() { + CordRep* sum = nullptr; + for (auto* node : trees_) { + if (node == nullptr) continue; + + sum = PrependNode(node, sum); + root_length_ -= node->length; + if (root_length_ == 0) break; + } + ABSL_INTERNAL_CHECK(sum != nullptr, "Failed to locate sum node"); + return VerifyTree(sum); + } + + private: + CordRep* AppendNode(CordRep* node, CordRep* sum) { + return (sum == nullptr) ? node : MakeConcat(sum, node); + } + + CordRep* PrependNode(CordRep* node, CordRep* sum) { + return (sum == nullptr) ? node : MakeConcat(node, sum); + } + + void AddNode(CordRep* node) { + CordRep* sum = nullptr; + + // Collect together everything with which we will merge with node + int i = 0; + for (; node->length > min_length[i + 1]; ++i) { + auto& tree_at_i = trees_[i]; + + if (tree_at_i == nullptr) continue; + sum = PrependNode(tree_at_i, sum); + tree_at_i = nullptr; + } + + sum = AppendNode(node, sum); + + // Insert sum into appropriate place in the forest + for (; sum->length >= min_length[i]; ++i) { + auto& tree_at_i = trees_[i]; + if (tree_at_i == nullptr) continue; + + sum = MakeConcat(tree_at_i, sum); + tree_at_i = nullptr; + } + + // min_length[0] == 1, which means sum->length >= min_length[0] + assert(i > 0); + trees_[i - 1] = sum; + } + + // Make concat node trying to resue existing CordRepConcat nodes we + // already collected in the concat_freelist_. + CordRep* MakeConcat(CordRep* left, CordRep* right) { + if (concat_freelist_ == nullptr) return RawConcat(left, right); + + CordRepConcat* rep = concat_freelist_; + if (concat_freelist_->left == nullptr) { + concat_freelist_ = nullptr; + } else { + concat_freelist_ = concat_freelist_->left->concat(); + } + SetConcatChildren(rep, left, right); + + return rep; + } + + static void CheckNode(CordRep* node) { + ABSL_INTERNAL_CHECK(node->length != 0u, ""); if (node->IsConcat()) { - ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, ""); - ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, ""); - ABSL_INTERNAL_CHECK(node->length == (node->concat()->left->length + - node->concat()->right->length), - ""); - } - } - - size_t root_length_; - - // use an inlined vector instead of a flat array to get bounds checking - absl::InlinedVector<CordRep*, kInlinedVectorSize> trees_; - - // List of concat nodes we can re-use for Cord balancing. - CordRepConcat* concat_freelist_ = nullptr; -}; - -static CordRep* Rebalance(CordRep* node) { - VerifyTree(node); + ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, ""); + ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, ""); + ABSL_INTERNAL_CHECK(node->length == (node->concat()->left->length + + node->concat()->right->length), + ""); + } + } + + size_t root_length_; + + // use an inlined vector instead of a flat array to get bounds checking + absl::InlinedVector<CordRep*, kInlinedVectorSize> trees_; + + // List of concat nodes we can re-use for Cord balancing. + CordRepConcat* concat_freelist_ = nullptr; +}; + +static CordRep* Rebalance(CordRep* node) { + VerifyTree(node); assert(node->IsConcat()); - - if (node->length == 0) { - return nullptr; - } - - CordForest forest(node->length); - forest.Build(node); - return forest.ConcatNodes(); -} - -// -------------------------------------------------------------------- -// Comparators - -namespace { - -int ClampResult(int memcmp_res) { - return static_cast<int>(memcmp_res > 0) - static_cast<int>(memcmp_res < 0); -} - -int CompareChunks(absl::string_view* lhs, absl::string_view* rhs, - size_t* size_to_compare) { - size_t compared_size = std::min(lhs->size(), rhs->size()); - assert(*size_to_compare >= compared_size); - *size_to_compare -= compared_size; - - int memcmp_res = ::memcmp(lhs->data(), rhs->data(), compared_size); - if (memcmp_res != 0) return memcmp_res; - - lhs->remove_prefix(compared_size); - rhs->remove_prefix(compared_size); - - return 0; -} - -// This overload set computes comparison results from memcmp result. This -// interface is used inside GenericCompare below. Differet implementations -// are specialized for int and bool. For int we clamp result to {-1, 0, 1} -// set. For bool we just interested in "value == 0". -template <typename ResultType> -ResultType ComputeCompareResult(int memcmp_res) { - return ClampResult(memcmp_res); -} -template <> -bool ComputeCompareResult<bool>(int memcmp_res) { - return memcmp_res == 0; -} - -} // namespace - + + if (node->length == 0) { + return nullptr; + } + + CordForest forest(node->length); + forest.Build(node); + return forest.ConcatNodes(); +} + +// -------------------------------------------------------------------- +// Comparators + +namespace { + +int ClampResult(int memcmp_res) { + return static_cast<int>(memcmp_res > 0) - static_cast<int>(memcmp_res < 0); +} + +int CompareChunks(absl::string_view* lhs, absl::string_view* rhs, + size_t* size_to_compare) { + size_t compared_size = std::min(lhs->size(), rhs->size()); + assert(*size_to_compare >= compared_size); + *size_to_compare -= compared_size; + + int memcmp_res = ::memcmp(lhs->data(), rhs->data(), compared_size); + if (memcmp_res != 0) return memcmp_res; + + lhs->remove_prefix(compared_size); + rhs->remove_prefix(compared_size); + + return 0; +} + +// This overload set computes comparison results from memcmp result. This +// interface is used inside GenericCompare below. Differet implementations +// are specialized for int and bool. For int we clamp result to {-1, 0, 1} +// set. For bool we just interested in "value == 0". +template <typename ResultType> +ResultType ComputeCompareResult(int memcmp_res) { + return ClampResult(memcmp_res); +} +template <> +bool ComputeCompareResult<bool>(int memcmp_res) { + return memcmp_res == 0; +} + +} // namespace + // Helper routine. Locates the first flat or external chunk of the Cord without // initializing the iterator, and returns a string_view referencing the data. -inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const { +inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const { if (!is_tree()) { return absl::string_view(data_.as_chars(), data_.inline_size()); - } - - CordRep* node = tree(); + } + + CordRep* node = tree(); if (node->IsFlat()) { return absl::string_view(node->flat()->Data(), node->length); - } - + } + if (node->IsExternal()) { - return absl::string_view(node->external()->base, node->length); - } - + return absl::string_view(node->external()->base, node->length); + } + if (node->IsBtree()) { CordRepBtree* tree = node->btree(); int height = tree->height(); @@ -1274,264 +1274,264 @@ inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const { return tree->Data(tree->begin()); } - // Walk down the left branches until we hit a non-CONCAT node. + // Walk down the left branches until we hit a non-CONCAT node. while (node->IsConcat()) { - node = node->concat()->left; - } - - // Get the child node if we encounter a SUBSTRING. - size_t offset = 0; - size_t length = node->length; - assert(length != 0); - + node = node->concat()->left; + } + + // Get the child node if we encounter a SUBSTRING. + size_t offset = 0; + size_t length = node->length; + assert(length != 0); + if (node->IsSubstring()) { - offset = node->substring()->start; - node = node->substring()->child; - } - + offset = node->substring()->start; + node = node->substring()->child; + } + if (node->IsFlat()) { return absl::string_view(node->flat()->Data() + offset, length); - } - + } + assert(node->IsExternal() && "Expect FLAT or EXTERNAL node here"); - - return absl::string_view(node->external()->base + offset, length); -} - -inline int Cord::CompareSlowPath(absl::string_view rhs, size_t compared_size, - size_t size_to_compare) const { - auto advance = [](Cord::ChunkIterator* it, absl::string_view* chunk) { - if (!chunk->empty()) return true; - ++*it; - if (it->bytes_remaining_ == 0) return false; - *chunk = **it; - return true; - }; - - Cord::ChunkIterator lhs_it = chunk_begin(); - - // compared_size is inside first chunk. - absl::string_view lhs_chunk = - (lhs_it.bytes_remaining_ != 0) ? *lhs_it : absl::string_view(); - assert(compared_size <= lhs_chunk.size()); - assert(compared_size <= rhs.size()); - lhs_chunk.remove_prefix(compared_size); - rhs.remove_prefix(compared_size); - size_to_compare -= compared_size; // skip already compared size. - - while (advance(&lhs_it, &lhs_chunk) && !rhs.empty()) { - int comparison_result = CompareChunks(&lhs_chunk, &rhs, &size_to_compare); - if (comparison_result != 0) return comparison_result; - if (size_to_compare == 0) return 0; - } - - return static_cast<int>(rhs.empty()) - static_cast<int>(lhs_chunk.empty()); -} - -inline int Cord::CompareSlowPath(const Cord& rhs, size_t compared_size, - size_t size_to_compare) const { - auto advance = [](Cord::ChunkIterator* it, absl::string_view* chunk) { - if (!chunk->empty()) return true; - ++*it; - if (it->bytes_remaining_ == 0) return false; - *chunk = **it; - return true; - }; - - Cord::ChunkIterator lhs_it = chunk_begin(); - Cord::ChunkIterator rhs_it = rhs.chunk_begin(); - - // compared_size is inside both first chunks. - absl::string_view lhs_chunk = - (lhs_it.bytes_remaining_ != 0) ? *lhs_it : absl::string_view(); - absl::string_view rhs_chunk = - (rhs_it.bytes_remaining_ != 0) ? *rhs_it : absl::string_view(); - assert(compared_size <= lhs_chunk.size()); - assert(compared_size <= rhs_chunk.size()); - lhs_chunk.remove_prefix(compared_size); - rhs_chunk.remove_prefix(compared_size); - size_to_compare -= compared_size; // skip already compared size. - - while (advance(&lhs_it, &lhs_chunk) && advance(&rhs_it, &rhs_chunk)) { - int memcmp_res = CompareChunks(&lhs_chunk, &rhs_chunk, &size_to_compare); - if (memcmp_res != 0) return memcmp_res; - if (size_to_compare == 0) return 0; - } - - return static_cast<int>(rhs_chunk.empty()) - - static_cast<int>(lhs_chunk.empty()); -} - -inline absl::string_view Cord::GetFirstChunk(const Cord& c) { - return c.contents_.FindFlatStartPiece(); -} -inline absl::string_view Cord::GetFirstChunk(absl::string_view sv) { - return sv; -} - -// Compares up to 'size_to_compare' bytes of 'lhs' with 'rhs'. It is assumed -// that 'size_to_compare' is greater that size of smallest of first chunks. -template <typename ResultType, typename RHS> -ResultType GenericCompare(const Cord& lhs, const RHS& rhs, - size_t size_to_compare) { - absl::string_view lhs_chunk = Cord::GetFirstChunk(lhs); - absl::string_view rhs_chunk = Cord::GetFirstChunk(rhs); - - size_t compared_size = std::min(lhs_chunk.size(), rhs_chunk.size()); - assert(size_to_compare >= compared_size); - int memcmp_res = ::memcmp(lhs_chunk.data(), rhs_chunk.data(), compared_size); - if (compared_size == size_to_compare || memcmp_res != 0) { - return ComputeCompareResult<ResultType>(memcmp_res); - } - - return ComputeCompareResult<ResultType>( - lhs.CompareSlowPath(rhs, compared_size, size_to_compare)); -} - -bool Cord::EqualsImpl(absl::string_view rhs, size_t size_to_compare) const { - return GenericCompare<bool>(*this, rhs, size_to_compare); -} - -bool Cord::EqualsImpl(const Cord& rhs, size_t size_to_compare) const { - return GenericCompare<bool>(*this, rhs, size_to_compare); -} - -template <typename RHS> -inline int SharedCompareImpl(const Cord& lhs, const RHS& rhs) { - size_t lhs_size = lhs.size(); - size_t rhs_size = rhs.size(); - if (lhs_size == rhs_size) { - return GenericCompare<int>(lhs, rhs, lhs_size); - } - if (lhs_size < rhs_size) { - auto data_comp_res = GenericCompare<int>(lhs, rhs, lhs_size); - return data_comp_res == 0 ? -1 : data_comp_res; - } - - auto data_comp_res = GenericCompare<int>(lhs, rhs, rhs_size); - return data_comp_res == 0 ? +1 : data_comp_res; -} - -int Cord::Compare(absl::string_view rhs) const { - return SharedCompareImpl(*this, rhs); -} - -int Cord::CompareImpl(const Cord& rhs) const { - return SharedCompareImpl(*this, rhs); -} - -bool Cord::EndsWith(absl::string_view rhs) const { - size_t my_size = size(); - size_t rhs_size = rhs.size(); - - if (my_size < rhs_size) return false; - - Cord tmp(*this); - tmp.RemovePrefix(my_size - rhs_size); - return tmp.EqualsImpl(rhs, rhs_size); -} - -bool Cord::EndsWith(const Cord& rhs) const { - size_t my_size = size(); - size_t rhs_size = rhs.size(); - - if (my_size < rhs_size) return false; - - Cord tmp(*this); - tmp.RemovePrefix(my_size - rhs_size); - return tmp.EqualsImpl(rhs, rhs_size); -} - -// -------------------------------------------------------------------- -// Misc. - -Cord::operator std::string() const { - std::string s; - absl::CopyCordToString(*this, &s); - return s; -} - -void CopyCordToString(const Cord& src, std::string* dst) { - if (!src.contents_.is_tree()) { - src.contents_.CopyTo(dst); - } else { - absl::strings_internal::STLStringResizeUninitialized(dst, src.size()); - src.CopyToArraySlowPath(&(*dst)[0]); - } -} - -void Cord::CopyToArraySlowPath(char* dst) const { - assert(contents_.is_tree()); - absl::string_view fragment; - if (GetFlatAux(contents_.tree(), &fragment)) { - memcpy(dst, fragment.data(), fragment.size()); - return; - } - for (absl::string_view chunk : Chunks()) { - memcpy(dst, chunk.data(), chunk.size()); - dst += chunk.size(); - } -} - + + return absl::string_view(node->external()->base + offset, length); +} + +inline int Cord::CompareSlowPath(absl::string_view rhs, size_t compared_size, + size_t size_to_compare) const { + auto advance = [](Cord::ChunkIterator* it, absl::string_view* chunk) { + if (!chunk->empty()) return true; + ++*it; + if (it->bytes_remaining_ == 0) return false; + *chunk = **it; + return true; + }; + + Cord::ChunkIterator lhs_it = chunk_begin(); + + // compared_size is inside first chunk. + absl::string_view lhs_chunk = + (lhs_it.bytes_remaining_ != 0) ? *lhs_it : absl::string_view(); + assert(compared_size <= lhs_chunk.size()); + assert(compared_size <= rhs.size()); + lhs_chunk.remove_prefix(compared_size); + rhs.remove_prefix(compared_size); + size_to_compare -= compared_size; // skip already compared size. + + while (advance(&lhs_it, &lhs_chunk) && !rhs.empty()) { + int comparison_result = CompareChunks(&lhs_chunk, &rhs, &size_to_compare); + if (comparison_result != 0) return comparison_result; + if (size_to_compare == 0) return 0; + } + + return static_cast<int>(rhs.empty()) - static_cast<int>(lhs_chunk.empty()); +} + +inline int Cord::CompareSlowPath(const Cord& rhs, size_t compared_size, + size_t size_to_compare) const { + auto advance = [](Cord::ChunkIterator* it, absl::string_view* chunk) { + if (!chunk->empty()) return true; + ++*it; + if (it->bytes_remaining_ == 0) return false; + *chunk = **it; + return true; + }; + + Cord::ChunkIterator lhs_it = chunk_begin(); + Cord::ChunkIterator rhs_it = rhs.chunk_begin(); + + // compared_size is inside both first chunks. + absl::string_view lhs_chunk = + (lhs_it.bytes_remaining_ != 0) ? *lhs_it : absl::string_view(); + absl::string_view rhs_chunk = + (rhs_it.bytes_remaining_ != 0) ? *rhs_it : absl::string_view(); + assert(compared_size <= lhs_chunk.size()); + assert(compared_size <= rhs_chunk.size()); + lhs_chunk.remove_prefix(compared_size); + rhs_chunk.remove_prefix(compared_size); + size_to_compare -= compared_size; // skip already compared size. + + while (advance(&lhs_it, &lhs_chunk) && advance(&rhs_it, &rhs_chunk)) { + int memcmp_res = CompareChunks(&lhs_chunk, &rhs_chunk, &size_to_compare); + if (memcmp_res != 0) return memcmp_res; + if (size_to_compare == 0) return 0; + } + + return static_cast<int>(rhs_chunk.empty()) - + static_cast<int>(lhs_chunk.empty()); +} + +inline absl::string_view Cord::GetFirstChunk(const Cord& c) { + return c.contents_.FindFlatStartPiece(); +} +inline absl::string_view Cord::GetFirstChunk(absl::string_view sv) { + return sv; +} + +// Compares up to 'size_to_compare' bytes of 'lhs' with 'rhs'. It is assumed +// that 'size_to_compare' is greater that size of smallest of first chunks. +template <typename ResultType, typename RHS> +ResultType GenericCompare(const Cord& lhs, const RHS& rhs, + size_t size_to_compare) { + absl::string_view lhs_chunk = Cord::GetFirstChunk(lhs); + absl::string_view rhs_chunk = Cord::GetFirstChunk(rhs); + + size_t compared_size = std::min(lhs_chunk.size(), rhs_chunk.size()); + assert(size_to_compare >= compared_size); + int memcmp_res = ::memcmp(lhs_chunk.data(), rhs_chunk.data(), compared_size); + if (compared_size == size_to_compare || memcmp_res != 0) { + return ComputeCompareResult<ResultType>(memcmp_res); + } + + return ComputeCompareResult<ResultType>( + lhs.CompareSlowPath(rhs, compared_size, size_to_compare)); +} + +bool Cord::EqualsImpl(absl::string_view rhs, size_t size_to_compare) const { + return GenericCompare<bool>(*this, rhs, size_to_compare); +} + +bool Cord::EqualsImpl(const Cord& rhs, size_t size_to_compare) const { + return GenericCompare<bool>(*this, rhs, size_to_compare); +} + +template <typename RHS> +inline int SharedCompareImpl(const Cord& lhs, const RHS& rhs) { + size_t lhs_size = lhs.size(); + size_t rhs_size = rhs.size(); + if (lhs_size == rhs_size) { + return GenericCompare<int>(lhs, rhs, lhs_size); + } + if (lhs_size < rhs_size) { + auto data_comp_res = GenericCompare<int>(lhs, rhs, lhs_size); + return data_comp_res == 0 ? -1 : data_comp_res; + } + + auto data_comp_res = GenericCompare<int>(lhs, rhs, rhs_size); + return data_comp_res == 0 ? +1 : data_comp_res; +} + +int Cord::Compare(absl::string_view rhs) const { + return SharedCompareImpl(*this, rhs); +} + +int Cord::CompareImpl(const Cord& rhs) const { + return SharedCompareImpl(*this, rhs); +} + +bool Cord::EndsWith(absl::string_view rhs) const { + size_t my_size = size(); + size_t rhs_size = rhs.size(); + + if (my_size < rhs_size) return false; + + Cord tmp(*this); + tmp.RemovePrefix(my_size - rhs_size); + return tmp.EqualsImpl(rhs, rhs_size); +} + +bool Cord::EndsWith(const Cord& rhs) const { + size_t my_size = size(); + size_t rhs_size = rhs.size(); + + if (my_size < rhs_size) return false; + + Cord tmp(*this); + tmp.RemovePrefix(my_size - rhs_size); + return tmp.EqualsImpl(rhs, rhs_size); +} + +// -------------------------------------------------------------------- +// Misc. + +Cord::operator std::string() const { + std::string s; + absl::CopyCordToString(*this, &s); + return s; +} + +void CopyCordToString(const Cord& src, std::string* dst) { + if (!src.contents_.is_tree()) { + src.contents_.CopyTo(dst); + } else { + absl::strings_internal::STLStringResizeUninitialized(dst, src.size()); + src.CopyToArraySlowPath(&(*dst)[0]); + } +} + +void Cord::CopyToArraySlowPath(char* dst) const { + assert(contents_.is_tree()); + absl::string_view fragment; + if (GetFlatAux(contents_.tree(), &fragment)) { + memcpy(dst, fragment.data(), fragment.size()); + return; + } + for (absl::string_view chunk : Chunks()) { + memcpy(dst, chunk.data(), chunk.size()); + dst += chunk.size(); + } +} + Cord::ChunkIterator& Cord::ChunkIterator::AdvanceStack() { auto& stack_of_right_children = stack_of_right_children_; if (stack_of_right_children.empty()) { - assert(!current_chunk_.empty()); // Called on invalid iterator. - // We have reached the end of the Cord. - return *this; - } - - // Process the next node on the stack. + assert(!current_chunk_.empty()); // Called on invalid iterator. + // We have reached the end of the Cord. + return *this; + } + + // Process the next node on the stack. CordRep* node = stack_of_right_children.back(); stack_of_right_children.pop_back(); - - // Walk down the left branches until we hit a non-CONCAT node. Save the - // right children to the stack for subsequent traversal. + + // Walk down the left branches until we hit a non-CONCAT node. Save the + // right children to the stack for subsequent traversal. while (node->IsConcat()) { stack_of_right_children.push_back(node->concat()->right); - node = node->concat()->left; - } - - // Get the child node if we encounter a SUBSTRING. - size_t offset = 0; - size_t length = node->length; + node = node->concat()->left; + } + + // Get the child node if we encounter a SUBSTRING. + size_t offset = 0; + size_t length = node->length; if (node->IsSubstring()) { - offset = node->substring()->start; - node = node->substring()->child; - } - + offset = node->substring()->start; + node = node->substring()->child; + } + assert(node->IsExternal() || node->IsFlat()); - assert(length != 0); - const char* data = + assert(length != 0); + const char* data = node->IsExternal() ? node->external()->base : node->flat()->Data(); - current_chunk_ = absl::string_view(data + offset, length); - current_leaf_ = node; - return *this; -} - -Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { - ABSL_HARDENING_ASSERT(bytes_remaining_ >= n && - "Attempted to iterate past `end()`"); - Cord subcord; + current_chunk_ = absl::string_view(data + offset, length); + current_leaf_ = node; + return *this; +} + +Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { + ABSL_HARDENING_ASSERT(bytes_remaining_ >= n && + "Attempted to iterate past `end()`"); + Cord subcord; auto constexpr method = CordzUpdateTracker::kCordReader; - - if (n <= InlineRep::kMaxInline) { - // Range to read fits in inline data. Flatten it. - char* data = subcord.contents_.set_data(n); - while (n > current_chunk_.size()) { - memcpy(data, current_chunk_.data(), current_chunk_.size()); - data += current_chunk_.size(); - n -= current_chunk_.size(); - ++*this; - } - memcpy(data, current_chunk_.data(), n); - if (n < current_chunk_.size()) { - RemoveChunkPrefix(n); - } else if (n > 0) { - ++*this; - } - return subcord; - } + + if (n <= InlineRep::kMaxInline) { + // Range to read fits in inline data. Flatten it. + char* data = subcord.contents_.set_data(n); + while (n > current_chunk_.size()) { + memcpy(data, current_chunk_.data(), current_chunk_.size()); + data += current_chunk_.size(); + n -= current_chunk_.size(); + ++*this; + } + memcpy(data, current_chunk_.data(), n); + if (n < current_chunk_.size()) { + RemoveChunkPrefix(n); + } else if (n > 0) { + ++*this; + } + return subcord; + } if (btree_reader_) { size_t chunk_size = current_chunk_.size(); @@ -1552,261 +1552,261 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { } auto& stack_of_right_children = stack_of_right_children_; - if (n < current_chunk_.size()) { - // Range to read is a proper subrange of the current chunk. - assert(current_leaf_ != nullptr); + if (n < current_chunk_.size()) { + // Range to read is a proper subrange of the current chunk. + assert(current_leaf_ != nullptr); CordRep* subnode = CordRep::Ref(current_leaf_); const char* data = subnode->IsExternal() ? subnode->external()->base : subnode->flat()->Data(); - subnode = NewSubstring(subnode, current_chunk_.data() - data, n); + subnode = NewSubstring(subnode, current_chunk_.data() - data, n); subcord.contents_.EmplaceTree(VerifyTree(subnode), method); - RemoveChunkPrefix(n); - return subcord; - } - - // Range to read begins with a proper subrange of the current chunk. - assert(!current_chunk_.empty()); - assert(current_leaf_ != nullptr); + RemoveChunkPrefix(n); + return subcord; + } + + // Range to read begins with a proper subrange of the current chunk. + assert(!current_chunk_.empty()); + assert(current_leaf_ != nullptr); CordRep* subnode = CordRep::Ref(current_leaf_); - if (current_chunk_.size() < subnode->length) { + if (current_chunk_.size() < subnode->length) { const char* data = subnode->IsExternal() ? subnode->external()->base : subnode->flat()->Data(); - subnode = NewSubstring(subnode, current_chunk_.data() - data, - current_chunk_.size()); - } - n -= current_chunk_.size(); - bytes_remaining_ -= current_chunk_.size(); - - // Process the next node(s) on the stack, reading whole subtrees depending on - // their length and how many bytes we are advancing. - CordRep* node = nullptr; + subnode = NewSubstring(subnode, current_chunk_.data() - data, + current_chunk_.size()); + } + n -= current_chunk_.size(); + bytes_remaining_ -= current_chunk_.size(); + + // Process the next node(s) on the stack, reading whole subtrees depending on + // their length and how many bytes we are advancing. + CordRep* node = nullptr; while (!stack_of_right_children.empty()) { node = stack_of_right_children.back(); stack_of_right_children.pop_back(); - if (node->length > n) break; - // TODO(qrczak): This might unnecessarily recreate existing concat nodes. - // Avoiding that would need pretty complicated logic (instead of + if (node->length > n) break; + // TODO(qrczak): This might unnecessarily recreate existing concat nodes. + // Avoiding that would need pretty complicated logic (instead of // current_leaf, keep current_subtree_ which points to the highest node - // such that the current leaf can be found on the path of left children - // starting from current_subtree_; delay creating subnode while node is - // below current_subtree_; find the proper node along the path of left - // children starting from current_subtree_ if this loop exits while staying - // below current_subtree_; etc.; alternatively, push parents instead of - // right children on the stack). + // such that the current leaf can be found on the path of left children + // starting from current_subtree_; delay creating subnode while node is + // below current_subtree_; find the proper node along the path of left + // children starting from current_subtree_ if this loop exits while staying + // below current_subtree_; etc.; alternatively, push parents instead of + // right children on the stack). subnode = Concat(subnode, CordRep::Ref(node)); - n -= node->length; - bytes_remaining_ -= node->length; - node = nullptr; - } - - if (node == nullptr) { - // We have reached the end of the Cord. - assert(bytes_remaining_ == 0); + n -= node->length; + bytes_remaining_ -= node->length; + node = nullptr; + } + + if (node == nullptr) { + // We have reached the end of the Cord. + assert(bytes_remaining_ == 0); subcord.contents_.EmplaceTree(VerifyTree(subnode), method); - return subcord; - } - - // Walk down the appropriate branches until we hit a non-CONCAT node. Save the - // right children to the stack for subsequent traversal. + return subcord; + } + + // Walk down the appropriate branches until we hit a non-CONCAT node. Save the + // right children to the stack for subsequent traversal. while (node->IsConcat()) { - if (node->concat()->left->length > n) { - // Push right, descend left. + if (node->concat()->left->length > n) { + // Push right, descend left. stack_of_right_children.push_back(node->concat()->right); - node = node->concat()->left; - } else { - // Read left, descend right. + node = node->concat()->left; + } else { + // Read left, descend right. subnode = Concat(subnode, CordRep::Ref(node->concat()->left)); - n -= node->concat()->left->length; - bytes_remaining_ -= node->concat()->left->length; - node = node->concat()->right; - } - } - - // Get the child node if we encounter a SUBSTRING. - size_t offset = 0; - size_t length = node->length; + n -= node->concat()->left->length; + bytes_remaining_ -= node->concat()->left->length; + node = node->concat()->right; + } + } + + // Get the child node if we encounter a SUBSTRING. + size_t offset = 0; + size_t length = node->length; if (node->IsSubstring()) { - offset = node->substring()->start; - node = node->substring()->child; - } - - // Range to read ends with a proper (possibly empty) subrange of the current - // chunk. + offset = node->substring()->start; + node = node->substring()->child; + } + + // Range to read ends with a proper (possibly empty) subrange of the current + // chunk. assert(node->IsExternal() || node->IsFlat()); - assert(length > n); + assert(length > n); if (n > 0) { subnode = Concat(subnode, NewSubstring(CordRep::Ref(node), offset, n)); } - const char* data = + const char* data = node->IsExternal() ? node->external()->base : node->flat()->Data(); - current_chunk_ = absl::string_view(data + offset + n, length - n); - current_leaf_ = node; - bytes_remaining_ -= n; + current_chunk_ = absl::string_view(data + offset + n, length - n); + current_leaf_ = node; + bytes_remaining_ -= n; subcord.contents_.EmplaceTree(VerifyTree(subnode), method); - return subcord; -} - -void Cord::ChunkIterator::AdvanceBytesSlowPath(size_t n) { - assert(bytes_remaining_ >= n && "Attempted to iterate past `end()`"); - assert(n >= current_chunk_.size()); // This should only be called when - // iterating to a new node. - - n -= current_chunk_.size(); - bytes_remaining_ -= current_chunk_.size(); - + return subcord; +} + +void Cord::ChunkIterator::AdvanceBytesSlowPath(size_t n) { + assert(bytes_remaining_ >= n && "Attempted to iterate past `end()`"); + assert(n >= current_chunk_.size()); // This should only be called when + // iterating to a new node. + + n -= current_chunk_.size(); + bytes_remaining_ -= current_chunk_.size(); + if (stack_of_right_children_.empty()) { // We have reached the end of the Cord. assert(bytes_remaining_ == 0); return; } - // Process the next node(s) on the stack, skipping whole subtrees depending on - // their length and how many bytes we are advancing. - CordRep* node = nullptr; + // Process the next node(s) on the stack, skipping whole subtrees depending on + // their length and how many bytes we are advancing. + CordRep* node = nullptr; auto& stack_of_right_children = stack_of_right_children_; while (!stack_of_right_children.empty()) { node = stack_of_right_children.back(); stack_of_right_children.pop_back(); - if (node->length > n) break; - n -= node->length; - bytes_remaining_ -= node->length; - node = nullptr; - } - - if (node == nullptr) { - // We have reached the end of the Cord. - assert(bytes_remaining_ == 0); - return; - } - - // Walk down the appropriate branches until we hit a non-CONCAT node. Save the - // right children to the stack for subsequent traversal. + if (node->length > n) break; + n -= node->length; + bytes_remaining_ -= node->length; + node = nullptr; + } + + if (node == nullptr) { + // We have reached the end of the Cord. + assert(bytes_remaining_ == 0); + return; + } + + // Walk down the appropriate branches until we hit a non-CONCAT node. Save the + // right children to the stack for subsequent traversal. while (node->IsConcat()) { - if (node->concat()->left->length > n) { - // Push right, descend left. + if (node->concat()->left->length > n) { + // Push right, descend left. stack_of_right_children.push_back(node->concat()->right); - node = node->concat()->left; - } else { - // Skip left, descend right. - n -= node->concat()->left->length; - bytes_remaining_ -= node->concat()->left->length; - node = node->concat()->right; - } - } - - // Get the child node if we encounter a SUBSTRING. - size_t offset = 0; - size_t length = node->length; + node = node->concat()->left; + } else { + // Skip left, descend right. + n -= node->concat()->left->length; + bytes_remaining_ -= node->concat()->left->length; + node = node->concat()->right; + } + } + + // Get the child node if we encounter a SUBSTRING. + size_t offset = 0; + size_t length = node->length; if (node->IsSubstring()) { - offset = node->substring()->start; - node = node->substring()->child; - } - + offset = node->substring()->start; + node = node->substring()->child; + } + assert(node->IsExternal() || node->IsFlat()); - assert(length > n); - const char* data = + assert(length > n); + const char* data = node->IsExternal() ? node->external()->base : node->flat()->Data(); - current_chunk_ = absl::string_view(data + offset + n, length - n); - current_leaf_ = node; - bytes_remaining_ -= n; -} - -char Cord::operator[](size_t i) const { - ABSL_HARDENING_ASSERT(i < size()); - size_t offset = i; - const CordRep* rep = contents_.tree(); - if (rep == nullptr) { - return contents_.data()[i]; - } - while (true) { - assert(rep != nullptr); - assert(offset < rep->length); + current_chunk_ = absl::string_view(data + offset + n, length - n); + current_leaf_ = node; + bytes_remaining_ -= n; +} + +char Cord::operator[](size_t i) const { + ABSL_HARDENING_ASSERT(i < size()); + size_t offset = i; + const CordRep* rep = contents_.tree(); + if (rep == nullptr) { + return contents_.data()[i]; + } + while (true) { + assert(rep != nullptr); + assert(offset < rep->length); if (rep->IsFlat()) { - // Get the "i"th character directly from the flat array. + // Get the "i"th character directly from the flat array. return rep->flat()->Data()[offset]; } else if (rep->IsBtree()) { return rep->btree()->GetCharacter(offset); } else if (rep->IsExternal()) { - // Get the "i"th character from the external array. - return rep->external()->base[offset]; + // Get the "i"th character from the external array. + return rep->external()->base[offset]; } else if (rep->IsConcat()) { - // Recursively branch to the side of the concatenation that the "i"th - // character is on. - size_t left_length = rep->concat()->left->length; - if (offset < left_length) { - rep = rep->concat()->left; - } else { - offset -= left_length; - rep = rep->concat()->right; - } - } else { - // This must be a substring a node, so bypass it to get to the child. + // Recursively branch to the side of the concatenation that the "i"th + // character is on. + size_t left_length = rep->concat()->left->length; + if (offset < left_length) { + rep = rep->concat()->left; + } else { + offset -= left_length; + rep = rep->concat()->right; + } + } else { + // This must be a substring a node, so bypass it to get to the child. assert(rep->IsSubstring()); - offset += rep->substring()->start; - rep = rep->substring()->child; - } - } -} - -absl::string_view Cord::FlattenSlowPath() { + offset += rep->substring()->start; + rep = rep->substring()->child; + } + } +} + +absl::string_view Cord::FlattenSlowPath() { assert(contents_.is_tree()); - size_t total_size = size(); - CordRep* new_rep; - char* new_buffer; - - // Try to put the contents into a new flat rep. If they won't fit in the - // biggest possible flat node, use an external rep instead. - if (total_size <= kMaxFlatLength) { + size_t total_size = size(); + CordRep* new_rep; + char* new_buffer; + + // Try to put the contents into a new flat rep. If they won't fit in the + // biggest possible flat node, use an external rep instead. + if (total_size <= kMaxFlatLength) { new_rep = CordRepFlat::New(total_size); - new_rep->length = total_size; + new_rep->length = total_size; new_buffer = new_rep->flat()->Data(); - CopyToArraySlowPath(new_buffer); - } else { - new_buffer = std::allocator<char>().allocate(total_size); - CopyToArraySlowPath(new_buffer); - new_rep = absl::cord_internal::NewExternalRep( - absl::string_view(new_buffer, total_size), [](absl::string_view s) { - std::allocator<char>().deallocate(const_cast<char*>(s.data()), - s.size()); - }); - } + CopyToArraySlowPath(new_buffer); + } else { + new_buffer = std::allocator<char>().allocate(total_size); + CopyToArraySlowPath(new_buffer); + new_rep = absl::cord_internal::NewExternalRep( + absl::string_view(new_buffer, total_size), [](absl::string_view s) { + std::allocator<char>().deallocate(const_cast<char*>(s.data()), + s.size()); + }); + } CordzUpdateScope scope(contents_.cordz_info(), CordzUpdateTracker::kFlatten); CordRep::Unref(contents_.as_tree()); contents_.SetTree(new_rep, scope); - return absl::string_view(new_buffer, total_size); -} - -/* static */ bool Cord::GetFlatAux(CordRep* rep, absl::string_view* fragment) { - assert(rep != nullptr); + return absl::string_view(new_buffer, total_size); +} + +/* static */ bool Cord::GetFlatAux(CordRep* rep, absl::string_view* fragment) { + assert(rep != nullptr); if (rep->IsFlat()) { *fragment = absl::string_view(rep->flat()->Data(), rep->length); - return true; + return true; } else if (rep->IsExternal()) { - *fragment = absl::string_view(rep->external()->base, rep->length); - return true; + *fragment = absl::string_view(rep->external()->base, rep->length); + return true; } else if (rep->IsBtree()) { return rep->btree()->IsFlat(fragment); } else if (rep->IsSubstring()) { - CordRep* child = rep->substring()->child; + CordRep* child = rep->substring()->child; if (child->IsFlat()) { *fragment = absl::string_view( child->flat()->Data() + rep->substring()->start, rep->length); - return true; + return true; } else if (child->IsExternal()) { - *fragment = absl::string_view( - child->external()->base + rep->substring()->start, rep->length); - return true; + *fragment = absl::string_view( + child->external()->base + rep->substring()->start, rep->length); + return true; } else if (child->IsBtree()) { return child->btree()->IsFlat(rep->substring()->start, rep->length, fragment); - } - } - return false; -} - -/* static */ void Cord::ForEachChunkAux( - absl::cord_internal::CordRep* rep, - absl::FunctionRef<void(absl::string_view)> callback) { + } + } + return false; +} + +/* static */ void Cord::ForEachChunkAux( + absl::cord_internal::CordRep* rep, + absl::FunctionRef<void(absl::string_view)> callback) { if (rep->IsBtree()) { ChunkIterator it(rep), end; while (it != end) { @@ -1816,175 +1816,175 @@ absl::string_view Cord::FlattenSlowPath() { return; } - assert(rep != nullptr); - int stack_pos = 0; - constexpr int stack_max = 128; - // Stack of right branches for tree traversal - absl::cord_internal::CordRep* stack[stack_max]; - absl::cord_internal::CordRep* current_node = rep; - while (true) { + assert(rep != nullptr); + int stack_pos = 0; + constexpr int stack_max = 128; + // Stack of right branches for tree traversal + absl::cord_internal::CordRep* stack[stack_max]; + absl::cord_internal::CordRep* current_node = rep; + while (true) { if (current_node->IsConcat()) { - if (stack_pos == stack_max) { - // There's no more room on our stack array to add another right branch, - // and the idea is to avoid allocations, so call this function - // recursively to navigate this subtree further. (This is not something - // we expect to happen in practice). - ForEachChunkAux(current_node, callback); - - // Pop the next right branch and iterate. - current_node = stack[--stack_pos]; - continue; - } else { - // Save the right branch for later traversal and continue down the left - // branch. - stack[stack_pos++] = current_node->concat()->right; - current_node = current_node->concat()->left; - continue; - } - } - // This is a leaf node, so invoke our callback. - absl::string_view chunk; - bool success = GetFlatAux(current_node, &chunk); - assert(success); - if (success) { - callback(chunk); - } - if (stack_pos == 0) { - // end of traversal - return; - } - current_node = stack[--stack_pos]; - } -} - + if (stack_pos == stack_max) { + // There's no more room on our stack array to add another right branch, + // and the idea is to avoid allocations, so call this function + // recursively to navigate this subtree further. (This is not something + // we expect to happen in practice). + ForEachChunkAux(current_node, callback); + + // Pop the next right branch and iterate. + current_node = stack[--stack_pos]; + continue; + } else { + // Save the right branch for later traversal and continue down the left + // branch. + stack[stack_pos++] = current_node->concat()->right; + current_node = current_node->concat()->left; + continue; + } + } + // This is a leaf node, so invoke our callback. + absl::string_view chunk; + bool success = GetFlatAux(current_node, &chunk); + assert(success); + if (success) { + callback(chunk); + } + if (stack_pos == 0) { + // end of traversal + return; + } + current_node = stack[--stack_pos]; + } +} + static void DumpNode(CordRep* rep, bool include_data, std::ostream* os, int indent) { - const int kIndentStep = 1; - absl::InlinedVector<CordRep*, kInlinedVectorSize> stack; - absl::InlinedVector<int, kInlinedVectorSize> indents; - for (;;) { - *os << std::setw(3) << rep->refcount.Get(); - *os << " " << std::setw(7) << rep->length; - *os << " ["; - if (include_data) *os << static_cast<void*>(rep); - *os << "]"; - *os << " " << (IsRootBalanced(rep) ? 'b' : 'u'); - *os << " " << std::setw(indent) << ""; + const int kIndentStep = 1; + absl::InlinedVector<CordRep*, kInlinedVectorSize> stack; + absl::InlinedVector<int, kInlinedVectorSize> indents; + for (;;) { + *os << std::setw(3) << rep->refcount.Get(); + *os << " " << std::setw(7) << rep->length; + *os << " ["; + if (include_data) *os << static_cast<void*>(rep); + *os << "]"; + *os << " " << (IsRootBalanced(rep) ? 'b' : 'u'); + *os << " " << std::setw(indent) << ""; if (rep->IsConcat()) { - *os << "CONCAT depth=" << Depth(rep) << "\n"; - indent += kIndentStep; - indents.push_back(indent); - stack.push_back(rep->concat()->right); - rep = rep->concat()->left; + *os << "CONCAT depth=" << Depth(rep) << "\n"; + indent += kIndentStep; + indents.push_back(indent); + stack.push_back(rep->concat()->right); + rep = rep->concat()->left; } else if (rep->IsSubstring()) { - *os << "SUBSTRING @ " << rep->substring()->start << "\n"; - indent += kIndentStep; - rep = rep->substring()->child; + *os << "SUBSTRING @ " << rep->substring()->start << "\n"; + indent += kIndentStep; + rep = rep->substring()->child; } else { // Leaf or ring if (rep->IsExternal()) { - *os << "EXTERNAL ["; - if (include_data) - *os << absl::CEscape(std::string(rep->external()->base, rep->length)); - *os << "]\n"; + *os << "EXTERNAL ["; + if (include_data) + *os << absl::CEscape(std::string(rep->external()->base, rep->length)); + *os << "]\n"; } else if (rep->IsFlat()) { *os << "FLAT cap=" << rep->flat()->Capacity() << " ["; - if (include_data) + if (include_data) *os << absl::CEscape(std::string(rep->flat()->Data(), rep->length)); - *os << "]\n"; + *os << "]\n"; } else { CordRepBtree::Dump(rep, /*label=*/ "", include_data, *os); - } - if (stack.empty()) break; - rep = stack.back(); - stack.pop_back(); - indent = indents.back(); - indents.pop_back(); - } - } - ABSL_INTERNAL_CHECK(indents.empty(), ""); -} - -static std::string ReportError(CordRep* root, CordRep* node) { - std::ostringstream buf; - buf << "Error at node " << node << " in:"; - DumpNode(root, true, &buf); - return buf.str(); -} - -static bool VerifyNode(CordRep* root, CordRep* start_node, - bool full_validation) { - absl::InlinedVector<CordRep*, 2> worklist; - worklist.push_back(start_node); - do { - CordRep* node = worklist.back(); - worklist.pop_back(); - - ABSL_INTERNAL_CHECK(node != nullptr, ReportError(root, node)); - if (node != root) { - ABSL_INTERNAL_CHECK(node->length != 0, ReportError(root, node)); - } - + } + if (stack.empty()) break; + rep = stack.back(); + stack.pop_back(); + indent = indents.back(); + indents.pop_back(); + } + } + ABSL_INTERNAL_CHECK(indents.empty(), ""); +} + +static std::string ReportError(CordRep* root, CordRep* node) { + std::ostringstream buf; + buf << "Error at node " << node << " in:"; + DumpNode(root, true, &buf); + return buf.str(); +} + +static bool VerifyNode(CordRep* root, CordRep* start_node, + bool full_validation) { + absl::InlinedVector<CordRep*, 2> worklist; + worklist.push_back(start_node); + do { + CordRep* node = worklist.back(); + worklist.pop_back(); + + ABSL_INTERNAL_CHECK(node != nullptr, ReportError(root, node)); + if (node != root) { + ABSL_INTERNAL_CHECK(node->length != 0, ReportError(root, node)); + } + if (node->IsConcat()) { - ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, - ReportError(root, node)); - ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, - ReportError(root, node)); - ABSL_INTERNAL_CHECK((node->length == node->concat()->left->length + - node->concat()->right->length), - ReportError(root, node)); - if (full_validation) { - worklist.push_back(node->concat()->right); - worklist.push_back(node->concat()->left); - } + ABSL_INTERNAL_CHECK(node->concat()->left != nullptr, + ReportError(root, node)); + ABSL_INTERNAL_CHECK(node->concat()->right != nullptr, + ReportError(root, node)); + ABSL_INTERNAL_CHECK((node->length == node->concat()->left->length + + node->concat()->right->length), + ReportError(root, node)); + if (full_validation) { + worklist.push_back(node->concat()->right); + worklist.push_back(node->concat()->left); + } } else if (node->IsFlat()) { ABSL_INTERNAL_CHECK(node->length <= node->flat()->Capacity(), ReportError(root, node)); } else if (node->IsExternal()) { - ABSL_INTERNAL_CHECK(node->external()->base != nullptr, - ReportError(root, node)); + ABSL_INTERNAL_CHECK(node->external()->base != nullptr, + ReportError(root, node)); } else if (node->IsSubstring()) { - ABSL_INTERNAL_CHECK( - node->substring()->start < node->substring()->child->length, - ReportError(root, node)); - ABSL_INTERNAL_CHECK(node->substring()->start + node->length <= - node->substring()->child->length, - ReportError(root, node)); - } - } while (!worklist.empty()); - return true; -} - -// Traverses the tree and computes the total memory allocated. -/* static */ size_t Cord::MemoryUsageAux(const CordRep* rep) { - size_t total_mem_usage = 0; - - // Allow a quick exit for the common case that the root is a leaf. - if (RepMemoryUsageLeaf(rep, &total_mem_usage)) { - return total_mem_usage; - } - - // Iterate over the tree. cur_node is never a leaf node and leaf nodes will - // never be appended to tree_stack. This reduces overhead from manipulating - // tree_stack. - absl::InlinedVector<const CordRep*, kInlinedVectorSize> tree_stack; - const CordRep* cur_node = rep; - while (true) { - const CordRep* next_node = nullptr; - + ABSL_INTERNAL_CHECK( + node->substring()->start < node->substring()->child->length, + ReportError(root, node)); + ABSL_INTERNAL_CHECK(node->substring()->start + node->length <= + node->substring()->child->length, + ReportError(root, node)); + } + } while (!worklist.empty()); + return true; +} + +// Traverses the tree and computes the total memory allocated. +/* static */ size_t Cord::MemoryUsageAux(const CordRep* rep) { + size_t total_mem_usage = 0; + + // Allow a quick exit for the common case that the root is a leaf. + if (RepMemoryUsageLeaf(rep, &total_mem_usage)) { + return total_mem_usage; + } + + // Iterate over the tree. cur_node is never a leaf node and leaf nodes will + // never be appended to tree_stack. This reduces overhead from manipulating + // tree_stack. + absl::InlinedVector<const CordRep*, kInlinedVectorSize> tree_stack; + const CordRep* cur_node = rep; + while (true) { + const CordRep* next_node = nullptr; + if (cur_node->IsConcat()) { - total_mem_usage += sizeof(CordRepConcat); - const CordRep* left = cur_node->concat()->left; - if (!RepMemoryUsageLeaf(left, &total_mem_usage)) { - next_node = left; - } - - const CordRep* right = cur_node->concat()->right; - if (!RepMemoryUsageLeaf(right, &total_mem_usage)) { - if (next_node) { - tree_stack.push_back(next_node); - } - next_node = right; - } + total_mem_usage += sizeof(CordRepConcat); + const CordRep* left = cur_node->concat()->left; + if (!RepMemoryUsageLeaf(left, &total_mem_usage)) { + next_node = left; + } + + const CordRep* right = cur_node->concat()->right; + if (!RepMemoryUsageLeaf(right, &total_mem_usage)) { + if (next_node) { + tree_stack.push_back(next_node); + } + next_node = right; + } } else if (cur_node->IsBtree()) { total_mem_usage += sizeof(CordRepBtree); const CordRepBtree* node = cur_node->btree(); @@ -1997,51 +1997,51 @@ static bool VerifyNode(CordRep* root, CordRep* start_node, tree_stack.push_back(edge); } } - } else { - // Since cur_node is not a leaf or a concat node it must be a substring. + } else { + // Since cur_node is not a leaf or a concat node it must be a substring. assert(cur_node->IsSubstring()); - total_mem_usage += sizeof(CordRepSubstring); - next_node = cur_node->substring()->child; - if (RepMemoryUsageLeaf(next_node, &total_mem_usage)) { - next_node = nullptr; - } - } - - if (!next_node) { - if (tree_stack.empty()) { - return total_mem_usage; - } - next_node = tree_stack.back(); - tree_stack.pop_back(); - } - cur_node = next_node; - } -} - -std::ostream& operator<<(std::ostream& out, const Cord& cord) { - for (absl::string_view chunk : cord.Chunks()) { - out.write(chunk.data(), chunk.size()); - } - return out; -} - -namespace strings_internal { + total_mem_usage += sizeof(CordRepSubstring); + next_node = cur_node->substring()->child; + if (RepMemoryUsageLeaf(next_node, &total_mem_usage)) { + next_node = nullptr; + } + } + + if (!next_node) { + if (tree_stack.empty()) { + return total_mem_usage; + } + next_node = tree_stack.back(); + tree_stack.pop_back(); + } + cur_node = next_node; + } +} + +std::ostream& operator<<(std::ostream& out, const Cord& cord) { + for (absl::string_view chunk : cord.Chunks()) { + out.write(chunk.data(), chunk.size()); + } + return out; +} + +namespace strings_internal { size_t CordTestAccess::FlatOverhead() { return cord_internal::kFlatOverhead; } size_t CordTestAccess::MaxFlatLength() { return cord_internal::kMaxFlatLength; } -size_t CordTestAccess::FlatTagToLength(uint8_t tag) { +size_t CordTestAccess::FlatTagToLength(uint8_t tag) { return cord_internal::TagToLength(tag); -} -uint8_t CordTestAccess::LengthToTag(size_t s) { - ABSL_INTERNAL_CHECK(s <= kMaxFlatLength, absl::StrCat("Invalid length ", s)); +} +uint8_t CordTestAccess::LengthToTag(size_t s) { + ABSL_INTERNAL_CHECK(s <= kMaxFlatLength, absl::StrCat("Invalid length ", s)); return cord_internal::AllocatedSizeToTag(s + cord_internal::kFlatOverhead); -} -size_t CordTestAccess::SizeofCordRepConcat() { return sizeof(CordRepConcat); } -size_t CordTestAccess::SizeofCordRepExternal() { - return sizeof(CordRepExternal); -} -size_t CordTestAccess::SizeofCordRepSubstring() { - return sizeof(CordRepSubstring); -} -} // namespace strings_internal -ABSL_NAMESPACE_END -} // namespace absl +} +size_t CordTestAccess::SizeofCordRepConcat() { return sizeof(CordRepConcat); } +size_t CordTestAccess::SizeofCordRepExternal() { + return sizeof(CordRepExternal); +} +size_t CordTestAccess::SizeofCordRepSubstring() { + return sizeof(CordRepSubstring); +} +} // namespace strings_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord.h b/contrib/restricted/abseil-cpp/absl/strings/cord.h index f0a1991471..d5753e5839 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/cord.h +++ b/contrib/restricted/abseil-cpp/absl/strings/cord.h @@ -1,84 +1,84 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// File: cord.h -// ----------------------------------------------------------------------------- -// -// This file defines the `absl::Cord` data structure and operations on that data -// structure. A Cord is a string-like sequence of characters optimized for -// specific use cases. Unlike a `std::string`, which stores an array of -// contiguous characters, Cord data is stored in a structure consisting of -// separate, reference-counted "chunks." (Currently, this implementation is a -// tree structure, though that implementation may change.) -// -// Because a Cord consists of these chunks, data can be added to or removed from -// a Cord during its lifetime. Chunks may also be shared between Cords. Unlike a +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// File: cord.h +// ----------------------------------------------------------------------------- +// +// This file defines the `absl::Cord` data structure and operations on that data +// structure. A Cord is a string-like sequence of characters optimized for +// specific use cases. Unlike a `std::string`, which stores an array of +// contiguous characters, Cord data is stored in a structure consisting of +// separate, reference-counted "chunks." (Currently, this implementation is a +// tree structure, though that implementation may change.) +// +// Because a Cord consists of these chunks, data can be added to or removed from +// a Cord during its lifetime. Chunks may also be shared between Cords. Unlike a // `std::string`, a Cord can therefore accommodate data that changes over its -// lifetime, though it's not quite "mutable"; it can change only in the -// attachment, detachment, or rearrangement of chunks of its constituent data. -// -// A Cord provides some benefit over `std::string` under the following (albeit -// narrow) circumstances: -// -// * Cord data is designed to grow and shrink over a Cord's lifetime. Cord -// provides efficient insertions and deletions at the start and end of the -// character sequences, avoiding copies in those cases. Static data should -// generally be stored as strings. -// * External memory consisting of string-like data can be directly added to -// a Cord without requiring copies or allocations. -// * Cord data may be shared and copied cheaply. Cord provides a copy-on-write -// implementation and cheap sub-Cord operations. Copying a Cord is an O(1) -// operation. -// -// As a consequence to the above, Cord data is generally large. Small data -// should generally use strings, as construction of a Cord requires some -// overhead. Small Cords (<= 15 bytes) are represented inline, but most small -// Cords are expected to grow over their lifetimes. -// -// Note that because a Cord is made up of separate chunked data, random access -// to character data within a Cord is slower than within a `std::string`. -// -// Thread Safety -// -// Cord has the same thread-safety properties as many other types like -// std::string, std::vector<>, int, etc -- it is thread-compatible. In -// particular, if threads do not call non-const methods, then it is safe to call -// const methods without synchronization. Copying a Cord produces a new instance -// that can be used concurrently with the original in arbitrary ways. - -#ifndef ABSL_STRINGS_CORD_H_ -#define ABSL_STRINGS_CORD_H_ - -#include <algorithm> -#include <cstddef> -#include <cstdint> -#include <cstring> -#include <iosfwd> -#include <iterator> -#include <string> -#include <type_traits> - +// lifetime, though it's not quite "mutable"; it can change only in the +// attachment, detachment, or rearrangement of chunks of its constituent data. +// +// A Cord provides some benefit over `std::string` under the following (albeit +// narrow) circumstances: +// +// * Cord data is designed to grow and shrink over a Cord's lifetime. Cord +// provides efficient insertions and deletions at the start and end of the +// character sequences, avoiding copies in those cases. Static data should +// generally be stored as strings. +// * External memory consisting of string-like data can be directly added to +// a Cord without requiring copies or allocations. +// * Cord data may be shared and copied cheaply. Cord provides a copy-on-write +// implementation and cheap sub-Cord operations. Copying a Cord is an O(1) +// operation. +// +// As a consequence to the above, Cord data is generally large. Small data +// should generally use strings, as construction of a Cord requires some +// overhead. Small Cords (<= 15 bytes) are represented inline, but most small +// Cords are expected to grow over their lifetimes. +// +// Note that because a Cord is made up of separate chunked data, random access +// to character data within a Cord is slower than within a `std::string`. +// +// Thread Safety +// +// Cord has the same thread-safety properties as many other types like +// std::string, std::vector<>, int, etc -- it is thread-compatible. In +// particular, if threads do not call non-const methods, then it is safe to call +// const methods without synchronization. Copying a Cord produces a new instance +// that can be used concurrently with the original in arbitrary ways. + +#ifndef ABSL_STRINGS_CORD_H_ +#define ABSL_STRINGS_CORD_H_ + +#include <algorithm> +#include <cstddef> +#include <cstdint> +#include <cstring> +#include <iosfwd> +#include <iterator> +#include <string> +#include <type_traits> + #include "absl/base/config.h" -#include "absl/base/internal/endian.h" -#include "absl/base/internal/per_thread_tls.h" -#include "absl/base/macros.h" -#include "absl/base/port.h" -#include "absl/container/inlined_vector.h" -#include "absl/functional/function_ref.h" -#include "absl/meta/type_traits.h" -#include "absl/strings/internal/cord_internal.h" +#include "absl/base/internal/endian.h" +#include "absl/base/internal/per_thread_tls.h" +#include "absl/base/macros.h" +#include "absl/base/port.h" +#include "absl/container/inlined_vector.h" +#include "absl/functional/function_ref.h" +#include "absl/meta/type_traits.h" +#include "absl/strings/internal/cord_internal.h" #include "absl/strings/internal/cord_rep_btree.h" #include "absl/strings/internal/cord_rep_btree_reader.h" #include "absl/strings/internal/cord_rep_ring.h" @@ -87,287 +87,287 @@ #include "absl/strings/internal/cordz_statistics.h" #include "absl/strings/internal/cordz_update_scope.h" #include "absl/strings/internal/cordz_update_tracker.h" -#include "absl/strings/internal/resize_uninitialized.h" +#include "absl/strings/internal/resize_uninitialized.h" #include "absl/strings/internal/string_constant.h" -#include "absl/strings/string_view.h" -#include "absl/types/optional.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -class Cord; -class CordTestPeer; -template <typename Releaser> -Cord MakeCordFromExternal(absl::string_view, Releaser&&); -void CopyCordToString(const Cord& src, std::string* dst); - -// Cord -// -// A Cord is a sequence of characters, designed to be more efficient than a -// `std::string` in certain circumstances: namely, large string data that needs -// to change over its lifetime or shared, especially when such data is shared -// across API boundaries. -// -// A Cord stores its character data in a structure that allows efficient prepend -// and append operations. This makes a Cord useful for large string data sent -// over in a wire format that may need to be prepended or appended at some point -// during the data exchange (e.g. HTTP, protocol buffers). For example, a -// Cord is useful for storing an HTTP request, and prepending an HTTP header to -// such a request. -// -// Cords should not be used for storing general string data, however. They -// require overhead to construct and are slower than strings for random access. -// -// The Cord API provides the following common API operations: -// -// * Create or assign Cords out of existing string data, memory, or other Cords -// * Append and prepend data to an existing Cord -// * Create new Sub-Cords from existing Cord data -// * Swap Cord data and compare Cord equality -// * Write out Cord data by constructing a `std::string` -// -// Additionally, the API provides iterator utilities to iterate through Cord -// data via chunks or character bytes. -// -class Cord { - private: - template <typename T> - using EnableIfString = - absl::enable_if_t<std::is_same<T, std::string>::value, int>; - - public: - // Cord::Cord() Constructors. - - // Creates an empty Cord. - constexpr Cord() noexcept; - - // Creates a Cord from an existing Cord. Cord is copyable and efficiently - // movable. The moved-from state is valid but unspecified. - Cord(const Cord& src); - Cord(Cord&& src) noexcept; - Cord& operator=(const Cord& x); - Cord& operator=(Cord&& x) noexcept; - - // Creates a Cord from a `src` string. This constructor is marked explicit to - // prevent implicit Cord constructions from arguments convertible to an - // `absl::string_view`. - explicit Cord(absl::string_view src); - Cord& operator=(absl::string_view src); - - // Creates a Cord from a `std::string&&` rvalue. These constructors are - // templated to avoid ambiguities for types that are convertible to both - // `absl::string_view` and `std::string`, such as `const char*`. - template <typename T, EnableIfString<T> = 0> - explicit Cord(T&& src); - template <typename T, EnableIfString<T> = 0> - Cord& operator=(T&& src); - - // Cord::~Cord() - // - // Destructs the Cord. - ~Cord() { - if (contents_.is_tree()) DestroyCordSlow(); - } - - // MakeCordFromExternal() - // - // Creates a Cord that takes ownership of external string memory. The - // contents of `data` are not copied to the Cord; instead, the external - // memory is added to the Cord and reference-counted. This data may not be - // changed for the life of the Cord, though it may be prepended or appended - // to. - // - // `MakeCordFromExternal()` takes a callable "releaser" that is invoked when - // the reference count for `data` reaches zero. As noted above, this data must - // remain live until the releaser is invoked. The callable releaser also must: - // - // * be move constructible - // * support `void operator()(absl::string_view) const` or `void operator()` - // - // Example: - // - // Cord MakeCord(BlockPool* pool) { - // Block* block = pool->NewBlock(); - // FillBlock(block); - // return absl::MakeCordFromExternal( - // block->ToStringView(), - // [pool, block](absl::string_view v) { - // pool->FreeBlock(block, v); - // }); - // } - // - // WARNING: Because a Cord can be reference-counted, it's likely a bug if your - // releaser doesn't do anything. For example, consider the following: - // - // void Foo(const char* buffer, int len) { - // auto c = absl::MakeCordFromExternal(absl::string_view(buffer, len), - // [](absl::string_view) {}); - // - // // BUG: If Bar() copies its cord for any reason, including keeping a - // // substring of it, the lifetime of buffer might be extended beyond - // // when Foo() returns. - // Bar(c); - // } - template <typename Releaser> - friend Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser); - - // Cord::Clear() - // - // Releases the Cord data. Any nodes that share data with other Cords, if - // applicable, will have their reference counts reduced by 1. - void Clear(); - - // Cord::Append() - // - // Appends data to the Cord, which may come from another Cord or other string - // data. - void Append(const Cord& src); - void Append(Cord&& src); - void Append(absl::string_view src); - template <typename T, EnableIfString<T> = 0> - void Append(T&& src); - - // Cord::Prepend() - // - // Prepends data to the Cord, which may come from another Cord or other string - // data. - void Prepend(const Cord& src); - void Prepend(absl::string_view src); - template <typename T, EnableIfString<T> = 0> - void Prepend(T&& src); - - // Cord::RemovePrefix() - // - // Removes the first `n` bytes of a Cord. - void RemovePrefix(size_t n); - void RemoveSuffix(size_t n); - - // Cord::Subcord() - // - // Returns a new Cord representing the subrange [pos, pos + new_size) of - // *this. If pos >= size(), the result is empty(). If - // (pos + new_size) >= size(), the result is the subrange [pos, size()). - Cord Subcord(size_t pos, size_t new_size) const; - - // Cord::swap() - // - // Swaps the contents of the Cord with `other`. - void swap(Cord& other) noexcept; - - // swap() - // - // Swaps the contents of two Cords. +#include "absl/strings/string_view.h" +#include "absl/types/optional.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +class Cord; +class CordTestPeer; +template <typename Releaser> +Cord MakeCordFromExternal(absl::string_view, Releaser&&); +void CopyCordToString(const Cord& src, std::string* dst); + +// Cord +// +// A Cord is a sequence of characters, designed to be more efficient than a +// `std::string` in certain circumstances: namely, large string data that needs +// to change over its lifetime or shared, especially when such data is shared +// across API boundaries. +// +// A Cord stores its character data in a structure that allows efficient prepend +// and append operations. This makes a Cord useful for large string data sent +// over in a wire format that may need to be prepended or appended at some point +// during the data exchange (e.g. HTTP, protocol buffers). For example, a +// Cord is useful for storing an HTTP request, and prepending an HTTP header to +// such a request. +// +// Cords should not be used for storing general string data, however. They +// require overhead to construct and are slower than strings for random access. +// +// The Cord API provides the following common API operations: +// +// * Create or assign Cords out of existing string data, memory, or other Cords +// * Append and prepend data to an existing Cord +// * Create new Sub-Cords from existing Cord data +// * Swap Cord data and compare Cord equality +// * Write out Cord data by constructing a `std::string` +// +// Additionally, the API provides iterator utilities to iterate through Cord +// data via chunks or character bytes. +// +class Cord { + private: + template <typename T> + using EnableIfString = + absl::enable_if_t<std::is_same<T, std::string>::value, int>; + + public: + // Cord::Cord() Constructors. + + // Creates an empty Cord. + constexpr Cord() noexcept; + + // Creates a Cord from an existing Cord. Cord is copyable and efficiently + // movable. The moved-from state is valid but unspecified. + Cord(const Cord& src); + Cord(Cord&& src) noexcept; + Cord& operator=(const Cord& x); + Cord& operator=(Cord&& x) noexcept; + + // Creates a Cord from a `src` string. This constructor is marked explicit to + // prevent implicit Cord constructions from arguments convertible to an + // `absl::string_view`. + explicit Cord(absl::string_view src); + Cord& operator=(absl::string_view src); + + // Creates a Cord from a `std::string&&` rvalue. These constructors are + // templated to avoid ambiguities for types that are convertible to both + // `absl::string_view` and `std::string`, such as `const char*`. + template <typename T, EnableIfString<T> = 0> + explicit Cord(T&& src); + template <typename T, EnableIfString<T> = 0> + Cord& operator=(T&& src); + + // Cord::~Cord() + // + // Destructs the Cord. + ~Cord() { + if (contents_.is_tree()) DestroyCordSlow(); + } + + // MakeCordFromExternal() + // + // Creates a Cord that takes ownership of external string memory. The + // contents of `data` are not copied to the Cord; instead, the external + // memory is added to the Cord and reference-counted. This data may not be + // changed for the life of the Cord, though it may be prepended or appended + // to. + // + // `MakeCordFromExternal()` takes a callable "releaser" that is invoked when + // the reference count for `data` reaches zero. As noted above, this data must + // remain live until the releaser is invoked. The callable releaser also must: + // + // * be move constructible + // * support `void operator()(absl::string_view) const` or `void operator()` + // + // Example: + // + // Cord MakeCord(BlockPool* pool) { + // Block* block = pool->NewBlock(); + // FillBlock(block); + // return absl::MakeCordFromExternal( + // block->ToStringView(), + // [pool, block](absl::string_view v) { + // pool->FreeBlock(block, v); + // }); + // } + // + // WARNING: Because a Cord can be reference-counted, it's likely a bug if your + // releaser doesn't do anything. For example, consider the following: + // + // void Foo(const char* buffer, int len) { + // auto c = absl::MakeCordFromExternal(absl::string_view(buffer, len), + // [](absl::string_view) {}); + // + // // BUG: If Bar() copies its cord for any reason, including keeping a + // // substring of it, the lifetime of buffer might be extended beyond + // // when Foo() returns. + // Bar(c); + // } + template <typename Releaser> + friend Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser); + + // Cord::Clear() + // + // Releases the Cord data. Any nodes that share data with other Cords, if + // applicable, will have their reference counts reduced by 1. + void Clear(); + + // Cord::Append() + // + // Appends data to the Cord, which may come from another Cord or other string + // data. + void Append(const Cord& src); + void Append(Cord&& src); + void Append(absl::string_view src); + template <typename T, EnableIfString<T> = 0> + void Append(T&& src); + + // Cord::Prepend() + // + // Prepends data to the Cord, which may come from another Cord or other string + // data. + void Prepend(const Cord& src); + void Prepend(absl::string_view src); + template <typename T, EnableIfString<T> = 0> + void Prepend(T&& src); + + // Cord::RemovePrefix() + // + // Removes the first `n` bytes of a Cord. + void RemovePrefix(size_t n); + void RemoveSuffix(size_t n); + + // Cord::Subcord() + // + // Returns a new Cord representing the subrange [pos, pos + new_size) of + // *this. If pos >= size(), the result is empty(). If + // (pos + new_size) >= size(), the result is the subrange [pos, size()). + Cord Subcord(size_t pos, size_t new_size) const; + + // Cord::swap() + // + // Swaps the contents of the Cord with `other`. + void swap(Cord& other) noexcept; + + // swap() + // + // Swaps the contents of two Cords. friend void swap(Cord& x, Cord& y) noexcept { x.swap(y); } - - // Cord::size() - // - // Returns the size of the Cord. - size_t size() const; - - // Cord::empty() - // - // Determines whether the given Cord is empty, returning `true` is so. - bool empty() const; - - // Cord::EstimatedMemoryUsage() - // - // Returns the *approximate* number of bytes held in full or in part by this - // Cord (which may not remain the same between invocations). Note that Cords - // that share memory could each be "charged" independently for the same shared - // memory. - size_t EstimatedMemoryUsage() const; - - // Cord::Compare() - // - // Compares 'this' Cord with rhs. This function and its relatives treat Cords - // as sequences of unsigned bytes. The comparison is a straightforward - // lexicographic comparison. `Cord::Compare()` returns values as follows: - // - // -1 'this' Cord is smaller - // 0 two Cords are equal - // 1 'this' Cord is larger - int Compare(absl::string_view rhs) const; - int Compare(const Cord& rhs) const; - - // Cord::StartsWith() - // - // Determines whether the Cord starts with the passed string data `rhs`. - bool StartsWith(const Cord& rhs) const; - bool StartsWith(absl::string_view rhs) const; - + + // Cord::size() + // + // Returns the size of the Cord. + size_t size() const; + + // Cord::empty() + // + // Determines whether the given Cord is empty, returning `true` is so. + bool empty() const; + + // Cord::EstimatedMemoryUsage() + // + // Returns the *approximate* number of bytes held in full or in part by this + // Cord (which may not remain the same between invocations). Note that Cords + // that share memory could each be "charged" independently for the same shared + // memory. + size_t EstimatedMemoryUsage() const; + + // Cord::Compare() + // + // Compares 'this' Cord with rhs. This function and its relatives treat Cords + // as sequences of unsigned bytes. The comparison is a straightforward + // lexicographic comparison. `Cord::Compare()` returns values as follows: + // + // -1 'this' Cord is smaller + // 0 two Cords are equal + // 1 'this' Cord is larger + int Compare(absl::string_view rhs) const; + int Compare(const Cord& rhs) const; + + // Cord::StartsWith() + // + // Determines whether the Cord starts with the passed string data `rhs`. + bool StartsWith(const Cord& rhs) const; + bool StartsWith(absl::string_view rhs) const; + // Cord::EndsWith() - // - // Determines whether the Cord ends with the passed string data `rhs`. - bool EndsWith(absl::string_view rhs) const; - bool EndsWith(const Cord& rhs) const; - - // Cord::operator std::string() - // - // Converts a Cord into a `std::string()`. This operator is marked explicit to - // prevent unintended Cord usage in functions that take a string. - explicit operator std::string() const; - - // CopyCordToString() - // - // Copies the contents of a `src` Cord into a `*dst` string. - // - // This function optimizes the case of reusing the destination string since it - // can reuse previously allocated capacity. However, this function does not - // guarantee that pointers previously returned by `dst->data()` remain valid - // even if `*dst` had enough capacity to hold `src`. If `*dst` is a new - // object, prefer to simply use the conversion operator to `std::string`. - friend void CopyCordToString(const Cord& src, std::string* dst); - - class CharIterator; - - //---------------------------------------------------------------------------- - // Cord::ChunkIterator - //---------------------------------------------------------------------------- - // - // A `Cord::ChunkIterator` allows iteration over the constituent chunks of its - // Cord. Such iteration allows you to perform non-const operatons on the data - // of a Cord without modifying it. - // - // Generally, you do not instantiate a `Cord::ChunkIterator` directly; - // instead, you create one implicitly through use of the `Cord::Chunks()` - // member function. - // - // The `Cord::ChunkIterator` has the following properties: - // - // * The iterator is invalidated after any non-const operation on the - // Cord object over which it iterates. - // * The `string_view` returned by dereferencing a valid, non-`end()` - // iterator is guaranteed to be non-empty. - // * Two `ChunkIterator` objects can be compared equal if and only if they - // remain valid and iterate over the same Cord. - // * The iterator in this case is a proxy iterator; the `string_view` - // returned by the iterator does not live inside the Cord, and its - // lifetime is limited to the lifetime of the iterator itself. To help - // prevent lifetime issues, `ChunkIterator::reference` is not a true - // reference type and is equivalent to `value_type`. - // * The iterator keeps state that can grow for Cords that contain many - // nodes and are imbalanced due to sharing. Prefer to pass this type by - // const reference instead of by value. - class ChunkIterator { - public: - using iterator_category = std::input_iterator_tag; - using value_type = absl::string_view; - using difference_type = ptrdiff_t; - using pointer = const value_type*; - using reference = value_type; - - ChunkIterator() = default; - - ChunkIterator& operator++(); - ChunkIterator operator++(int); - bool operator==(const ChunkIterator& other) const; - bool operator!=(const ChunkIterator& other) const; - reference operator*() const; - pointer operator->() const; - - friend class Cord; - friend class CharIterator; - - private: + // + // Determines whether the Cord ends with the passed string data `rhs`. + bool EndsWith(absl::string_view rhs) const; + bool EndsWith(const Cord& rhs) const; + + // Cord::operator std::string() + // + // Converts a Cord into a `std::string()`. This operator is marked explicit to + // prevent unintended Cord usage in functions that take a string. + explicit operator std::string() const; + + // CopyCordToString() + // + // Copies the contents of a `src` Cord into a `*dst` string. + // + // This function optimizes the case of reusing the destination string since it + // can reuse previously allocated capacity. However, this function does not + // guarantee that pointers previously returned by `dst->data()` remain valid + // even if `*dst` had enough capacity to hold `src`. If `*dst` is a new + // object, prefer to simply use the conversion operator to `std::string`. + friend void CopyCordToString(const Cord& src, std::string* dst); + + class CharIterator; + + //---------------------------------------------------------------------------- + // Cord::ChunkIterator + //---------------------------------------------------------------------------- + // + // A `Cord::ChunkIterator` allows iteration over the constituent chunks of its + // Cord. Such iteration allows you to perform non-const operatons on the data + // of a Cord without modifying it. + // + // Generally, you do not instantiate a `Cord::ChunkIterator` directly; + // instead, you create one implicitly through use of the `Cord::Chunks()` + // member function. + // + // The `Cord::ChunkIterator` has the following properties: + // + // * The iterator is invalidated after any non-const operation on the + // Cord object over which it iterates. + // * The `string_view` returned by dereferencing a valid, non-`end()` + // iterator is guaranteed to be non-empty. + // * Two `ChunkIterator` objects can be compared equal if and only if they + // remain valid and iterate over the same Cord. + // * The iterator in this case is a proxy iterator; the `string_view` + // returned by the iterator does not live inside the Cord, and its + // lifetime is limited to the lifetime of the iterator itself. To help + // prevent lifetime issues, `ChunkIterator::reference` is not a true + // reference type and is equivalent to `value_type`. + // * The iterator keeps state that can grow for Cords that contain many + // nodes and are imbalanced due to sharing. Prefer to pass this type by + // const reference instead of by value. + class ChunkIterator { + public: + using iterator_category = std::input_iterator_tag; + using value_type = absl::string_view; + using difference_type = ptrdiff_t; + using pointer = const value_type*; + using reference = value_type; + + ChunkIterator() = default; + + ChunkIterator& operator++(); + ChunkIterator operator++(int); + bool operator==(const ChunkIterator& other) const; + bool operator!=(const ChunkIterator& other) const; + reference operator*() const; + pointer operator->() const; + + friend class Cord; + friend class CharIterator; + + private: using CordRep = absl::cord_internal::CordRep; using CordRepBtree = absl::cord_internal::CordRepBtree; using CordRepBtreeReader = absl::cord_internal::CordRepBtreeReader; @@ -381,17 +381,17 @@ class Cord { // Constructs a `begin()` iterator from `tree`. `tree` must not be null. explicit ChunkIterator(cord_internal::CordRep* tree); - // Constructs a `begin()` iterator from `cord`. - explicit ChunkIterator(const Cord* cord); - + // Constructs a `begin()` iterator from `cord`. + explicit ChunkIterator(const Cord* cord); + // Initializes this instance from a tree. Invoked by constructors. void InitTree(cord_internal::CordRep* tree); - // Removes `n` bytes from `current_chunk_`. Expects `n` to be smaller than - // `current_chunk_.size()`. - void RemoveChunkPrefix(size_t n); - Cord AdvanceAndReadBytes(size_t n); - void AdvanceBytes(size_t n); + // Removes `n` bytes from `current_chunk_`. Expects `n` to be smaller than + // `current_chunk_.size()`. + void RemoveChunkPrefix(size_t n); + Cord AdvanceAndReadBytes(size_t n); + void AdvanceBytes(size_t n); // Stack specific operator++ ChunkIterator& AdvanceStack(); @@ -400,66 +400,66 @@ class Cord { ChunkIterator& AdvanceBtree(); void AdvanceBytesBtree(size_t n); - // Iterates `n` bytes, where `n` is expected to be greater than or equal to - // `current_chunk_.size()`. - void AdvanceBytesSlowPath(size_t n); - - // A view into bytes of the current `CordRep`. It may only be a view to a - // suffix of bytes if this is being used by `CharIterator`. - absl::string_view current_chunk_; - // The current leaf, or `nullptr` if the iterator points to short data. - // If the current chunk is a substring node, current_leaf_ points to the - // underlying flat or external node. - absl::cord_internal::CordRep* current_leaf_ = nullptr; - // The number of bytes left in the `Cord` over which we are iterating. - size_t bytes_remaining_ = 0; + // Iterates `n` bytes, where `n` is expected to be greater than or equal to + // `current_chunk_.size()`. + void AdvanceBytesSlowPath(size_t n); + + // A view into bytes of the current `CordRep`. It may only be a view to a + // suffix of bytes if this is being used by `CharIterator`. + absl::string_view current_chunk_; + // The current leaf, or `nullptr` if the iterator points to short data. + // If the current chunk is a substring node, current_leaf_ points to the + // underlying flat or external node. + absl::cord_internal::CordRep* current_leaf_ = nullptr; + // The number of bytes left in the `Cord` over which we are iterating. + size_t bytes_remaining_ = 0; // Cord reader for cord btrees. Empty if not traversing a btree. CordRepBtreeReader btree_reader_; // See 'Stack' alias definition. Stack stack_of_right_children_; - }; - - // Cord::ChunkIterator::chunk_begin() - // - // Returns an iterator to the first chunk of the `Cord`. - // - // Generally, prefer using `Cord::Chunks()` within a range-based for loop for - // iterating over the chunks of a Cord. This method may be useful for getting - // a `ChunkIterator` where range-based for-loops are not useful. - // - // Example: - // - // absl::Cord::ChunkIterator FindAsChunk(const absl::Cord& c, - // absl::string_view s) { - // return std::find(c.chunk_begin(), c.chunk_end(), s); - // } - ChunkIterator chunk_begin() const; - - // Cord::ChunkItertator::chunk_end() - // - // Returns an iterator one increment past the last chunk of the `Cord`. - // - // Generally, prefer using `Cord::Chunks()` within a range-based for loop for - // iterating over the chunks of a Cord. This method may be useful for getting - // a `ChunkIterator` where range-based for-loops may not be available. - ChunkIterator chunk_end() const; - - //---------------------------------------------------------------------------- - // Cord::ChunkIterator::ChunkRange - //---------------------------------------------------------------------------- - // - // `ChunkRange` is a helper class for iterating over the chunks of the `Cord`, - // producing an iterator which can be used within a range-based for loop. - // Construction of a `ChunkRange` will return an iterator pointing to the - // first chunk of the Cord. Generally, do not construct a `ChunkRange` - // directly; instead, prefer to use the `Cord::Chunks()` method. - // - // Implementation note: `ChunkRange` is simply a convenience wrapper over - // `Cord::chunk_begin()` and `Cord::chunk_end()`. - class ChunkRange { - public: + }; + + // Cord::ChunkIterator::chunk_begin() + // + // Returns an iterator to the first chunk of the `Cord`. + // + // Generally, prefer using `Cord::Chunks()` within a range-based for loop for + // iterating over the chunks of a Cord. This method may be useful for getting + // a `ChunkIterator` where range-based for-loops are not useful. + // + // Example: + // + // absl::Cord::ChunkIterator FindAsChunk(const absl::Cord& c, + // absl::string_view s) { + // return std::find(c.chunk_begin(), c.chunk_end(), s); + // } + ChunkIterator chunk_begin() const; + + // Cord::ChunkItertator::chunk_end() + // + // Returns an iterator one increment past the last chunk of the `Cord`. + // + // Generally, prefer using `Cord::Chunks()` within a range-based for loop for + // iterating over the chunks of a Cord. This method may be useful for getting + // a `ChunkIterator` where range-based for-loops may not be available. + ChunkIterator chunk_end() const; + + //---------------------------------------------------------------------------- + // Cord::ChunkIterator::ChunkRange + //---------------------------------------------------------------------------- + // + // `ChunkRange` is a helper class for iterating over the chunks of the `Cord`, + // producing an iterator which can be used within a range-based for loop. + // Construction of a `ChunkRange` will return an iterator pointing to the + // first chunk of the Cord. Generally, do not construct a `ChunkRange` + // directly; instead, prefer to use the `Cord::Chunks()` method. + // + // Implementation note: `ChunkRange` is simply a convenience wrapper over + // `Cord::chunk_begin()` and `Cord::chunk_end()`. + class ChunkRange { + public: // Fulfill minimum c++ container requirements [container.requirements] // Theses (partial) container type definitions allow ChunkRange to be used // in various utilities expecting a subset of [container.requirements]. @@ -470,137 +470,137 @@ class Cord { using iterator = ChunkIterator; using const_iterator = ChunkIterator; - explicit ChunkRange(const Cord* cord) : cord_(cord) {} - - ChunkIterator begin() const; - ChunkIterator end() const; - - private: - const Cord* cord_; - }; - - // Cord::Chunks() - // - // Returns a `Cord::ChunkIterator::ChunkRange` for iterating over the chunks - // of a `Cord` with a range-based for-loop. For most iteration tasks on a - // Cord, use `Cord::Chunks()` to retrieve this iterator. - // - // Example: - // - // void ProcessChunks(const Cord& cord) { - // for (absl::string_view chunk : cord.Chunks()) { ... } - // } - // - // Note that the ordinary caveats of temporary lifetime extension apply: - // - // void Process() { - // for (absl::string_view chunk : CordFactory().Chunks()) { - // // The temporary Cord returned by CordFactory has been destroyed! - // } - // } - ChunkRange Chunks() const; - - //---------------------------------------------------------------------------- - // Cord::CharIterator - //---------------------------------------------------------------------------- - // - // A `Cord::CharIterator` allows iteration over the constituent characters of - // a `Cord`. - // - // Generally, you do not instantiate a `Cord::CharIterator` directly; instead, - // you create one implicitly through use of the `Cord::Chars()` member - // function. - // - // A `Cord::CharIterator` has the following properties: - // - // * The iterator is invalidated after any non-const operation on the - // Cord object over which it iterates. - // * Two `CharIterator` objects can be compared equal if and only if they - // remain valid and iterate over the same Cord. - // * The iterator keeps state that can grow for Cords that contain many - // nodes and are imbalanced due to sharing. Prefer to pass this type by - // const reference instead of by value. - // * This type cannot act as a forward iterator because a `Cord` can reuse - // sections of memory. This fact violates the requirement for forward - // iterators to compare equal if dereferencing them returns the same - // object. - class CharIterator { - public: - using iterator_category = std::input_iterator_tag; - using value_type = char; - using difference_type = ptrdiff_t; - using pointer = const char*; - using reference = const char&; - - CharIterator() = default; - - CharIterator& operator++(); - CharIterator operator++(int); - bool operator==(const CharIterator& other) const; - bool operator!=(const CharIterator& other) const; - reference operator*() const; - pointer operator->() const; - - friend Cord; - - private: - explicit CharIterator(const Cord* cord) : chunk_iterator_(cord) {} - - ChunkIterator chunk_iterator_; - }; - - // Cord::CharIterator::AdvanceAndRead() - // - // Advances the `Cord::CharIterator` by `n_bytes` and returns the bytes - // advanced as a separate `Cord`. `n_bytes` must be less than or equal to the - // number of bytes within the Cord; otherwise, behavior is undefined. It is - // valid to pass `char_end()` and `0`. - static Cord AdvanceAndRead(CharIterator* it, size_t n_bytes); - - // Cord::CharIterator::Advance() - // - // Advances the `Cord::CharIterator` by `n_bytes`. `n_bytes` must be less than - // or equal to the number of bytes remaining within the Cord; otherwise, - // behavior is undefined. It is valid to pass `char_end()` and `0`. - static void Advance(CharIterator* it, size_t n_bytes); - - // Cord::CharIterator::ChunkRemaining() - // - // Returns the longest contiguous view starting at the iterator's position. - // - // `it` must be dereferenceable. - static absl::string_view ChunkRemaining(const CharIterator& it); - - // Cord::CharIterator::char_begin() - // - // Returns an iterator to the first character of the `Cord`. - // - // Generally, prefer using `Cord::Chars()` within a range-based for loop for - // iterating over the chunks of a Cord. This method may be useful for getting - // a `CharIterator` where range-based for-loops may not be available. - CharIterator char_begin() const; - - // Cord::CharIterator::char_end() - // - // Returns an iterator to one past the last character of the `Cord`. - // - // Generally, prefer using `Cord::Chars()` within a range-based for loop for - // iterating over the chunks of a Cord. This method may be useful for getting - // a `CharIterator` where range-based for-loops are not useful. - CharIterator char_end() const; - - // Cord::CharIterator::CharRange - // - // `CharRange` is a helper class for iterating over the characters of a - // producing an iterator which can be used within a range-based for loop. - // Construction of a `CharRange` will return an iterator pointing to the first - // character of the Cord. Generally, do not construct a `CharRange` directly; - // instead, prefer to use the `Cord::Chars()` method show below. - // - // Implementation note: `CharRange` is simply a convenience wrapper over - // `Cord::char_begin()` and `Cord::char_end()`. - class CharRange { - public: + explicit ChunkRange(const Cord* cord) : cord_(cord) {} + + ChunkIterator begin() const; + ChunkIterator end() const; + + private: + const Cord* cord_; + }; + + // Cord::Chunks() + // + // Returns a `Cord::ChunkIterator::ChunkRange` for iterating over the chunks + // of a `Cord` with a range-based for-loop. For most iteration tasks on a + // Cord, use `Cord::Chunks()` to retrieve this iterator. + // + // Example: + // + // void ProcessChunks(const Cord& cord) { + // for (absl::string_view chunk : cord.Chunks()) { ... } + // } + // + // Note that the ordinary caveats of temporary lifetime extension apply: + // + // void Process() { + // for (absl::string_view chunk : CordFactory().Chunks()) { + // // The temporary Cord returned by CordFactory has been destroyed! + // } + // } + ChunkRange Chunks() const; + + //---------------------------------------------------------------------------- + // Cord::CharIterator + //---------------------------------------------------------------------------- + // + // A `Cord::CharIterator` allows iteration over the constituent characters of + // a `Cord`. + // + // Generally, you do not instantiate a `Cord::CharIterator` directly; instead, + // you create one implicitly through use of the `Cord::Chars()` member + // function. + // + // A `Cord::CharIterator` has the following properties: + // + // * The iterator is invalidated after any non-const operation on the + // Cord object over which it iterates. + // * Two `CharIterator` objects can be compared equal if and only if they + // remain valid and iterate over the same Cord. + // * The iterator keeps state that can grow for Cords that contain many + // nodes and are imbalanced due to sharing. Prefer to pass this type by + // const reference instead of by value. + // * This type cannot act as a forward iterator because a `Cord` can reuse + // sections of memory. This fact violates the requirement for forward + // iterators to compare equal if dereferencing them returns the same + // object. + class CharIterator { + public: + using iterator_category = std::input_iterator_tag; + using value_type = char; + using difference_type = ptrdiff_t; + using pointer = const char*; + using reference = const char&; + + CharIterator() = default; + + CharIterator& operator++(); + CharIterator operator++(int); + bool operator==(const CharIterator& other) const; + bool operator!=(const CharIterator& other) const; + reference operator*() const; + pointer operator->() const; + + friend Cord; + + private: + explicit CharIterator(const Cord* cord) : chunk_iterator_(cord) {} + + ChunkIterator chunk_iterator_; + }; + + // Cord::CharIterator::AdvanceAndRead() + // + // Advances the `Cord::CharIterator` by `n_bytes` and returns the bytes + // advanced as a separate `Cord`. `n_bytes` must be less than or equal to the + // number of bytes within the Cord; otherwise, behavior is undefined. It is + // valid to pass `char_end()` and `0`. + static Cord AdvanceAndRead(CharIterator* it, size_t n_bytes); + + // Cord::CharIterator::Advance() + // + // Advances the `Cord::CharIterator` by `n_bytes`. `n_bytes` must be less than + // or equal to the number of bytes remaining within the Cord; otherwise, + // behavior is undefined. It is valid to pass `char_end()` and `0`. + static void Advance(CharIterator* it, size_t n_bytes); + + // Cord::CharIterator::ChunkRemaining() + // + // Returns the longest contiguous view starting at the iterator's position. + // + // `it` must be dereferenceable. + static absl::string_view ChunkRemaining(const CharIterator& it); + + // Cord::CharIterator::char_begin() + // + // Returns an iterator to the first character of the `Cord`. + // + // Generally, prefer using `Cord::Chars()` within a range-based for loop for + // iterating over the chunks of a Cord. This method may be useful for getting + // a `CharIterator` where range-based for-loops may not be available. + CharIterator char_begin() const; + + // Cord::CharIterator::char_end() + // + // Returns an iterator to one past the last character of the `Cord`. + // + // Generally, prefer using `Cord::Chars()` within a range-based for loop for + // iterating over the chunks of a Cord. This method may be useful for getting + // a `CharIterator` where range-based for-loops are not useful. + CharIterator char_end() const; + + // Cord::CharIterator::CharRange + // + // `CharRange` is a helper class for iterating over the characters of a + // producing an iterator which can be used within a range-based for loop. + // Construction of a `CharRange` will return an iterator pointing to the first + // character of the Cord. Generally, do not construct a `CharRange` directly; + // instead, prefer to use the `Cord::Chars()` method show below. + // + // Implementation note: `CharRange` is simply a convenience wrapper over + // `Cord::char_begin()` and `Cord::char_end()`. + class CharRange { + public: // Fulfill minimum c++ container requirements [container.requirements] // Theses (partial) container type definitions allow CharRange to be used // in various utilities expecting a subset of [container.requirements]. @@ -611,75 +611,75 @@ class Cord { using iterator = CharIterator; using const_iterator = CharIterator; - explicit CharRange(const Cord* cord) : cord_(cord) {} - - CharIterator begin() const; - CharIterator end() const; - - private: - const Cord* cord_; - }; - - // Cord::CharIterator::Chars() - // - // Returns a `Cord::CharIterator` for iterating over the characters of a - // `Cord` with a range-based for-loop. For most character-based iteration - // tasks on a Cord, use `Cord::Chars()` to retrieve this iterator. - // - // Example: - // - // void ProcessCord(const Cord& cord) { - // for (char c : cord.Chars()) { ... } - // } - // - // Note that the ordinary caveats of temporary lifetime extension apply: - // - // void Process() { - // for (char c : CordFactory().Chars()) { - // // The temporary Cord returned by CordFactory has been destroyed! - // } - // } - CharRange Chars() const; - - // Cord::operator[] - // - // Gets the "i"th character of the Cord and returns it, provided that - // 0 <= i < Cord.size(). - // - // NOTE: This routine is reasonably efficient. It is roughly - // logarithmic based on the number of chunks that make up the cord. Still, - // if you need to iterate over the contents of a cord, you should - // use a CharIterator/ChunkIterator rather than call operator[] or Get() - // repeatedly in a loop. - char operator[](size_t i) const; - - // Cord::TryFlat() - // - // If this cord's representation is a single flat array, returns a - // string_view referencing that array. Otherwise returns nullopt. - absl::optional<absl::string_view> TryFlat() const; - - // Cord::Flatten() - // - // Flattens the cord into a single array and returns a view of the data. - // - // If the cord was already flat, the contents are not modified. - absl::string_view Flatten(); - - // Supports absl::Cord as a sink object for absl::Format(). - friend void AbslFormatFlush(absl::Cord* cord, absl::string_view part) { - cord->Append(part); - } - - template <typename H> - friend H AbslHashValue(H hash_state, const absl::Cord& c) { - absl::optional<absl::string_view> maybe_flat = c.TryFlat(); - if (maybe_flat.has_value()) { - return H::combine(std::move(hash_state), *maybe_flat); - } - return c.HashFragmented(std::move(hash_state)); - } - + explicit CharRange(const Cord* cord) : cord_(cord) {} + + CharIterator begin() const; + CharIterator end() const; + + private: + const Cord* cord_; + }; + + // Cord::CharIterator::Chars() + // + // Returns a `Cord::CharIterator` for iterating over the characters of a + // `Cord` with a range-based for-loop. For most character-based iteration + // tasks on a Cord, use `Cord::Chars()` to retrieve this iterator. + // + // Example: + // + // void ProcessCord(const Cord& cord) { + // for (char c : cord.Chars()) { ... } + // } + // + // Note that the ordinary caveats of temporary lifetime extension apply: + // + // void Process() { + // for (char c : CordFactory().Chars()) { + // // The temporary Cord returned by CordFactory has been destroyed! + // } + // } + CharRange Chars() const; + + // Cord::operator[] + // + // Gets the "i"th character of the Cord and returns it, provided that + // 0 <= i < Cord.size(). + // + // NOTE: This routine is reasonably efficient. It is roughly + // logarithmic based on the number of chunks that make up the cord. Still, + // if you need to iterate over the contents of a cord, you should + // use a CharIterator/ChunkIterator rather than call operator[] or Get() + // repeatedly in a loop. + char operator[](size_t i) const; + + // Cord::TryFlat() + // + // If this cord's representation is a single flat array, returns a + // string_view referencing that array. Otherwise returns nullopt. + absl::optional<absl::string_view> TryFlat() const; + + // Cord::Flatten() + // + // Flattens the cord into a single array and returns a view of the data. + // + // If the cord was already flat, the contents are not modified. + absl::string_view Flatten(); + + // Supports absl::Cord as a sink object for absl::Format(). + friend void AbslFormatFlush(absl::Cord* cord, absl::string_view part) { + cord->Append(part); + } + + template <typename H> + friend H AbslHashValue(H hash_state, const absl::Cord& c) { + absl::optional<absl::string_view> maybe_flat = c.TryFlat(); + if (maybe_flat.has_value()) { + return H::combine(std::move(hash_state), *maybe_flat); + } + return c.HashFragmented(std::move(hash_state)); + } + // Create a Cord with the contents of StringConstant<T>::value. // No allocations will be done and no data will be copied. // This is an INTERNAL API and subject to change or removal. This API can only @@ -688,7 +688,7 @@ class Cord { template <typename T> explicit constexpr Cord(strings_internal::StringConstant<T>); - private: + private: using CordRep = absl::cord_internal::CordRep; using CordRepFlat = absl::cord_internal::CordRepFlat; using CordzInfo = cord_internal::CordzInfo; @@ -701,56 +701,56 @@ class Cord { // public API call causing the cord to be created. explicit Cord(absl::string_view src, MethodIdentifier method); - friend class CordTestPeer; - friend bool operator==(const Cord& lhs, const Cord& rhs); - friend bool operator==(const Cord& lhs, absl::string_view rhs); - + friend class CordTestPeer; + friend bool operator==(const Cord& lhs, const Cord& rhs); + friend bool operator==(const Cord& lhs, absl::string_view rhs); + friend const CordzInfo* GetCordzInfoForTesting(const Cord& cord); - // Calls the provided function once for each cord chunk, in order. Unlike - // Chunks(), this API will not allocate memory. - void ForEachChunk(absl::FunctionRef<void(absl::string_view)>) const; - - // Allocates new contiguous storage for the contents of the cord. This is - // called by Flatten() when the cord was not already flat. - absl::string_view FlattenSlowPath(); - - // Actual cord contents are hidden inside the following simple - // class so that we can isolate the bulk of cord.cc from changes - // to the representation. - // - // InlineRep holds either a tree pointer, or an array of kMaxInline bytes. - class InlineRep { - public: - static constexpr unsigned char kMaxInline = cord_internal::kMaxInline; - static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*), ""); - - constexpr InlineRep() : data_() {} + // Calls the provided function once for each cord chunk, in order. Unlike + // Chunks(), this API will not allocate memory. + void ForEachChunk(absl::FunctionRef<void(absl::string_view)>) const; + + // Allocates new contiguous storage for the contents of the cord. This is + // called by Flatten() when the cord was not already flat. + absl::string_view FlattenSlowPath(); + + // Actual cord contents are hidden inside the following simple + // class so that we can isolate the bulk of cord.cc from changes + // to the representation. + // + // InlineRep holds either a tree pointer, or an array of kMaxInline bytes. + class InlineRep { + public: + static constexpr unsigned char kMaxInline = cord_internal::kMaxInline; + static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*), ""); + + constexpr InlineRep() : data_() {} explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {} - InlineRep(const InlineRep& src); - InlineRep(InlineRep&& src); - InlineRep& operator=(const InlineRep& src); - InlineRep& operator=(InlineRep&& src) noexcept; - + InlineRep(const InlineRep& src); + InlineRep(InlineRep&& src); + InlineRep& operator=(const InlineRep& src); + InlineRep& operator=(InlineRep&& src) noexcept; + explicit constexpr InlineRep(cord_internal::InlineData data); - void Swap(InlineRep* rhs); - bool empty() const; - size_t size() const; - const char* data() const; // Returns nullptr if holding pointer - void set_data(const char* data, size_t n, - bool nullify_tail); // Discards pointer, if any + void Swap(InlineRep* rhs); + bool empty() const; + size_t size() const; + const char* data() const; // Returns nullptr if holding pointer + void set_data(const char* data, size_t n, + bool nullify_tail); // Discards pointer, if any char* set_data(size_t n); // Write data to the result - // Returns nullptr if holding bytes - absl::cord_internal::CordRep* tree() const; + // Returns nullptr if holding bytes + absl::cord_internal::CordRep* tree() const; absl::cord_internal::CordRep* as_tree() const; - // Returns non-null iff was holding a pointer - absl::cord_internal::CordRep* clear(); - // Converts to pointer if necessary. + // Returns non-null iff was holding a pointer + absl::cord_internal::CordRep* clear(); + // Converts to pointer if necessary. void reduce_size(size_t n); // REQUIRES: holding data - void remove_prefix(size_t n); // REQUIRES: holding data + void remove_prefix(size_t n); // REQUIRES: holding data void AppendArray(absl::string_view src, MethodIdentifier method); - absl::string_view FindFlatStartPiece() const; + absl::string_view FindFlatStartPiece() const; // Creates a CordRepFlat instance from the current inlined data with `extra' // bytes of desired additional capacity. @@ -794,40 +794,40 @@ class Cord { template <bool has_length> void GetAppendRegion(char** region, size_t* size, size_t length); - bool IsSame(const InlineRep& other) const { - return memcmp(&data_, &other.data_, sizeof(data_)) == 0; - } - int BitwiseCompare(const InlineRep& other) const { - uint64_t x, y; - // Use memcpy to avoid aliasing issues. - memcpy(&x, &data_, sizeof(x)); - memcpy(&y, &other.data_, sizeof(y)); - if (x == y) { - memcpy(&x, reinterpret_cast<const char*>(&data_) + 8, sizeof(x)); - memcpy(&y, reinterpret_cast<const char*>(&other.data_) + 8, sizeof(y)); - if (x == y) return 0; - } - return absl::big_endian::FromHost64(x) < absl::big_endian::FromHost64(y) - ? -1 - : 1; - } - void CopyTo(std::string* dst) const { - // memcpy is much faster when operating on a known size. On most supported - // platforms, the small string optimization is large enough that resizing - // to 15 bytes does not cause a memory allocation. - absl::strings_internal::STLStringResizeUninitialized(dst, - sizeof(data_) - 1); - memcpy(&(*dst)[0], &data_, sizeof(data_) - 1); - // erase is faster than resize because the logic for memory allocation is - // not needed. + bool IsSame(const InlineRep& other) const { + return memcmp(&data_, &other.data_, sizeof(data_)) == 0; + } + int BitwiseCompare(const InlineRep& other) const { + uint64_t x, y; + // Use memcpy to avoid aliasing issues. + memcpy(&x, &data_, sizeof(x)); + memcpy(&y, &other.data_, sizeof(y)); + if (x == y) { + memcpy(&x, reinterpret_cast<const char*>(&data_) + 8, sizeof(x)); + memcpy(&y, reinterpret_cast<const char*>(&other.data_) + 8, sizeof(y)); + if (x == y) return 0; + } + return absl::big_endian::FromHost64(x) < absl::big_endian::FromHost64(y) + ? -1 + : 1; + } + void CopyTo(std::string* dst) const { + // memcpy is much faster when operating on a known size. On most supported + // platforms, the small string optimization is large enough that resizing + // to 15 bytes does not cause a memory allocation. + absl::strings_internal::STLStringResizeUninitialized(dst, + sizeof(data_) - 1); + memcpy(&(*dst)[0], &data_, sizeof(data_) - 1); + // erase is faster than resize because the logic for memory allocation is + // not needed. dst->erase(inline_size()); - } - - // Copies the inline contents into `dst`. Assumes the cord is not empty. - void CopyToArray(char* dst) const; - + } + + // Copies the inline contents into `dst`. Assumes the cord is not empty. + void CopyToArray(char* dst) const; + bool is_tree() const { return data_.is_tree(); } - + // Returns true if the Cord is being profiled by cordz. bool is_profiled() const { return data_.is_tree() && data_.is_profiled(); } @@ -845,62 +845,62 @@ class Cord { // Resets the current cordz_info to null / empty. void clear_cordz_info() { data_.clear_cordz_info(); } - private: - friend class Cord; - - void AssignSlow(const InlineRep& src); + private: + friend class Cord; + + void AssignSlow(const InlineRep& src); // Unrefs the tree and stops profiling. void UnrefTree(); - - void ResetToEmpty() { data_ = {}; } - + + void ResetToEmpty() { data_ = {}; } + void set_inline_size(size_t size) { data_.set_inline_size(size); } size_t inline_size() const { return data_.inline_size(); } - - cord_internal::InlineData data_; - }; - InlineRep contents_; - - // Helper for MemoryUsage(). - static size_t MemoryUsageAux(const absl::cord_internal::CordRep* rep); - - // Helper for GetFlat() and TryFlat(). - static bool GetFlatAux(absl::cord_internal::CordRep* rep, - absl::string_view* fragment); - - // Helper for ForEachChunk(). - static void ForEachChunkAux( - absl::cord_internal::CordRep* rep, - absl::FunctionRef<void(absl::string_view)> callback); - - // The destructor for non-empty Cords. - void DestroyCordSlow(); - - // Out-of-line implementation of slower parts of logic. - void CopyToArraySlowPath(char* dst) const; - int CompareSlowPath(absl::string_view rhs, size_t compared_size, - size_t size_to_compare) const; - int CompareSlowPath(const Cord& rhs, size_t compared_size, - size_t size_to_compare) const; - bool EqualsImpl(absl::string_view rhs, size_t size_to_compare) const; - bool EqualsImpl(const Cord& rhs, size_t size_to_compare) const; - int CompareImpl(const Cord& rhs) const; - - template <typename ResultType, typename RHS> - friend ResultType GenericCompare(const Cord& lhs, const RHS& rhs, - size_t size_to_compare); - static absl::string_view GetFirstChunk(const Cord& c); - static absl::string_view GetFirstChunk(absl::string_view sv); - - // Returns a new reference to contents_.tree(), or steals an existing - // reference if called on an rvalue. - absl::cord_internal::CordRep* TakeRep() const&; - absl::cord_internal::CordRep* TakeRep() &&; - - // Helper for Append(). - template <typename C> - void AppendImpl(C&& src); - + + cord_internal::InlineData data_; + }; + InlineRep contents_; + + // Helper for MemoryUsage(). + static size_t MemoryUsageAux(const absl::cord_internal::CordRep* rep); + + // Helper for GetFlat() and TryFlat(). + static bool GetFlatAux(absl::cord_internal::CordRep* rep, + absl::string_view* fragment); + + // Helper for ForEachChunk(). + static void ForEachChunkAux( + absl::cord_internal::CordRep* rep, + absl::FunctionRef<void(absl::string_view)> callback); + + // The destructor for non-empty Cords. + void DestroyCordSlow(); + + // Out-of-line implementation of slower parts of logic. + void CopyToArraySlowPath(char* dst) const; + int CompareSlowPath(absl::string_view rhs, size_t compared_size, + size_t size_to_compare) const; + int CompareSlowPath(const Cord& rhs, size_t compared_size, + size_t size_to_compare) const; + bool EqualsImpl(absl::string_view rhs, size_t size_to_compare) const; + bool EqualsImpl(const Cord& rhs, size_t size_to_compare) const; + int CompareImpl(const Cord& rhs) const; + + template <typename ResultType, typename RHS> + friend ResultType GenericCompare(const Cord& lhs, const RHS& rhs, + size_t size_to_compare); + static absl::string_view GetFirstChunk(const Cord& c); + static absl::string_view GetFirstChunk(absl::string_view sv); + + // Returns a new reference to contents_.tree(), or steals an existing + // reference if called on an rvalue. + absl::cord_internal::CordRep* TakeRep() const&; + absl::cord_internal::CordRep* TakeRep() &&; + + // Helper for Append(). + template <typename C> + void AppendImpl(C&& src); + // Prepends the provided data to this instance. `method` contains the public // API method for this action which is tracked for Cordz sampling purposes. void PrependArray(absl::string_view src, MethodIdentifier method); @@ -909,116 +909,116 @@ class Cord { // Requires src.length() > kMaxBytesToCopy. Cord& AssignLargeString(std::string&& src); - // Helper for AbslHashValue(). - template <typename H> - H HashFragmented(H hash_state) const { - typename H::AbslInternalPiecewiseCombiner combiner; - ForEachChunk([&combiner, &hash_state](absl::string_view chunk) { - hash_state = combiner.add_buffer(std::move(hash_state), chunk.data(), - chunk.size()); - }); - return H::combine(combiner.finalize(std::move(hash_state)), size()); - } -}; - -ABSL_NAMESPACE_END -} // namespace absl - -namespace absl { -ABSL_NAMESPACE_BEGIN - -// allow a Cord to be logged -extern std::ostream& operator<<(std::ostream& out, const Cord& cord); - -// ------------------------------------------------------------------ -// Internal details follow. Clients should ignore. - -namespace cord_internal { - -// Fast implementation of memmove for up to 15 bytes. This implementation is -// safe for overlapping regions. If nullify_tail is true, the destination is -// padded with '\0' up to 16 bytes. -inline void SmallMemmove(char* dst, const char* src, size_t n, - bool nullify_tail = false) { - if (n >= 8) { - assert(n <= 16); - uint64_t buf1; - uint64_t buf2; - memcpy(&buf1, src, 8); - memcpy(&buf2, src + n - 8, 8); - if (nullify_tail) { - memset(dst + 8, 0, 8); - } - memcpy(dst, &buf1, 8); - memcpy(dst + n - 8, &buf2, 8); - } else if (n >= 4) { - uint32_t buf1; - uint32_t buf2; - memcpy(&buf1, src, 4); - memcpy(&buf2, src + n - 4, 4); - if (nullify_tail) { - memset(dst + 4, 0, 4); - memset(dst + 8, 0, 8); - } - memcpy(dst, &buf1, 4); - memcpy(dst + n - 4, &buf2, 4); - } else { - if (n != 0) { - dst[0] = src[0]; - dst[n / 2] = src[n / 2]; - dst[n - 1] = src[n - 1]; - } - if (nullify_tail) { - memset(dst + 8, 0, 8); - memset(dst + n, 0, 8); - } - } -} - -// Does non-template-specific `CordRepExternal` initialization. -// Expects `data` to be non-empty. -void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep); - -// Creates a new `CordRep` that owns `data` and `releaser` and returns a pointer -// to it, or `nullptr` if `data` was empty. -template <typename Releaser> -// NOLINTNEXTLINE - suppress clang-tidy raw pointer return. -CordRep* NewExternalRep(absl::string_view data, Releaser&& releaser) { - using ReleaserType = absl::decay_t<Releaser>; - if (data.empty()) { - // Never create empty external nodes. - InvokeReleaser(Rank0{}, ReleaserType(std::forward<Releaser>(releaser)), - data); - return nullptr; - } - - CordRepExternal* rep = new CordRepExternalImpl<ReleaserType>( - std::forward<Releaser>(releaser), 0); - InitializeCordRepExternal(data, rep); - return rep; -} - -// Overload for function reference types that dispatches using a function -// pointer because there are no `alignof()` or `sizeof()` a function reference. -// NOLINTNEXTLINE - suppress clang-tidy raw pointer return. -inline CordRep* NewExternalRep(absl::string_view data, - void (&releaser)(absl::string_view)) { - return NewExternalRep(data, &releaser); -} - -} // namespace cord_internal - -template <typename Releaser> -Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser) { - Cord cord; + // Helper for AbslHashValue(). + template <typename H> + H HashFragmented(H hash_state) const { + typename H::AbslInternalPiecewiseCombiner combiner; + ForEachChunk([&combiner, &hash_state](absl::string_view chunk) { + hash_state = combiner.add_buffer(std::move(hash_state), chunk.data(), + chunk.size()); + }); + return H::combine(combiner.finalize(std::move(hash_state)), size()); + } +}; + +ABSL_NAMESPACE_END +} // namespace absl + +namespace absl { +ABSL_NAMESPACE_BEGIN + +// allow a Cord to be logged +extern std::ostream& operator<<(std::ostream& out, const Cord& cord); + +// ------------------------------------------------------------------ +// Internal details follow. Clients should ignore. + +namespace cord_internal { + +// Fast implementation of memmove for up to 15 bytes. This implementation is +// safe for overlapping regions. If nullify_tail is true, the destination is +// padded with '\0' up to 16 bytes. +inline void SmallMemmove(char* dst, const char* src, size_t n, + bool nullify_tail = false) { + if (n >= 8) { + assert(n <= 16); + uint64_t buf1; + uint64_t buf2; + memcpy(&buf1, src, 8); + memcpy(&buf2, src + n - 8, 8); + if (nullify_tail) { + memset(dst + 8, 0, 8); + } + memcpy(dst, &buf1, 8); + memcpy(dst + n - 8, &buf2, 8); + } else if (n >= 4) { + uint32_t buf1; + uint32_t buf2; + memcpy(&buf1, src, 4); + memcpy(&buf2, src + n - 4, 4); + if (nullify_tail) { + memset(dst + 4, 0, 4); + memset(dst + 8, 0, 8); + } + memcpy(dst, &buf1, 4); + memcpy(dst + n - 4, &buf2, 4); + } else { + if (n != 0) { + dst[0] = src[0]; + dst[n / 2] = src[n / 2]; + dst[n - 1] = src[n - 1]; + } + if (nullify_tail) { + memset(dst + 8, 0, 8); + memset(dst + n, 0, 8); + } + } +} + +// Does non-template-specific `CordRepExternal` initialization. +// Expects `data` to be non-empty. +void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep); + +// Creates a new `CordRep` that owns `data` and `releaser` and returns a pointer +// to it, or `nullptr` if `data` was empty. +template <typename Releaser> +// NOLINTNEXTLINE - suppress clang-tidy raw pointer return. +CordRep* NewExternalRep(absl::string_view data, Releaser&& releaser) { + using ReleaserType = absl::decay_t<Releaser>; + if (data.empty()) { + // Never create empty external nodes. + InvokeReleaser(Rank0{}, ReleaserType(std::forward<Releaser>(releaser)), + data); + return nullptr; + } + + CordRepExternal* rep = new CordRepExternalImpl<ReleaserType>( + std::forward<Releaser>(releaser), 0); + InitializeCordRepExternal(data, rep); + return rep; +} + +// Overload for function reference types that dispatches using a function +// pointer because there are no `alignof()` or `sizeof()` a function reference. +// NOLINTNEXTLINE - suppress clang-tidy raw pointer return. +inline CordRep* NewExternalRep(absl::string_view data, + void (&releaser)(absl::string_view)) { + return NewExternalRep(data, &releaser); +} + +} // namespace cord_internal + +template <typename Releaser> +Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser) { + Cord cord; if (auto* rep = ::absl::cord_internal::NewExternalRep( data, std::forward<Releaser>(releaser))) { cord.contents_.EmplaceTree(rep, Cord::MethodIdentifier::kMakeCordFromExternal); } - return cord; -} - + return cord; +} + constexpr Cord::InlineRep::InlineRep(cord_internal::InlineData data) : data_(data) {} @@ -1030,64 +1030,64 @@ inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src) } else { data_ = src.data_; } -} - +} + inline Cord::InlineRep::InlineRep(Cord::InlineRep&& src) : data_(src.data_) { - src.ResetToEmpty(); -} - -inline Cord::InlineRep& Cord::InlineRep::operator=(const Cord::InlineRep& src) { - if (this == &src) { - return *this; - } - if (!is_tree() && !src.is_tree()) { - data_ = src.data_; - return *this; - } - AssignSlow(src); - return *this; -} - -inline Cord::InlineRep& Cord::InlineRep::operator=( - Cord::InlineRep&& src) noexcept { - if (is_tree()) { + src.ResetToEmpty(); +} + +inline Cord::InlineRep& Cord::InlineRep::operator=(const Cord::InlineRep& src) { + if (this == &src) { + return *this; + } + if (!is_tree() && !src.is_tree()) { + data_ = src.data_; + return *this; + } + AssignSlow(src); + return *this; +} + +inline Cord::InlineRep& Cord::InlineRep::operator=( + Cord::InlineRep&& src) noexcept { + if (is_tree()) { UnrefTree(); - } - data_ = src.data_; - src.ResetToEmpty(); - return *this; -} - -inline void Cord::InlineRep::Swap(Cord::InlineRep* rhs) { - if (rhs == this) { - return; - } - std::swap(data_, rhs->data_); -} - -inline const char* Cord::InlineRep::data() const { + } + data_ = src.data_; + src.ResetToEmpty(); + return *this; +} + +inline void Cord::InlineRep::Swap(Cord::InlineRep* rhs) { + if (rhs == this) { + return; + } + std::swap(data_, rhs->data_); +} + +inline const char* Cord::InlineRep::data() const { return is_tree() ? nullptr : data_.as_chars(); -} - +} + inline absl::cord_internal::CordRep* Cord::InlineRep::as_tree() const { assert(data_.is_tree()); return data_.as_tree(); } -inline absl::cord_internal::CordRep* Cord::InlineRep::tree() const { - if (is_tree()) { +inline absl::cord_internal::CordRep* Cord::InlineRep::tree() const { + if (is_tree()) { return as_tree(); - } else { - return nullptr; - } -} - + } else { + return nullptr; + } +} + inline bool Cord::InlineRep::empty() const { return data_.is_empty(); } - -inline size_t Cord::InlineRep::size() const { + +inline size_t Cord::InlineRep::size() const { return is_tree() ? as_tree()->length : inline_size(); -} - +} + inline cord_internal::CordRepFlat* Cord::InlineRep::MakeFlatWithExtraCapacity( size_t extra) { static_assert(cord_internal::kMinFlatLength >= sizeof(data_), ""); @@ -1124,12 +1124,12 @@ inline void Cord::InlineRep::SetTreeOrEmpty(CordRep* rep, assert(data_.is_tree()); if (rep) { data_.set_tree(rep); - } else { + } else { data_ = {}; - } + } scope.SetCordRep(rep); -} - +} + inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep, const CordzUpdateScope& scope, MethodIdentifier method) { @@ -1137,27 +1137,27 @@ inline void Cord::InlineRep::CommitTree(const CordRep* old_rep, CordRep* rep, SetTree(rep, scope); } else { EmplaceTree(rep, method); - } -} - -inline absl::cord_internal::CordRep* Cord::InlineRep::clear() { + } +} + +inline absl::cord_internal::CordRep* Cord::InlineRep::clear() { if (is_tree()) { CordzInfo::MaybeUntrackCord(cordz_info()); } - absl::cord_internal::CordRep* result = tree(); - ResetToEmpty(); - return result; -} - -inline void Cord::InlineRep::CopyToArray(char* dst) const { - assert(!is_tree()); + absl::cord_internal::CordRep* result = tree(); + ResetToEmpty(); + return result; +} + +inline void Cord::InlineRep::CopyToArray(char* dst) const { + assert(!is_tree()); size_t n = inline_size(); - assert(n != 0); + assert(n != 0); cord_internal::SmallMemmove(dst, data_.as_chars(), n); -} - -constexpr inline Cord::Cord() noexcept {} - +} + +constexpr inline Cord::Cord() noexcept {} + inline Cord::Cord(absl::string_view src) : Cord(src, CordzUpdateTracker::kConstructorString) {} @@ -1171,11 +1171,11 @@ constexpr Cord::Cord(strings_internal::StringConstant<T>) &cord_internal::ConstInitExternalStorage< strings_internal::StringConstant<T>>::value)) {} -inline Cord& Cord::operator=(const Cord& x) { - contents_ = x.contents_; - return *this; -} - +inline Cord& Cord::operator=(const Cord& x) { + contents_ = x.contents_; + return *this; +} + template <typename T, Cord::EnableIfString<T>> Cord& Cord::operator=(T&& src) { if (src.size() <= cord_internal::kMaxBytesToCopy) { @@ -1187,92 +1187,92 @@ Cord& Cord::operator=(T&& src) { inline Cord::Cord(const Cord& src) : contents_(src.contents_) {} -inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {} - -inline void Cord::swap(Cord& other) noexcept { - contents_.Swap(&other.contents_); -} - -inline Cord& Cord::operator=(Cord&& x) noexcept { - contents_ = std::move(x.contents_); - return *this; -} - -extern template Cord::Cord(std::string&& src); - -inline size_t Cord::size() const { - // Length is 1st field in str.rep_ - return contents_.size(); -} - -inline bool Cord::empty() const { return contents_.empty(); } - -inline size_t Cord::EstimatedMemoryUsage() const { - size_t result = sizeof(Cord); - if (const absl::cord_internal::CordRep* rep = contents_.tree()) { - result += MemoryUsageAux(rep); - } - return result; -} - -inline absl::optional<absl::string_view> Cord::TryFlat() const { - absl::cord_internal::CordRep* rep = contents_.tree(); - if (rep == nullptr) { - return absl::string_view(contents_.data(), contents_.size()); - } - absl::string_view fragment; - if (GetFlatAux(rep, &fragment)) { - return fragment; - } - return absl::nullopt; -} - -inline absl::string_view Cord::Flatten() { - absl::cord_internal::CordRep* rep = contents_.tree(); - if (rep == nullptr) { - return absl::string_view(contents_.data(), contents_.size()); - } else { - absl::string_view already_flat_contents; - if (GetFlatAux(rep, &already_flat_contents)) { - return already_flat_contents; - } - } - return FlattenSlowPath(); -} - -inline void Cord::Append(absl::string_view src) { +inline Cord::Cord(Cord&& src) noexcept : contents_(std::move(src.contents_)) {} + +inline void Cord::swap(Cord& other) noexcept { + contents_.Swap(&other.contents_); +} + +inline Cord& Cord::operator=(Cord&& x) noexcept { + contents_ = std::move(x.contents_); + return *this; +} + +extern template Cord::Cord(std::string&& src); + +inline size_t Cord::size() const { + // Length is 1st field in str.rep_ + return contents_.size(); +} + +inline bool Cord::empty() const { return contents_.empty(); } + +inline size_t Cord::EstimatedMemoryUsage() const { + size_t result = sizeof(Cord); + if (const absl::cord_internal::CordRep* rep = contents_.tree()) { + result += MemoryUsageAux(rep); + } + return result; +} + +inline absl::optional<absl::string_view> Cord::TryFlat() const { + absl::cord_internal::CordRep* rep = contents_.tree(); + if (rep == nullptr) { + return absl::string_view(contents_.data(), contents_.size()); + } + absl::string_view fragment; + if (GetFlatAux(rep, &fragment)) { + return fragment; + } + return absl::nullopt; +} + +inline absl::string_view Cord::Flatten() { + absl::cord_internal::CordRep* rep = contents_.tree(); + if (rep == nullptr) { + return absl::string_view(contents_.data(), contents_.size()); + } else { + absl::string_view already_flat_contents; + if (GetFlatAux(rep, &already_flat_contents)) { + return already_flat_contents; + } + } + return FlattenSlowPath(); +} + +inline void Cord::Append(absl::string_view src) { contents_.AppendArray(src, CordzUpdateTracker::kAppendString); -} - +} + inline void Cord::Prepend(absl::string_view src) { PrependArray(src, CordzUpdateTracker::kPrependString); } -extern template void Cord::Append(std::string&& src); -extern template void Cord::Prepend(std::string&& src); - -inline int Cord::Compare(const Cord& rhs) const { - if (!contents_.is_tree() && !rhs.contents_.is_tree()) { - return contents_.BitwiseCompare(rhs.contents_); - } - - return CompareImpl(rhs); -} - -// Does 'this' cord start/end with rhs -inline bool Cord::StartsWith(const Cord& rhs) const { - if (contents_.IsSame(rhs.contents_)) return true; - size_t rhs_size = rhs.size(); - if (size() < rhs_size) return false; - return EqualsImpl(rhs, rhs_size); -} - -inline bool Cord::StartsWith(absl::string_view rhs) const { - size_t rhs_size = rhs.size(); - if (size() < rhs_size) return false; - return EqualsImpl(rhs, rhs_size); -} - +extern template void Cord::Append(std::string&& src); +extern template void Cord::Prepend(std::string&& src); + +inline int Cord::Compare(const Cord& rhs) const { + if (!contents_.is_tree() && !rhs.contents_.is_tree()) { + return contents_.BitwiseCompare(rhs.contents_); + } + + return CompareImpl(rhs); +} + +// Does 'this' cord start/end with rhs +inline bool Cord::StartsWith(const Cord& rhs) const { + if (contents_.IsSame(rhs.contents_)) return true; + size_t rhs_size = rhs.size(); + if (size() < rhs_size) return false; + return EqualsImpl(rhs, rhs_size); +} + +inline bool Cord::StartsWith(absl::string_view rhs) const { + size_t rhs_size = rhs.size(); + if (size() < rhs_size) return false; + return EqualsImpl(rhs, rhs_size); +} + inline void Cord::ChunkIterator::InitTree(cord_internal::CordRep* tree) { if (tree->tag == cord_internal::BTREE) { current_chunk_ = btree_reader_.Init(tree->btree()); @@ -1288,16 +1288,16 @@ inline Cord::ChunkIterator::ChunkIterator(cord_internal::CordRep* tree) InitTree(tree); } -inline Cord::ChunkIterator::ChunkIterator(const Cord* cord) - : bytes_remaining_(cord->size()) { - if (cord->contents_.is_tree()) { +inline Cord::ChunkIterator::ChunkIterator(const Cord* cord) + : bytes_remaining_(cord->size()) { + if (cord->contents_.is_tree()) { InitTree(cord->contents_.as_tree()); - } else { + } else { current_chunk_ = absl::string_view(cord->contents_.data(), bytes_remaining_); - } -} - + } +} + inline Cord::ChunkIterator& Cord::ChunkIterator::AdvanceBtree() { current_chunk_ = btree_reader_.Next(); return *this; @@ -1331,191 +1331,191 @@ inline Cord::ChunkIterator& Cord::ChunkIterator::operator++() { return *this; } -inline Cord::ChunkIterator Cord::ChunkIterator::operator++(int) { - ChunkIterator tmp(*this); - operator++(); - return tmp; -} - -inline bool Cord::ChunkIterator::operator==(const ChunkIterator& other) const { - return bytes_remaining_ == other.bytes_remaining_; -} - -inline bool Cord::ChunkIterator::operator!=(const ChunkIterator& other) const { - return !(*this == other); -} - -inline Cord::ChunkIterator::reference Cord::ChunkIterator::operator*() const { - ABSL_HARDENING_ASSERT(bytes_remaining_ != 0); - return current_chunk_; -} - -inline Cord::ChunkIterator::pointer Cord::ChunkIterator::operator->() const { - ABSL_HARDENING_ASSERT(bytes_remaining_ != 0); - return ¤t_chunk_; -} - -inline void Cord::ChunkIterator::RemoveChunkPrefix(size_t n) { - assert(n < current_chunk_.size()); - current_chunk_.remove_prefix(n); - bytes_remaining_ -= n; -} - -inline void Cord::ChunkIterator::AdvanceBytes(size_t n) { +inline Cord::ChunkIterator Cord::ChunkIterator::operator++(int) { + ChunkIterator tmp(*this); + operator++(); + return tmp; +} + +inline bool Cord::ChunkIterator::operator==(const ChunkIterator& other) const { + return bytes_remaining_ == other.bytes_remaining_; +} + +inline bool Cord::ChunkIterator::operator!=(const ChunkIterator& other) const { + return !(*this == other); +} + +inline Cord::ChunkIterator::reference Cord::ChunkIterator::operator*() const { + ABSL_HARDENING_ASSERT(bytes_remaining_ != 0); + return current_chunk_; +} + +inline Cord::ChunkIterator::pointer Cord::ChunkIterator::operator->() const { + ABSL_HARDENING_ASSERT(bytes_remaining_ != 0); + return ¤t_chunk_; +} + +inline void Cord::ChunkIterator::RemoveChunkPrefix(size_t n) { + assert(n < current_chunk_.size()); + current_chunk_.remove_prefix(n); + bytes_remaining_ -= n; +} + +inline void Cord::ChunkIterator::AdvanceBytes(size_t n) { assert(bytes_remaining_ >= n); - if (ABSL_PREDICT_TRUE(n < current_chunk_.size())) { - RemoveChunkPrefix(n); - } else if (n != 0) { + if (ABSL_PREDICT_TRUE(n < current_chunk_.size())) { + RemoveChunkPrefix(n); + } else if (n != 0) { btree_reader_ ? AdvanceBytesBtree(n) : AdvanceBytesSlowPath(n); - } -} - -inline Cord::ChunkIterator Cord::chunk_begin() const { - return ChunkIterator(this); -} - -inline Cord::ChunkIterator Cord::chunk_end() const { return ChunkIterator(); } - -inline Cord::ChunkIterator Cord::ChunkRange::begin() const { - return cord_->chunk_begin(); -} - -inline Cord::ChunkIterator Cord::ChunkRange::end() const { - return cord_->chunk_end(); -} - -inline Cord::ChunkRange Cord::Chunks() const { return ChunkRange(this); } - -inline Cord::CharIterator& Cord::CharIterator::operator++() { - if (ABSL_PREDICT_TRUE(chunk_iterator_->size() > 1)) { - chunk_iterator_.RemoveChunkPrefix(1); - } else { - ++chunk_iterator_; - } - return *this; -} - -inline Cord::CharIterator Cord::CharIterator::operator++(int) { - CharIterator tmp(*this); - operator++(); - return tmp; -} - -inline bool Cord::CharIterator::operator==(const CharIterator& other) const { - return chunk_iterator_ == other.chunk_iterator_; -} - -inline bool Cord::CharIterator::operator!=(const CharIterator& other) const { - return !(*this == other); -} - -inline Cord::CharIterator::reference Cord::CharIterator::operator*() const { - return *chunk_iterator_->data(); -} - -inline Cord::CharIterator::pointer Cord::CharIterator::operator->() const { - return chunk_iterator_->data(); -} - -inline Cord Cord::AdvanceAndRead(CharIterator* it, size_t n_bytes) { - assert(it != nullptr); - return it->chunk_iterator_.AdvanceAndReadBytes(n_bytes); -} - -inline void Cord::Advance(CharIterator* it, size_t n_bytes) { - assert(it != nullptr); - it->chunk_iterator_.AdvanceBytes(n_bytes); -} - -inline absl::string_view Cord::ChunkRemaining(const CharIterator& it) { - return *it.chunk_iterator_; -} - -inline Cord::CharIterator Cord::char_begin() const { - return CharIterator(this); -} - -inline Cord::CharIterator Cord::char_end() const { return CharIterator(); } - -inline Cord::CharIterator Cord::CharRange::begin() const { - return cord_->char_begin(); -} - -inline Cord::CharIterator Cord::CharRange::end() const { - return cord_->char_end(); -} - -inline Cord::CharRange Cord::Chars() const { return CharRange(this); } - -inline void Cord::ForEachChunk( - absl::FunctionRef<void(absl::string_view)> callback) const { - absl::cord_internal::CordRep* rep = contents_.tree(); - if (rep == nullptr) { - callback(absl::string_view(contents_.data(), contents_.size())); - } else { - return ForEachChunkAux(rep, callback); - } -} - -// Nonmember Cord-to-Cord relational operarators. -inline bool operator==(const Cord& lhs, const Cord& rhs) { - if (lhs.contents_.IsSame(rhs.contents_)) return true; - size_t rhs_size = rhs.size(); - if (lhs.size() != rhs_size) return false; - return lhs.EqualsImpl(rhs, rhs_size); -} - -inline bool operator!=(const Cord& x, const Cord& y) { return !(x == y); } + } +} + +inline Cord::ChunkIterator Cord::chunk_begin() const { + return ChunkIterator(this); +} + +inline Cord::ChunkIterator Cord::chunk_end() const { return ChunkIterator(); } + +inline Cord::ChunkIterator Cord::ChunkRange::begin() const { + return cord_->chunk_begin(); +} + +inline Cord::ChunkIterator Cord::ChunkRange::end() const { + return cord_->chunk_end(); +} + +inline Cord::ChunkRange Cord::Chunks() const { return ChunkRange(this); } + +inline Cord::CharIterator& Cord::CharIterator::operator++() { + if (ABSL_PREDICT_TRUE(chunk_iterator_->size() > 1)) { + chunk_iterator_.RemoveChunkPrefix(1); + } else { + ++chunk_iterator_; + } + return *this; +} + +inline Cord::CharIterator Cord::CharIterator::operator++(int) { + CharIterator tmp(*this); + operator++(); + return tmp; +} + +inline bool Cord::CharIterator::operator==(const CharIterator& other) const { + return chunk_iterator_ == other.chunk_iterator_; +} + +inline bool Cord::CharIterator::operator!=(const CharIterator& other) const { + return !(*this == other); +} + +inline Cord::CharIterator::reference Cord::CharIterator::operator*() const { + return *chunk_iterator_->data(); +} + +inline Cord::CharIterator::pointer Cord::CharIterator::operator->() const { + return chunk_iterator_->data(); +} + +inline Cord Cord::AdvanceAndRead(CharIterator* it, size_t n_bytes) { + assert(it != nullptr); + return it->chunk_iterator_.AdvanceAndReadBytes(n_bytes); +} + +inline void Cord::Advance(CharIterator* it, size_t n_bytes) { + assert(it != nullptr); + it->chunk_iterator_.AdvanceBytes(n_bytes); +} + +inline absl::string_view Cord::ChunkRemaining(const CharIterator& it) { + return *it.chunk_iterator_; +} + +inline Cord::CharIterator Cord::char_begin() const { + return CharIterator(this); +} + +inline Cord::CharIterator Cord::char_end() const { return CharIterator(); } + +inline Cord::CharIterator Cord::CharRange::begin() const { + return cord_->char_begin(); +} + +inline Cord::CharIterator Cord::CharRange::end() const { + return cord_->char_end(); +} + +inline Cord::CharRange Cord::Chars() const { return CharRange(this); } + +inline void Cord::ForEachChunk( + absl::FunctionRef<void(absl::string_view)> callback) const { + absl::cord_internal::CordRep* rep = contents_.tree(); + if (rep == nullptr) { + callback(absl::string_view(contents_.data(), contents_.size())); + } else { + return ForEachChunkAux(rep, callback); + } +} + +// Nonmember Cord-to-Cord relational operarators. +inline bool operator==(const Cord& lhs, const Cord& rhs) { + if (lhs.contents_.IsSame(rhs.contents_)) return true; + size_t rhs_size = rhs.size(); + if (lhs.size() != rhs_size) return false; + return lhs.EqualsImpl(rhs, rhs_size); +} + +inline bool operator!=(const Cord& x, const Cord& y) { return !(x == y); } inline bool operator<(const Cord& x, const Cord& y) { return x.Compare(y) < 0; } inline bool operator>(const Cord& x, const Cord& y) { return x.Compare(y) > 0; } -inline bool operator<=(const Cord& x, const Cord& y) { - return x.Compare(y) <= 0; -} -inline bool operator>=(const Cord& x, const Cord& y) { - return x.Compare(y) >= 0; -} - -// Nonmember Cord-to-absl::string_view relational operators. -// -// Due to implicit conversions, these also enable comparisons of Cord with -// with std::string, ::string, and const char*. -inline bool operator==(const Cord& lhs, absl::string_view rhs) { - size_t lhs_size = lhs.size(); - size_t rhs_size = rhs.size(); - if (lhs_size != rhs_size) return false; - return lhs.EqualsImpl(rhs, rhs_size); -} - -inline bool operator==(absl::string_view x, const Cord& y) { return y == x; } -inline bool operator!=(const Cord& x, absl::string_view y) { return !(x == y); } -inline bool operator!=(absl::string_view x, const Cord& y) { return !(x == y); } -inline bool operator<(const Cord& x, absl::string_view y) { - return x.Compare(y) < 0; -} -inline bool operator<(absl::string_view x, const Cord& y) { - return y.Compare(x) > 0; -} -inline bool operator>(const Cord& x, absl::string_view y) { return y < x; } -inline bool operator>(absl::string_view x, const Cord& y) { return y < x; } -inline bool operator<=(const Cord& x, absl::string_view y) { return !(y < x); } -inline bool operator<=(absl::string_view x, const Cord& y) { return !(y < x); } -inline bool operator>=(const Cord& x, absl::string_view y) { return !(x < y); } -inline bool operator>=(absl::string_view x, const Cord& y) { return !(x < y); } - -// Some internals exposed to test code. -namespace strings_internal { -class CordTestAccess { - public: - static size_t FlatOverhead(); - static size_t MaxFlatLength(); - static size_t SizeofCordRepConcat(); - static size_t SizeofCordRepExternal(); - static size_t SizeofCordRepSubstring(); - static size_t FlatTagToLength(uint8_t tag); - static uint8_t LengthToTag(size_t s); -}; -} // namespace strings_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_CORD_H_ +inline bool operator<=(const Cord& x, const Cord& y) { + return x.Compare(y) <= 0; +} +inline bool operator>=(const Cord& x, const Cord& y) { + return x.Compare(y) >= 0; +} + +// Nonmember Cord-to-absl::string_view relational operators. +// +// Due to implicit conversions, these also enable comparisons of Cord with +// with std::string, ::string, and const char*. +inline bool operator==(const Cord& lhs, absl::string_view rhs) { + size_t lhs_size = lhs.size(); + size_t rhs_size = rhs.size(); + if (lhs_size != rhs_size) return false; + return lhs.EqualsImpl(rhs, rhs_size); +} + +inline bool operator==(absl::string_view x, const Cord& y) { return y == x; } +inline bool operator!=(const Cord& x, absl::string_view y) { return !(x == y); } +inline bool operator!=(absl::string_view x, const Cord& y) { return !(x == y); } +inline bool operator<(const Cord& x, absl::string_view y) { + return x.Compare(y) < 0; +} +inline bool operator<(absl::string_view x, const Cord& y) { + return y.Compare(x) > 0; +} +inline bool operator>(const Cord& x, absl::string_view y) { return y < x; } +inline bool operator>(absl::string_view x, const Cord& y) { return y < x; } +inline bool operator<=(const Cord& x, absl::string_view y) { return !(y < x); } +inline bool operator<=(absl::string_view x, const Cord& y) { return !(y < x); } +inline bool operator>=(const Cord& x, absl::string_view y) { return !(x < y); } +inline bool operator>=(absl::string_view x, const Cord& y) { return !(x < y); } + +// Some internals exposed to test code. +namespace strings_internal { +class CordTestAccess { + public: + static size_t FlatOverhead(); + static size_t MaxFlatLength(); + static size_t SizeofCordRepConcat(); + static size_t SizeofCordRepExternal(); + static size_t SizeofCordRepSubstring(); + static size_t FlatTagToLength(uint8_t tag); + static uint8_t LengthToTag(size_t s); +}; +} // namespace strings_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_CORD_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord_test_helpers.h b/contrib/restricted/abseil-cpp/absl/strings/cord_test_helpers.h index 31a1dc8980..e8832f72c1 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/cord_test_helpers.h +++ b/contrib/restricted/abseil-cpp/absl/strings/cord_test_helpers.h @@ -1,34 +1,34 @@ -// -// Copyright 2018 The Abseil Authors. -// -// 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 -// -// https://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. -// - -#ifndef ABSL_STRINGS_CORD_TEST_HELPERS_H_ -#define ABSL_STRINGS_CORD_TEST_HELPERS_H_ - +// +// Copyright 2018 The Abseil Authors. +// +// 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 +// +// https://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. +// + +#ifndef ABSL_STRINGS_CORD_TEST_HELPERS_H_ +#define ABSL_STRINGS_CORD_TEST_HELPERS_H_ + #include <cstdint> #include <iostream> #include <string> #include "absl/base/config.h" -#include "absl/strings/cord.h" +#include "absl/strings/cord.h" #include "absl/strings/internal/cord_internal.h" #include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - + +namespace absl { +ABSL_NAMESPACE_BEGIN + // Cord sizes relevant for testing enum class TestCordSize { // An empty value @@ -84,39 +84,39 @@ inline std::ostream& operator<<(std::ostream& stream, TestCordSize size) { return stream << ToString(size); } -// Creates a multi-segment Cord from an iterable container of strings. The -// resulting Cord is guaranteed to have one segment for every string in the -// container. This allows code to be unit tested with multi-segment Cord -// inputs. -// -// Example: -// -// absl::Cord c = absl::MakeFragmentedCord({"A ", "fragmented ", "Cord"}); -// EXPECT_FALSE(c.GetFlat(&unused)); -// -// The mechanism by which this Cord is created is an implementation detail. Any -// implementation that produces a multi-segment Cord may produce a flat Cord in -// the future as new optimizations are added to the Cord class. -// MakeFragmentedCord will, however, always be updated to return a multi-segment -// Cord. -template <typename Container> -Cord MakeFragmentedCord(const Container& c) { - Cord result; - for (const auto& s : c) { - auto* external = new std::string(s); - Cord tmp = absl::MakeCordFromExternal( - *external, [external](absl::string_view) { delete external; }); - tmp.Prepend(result); - result = tmp; - } - return result; -} - -inline Cord MakeFragmentedCord(std::initializer_list<absl::string_view> list) { - return MakeFragmentedCord<std::initializer_list<absl::string_view>>(list); -} - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_CORD_TEST_HELPERS_H_ +// Creates a multi-segment Cord from an iterable container of strings. The +// resulting Cord is guaranteed to have one segment for every string in the +// container. This allows code to be unit tested with multi-segment Cord +// inputs. +// +// Example: +// +// absl::Cord c = absl::MakeFragmentedCord({"A ", "fragmented ", "Cord"}); +// EXPECT_FALSE(c.GetFlat(&unused)); +// +// The mechanism by which this Cord is created is an implementation detail. Any +// implementation that produces a multi-segment Cord may produce a flat Cord in +// the future as new optimizations are added to the Cord class. +// MakeFragmentedCord will, however, always be updated to return a multi-segment +// Cord. +template <typename Container> +Cord MakeFragmentedCord(const Container& c) { + Cord result; + for (const auto& s : c) { + auto* external = new std::string(s); + Cord tmp = absl::MakeCordFromExternal( + *external, [external](absl::string_view) { delete external; }); + tmp.Prepend(result); + result = tmp; + } + return result; +} + +inline Cord MakeFragmentedCord(std::initializer_list<absl::string_view> list) { + return MakeFragmentedCord<std::initializer_list<absl::string_view>>(list); +} + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_CORD_TEST_HELPERS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/escaping.cc b/contrib/restricted/abseil-cpp/absl/strings/escaping.cc index 18b20b83fd..0c4a52f877 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/escaping.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/escaping.cc @@ -26,7 +26,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/base/internal/unaligned_access.h" #include "absl/strings/internal/char_map.h" -#include "absl/strings/internal/escaping.h" +#include "absl/strings/internal/escaping.h" #include "absl/strings/internal/resize_uninitialized.h" #include "absl/strings/internal/utf8.h" #include "absl/strings/str_cat.h" @@ -34,7 +34,7 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { // These are used for the leave_nulls_escaped argument to CUnescapeInternal(). @@ -450,7 +450,7 @@ bool Base64UnescapeInternal(const char* src_param, size_t szsrc, char* dest, // The GET_INPUT macro gets the next input character, skipping // over any whitespace, and stopping when we reach the end of the - // string or when we read any non-data character. The arguments are + // string or when we read any non-data character. The arguments are // an arbitrary identifier (used as a label for goto) and the number // of data bytes that must remain in the input to avoid aborting the // loop. @@ -473,18 +473,18 @@ bool Base64UnescapeInternal(const char* src_param, size_t szsrc, char* dest, if (dest) { // This loop consumes 4 input bytes and produces 3 output bytes // per iteration. We can't know at the start that there is enough - // data left in the string for a full iteration, so the loop may + // data left in the string for a full iteration, so the loop may // break out in the middle; if so 'state' will be set to the // number of input bytes read. while (szsrc >= 4) { // We'll start by optimistically assuming that the next four - // bytes of the string (src[0..3]) are four good data bytes + // bytes of the string (src[0..3]) are four good data bytes // (that is, no nulls, whitespace, padding chars, or illegal // chars). We need to test src[0..2] for nulls individually // before constructing temp to preserve the property that we - // never read past a null in the string (no matter how long - // szsrc claims the string is). + // never read past a null in the string (no matter how long + // szsrc claims the string is). if (!src[0] || !src[1] || !src[2] || ((temp = ((unsigned(unbase64[src[0]]) << 18) | @@ -509,7 +509,7 @@ bool Base64UnescapeInternal(const char* src_param, size_t szsrc, char* dest, temp = (temp << 6) | decode; } else { // We really did have four good data bytes, so advance four - // characters in the string. + // characters in the string. szsrc -= 4; src += 4; @@ -644,7 +644,7 @@ bool Base64UnescapeInternal(const char* src_param, size_t szsrc, char* dest, state); } - // The remainder of the string should be all whitespace, mixed with + // The remainder of the string should be all whitespace, mixed with // exactly 0 equals signs, or exactly 'expected_equals' equals // signs. (Always accepting 0 equals signs is an Abseil extension // not covered in the RFC, as is accepting dot as the pad character.) @@ -771,7 +771,7 @@ constexpr char kWebSafeBase64Chars[] = template <typename String> bool Base64UnescapeInternal(const char* src, size_t slen, String* dest, const signed char* unbase64) { - // Determine the size of the output string. Base64 encodes every 3 bytes into + // Determine the size of the output string. Base64 encodes every 3 bytes into // 4 characters. any leftover chars are added directly for good measure. // This is documented in the base64 RFC: http://tools.ietf.org/html/rfc3548 const size_t dest_len = 3 * (slen / 4) + (slen % 4); @@ -779,7 +779,7 @@ bool Base64UnescapeInternal(const char* src, size_t slen, String* dest, strings_internal::STLStringResizeUninitialized(dest, dest_len); // We are getting the destination buffer by getting the beginning of the - // string and converting it into a char *. + // string and converting it into a char *. size_t len; const bool ok = Base64UnescapeInternal(src, slen, &(*dest)[0], dest_len, unbase64, &len); @@ -796,7 +796,7 @@ bool Base64UnescapeInternal(const char* src, size_t slen, String* dest, } /* clang-format off */ -constexpr char kHexValueLenient[256] = { +constexpr char kHexValueLenient[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -812,9 +812,9 @@ constexpr char kHexValueLenient[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; - + /* clang-format on */ // This is a templated function so that T can be either a char* @@ -823,8 +823,8 @@ constexpr char kHexValueLenient[256] = { template <typename T> void HexStringToBytesInternal(const char* from, T to, ptrdiff_t num) { for (int i = 0; i < num; i++) { - to[i] = (kHexValueLenient[from[i * 2] & 0xFF] << 4) + - (kHexValueLenient[from[i * 2 + 1] & 0xFF]); + to[i] = (kHexValueLenient[from[i * 2] & 0xFF] << 4) + + (kHexValueLenient[from[i * 2 + 1] & 0xFF]); } } @@ -902,30 +902,30 @@ bool WebSafeBase64Unescape(absl::string_view src, std::string* dest) { } void Base64Escape(absl::string_view src, std::string* dest) { - strings_internal::Base64EscapeInternal( - reinterpret_cast<const unsigned char*>(src.data()), src.size(), dest, - true, strings_internal::kBase64Chars); + strings_internal::Base64EscapeInternal( + reinterpret_cast<const unsigned char*>(src.data()), src.size(), dest, + true, strings_internal::kBase64Chars); } void WebSafeBase64Escape(absl::string_view src, std::string* dest) { - strings_internal::Base64EscapeInternal( - reinterpret_cast<const unsigned char*>(src.data()), src.size(), dest, - false, kWebSafeBase64Chars); + strings_internal::Base64EscapeInternal( + reinterpret_cast<const unsigned char*>(src.data()), src.size(), dest, + false, kWebSafeBase64Chars); } std::string Base64Escape(absl::string_view src) { std::string dest; - strings_internal::Base64EscapeInternal( - reinterpret_cast<const unsigned char*>(src.data()), src.size(), &dest, - true, strings_internal::kBase64Chars); + strings_internal::Base64EscapeInternal( + reinterpret_cast<const unsigned char*>(src.data()), src.size(), &dest, + true, strings_internal::kBase64Chars); return dest; } std::string WebSafeBase64Escape(absl::string_view src) { std::string dest; - strings_internal::Base64EscapeInternal( - reinterpret_cast<const unsigned char*>(src.data()), src.size(), &dest, - false, kWebSafeBase64Chars); + strings_internal::Base64EscapeInternal( + reinterpret_cast<const unsigned char*>(src.data()), src.size(), &dest, + false, kWebSafeBase64Chars); return dest; } @@ -945,5 +945,5 @@ std::string BytesToHexString(absl::string_view from) { return result; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/escaping.h b/contrib/restricted/abseil-cpp/absl/strings/escaping.h index f5ca26c5da..e2a6b106ae 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/escaping.h +++ b/contrib/restricted/abseil-cpp/absl/strings/escaping.h @@ -33,7 +33,7 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // CUnescape() // @@ -158,7 +158,7 @@ std::string HexStringToBytes(absl::string_view from); // `2*from.size()`. std::string BytesToHexString(absl::string_view from); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_ESCAPING_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal/ya.make b/contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal/ya.make index 2c62f6421a..38fe96f8ef 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal/ya.make +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal/ya.make @@ -8,13 +8,13 @@ OWNER(g:cpp-contrib) LICENSE(Apache-2.0) -PEERDIR( +PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/raw_logging + contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait - contrib/restricted/abseil-cpp/absl/base/log_severity -) - + contrib/restricted/abseil-cpp/absl/base/log_severity +) + ADDINCL( GLOBAL contrib/restricted/abseil-cpp ) @@ -23,14 +23,14 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) SRCS( - escaping.cc + escaping.cc ostringstream.cc utf8.cc ) diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/char_map.h b/contrib/restricted/abseil-cpp/absl/strings/internal/char_map.h index 61484de0b7..9fb6fca1ad 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/char_map.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/char_map.h @@ -28,7 +28,7 @@ #include "absl/base/port.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { class Charmap { @@ -72,7 +72,7 @@ class Charmap { CharMaskForWord(x, 2), CharMaskForWord(x, 3)); } - // Containing all the chars in the C-string 's'. + // Containing all the chars in the C-string 's'. // Note that this is expensively recursive because of the C++11 constexpr // formulation. Use only in constexpr initializers. static constexpr Charmap FromString(const char* s) { @@ -150,7 +150,7 @@ constexpr Charmap GraphCharmap() { return PrintCharmap() & ~SpaceCharmap(); } constexpr Charmap PunctCharmap() { return GraphCharmap() & ~AlnumCharmap(); } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_CHAR_MAP_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.cc index ebf8c0791a..ab4de5da19 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.cc @@ -19,7 +19,7 @@ #include <string> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { namespace { @@ -158,12 +158,12 @@ const uint32_t* LargePowerOfFiveData(int i) { int LargePowerOfFiveSize(int i) { return 2 * i; } } // namespace -ABSL_DLL const uint32_t kFiveToNth[14] = { +ABSL_DLL const uint32_t kFiveToNth[14] = { 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125, }; -ABSL_DLL const uint32_t kTenToNth[10] = { +ABSL_DLL const uint32_t kTenToNth[10] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, }; @@ -208,7 +208,7 @@ int BigUnsigned<max_words>::ReadDigits(const char* begin, const char* end, ++dropped_digits; } if (begin < end && *std::prev(end) == '.') { - // If the string ends in '.', either before or after dropping zeroes, then + // If the string ends in '.', either before or after dropping zeroes, then // drop the decimal point and look for more digits to drop. dropped_digits = 0; --end; @@ -355,5 +355,5 @@ template class BigUnsigned<4>; template class BigUnsigned<84>; } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.h b/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.h index 8f702976a8..bb5350f4c8 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_bigint.h @@ -20,13 +20,13 @@ #include <iostream> #include <string> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/strings/ascii.h" #include "absl/strings/internal/charconv_parse.h" #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // The largest power that 5 that can be raised to, and still fit in a uint32_t. @@ -34,9 +34,9 @@ constexpr int kMaxSmallPowerOfFive = 13; // The largest power that 10 that can be raised to, and still fit in a uint32_t. constexpr int kMaxSmallPowerOfTen = 9; -ABSL_DLL extern const uint32_t - kFiveToNth[kMaxSmallPowerOfFive + 1]; -ABSL_DLL extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1]; +ABSL_DLL extern const uint32_t + kFiveToNth[kMaxSmallPowerOfFive + 1]; +ABSL_DLL extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1]; // Large, fixed-width unsigned integer. // @@ -66,7 +66,7 @@ class BigUnsigned { static_cast<uint32_t>(v >> 32)} {} // Constructs a BigUnsigned from the given string_view containing a decimal - // value. If the input string is not a decimal integer, constructs a 0 + // value. If the input string is not a decimal integer, constructs a 0 // instead. explicit BigUnsigned(absl::string_view sv) : size_(0), words_{} { // Check for valid input, returning a 0 otherwise. This is reasonable @@ -210,7 +210,7 @@ class BigUnsigned { return words_[index]; } - // Returns this integer as a decimal string. This is not used in the decimal- + // Returns this integer as a decimal string. This is not used in the decimal- // to-binary conversion; it is intended to aid in testing. std::string ToString() const; @@ -417,7 +417,7 @@ extern template class BigUnsigned<4>; extern template class BigUnsigned<84>; } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_CHARCONV_BIGINT_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_parse.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_parse.cc index d29acaf462..31df50d2a5 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_parse.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_parse.cc @@ -22,7 +22,7 @@ #include "absl/strings/internal/memutil.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { // ParseFloat<10> will read the first 19 significant digits of the mantissa. @@ -302,7 +302,7 @@ bool ParseInfinityOrNan(const char* begin, const char* end, switch (*begin) { case 'i': case 'I': { - // An infinity string consists of the characters "inf" or "infinity", + // An infinity string consists of the characters "inf" or "infinity", // case insensitive. if (strings_internal::memcasecmp(begin + 1, "nf", 2) != 0) { return false; @@ -326,7 +326,7 @@ bool ParseInfinityOrNan(const char* begin, const char* end, } out->type = strings_internal::FloatType::kNan; out->end = begin + 3; - // NaN is allowed to be followed by a parenthesized string, consisting of + // NaN is allowed to be followed by a parenthesized string, consisting of // only the characters [a-zA-Z0-9_]. Match that if it's present. begin += 3; if (begin < end && *begin == '(') { @@ -500,5 +500,5 @@ template ParsedFloat ParseFloat<16>(const char* begin, const char* end, chars_format format_flags); } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_parse.h b/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_parse.h index 505998b539..12d828f4c8 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_parse.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/charconv_parse.h @@ -17,11 +17,11 @@ #include <cstdint> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/strings/charconv.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // Enum indicating whether a parsed float is a number or special value. @@ -94,6 +94,6 @@ extern template ParsedFloat ParseFloat<16>(const char* begin, const char* end, absl::chars_format format_flags); } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_CHARCONV_PARSE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h index bfe5564e46..1656482024 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cord_internal.h @@ -1,38 +1,38 @@ // Copyright 2021 The Abseil Authors. -// -// 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 -// -// https://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. - -#ifndef ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_ -#define ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_ - -#include <atomic> -#include <cassert> -#include <cstddef> -#include <cstdint> -#include <type_traits> - +// +// 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 +// +// https://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. + +#ifndef ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_ +#define ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_ + +#include <atomic> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <type_traits> + #include "absl/base/config.h" #include "absl/base/internal/endian.h" -#include "absl/base/internal/invoke.h" +#include "absl/base/internal/invoke.h" #include "absl/base/optimization.h" -#include "absl/container/internal/compressed_tuple.h" -#include "absl/meta/type_traits.h" -#include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace cord_internal { - +#include "absl/container/internal/compressed_tuple.h" +#include "absl/meta/type_traits.h" +#include "absl/strings/string_view.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace cord_internal { + class CordzInfo; // Default feature enable states for cord ring buffers @@ -83,48 +83,48 @@ enum Constants { // Compact class for tracking the reference count and state flags for CordRep // instances. Data is stored in an atomic int32_t for compactness and speed. class RefcountAndFlags { - public: + public: constexpr RefcountAndFlags() : count_{kRefIncrement} {} struct Immortal {}; explicit constexpr RefcountAndFlags(Immortal) : count_(kImmortalFlag) {} struct WithCrc {}; explicit constexpr RefcountAndFlags(WithCrc) : count_(kCrcFlag | kRefIncrement) {} - + // Increments the reference count. Imposes no memory ordering. inline void Increment() { count_.fetch_add(kRefIncrement, std::memory_order_relaxed); } - - // Asserts that the current refcount is greater than 0. If the refcount is + + // Asserts that the current refcount is greater than 0. If the refcount is // greater than 1, decrements the reference count. - // - // Returns false if there are no references outstanding; true otherwise. - // Inserts barriers to ensure that state written before this method returns - // false will be visible to a thread that just observed this method returning + // + // Returns false if there are no references outstanding; true otherwise. + // Inserts barriers to ensure that state written before this method returns + // false will be visible to a thread that just observed this method returning // false. Always returns false when the immortal bit is set. - inline bool Decrement() { + inline bool Decrement() { int32_t refcount = count_.load(std::memory_order_acquire) & kRefcountMask; assert(refcount > 0 || refcount & kImmortalFlag); return refcount != kRefIncrement && (count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) & kRefcountMask) != kRefIncrement; - } - - // Same as Decrement but expect that refcount is greater than 1. - inline bool DecrementExpectHighRefcount() { + } + + // Same as Decrement but expect that refcount is greater than 1. + inline bool DecrementExpectHighRefcount() { int32_t refcount = count_.fetch_sub(kRefIncrement, std::memory_order_acq_rel) & kRefcountMask; assert(refcount > 0 || refcount & kImmortalFlag); return refcount != kRefIncrement; - } - - // Returns the current reference count using acquire semantics. + } + + // Returns the current reference count using acquire semantics. inline int32_t Get() const { return count_.load(std::memory_order_acquire) >> kNumFlags; } - + // Returns true if the referenced object carries a CRC value. bool HasCrc() const { return (count_.load(std::memory_order_relaxed) & kCrcFlag) != 0; @@ -155,12 +155,12 @@ class RefcountAndFlags { return (count_.load(std::memory_order_acquire) & kRefcountMask) == kRefIncrement; } - + bool IsImmortal() const { return (count_.load(std::memory_order_relaxed) & kImmortalFlag) != 0; } - private: + private: // We reserve the bottom bits for flags. // kImmortalBit indicates that this entity should never be collected; it is // used for the StringConstant constructor to avoid collecting immutable @@ -180,30 +180,30 @@ class RefcountAndFlags { kRefcountMask = ~kCrcFlag, }; - std::atomic<int32_t> count_; -}; - -// The overhead of a vtable is too much for Cord, so we roll our own subclasses -// using only a single byte to differentiate classes from each other - the "tag" -// byte. Define the subclasses first so we can provide downcasting helper -// functions in the base class. - -struct CordRepConcat; + std::atomic<int32_t> count_; +}; + +// The overhead of a vtable is too much for Cord, so we roll our own subclasses +// using only a single byte to differentiate classes from each other - the "tag" +// byte. Define the subclasses first so we can provide downcasting helper +// functions in the base class. + +struct CordRepConcat; struct CordRepExternal; struct CordRepFlat; -struct CordRepSubstring; +struct CordRepSubstring; class CordRepRing; class CordRepBtree; - -// Various representations that we allow -enum CordRepKind { + +// Various representations that we allow +enum CordRepKind { CONCAT = 0, SUBSTRING = 1, BTREE = 2, RING = 3, EXTERNAL = 4, - - // We have different tags for different sized flat arrays, + + // We have different tags for different sized flat arrays, // starting with FLAT, and limited to MAX_FLAT_TAG. The 225 value is based on // the current 'size to tag' encoding of 8 / 32 bytes. If a new tag is needed // in the future, then 'FLAT' and 'MAX_FLAT_TAG' should be adjusted as well @@ -211,8 +211,8 @@ enum CordRepKind { // allocation size. (32 bytes as of now). FLAT = 5, MAX_FLAT_TAG = 225 -}; - +}; + // There are various locations where we want to check if some rep is a 'plain' // data edge, i.e. an external or flat rep. By having FLAT == EXTERNAL + 1, we // can perform this check in a single branch as 'tag >= EXTERNAL' @@ -224,19 +224,19 @@ static_assert(RING == BTREE + 1, "BTREE and RING not consecutive"); static_assert(EXTERNAL == RING + 1, "BTREE and EXTERNAL not consecutive"); static_assert(FLAT == EXTERNAL + 1, "EXTERNAL and FLAT not consecutive"); -struct CordRep { +struct CordRep { CordRep() = default; constexpr CordRep(RefcountAndFlags::Immortal immortal, size_t l) : length(l), refcount(immortal), tag(EXTERNAL), storage{} {} - // The following three fields have to be less than 32 bytes since - // that is the smallest supported flat node size. - size_t length; + // The following three fields have to be less than 32 bytes since + // that is the smallest supported flat node size. + size_t length; RefcountAndFlags refcount; - // If tag < FLAT, it represents CordRepKind and indicates the type of node. - // Otherwise, the node type is CordRepFlat and the tag is the encoded size. - uint8_t tag; - + // If tag < FLAT, it represents CordRepKind and indicates the type of node. + // Otherwise, the node type is CordRepFlat and the tag is the encoded size. + uint8_t tag; + // `storage` provides two main purposes: // - the starting point for FlatCordRep.Data() [flexible-array-member] // - 3 bytes of additional storage for use by derived classes. @@ -257,12 +257,12 @@ struct CordRep { inline CordRepRing* ring(); inline const CordRepRing* ring() const; - inline CordRepConcat* concat(); - inline const CordRepConcat* concat() const; - inline CordRepSubstring* substring(); - inline const CordRepSubstring* substring() const; - inline CordRepExternal* external(); - inline const CordRepExternal* external() const; + inline CordRepConcat* concat(); + inline const CordRepConcat* concat() const; + inline CordRepSubstring* substring(); + inline const CordRepSubstring* substring() const; + inline CordRepExternal* external(); + inline const CordRepExternal* external() const; inline CordRepFlat* flat(); inline const CordRepFlat* flat() const; inline CordRepBtree* btree(); @@ -281,82 +281,82 @@ struct CordRep { // Decrements the reference count of `rep`. Destroys rep if count reaches // zero. Requires `rep` to be a non-null pointer value. static inline void Unref(CordRep* rep); -}; - -struct CordRepConcat : public CordRep { - CordRep* left; - CordRep* right; - +}; + +struct CordRepConcat : public CordRep { + CordRep* left; + CordRep* right; + uint8_t depth() const { return storage[0]; } void set_depth(uint8_t depth) { storage[0] = depth; } -}; - -struct CordRepSubstring : public CordRep { - size_t start; // Starting offset of substring in child - CordRep* child; -}; - -// Type for function pointer that will invoke the releaser function and also -// delete the `CordRepExternalImpl` corresponding to the passed in -// `CordRepExternal`. -using ExternalReleaserInvoker = void (*)(CordRepExternal*); - -// External CordReps are allocated together with a type erased releaser. The -// releaser is stored in the memory directly following the CordRepExternal. -struct CordRepExternal : public CordRep { +}; + +struct CordRepSubstring : public CordRep { + size_t start; // Starting offset of substring in child + CordRep* child; +}; + +// Type for function pointer that will invoke the releaser function and also +// delete the `CordRepExternalImpl` corresponding to the passed in +// `CordRepExternal`. +using ExternalReleaserInvoker = void (*)(CordRepExternal*); + +// External CordReps are allocated together with a type erased releaser. The +// releaser is stored in the memory directly following the CordRepExternal. +struct CordRepExternal : public CordRep { CordRepExternal() = default; explicit constexpr CordRepExternal(absl::string_view str) : CordRep(RefcountAndFlags::Immortal{}, str.size()), base(str.data()), releaser_invoker(nullptr) {} - const char* base; - // Pointer to function that knows how to call and destroy the releaser. - ExternalReleaserInvoker releaser_invoker; + const char* base; + // Pointer to function that knows how to call and destroy the releaser. + ExternalReleaserInvoker releaser_invoker; // Deletes (releases) the external rep. // Requires rep != nullptr and rep->IsExternal() static void Delete(CordRep* rep); -}; - -struct Rank1 {}; -struct Rank0 : Rank1 {}; - -template <typename Releaser, typename = ::absl::base_internal::invoke_result_t< - Releaser, absl::string_view>> -void InvokeReleaser(Rank0, Releaser&& releaser, absl::string_view data) { - ::absl::base_internal::invoke(std::forward<Releaser>(releaser), data); -} - -template <typename Releaser, - typename = ::absl::base_internal::invoke_result_t<Releaser>> -void InvokeReleaser(Rank1, Releaser&& releaser, absl::string_view) { - ::absl::base_internal::invoke(std::forward<Releaser>(releaser)); -} - -// We use CompressedTuple so that we can benefit from EBCO. -template <typename Releaser> -struct CordRepExternalImpl - : public CordRepExternal, - public ::absl::container_internal::CompressedTuple<Releaser> { - // The extra int arg is so that we can avoid interfering with copy/move - // constructors while still benefitting from perfect forwarding. - template <typename T> - CordRepExternalImpl(T&& releaser, int) - : CordRepExternalImpl::CompressedTuple(std::forward<T>(releaser)) { - this->releaser_invoker = &Release; - } - - ~CordRepExternalImpl() { - InvokeReleaser(Rank0{}, std::move(this->template get<0>()), - absl::string_view(base, length)); - } - - static void Release(CordRepExternal* rep) { - delete static_cast<CordRepExternalImpl*>(rep); - } -}; - +}; + +struct Rank1 {}; +struct Rank0 : Rank1 {}; + +template <typename Releaser, typename = ::absl::base_internal::invoke_result_t< + Releaser, absl::string_view>> +void InvokeReleaser(Rank0, Releaser&& releaser, absl::string_view data) { + ::absl::base_internal::invoke(std::forward<Releaser>(releaser), data); +} + +template <typename Releaser, + typename = ::absl::base_internal::invoke_result_t<Releaser>> +void InvokeReleaser(Rank1, Releaser&& releaser, absl::string_view) { + ::absl::base_internal::invoke(std::forward<Releaser>(releaser)); +} + +// We use CompressedTuple so that we can benefit from EBCO. +template <typename Releaser> +struct CordRepExternalImpl + : public CordRepExternal, + public ::absl::container_internal::CompressedTuple<Releaser> { + // The extra int arg is so that we can avoid interfering with copy/move + // constructors while still benefitting from perfect forwarding. + template <typename T> + CordRepExternalImpl(T&& releaser, int) + : CordRepExternalImpl::CompressedTuple(std::forward<T>(releaser)) { + this->releaser_invoker = &Release; + } + + ~CordRepExternalImpl() { + InvokeReleaser(Rank0{}, std::move(this->template get<0>()), + absl::string_view(base, length)); + } + + static void Release(CordRepExternal* rep) { + delete static_cast<CordRepExternalImpl*>(rep); + } +}; + inline void CordRepExternal::Delete(CordRep* rep) { assert(rep != nullptr && rep->IsExternal()); auto* rep_external = static_cast<CordRepExternal*>(rep); @@ -372,10 +372,10 @@ struct ConstInitExternalStorage { template <typename Str> CordRepExternal ConstInitExternalStorage<Str>::value(Str::value); -enum { - kMaxInline = 15, -}; - +enum { + kMaxInline = 15, +}; + constexpr char GetOrNull(absl::string_view data, size_t pos) { return pos < data.size() ? data[pos] : '\0'; } @@ -564,10 +564,10 @@ class InlineData { char as_chars_[kMaxInline + 1]; AsTree as_tree_; }; -}; - -static_assert(sizeof(InlineData) == kMaxInline + 1, ""); - +}; + +static_assert(sizeof(InlineData) == kMaxInline + 1, ""); + inline CordRepConcat* CordRep::concat() { assert(IsConcat()); return static_cast<CordRepConcat*>(this); @@ -613,8 +613,8 @@ inline void CordRep::Unref(CordRep* rep) { } } -} // namespace cord_internal +} // namespace cord_internal -ABSL_NAMESPACE_END -} // namespace absl -#endif // ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_ +ABSL_NAMESPACE_END +} // namespace absl +#endif // ABSL_STRINGS_INTERNAL_CORD_INTERNAL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions/ya.make b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions/ya.make index 6dc8a23cc5..69f582d096 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions/ya.make +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/cordz_functions/ya.make @@ -22,10 +22,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/strings/internal) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/escaping.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/escaping.cc index c5271286ad..73de85e483 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/escaping.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/escaping.cc @@ -1,180 +1,180 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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 "absl/strings/internal/escaping.h" - -#include "absl/base/internal/endian.h" -#include "absl/base/internal/raw_logging.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace strings_internal { - -const char kBase64Chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { - // Base64 encodes three bytes of input at a time. If the input is not - // divisible by three, we pad as appropriate. - // - // (from https://tools.ietf.org/html/rfc3548) - // Special processing is performed if fewer than 24 bits are available - // at the end of the data being encoded. A full encoding quantum is - // always completed at the end of a quantity. When fewer than 24 input - // bits are available in an input group, zero bits are added (on the - // right) to form an integral number of 6-bit groups. Padding at the - // end of the data is performed using the '=' character. Since all base - // 64 input is an integral number of octets, only the following cases - // can arise: - - // Base64 encodes each three bytes of input into four bytes of output. - size_t len = (input_len / 3) * 4; - - if (input_len % 3 == 0) { - // (from https://tools.ietf.org/html/rfc3548) - // (1) the final quantum of encoding input is an integral multiple of 24 - // bits; here, the final unit of encoded output will be an integral - // multiple of 4 characters with no "=" padding, - } else if (input_len % 3 == 1) { - // (from https://tools.ietf.org/html/rfc3548) - // (2) the final quantum of encoding input is exactly 8 bits; here, the - // final unit of encoded output will be two characters followed by two - // "=" padding characters, or - len += 2; - if (do_padding) { - len += 2; - } - } else { // (input_len % 3 == 2) - // (from https://tools.ietf.org/html/rfc3548) - // (3) the final quantum of encoding input is exactly 16 bits; here, the - // final unit of encoded output will be three characters followed by one - // "=" padding character. - len += 3; - if (do_padding) { - len += 1; - } - } - - assert(len >= input_len); // make sure we didn't overflow - return len; -} - -size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, - size_t szdest, const char* base64, - bool do_padding) { - static const char kPad64 = '='; - - if (szsrc * 4 > szdest * 3) return 0; - - char* cur_dest = dest; - const unsigned char* cur_src = src; - - char* const limit_dest = dest + szdest; - const unsigned char* const limit_src = src + szsrc; - - // Three bytes of data encodes to four characters of cyphertext. - // So we can pump through three-byte chunks atomically. - if (szsrc >= 3) { // "limit_src - 3" is UB if szsrc < 3. - while (cur_src < limit_src - 3) { // While we have >= 32 bits. - uint32_t in = absl::big_endian::Load32(cur_src) >> 8; - - cur_dest[0] = base64[in >> 18]; - in &= 0x3FFFF; - cur_dest[1] = base64[in >> 12]; - in &= 0xFFF; - cur_dest[2] = base64[in >> 6]; - in &= 0x3F; - cur_dest[3] = base64[in]; - - cur_dest += 4; - cur_src += 3; - } - } - // To save time, we didn't update szdest or szsrc in the loop. So do it now. - szdest = limit_dest - cur_dest; - szsrc = limit_src - cur_src; - - /* now deal with the tail (<=3 bytes) */ - switch (szsrc) { - case 0: - // Nothing left; nothing more to do. - break; - case 1: { - // One byte left: this encodes to two characters, and (optionally) - // two pad characters to round out the four-character cypherblock. - if (szdest < 2) return 0; - uint32_t in = cur_src[0]; - cur_dest[0] = base64[in >> 2]; - in &= 0x3; - cur_dest[1] = base64[in << 4]; - cur_dest += 2; - szdest -= 2; - if (do_padding) { - if (szdest < 2) return 0; - cur_dest[0] = kPad64; - cur_dest[1] = kPad64; - cur_dest += 2; - szdest -= 2; - } - break; - } - case 2: { - // Two bytes left: this encodes to three characters, and (optionally) - // one pad character to round out the four-character cypherblock. - if (szdest < 3) return 0; - uint32_t in = absl::big_endian::Load16(cur_src); - cur_dest[0] = base64[in >> 10]; - in &= 0x3FF; - cur_dest[1] = base64[in >> 4]; - in &= 0x00F; - cur_dest[2] = base64[in << 2]; - cur_dest += 3; - szdest -= 3; - if (do_padding) { - if (szdest < 1) return 0; - cur_dest[0] = kPad64; - cur_dest += 1; - szdest -= 1; - } - break; - } - case 3: { - // Three bytes left: same as in the big loop above. We can't do this in - // the loop because the loop above always reads 4 bytes, and the fourth - // byte is past the end of the input. - if (szdest < 4) return 0; - uint32_t in = (cur_src[0] << 16) + absl::big_endian::Load16(cur_src + 1); - cur_dest[0] = base64[in >> 18]; - in &= 0x3FFFF; - cur_dest[1] = base64[in >> 12]; - in &= 0xFFF; - cur_dest[2] = base64[in >> 6]; - in &= 0x3F; - cur_dest[3] = base64[in]; - cur_dest += 4; - szdest -= 4; - break; - } - default: - // Should not be reached: blocks of 4 bytes are handled - // in the while loop before this switch statement. - ABSL_RAW_LOG(FATAL, "Logic problem? szsrc = %zu", szsrc); - break; - } - return (cur_dest - dest); -} - -} // namespace strings_internal -ABSL_NAMESPACE_END -} // namespace absl +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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 "absl/strings/internal/escaping.h" + +#include "absl/base/internal/endian.h" +#include "absl/base/internal/raw_logging.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace strings_internal { + +const char kBase64Chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { + // Base64 encodes three bytes of input at a time. If the input is not + // divisible by three, we pad as appropriate. + // + // (from https://tools.ietf.org/html/rfc3548) + // Special processing is performed if fewer than 24 bits are available + // at the end of the data being encoded. A full encoding quantum is + // always completed at the end of a quantity. When fewer than 24 input + // bits are available in an input group, zero bits are added (on the + // right) to form an integral number of 6-bit groups. Padding at the + // end of the data is performed using the '=' character. Since all base + // 64 input is an integral number of octets, only the following cases + // can arise: + + // Base64 encodes each three bytes of input into four bytes of output. + size_t len = (input_len / 3) * 4; + + if (input_len % 3 == 0) { + // (from https://tools.ietf.org/html/rfc3548) + // (1) the final quantum of encoding input is an integral multiple of 24 + // bits; here, the final unit of encoded output will be an integral + // multiple of 4 characters with no "=" padding, + } else if (input_len % 3 == 1) { + // (from https://tools.ietf.org/html/rfc3548) + // (2) the final quantum of encoding input is exactly 8 bits; here, the + // final unit of encoded output will be two characters followed by two + // "=" padding characters, or + len += 2; + if (do_padding) { + len += 2; + } + } else { // (input_len % 3 == 2) + // (from https://tools.ietf.org/html/rfc3548) + // (3) the final quantum of encoding input is exactly 16 bits; here, the + // final unit of encoded output will be three characters followed by one + // "=" padding character. + len += 3; + if (do_padding) { + len += 1; + } + } + + assert(len >= input_len); // make sure we didn't overflow + return len; +} + +size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, + size_t szdest, const char* base64, + bool do_padding) { + static const char kPad64 = '='; + + if (szsrc * 4 > szdest * 3) return 0; + + char* cur_dest = dest; + const unsigned char* cur_src = src; + + char* const limit_dest = dest + szdest; + const unsigned char* const limit_src = src + szsrc; + + // Three bytes of data encodes to four characters of cyphertext. + // So we can pump through three-byte chunks atomically. + if (szsrc >= 3) { // "limit_src - 3" is UB if szsrc < 3. + while (cur_src < limit_src - 3) { // While we have >= 32 bits. + uint32_t in = absl::big_endian::Load32(cur_src) >> 8; + + cur_dest[0] = base64[in >> 18]; + in &= 0x3FFFF; + cur_dest[1] = base64[in >> 12]; + in &= 0xFFF; + cur_dest[2] = base64[in >> 6]; + in &= 0x3F; + cur_dest[3] = base64[in]; + + cur_dest += 4; + cur_src += 3; + } + } + // To save time, we didn't update szdest or szsrc in the loop. So do it now. + szdest = limit_dest - cur_dest; + szsrc = limit_src - cur_src; + + /* now deal with the tail (<=3 bytes) */ + switch (szsrc) { + case 0: + // Nothing left; nothing more to do. + break; + case 1: { + // One byte left: this encodes to two characters, and (optionally) + // two pad characters to round out the four-character cypherblock. + if (szdest < 2) return 0; + uint32_t in = cur_src[0]; + cur_dest[0] = base64[in >> 2]; + in &= 0x3; + cur_dest[1] = base64[in << 4]; + cur_dest += 2; + szdest -= 2; + if (do_padding) { + if (szdest < 2) return 0; + cur_dest[0] = kPad64; + cur_dest[1] = kPad64; + cur_dest += 2; + szdest -= 2; + } + break; + } + case 2: { + // Two bytes left: this encodes to three characters, and (optionally) + // one pad character to round out the four-character cypherblock. + if (szdest < 3) return 0; + uint32_t in = absl::big_endian::Load16(cur_src); + cur_dest[0] = base64[in >> 10]; + in &= 0x3FF; + cur_dest[1] = base64[in >> 4]; + in &= 0x00F; + cur_dest[2] = base64[in << 2]; + cur_dest += 3; + szdest -= 3; + if (do_padding) { + if (szdest < 1) return 0; + cur_dest[0] = kPad64; + cur_dest += 1; + szdest -= 1; + } + break; + } + case 3: { + // Three bytes left: same as in the big loop above. We can't do this in + // the loop because the loop above always reads 4 bytes, and the fourth + // byte is past the end of the input. + if (szdest < 4) return 0; + uint32_t in = (cur_src[0] << 16) + absl::big_endian::Load16(cur_src + 1); + cur_dest[0] = base64[in >> 18]; + in &= 0x3FFFF; + cur_dest[1] = base64[in >> 12]; + in &= 0xFFF; + cur_dest[2] = base64[in >> 6]; + in &= 0x3F; + cur_dest[3] = base64[in]; + cur_dest += 4; + szdest -= 4; + break; + } + default: + // Should not be reached: blocks of 4 bytes are handled + // in the while loop before this switch statement. + ABSL_RAW_LOG(FATAL, "Logic problem? szsrc = %zu", szsrc); + break; + } + return (cur_dest - dest); +} + +} // namespace strings_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/escaping.h b/contrib/restricted/abseil-cpp/absl/strings/internal/escaping.h index 6a9ce602d9..dc20940e75 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/escaping.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/escaping.h @@ -1,58 +1,58 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. - -#ifndef ABSL_STRINGS_INTERNAL_ESCAPING_H_ -#define ABSL_STRINGS_INTERNAL_ESCAPING_H_ - -#include <cassert> - -#include "absl/strings/internal/resize_uninitialized.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace strings_internal { - -ABSL_CONST_INIT extern const char kBase64Chars[]; - -// Calculates how long a string will be when it is base64 encoded given its -// length and whether or not the result should be padded. -size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding); - -// Base64-encodes `src` using the alphabet provided in `base64` and writes the -// result to `dest`. If `do_padding` is true, `dest` is padded with '=' chars -// until its length is a multiple of 3. Returns the length of `dest`. -size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, - size_t szdest, const char* base64, bool do_padding); - -// Base64-encodes `src` using the alphabet provided in `base64` and writes the -// result to `dest`. If `do_padding` is true, `dest` is padded with '=' chars -// until its length is a multiple of 3. -template <typename String> -void Base64EscapeInternal(const unsigned char* src, size_t szsrc, String* dest, - bool do_padding, const char* base64_chars) { - const size_t calc_escaped_size = - CalculateBase64EscapedLenInternal(szsrc, do_padding); - STLStringResizeUninitialized(dest, calc_escaped_size); - - const size_t escaped_len = Base64EscapeInternal( - src, szsrc, &(*dest)[0], dest->size(), base64_chars, do_padding); - assert(calc_escaped_size == escaped_len); - dest->erase(escaped_len); -} - -} // namespace strings_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_INTERNAL_ESCAPING_H_ +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. + +#ifndef ABSL_STRINGS_INTERNAL_ESCAPING_H_ +#define ABSL_STRINGS_INTERNAL_ESCAPING_H_ + +#include <cassert> + +#include "absl/strings/internal/resize_uninitialized.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace strings_internal { + +ABSL_CONST_INIT extern const char kBase64Chars[]; + +// Calculates how long a string will be when it is base64 encoded given its +// length and whether or not the result should be padded. +size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding); + +// Base64-encodes `src` using the alphabet provided in `base64` and writes the +// result to `dest`. If `do_padding` is true, `dest` is padded with '=' chars +// until its length is a multiple of 3. Returns the length of `dest`. +size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, + size_t szdest, const char* base64, bool do_padding); + +// Base64-encodes `src` using the alphabet provided in `base64` and writes the +// result to `dest`. If `do_padding` is true, `dest` is padded with '=' chars +// until its length is a multiple of 3. +template <typename String> +void Base64EscapeInternal(const unsigned char* src, size_t szsrc, String* dest, + bool do_padding, const char* base64_chars) { + const size_t calc_escaped_size = + CalculateBase64EscapedLenInternal(szsrc, do_padding); + STLStringResizeUninitialized(dest, calc_escaped_size); + + const size_t escaped_len = Base64EscapeInternal( + src, szsrc, &(*dest)[0], dest->size(), base64_chars, do_padding); + assert(calc_escaped_size == escaped_len); + dest->erase(escaped_len); +} + +} // namespace strings_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_ESCAPING_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/escaping_test_common.h b/contrib/restricted/abseil-cpp/absl/strings/internal/escaping_test_common.h index 7b18017a08..0e6fc75de7 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/escaping_test_common.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/escaping_test_common.h @@ -22,7 +22,7 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { struct base64_testcase { @@ -127,7 +127,7 @@ inline const std::array<base64_testcase, 5>& base64_strings() { } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_ESCAPING_TEST_COMMON_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/memutil.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/memutil.cc index 2519c6881e..22a33cc584 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/memutil.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/memutil.cc @@ -17,7 +17,7 @@ #include <cstdlib> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { int memcasecmp(const char* s1, const char* s2, size_t len) { @@ -108,5 +108,5 @@ const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle, } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/memutil.h b/contrib/restricted/abseil-cpp/absl/strings/internal/memutil.h index 9ad0535808..f0217db9f1 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/memutil.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/memutil.h @@ -69,7 +69,7 @@ #include "absl/strings/ascii.h" // for absl::ascii_tolower namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { inline char* memcat(char* dest, size_t destlen, const char* src, @@ -142,7 +142,7 @@ const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle, size_t neelen); } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_MEMUTIL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/numbers_test_common.h b/contrib/restricted/abseil-cpp/absl/strings/internal/numbers_test_common.h index eaa88a8897..709cc6b209 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/numbers_test_common.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/numbers_test_common.h @@ -23,10 +23,10 @@ #include <limits> #include <string> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { template <typename IntType> @@ -170,7 +170,7 @@ inline const std::array<uint64_test_case, 34>& strtouint64_test_cases() { {"0x1234", true, 16, 0x1234}, - // Base-10 string version. + // Base-10 string version. {"1234", true, 0, 1234}, {nullptr, false, 0, 0}, }}; @@ -178,7 +178,7 @@ inline const std::array<uint64_test_case, 34>& strtouint64_test_cases() { } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_NUMBERS_TEST_COMMON_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/ostringstream.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/ostringstream.cc index 05324c780c..290b3b1776 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/ostringstream.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/ostringstream.cc @@ -15,7 +15,7 @@ #include "absl/strings/internal/ostringstream.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { OStringStream::Buf::int_type OStringStream::overflow(int c) { @@ -32,5 +32,5 @@ std::streamsize OStringStream::xsputn(const char* s, std::streamsize n) { } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/ostringstream.h b/contrib/restricted/abseil-cpp/absl/strings/internal/ostringstream.h index d25d60473f..a219a0be4c 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/ostringstream.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/ostringstream.h @@ -23,7 +23,7 @@ #include "absl/base/port.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // The same as std::ostringstream but appends to a user-specified std::string, @@ -83,7 +83,7 @@ class OStringStream : private std::basic_streambuf<char>, public std::ostream { }; } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_OSTRINGSTREAM_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/pow10_helper.h b/contrib/restricted/abseil-cpp/absl/strings/internal/pow10_helper.h index c37c2c3ffe..5e124e4cac 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/pow10_helper.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/pow10_helper.h @@ -22,10 +22,10 @@ #include <vector> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // Computes the precise value of 10^exp. (I.e. the nearest representable @@ -34,7 +34,7 @@ namespace strings_internal { double Pow10(int exp); } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_POW10_HELPER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/resize_uninitialized.h b/contrib/restricted/abseil-cpp/absl/strings/internal/resize_uninitialized.h index 49859dcc7d..023a61c69b 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/resize_uninitialized.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/resize_uninitialized.h @@ -26,7 +26,7 @@ #include "absl/meta/type_traits.h" // for void_t namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // In this type trait, we look for a __resize_default_init member function, and @@ -113,7 +113,7 @@ void STLStringResizeUninitializedAmortized(string_type* s, size_t new_size) { } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/stl_type_traits.h b/contrib/restricted/abseil-cpp/absl/strings/internal/stl_type_traits.h index 6035ca45cb..20b0bee39e 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/stl_type_traits.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/stl_type_traits.h @@ -40,7 +40,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { template <typename C, template <typename...> class T> @@ -243,6 +243,6 @@ struct IsStrictlyBaseOfAndConvertibleToSTLContainer IsConvertibleToSTLContainer<C>> {}; } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STL_TYPE_TRAITS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.cc index e28a29b171..bf57d5fdc7 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.cc @@ -1,18 +1,18 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. - +// Copyright 2020 The Abseil Authors. // +// 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 +// +// https://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. + +// // POSIX spec: // http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html // @@ -26,10 +26,10 @@ #include "absl/base/port.h" #include "absl/strings/internal/str_format/float_conversion.h" -#include "absl/strings/numbers.h" +#include "absl/strings/numbers.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -61,179 +61,179 @@ struct IsSigned<absl::int128> : std::true_type {}; template <> struct IsSigned<absl::uint128> : std::false_type {}; -// Integral digit printer. -// Call one of the PrintAs* routines after construction once. -// Use with_neg_and_zero/without_neg_or_zero/is_negative to access the results. -class IntDigits { +// Integral digit printer. +// Call one of the PrintAs* routines after construction once. +// Use with_neg_and_zero/without_neg_or_zero/is_negative to access the results. +class IntDigits { public: - // Print the unsigned integer as octal. - // Supports unsigned integral types and uint128. + // Print the unsigned integer as octal. + // Supports unsigned integral types and uint128. template <typename T> - void PrintAsOct(T v) { - static_assert(!IsSigned<T>::value, ""); - char *p = storage_ + sizeof(storage_); - do { - *--p = static_cast<char>('0' + (static_cast<size_t>(v) & 7)); - v >>= 3; - } while (v); - start_ = p; - size_ = storage_ + sizeof(storage_) - p; - } - - // Print the signed or unsigned integer as decimal. - // Supports all integral types. - template <typename T> - void PrintAsDec(T v) { - static_assert(std::is_integral<T>::value, ""); - start_ = storage_; - size_ = numbers_internal::FastIntToBuffer(v, storage_) - storage_; - } - - void PrintAsDec(int128 v) { - auto u = static_cast<uint128>(v); - bool add_neg = false; - if (v < 0) { - add_neg = true; - u = uint128{} - u; + void PrintAsOct(T v) { + static_assert(!IsSigned<T>::value, ""); + char *p = storage_ + sizeof(storage_); + do { + *--p = static_cast<char>('0' + (static_cast<size_t>(v) & 7)); + v >>= 3; + } while (v); + start_ = p; + size_ = storage_ + sizeof(storage_) - p; + } + + // Print the signed or unsigned integer as decimal. + // Supports all integral types. + template <typename T> + void PrintAsDec(T v) { + static_assert(std::is_integral<T>::value, ""); + start_ = storage_; + size_ = numbers_internal::FastIntToBuffer(v, storage_) - storage_; + } + + void PrintAsDec(int128 v) { + auto u = static_cast<uint128>(v); + bool add_neg = false; + if (v < 0) { + add_neg = true; + u = uint128{} - u; } - PrintAsDec(u, add_neg); + PrintAsDec(u, add_neg); } - void PrintAsDec(uint128 v, bool add_neg = false) { - // This function can be sped up if needed. We can call FastIntToBuffer - // twice, or fix FastIntToBuffer to support uint128. - char *p = storage_ + sizeof(storage_); - do { - p -= 2; - numbers_internal::PutTwoDigits(static_cast<size_t>(v % 100), p); - v /= 100; - } while (v); - if (p[0] == '0') { - // We printed one too many hexits. - ++p; - } - if (add_neg) { - *--p = '-'; - } - size_ = storage_ + sizeof(storage_) - p; - start_ = p; + void PrintAsDec(uint128 v, bool add_neg = false) { + // This function can be sped up if needed. We can call FastIntToBuffer + // twice, or fix FastIntToBuffer to support uint128. + char *p = storage_ + sizeof(storage_); + do { + p -= 2; + numbers_internal::PutTwoDigits(static_cast<size_t>(v % 100), p); + v /= 100; + } while (v); + if (p[0] == '0') { + // We printed one too many hexits. + ++p; + } + if (add_neg) { + *--p = '-'; + } + size_ = storage_ + sizeof(storage_) - p; + start_ = p; } - // Print the unsigned integer as hex using lowercase. - // Supports unsigned integral types and uint128. + // Print the unsigned integer as hex using lowercase. + // Supports unsigned integral types and uint128. template <typename T> - void PrintAsHexLower(T v) { - static_assert(!IsSigned<T>::value, ""); - char *p = storage_ + sizeof(storage_); - - do { - p -= 2; - constexpr const char* table = numbers_internal::kHexTable; - std::memcpy(p, table + 2 * (static_cast<size_t>(v) & 0xFF), 2); - if (sizeof(T) == 1) break; - v >>= 8; - } while (v); - if (p[0] == '0') { - // We printed one too many digits. - ++p; + void PrintAsHexLower(T v) { + static_assert(!IsSigned<T>::value, ""); + char *p = storage_ + sizeof(storage_); + + do { + p -= 2; + constexpr const char* table = numbers_internal::kHexTable; + std::memcpy(p, table + 2 * (static_cast<size_t>(v) & 0xFF), 2); + if (sizeof(T) == 1) break; + v >>= 8; + } while (v); + if (p[0] == '0') { + // We printed one too many digits. + ++p; } - start_ = p; - size_ = storage_ + sizeof(storage_) - p; - } + start_ = p; + size_ = storage_ + sizeof(storage_) - p; + } - // Print the unsigned integer as hex using uppercase. - // Supports unsigned integral types and uint128. + // Print the unsigned integer as hex using uppercase. + // Supports unsigned integral types and uint128. template <typename T> - void PrintAsHexUpper(T v) { - static_assert(!IsSigned<T>::value, ""); - char *p = storage_ + sizeof(storage_); - - // kHexTable is only lowercase, so do it manually for uppercase. - do { - *--p = "0123456789ABCDEF"[static_cast<size_t>(v) & 15]; - v >>= 4; - } while (v); - start_ = p; - size_ = storage_ + sizeof(storage_) - p; + void PrintAsHexUpper(T v) { + static_assert(!IsSigned<T>::value, ""); + char *p = storage_ + sizeof(storage_); + + // kHexTable is only lowercase, so do it manually for uppercase. + do { + *--p = "0123456789ABCDEF"[static_cast<size_t>(v) & 15]; + v >>= 4; + } while (v); + start_ = p; + size_ = storage_ + sizeof(storage_) - p; } - // The printed value including the '-' sign if available. - // For inputs of value `0`, this will return "0" - string_view with_neg_and_zero() const { return {start_, size_}; } - - // The printed value not including the '-' sign. - // For inputs of value `0`, this will return "". - string_view without_neg_or_zero() const { - static_assert('-' < '0', "The check below verifies both."); - size_t advance = start_[0] <= '0' ? 1 : 0; - return {start_ + advance, size_ - advance}; + // The printed value including the '-' sign if available. + // For inputs of value `0`, this will return "0" + string_view with_neg_and_zero() const { return {start_, size_}; } + + // The printed value not including the '-' sign. + // For inputs of value `0`, this will return "". + string_view without_neg_or_zero() const { + static_assert('-' < '0', "The check below verifies both."); + size_t advance = start_[0] <= '0' ? 1 : 0; + return {start_ + advance, size_ - advance}; } - bool is_negative() const { return start_[0] == '-'; } + bool is_negative() const { return start_[0] == '-'; } - private: - const char *start_; - size_t size_; - // Max size: 128 bit value as octal -> 43 digits, plus sign char - char storage_[128 / 3 + 1 + 1]; + private: + const char *start_; + size_t size_; + // Max size: 128 bit value as octal -> 43 digits, plus sign char + char storage_[128 / 3 + 1 + 1]; }; // Note: 'o' conversions do not have a base indicator, it's just that // the '#' flag is specified to modify the precision for 'o' conversions. -string_view BaseIndicator(const IntDigits &as_digits, - const FormatConversionSpecImpl conv) { - // always show 0x for %p. - bool alt = conv.has_alt_flag() || - conv.conversion_char() == FormatConversionCharInternal::p; - bool hex = (conv.conversion_char() == FormatConversionCharInternal::x || - conv.conversion_char() == FormatConversionCharInternal::X || - conv.conversion_char() == FormatConversionCharInternal::p); +string_view BaseIndicator(const IntDigits &as_digits, + const FormatConversionSpecImpl conv) { + // always show 0x for %p. + bool alt = conv.has_alt_flag() || + conv.conversion_char() == FormatConversionCharInternal::p; + bool hex = (conv.conversion_char() == FormatConversionCharInternal::x || + conv.conversion_char() == FormatConversionCharInternal::X || + conv.conversion_char() == FormatConversionCharInternal::p); // From the POSIX description of '#' flag: // "For x or X conversion specifiers, a non-zero result shall have // 0x (or 0X) prefixed to it." - if (alt && hex && !as_digits.without_neg_or_zero().empty()) { - return conv.conversion_char() == FormatConversionCharInternal::X ? "0X" - : "0x"; + if (alt && hex && !as_digits.without_neg_or_zero().empty()) { + return conv.conversion_char() == FormatConversionCharInternal::X ? "0X" + : "0x"; } return {}; } -string_view SignColumn(bool neg, const FormatConversionSpecImpl conv) { - if (conv.conversion_char() == FormatConversionCharInternal::d || - conv.conversion_char() == FormatConversionCharInternal::i) { +string_view SignColumn(bool neg, const FormatConversionSpecImpl conv) { + if (conv.conversion_char() == FormatConversionCharInternal::d || + conv.conversion_char() == FormatConversionCharInternal::i) { if (neg) return "-"; - if (conv.has_show_pos_flag()) return "+"; - if (conv.has_sign_col_flag()) return " "; + if (conv.has_show_pos_flag()) return "+"; + if (conv.has_sign_col_flag()) return " "; } return {}; } -bool ConvertCharImpl(unsigned char v, const FormatConversionSpecImpl conv, +bool ConvertCharImpl(unsigned char v, const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { size_t fill = 0; if (conv.width() >= 0) fill = conv.width(); ReducePadding(1, &fill); - if (!conv.has_left_flag()) sink->Append(fill, ' '); + if (!conv.has_left_flag()) sink->Append(fill, ' '); sink->Append(1, v); - if (conv.has_left_flag()) sink->Append(fill, ' '); + if (conv.has_left_flag()) sink->Append(fill, ' '); return true; } -bool ConvertIntImplInnerSlow(const IntDigits &as_digits, - const FormatConversionSpecImpl conv, - FormatSinkImpl *sink) { +bool ConvertIntImplInnerSlow(const IntDigits &as_digits, + const FormatConversionSpecImpl conv, + FormatSinkImpl *sink) { // Print as a sequence of Substrings: // [left_spaces][sign][base_indicator][zeroes][formatted][right_spaces] size_t fill = 0; if (conv.width() >= 0) fill = conv.width(); - string_view formatted = as_digits.without_neg_or_zero(); + string_view formatted = as_digits.without_neg_or_zero(); ReducePadding(formatted, &fill); - string_view sign = SignColumn(as_digits.is_negative(), conv); + string_view sign = SignColumn(as_digits.is_negative(), conv); ReducePadding(sign, &fill); - string_view base_indicator = BaseIndicator(as_digits, conv); + string_view base_indicator = BaseIndicator(as_digits, conv); ReducePadding(base_indicator, &fill); int precision = conv.precision(); @@ -241,8 +241,8 @@ bool ConvertIntImplInnerSlow(const IntDigits &as_digits, if (!precision_specified) precision = 1; - if (conv.has_alt_flag() && - conv.conversion_char() == FormatConversionCharInternal::o) { + if (conv.has_alt_flag() && + conv.conversion_char() == FormatConversionCharInternal::o) { // From POSIX description of the '#' (alt) flag: // "For o conversion, it increases the precision (if necessary) to // force the first digit of the result to be zero." @@ -255,13 +255,13 @@ bool ConvertIntImplInnerSlow(const IntDigits &as_digits, size_t num_zeroes = Excess(formatted.size(), precision); ReducePadding(num_zeroes, &fill); - size_t num_left_spaces = !conv.has_left_flag() ? fill : 0; - size_t num_right_spaces = conv.has_left_flag() ? fill : 0; + size_t num_left_spaces = !conv.has_left_flag() ? fill : 0; + size_t num_right_spaces = conv.has_left_flag() ? fill : 0; // From POSIX description of the '0' (zero) flag: // "For d, i, o, u, x, and X conversion specifiers, if a precision // is specified, the '0' flag is ignored." - if (!precision_specified && conv.has_zero_flag()) { + if (!precision_specified && conv.has_zero_flag()) { num_zeroes += num_left_spaces; num_left_spaces = 0; } @@ -276,97 +276,97 @@ bool ConvertIntImplInnerSlow(const IntDigits &as_digits, } template <typename T> -bool ConvertIntArg(T v, const FormatConversionSpecImpl conv, - FormatSinkImpl *sink) { - using U = typename MakeUnsigned<T>::type; - IntDigits as_digits; - - // This odd casting is due to a bug in -Wswitch behavior in gcc49 which causes - // it to complain about a switch/case type mismatch, even though both are - // FormatConverionChar. Likely this is because at this point - // FormatConversionChar is declared, but not defined. - switch (static_cast<uint8_t>(conv.conversion_char())) { - case static_cast<uint8_t>(FormatConversionCharInternal::c): - return ConvertCharImpl(static_cast<unsigned char>(v), conv, sink); - - case static_cast<uint8_t>(FormatConversionCharInternal::o): - as_digits.PrintAsOct(static_cast<U>(v)); - break; - - case static_cast<uint8_t>(FormatConversionCharInternal::x): - as_digits.PrintAsHexLower(static_cast<U>(v)); - break; - case static_cast<uint8_t>(FormatConversionCharInternal::X): - as_digits.PrintAsHexUpper(static_cast<U>(v)); - break; - - case static_cast<uint8_t>(FormatConversionCharInternal::u): - as_digits.PrintAsDec(static_cast<U>(v)); - break; - - case static_cast<uint8_t>(FormatConversionCharInternal::d): - case static_cast<uint8_t>(FormatConversionCharInternal::i): - as_digits.PrintAsDec(v); - break; - - case static_cast<uint8_t>(FormatConversionCharInternal::a): - case static_cast<uint8_t>(FormatConversionCharInternal::e): - case static_cast<uint8_t>(FormatConversionCharInternal::f): - case static_cast<uint8_t>(FormatConversionCharInternal::g): - case static_cast<uint8_t>(FormatConversionCharInternal::A): - case static_cast<uint8_t>(FormatConversionCharInternal::E): - case static_cast<uint8_t>(FormatConversionCharInternal::F): - case static_cast<uint8_t>(FormatConversionCharInternal::G): - return ConvertFloatImpl(static_cast<double>(v), conv, sink); - - default: - ABSL_INTERNAL_ASSUME(false); +bool ConvertIntArg(T v, const FormatConversionSpecImpl conv, + FormatSinkImpl *sink) { + using U = typename MakeUnsigned<T>::type; + IntDigits as_digits; + + // This odd casting is due to a bug in -Wswitch behavior in gcc49 which causes + // it to complain about a switch/case type mismatch, even though both are + // FormatConverionChar. Likely this is because at this point + // FormatConversionChar is declared, but not defined. + switch (static_cast<uint8_t>(conv.conversion_char())) { + case static_cast<uint8_t>(FormatConversionCharInternal::c): + return ConvertCharImpl(static_cast<unsigned char>(v), conv, sink); + + case static_cast<uint8_t>(FormatConversionCharInternal::o): + as_digits.PrintAsOct(static_cast<U>(v)); + break; + + case static_cast<uint8_t>(FormatConversionCharInternal::x): + as_digits.PrintAsHexLower(static_cast<U>(v)); + break; + case static_cast<uint8_t>(FormatConversionCharInternal::X): + as_digits.PrintAsHexUpper(static_cast<U>(v)); + break; + + case static_cast<uint8_t>(FormatConversionCharInternal::u): + as_digits.PrintAsDec(static_cast<U>(v)); + break; + + case static_cast<uint8_t>(FormatConversionCharInternal::d): + case static_cast<uint8_t>(FormatConversionCharInternal::i): + as_digits.PrintAsDec(v); + break; + + case static_cast<uint8_t>(FormatConversionCharInternal::a): + case static_cast<uint8_t>(FormatConversionCharInternal::e): + case static_cast<uint8_t>(FormatConversionCharInternal::f): + case static_cast<uint8_t>(FormatConversionCharInternal::g): + case static_cast<uint8_t>(FormatConversionCharInternal::A): + case static_cast<uint8_t>(FormatConversionCharInternal::E): + case static_cast<uint8_t>(FormatConversionCharInternal::F): + case static_cast<uint8_t>(FormatConversionCharInternal::G): + return ConvertFloatImpl(static_cast<double>(v), conv, sink); + + default: + ABSL_INTERNAL_ASSUME(false); } - if (conv.is_basic()) { - sink->Append(as_digits.with_neg_and_zero()); - return true; + if (conv.is_basic()) { + sink->Append(as_digits.with_neg_and_zero()); + return true; } - return ConvertIntImplInnerSlow(as_digits, conv, sink); + return ConvertIntImplInnerSlow(as_digits, conv, sink); } template <typename T> -bool ConvertFloatArg(T v, const FormatConversionSpecImpl conv, - FormatSinkImpl *sink) { - return FormatConversionCharIsFloat(conv.conversion_char()) && - ConvertFloatImpl(v, conv, sink); +bool ConvertFloatArg(T v, const FormatConversionSpecImpl conv, + FormatSinkImpl *sink) { + return FormatConversionCharIsFloat(conv.conversion_char()) && + ConvertFloatImpl(v, conv, sink); } -inline bool ConvertStringArg(string_view v, const FormatConversionSpecImpl conv, +inline bool ConvertStringArg(string_view v, const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { - if (conv.is_basic()) { + if (conv.is_basic()) { sink->Append(v); return true; } return sink->PutPaddedString(v, conv.width(), conv.precision(), - conv.has_left_flag()); + conv.has_left_flag()); } } // namespace // ==================== Strings ==================== -StringConvertResult FormatConvertImpl(const std::string &v, - const FormatConversionSpecImpl conv, - FormatSinkImpl *sink) { +StringConvertResult FormatConvertImpl(const std::string &v, + const FormatConversionSpecImpl conv, + FormatSinkImpl *sink) { return {ConvertStringArg(v, conv, sink)}; } -StringConvertResult FormatConvertImpl(string_view v, - const FormatConversionSpecImpl conv, - FormatSinkImpl *sink) { +StringConvertResult FormatConvertImpl(string_view v, + const FormatConversionSpecImpl conv, + FormatSinkImpl *sink) { return {ConvertStringArg(v, conv, sink)}; } -ArgConvertResult<FormatConversionCharSetUnion( - FormatConversionCharSetInternal::s, FormatConversionCharSetInternal::p)> -FormatConvertImpl(const char *v, const FormatConversionSpecImpl conv, - FormatSinkImpl *sink) { - if (conv.conversion_char() == FormatConversionCharInternal::p) +ArgConvertResult<FormatConversionCharSetUnion( + FormatConversionCharSetInternal::s, FormatConversionCharSetInternal::p)> +FormatConvertImpl(const char *v, const FormatConversionSpecImpl conv, + FormatSinkImpl *sink) { + if (conv.conversion_char() == FormatConversionCharInternal::p) return {FormatConvertImpl(VoidPtr(v), conv, sink).value}; size_t len; if (v == nullptr) { @@ -374,106 +374,106 @@ FormatConvertImpl(const char *v, const FormatConversionSpecImpl conv, } else if (conv.precision() < 0) { len = std::strlen(v); } else { - // If precision is set, we look for the NUL-terminator on the valid range. + // If precision is set, we look for the NUL-terminator on the valid range. len = std::find(v, v + conv.precision(), '\0') - v; } return {ConvertStringArg(string_view(v, len), conv, sink)}; } // ==================== Raw pointers ==================== -ArgConvertResult<FormatConversionCharSetInternal::p> FormatConvertImpl( - VoidPtr v, const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { +ArgConvertResult<FormatConversionCharSetInternal::p> FormatConvertImpl( + VoidPtr v, const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { if (!v.value) { sink->Append("(nil)"); return {true}; } - IntDigits as_digits; - as_digits.PrintAsHexLower(v.value); - return {ConvertIntImplInnerSlow(as_digits, conv, sink)}; + IntDigits as_digits; + as_digits.PrintAsHexLower(v.value); + return {ConvertIntImplInnerSlow(as_digits, conv, sink)}; } // ==================== Floats ==================== -FloatingConvertResult FormatConvertImpl(float v, - const FormatConversionSpecImpl conv, +FloatingConvertResult FormatConvertImpl(float v, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertFloatArg(v, conv, sink)}; } -FloatingConvertResult FormatConvertImpl(double v, - const FormatConversionSpecImpl conv, +FloatingConvertResult FormatConvertImpl(double v, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertFloatArg(v, conv, sink)}; } FloatingConvertResult FormatConvertImpl(long double v, - const FormatConversionSpecImpl conv, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertFloatArg(v, conv, sink)}; } // ==================== Chars ==================== -IntegralConvertResult FormatConvertImpl(char v, - const FormatConversionSpecImpl conv, +IntegralConvertResult FormatConvertImpl(char v, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } IntegralConvertResult FormatConvertImpl(signed char v, - const FormatConversionSpecImpl conv, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } IntegralConvertResult FormatConvertImpl(unsigned char v, - const FormatConversionSpecImpl conv, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } // ==================== Ints ==================== IntegralConvertResult FormatConvertImpl(short v, // NOLINT - const FormatConversionSpecImpl conv, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } IntegralConvertResult FormatConvertImpl(unsigned short v, // NOLINT - const FormatConversionSpecImpl conv, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } -IntegralConvertResult FormatConvertImpl(int v, - const FormatConversionSpecImpl conv, +IntegralConvertResult FormatConvertImpl(int v, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } -IntegralConvertResult FormatConvertImpl(unsigned v, - const FormatConversionSpecImpl conv, +IntegralConvertResult FormatConvertImpl(unsigned v, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } IntegralConvertResult FormatConvertImpl(long v, // NOLINT - const FormatConversionSpecImpl conv, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } IntegralConvertResult FormatConvertImpl(unsigned long v, // NOLINT - const FormatConversionSpecImpl conv, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } IntegralConvertResult FormatConvertImpl(long long v, // NOLINT - const FormatConversionSpecImpl conv, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } IntegralConvertResult FormatConvertImpl(unsigned long long v, // NOLINT - const FormatConversionSpecImpl conv, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } IntegralConvertResult FormatConvertImpl(absl::int128 v, - const FormatConversionSpecImpl conv, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } IntegralConvertResult FormatConvertImpl(absl::uint128 v, - const FormatConversionSpecImpl conv, + const FormatConversionSpecImpl conv, FormatSinkImpl *sink) { return {ConvertIntArg(v, conv, sink)}; } @@ -484,5 +484,5 @@ ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(); } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h index 3c91be701f..fbfa00ee47 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/arg.h @@ -1,17 +1,17 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. - +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. + #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_ @@ -33,58 +33,58 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN -class Cord; +class Cord; class FormatCountCapture; class FormatSink; -template <absl::FormatConversionCharSet C> -struct FormatConvertResult; -class FormatConversionSpec; - +template <absl::FormatConversionCharSet C> +struct FormatConvertResult; +class FormatConversionSpec; + namespace str_format_internal { template <typename T, typename = void> struct HasUserDefinedConvert : std::false_type {}; template <typename T> -struct HasUserDefinedConvert<T, void_t<decltype(AbslFormatConvert( - std::declval<const T&>(), - std::declval<const FormatConversionSpec&>(), - std::declval<FormatSink*>()))>> - : std::true_type {}; - -void AbslFormatConvert(); // Stops the lexical name lookup -template <typename T> -auto FormatConvertImpl(const T& v, FormatConversionSpecImpl conv, - FormatSinkImpl* sink) - -> decltype(AbslFormatConvert(v, - std::declval<const FormatConversionSpec&>(), - std::declval<FormatSink*>())) { - using FormatConversionSpecT = - absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatConversionSpec>; - using FormatSinkT = - absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatSink>; - auto fcs = conv.Wrap<FormatConversionSpecT>(); - auto fs = sink->Wrap<FormatSinkT>(); - return AbslFormatConvert(v, fcs, &fs); -} +struct HasUserDefinedConvert<T, void_t<decltype(AbslFormatConvert( + std::declval<const T&>(), + std::declval<const FormatConversionSpec&>(), + std::declval<FormatSink*>()))>> + : std::true_type {}; +void AbslFormatConvert(); // Stops the lexical name lookup template <typename T> +auto FormatConvertImpl(const T& v, FormatConversionSpecImpl conv, + FormatSinkImpl* sink) + -> decltype(AbslFormatConvert(v, + std::declval<const FormatConversionSpec&>(), + std::declval<FormatSink*>())) { + using FormatConversionSpecT = + absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatConversionSpec>; + using FormatSinkT = + absl::enable_if_t<sizeof(const T& (*)()) != 0, FormatSink>; + auto fcs = conv.Wrap<FormatConversionSpecT>(); + auto fs = sink->Wrap<FormatSinkT>(); + return AbslFormatConvert(v, fcs, &fs); +} + +template <typename T> class StreamedWrapper; // If 'v' can be converted (in the printf sense) according to 'conv', // then convert it, appending to `sink` and return `true`. // Otherwise fail and return `false`. -// AbslFormatConvert(v, conv, sink) is intended to be found by ADL on 'v' -// as an extension mechanism. These FormatConvertImpl functions are the default -// implementations. -// The ADL search is augmented via the 'Sink*' parameter, which also -// serves as a disambiguator to reject possible unintended 'AbslFormatConvert' -// functions in the namespaces associated with 'v'. - +// AbslFormatConvert(v, conv, sink) is intended to be found by ADL on 'v' +// as an extension mechanism. These FormatConvertImpl functions are the default +// implementations. +// The ADL search is augmented via the 'Sink*' parameter, which also +// serves as a disambiguator to reject possible unintended 'AbslFormatConvert' +// functions in the namespaces associated with 'v'. + // Raw pointers. struct VoidPtr { VoidPtr() = default; @@ -95,33 +95,33 @@ struct VoidPtr { uintptr_t value; }; -template <FormatConversionCharSet C> -struct ArgConvertResult { - bool value; -}; - -template <FormatConversionCharSet C> -constexpr FormatConversionCharSet ExtractCharSet(FormatConvertResult<C>) { - return C; -} - -template <FormatConversionCharSet C> -constexpr FormatConversionCharSet ExtractCharSet(ArgConvertResult<C>) { - return C; -} - -using StringConvertResult = - ArgConvertResult<FormatConversionCharSetInternal::s>; -ArgConvertResult<FormatConversionCharSetInternal::p> FormatConvertImpl( - VoidPtr v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); - +template <FormatConversionCharSet C> +struct ArgConvertResult { + bool value; +}; + +template <FormatConversionCharSet C> +constexpr FormatConversionCharSet ExtractCharSet(FormatConvertResult<C>) { + return C; +} + +template <FormatConversionCharSet C> +constexpr FormatConversionCharSet ExtractCharSet(ArgConvertResult<C>) { + return C; +} + +using StringConvertResult = + ArgConvertResult<FormatConversionCharSetInternal::s>; +ArgConvertResult<FormatConversionCharSetInternal::p> FormatConvertImpl( + VoidPtr v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); + // Strings. -StringConvertResult FormatConvertImpl(const std::string& v, - FormatConversionSpecImpl conv, - FormatSinkImpl* sink); -StringConvertResult FormatConvertImpl(string_view v, - FormatConversionSpecImpl conv, - FormatSinkImpl* sink); +StringConvertResult FormatConvertImpl(const std::string& v, + FormatConversionSpecImpl conv, + FormatSinkImpl* sink); +StringConvertResult FormatConvertImpl(string_view v, + FormatConversionSpecImpl conv, + FormatSinkImpl* sink); #if defined(ABSL_HAVE_STD_STRING_VIEW) && !defined(ABSL_USES_STD_STRING_VIEW) inline StringConvertResult FormatConvertImpl(std::string_view v, FormatConversionSpecImpl conv, @@ -130,17 +130,17 @@ inline StringConvertResult FormatConvertImpl(std::string_view v, } #endif // ABSL_HAVE_STD_STRING_VIEW && !ABSL_USES_STD_STRING_VIEW -ArgConvertResult<FormatConversionCharSetUnion( - FormatConversionCharSetInternal::s, FormatConversionCharSetInternal::p)> -FormatConvertImpl(const char* v, const FormatConversionSpecImpl conv, - FormatSinkImpl* sink); - -template <class AbslCord, typename std::enable_if<std::is_same< - AbslCord, absl::Cord>::value>::type* = nullptr> -StringConvertResult FormatConvertImpl(const AbslCord& value, - FormatConversionSpecImpl conv, - FormatSinkImpl* sink) { - bool is_left = conv.has_left_flag(); +ArgConvertResult<FormatConversionCharSetUnion( + FormatConversionCharSetInternal::s, FormatConversionCharSetInternal::p)> +FormatConvertImpl(const char* v, const FormatConversionSpecImpl conv, + FormatSinkImpl* sink); + +template <class AbslCord, typename std::enable_if<std::is_same< + AbslCord, absl::Cord>::value>::type* = nullptr> +StringConvertResult FormatConvertImpl(const AbslCord& value, + FormatConversionSpecImpl conv, + FormatSinkImpl* sink) { + bool is_left = conv.has_left_flag(); size_t space_remaining = 0; int width = conv.width(); @@ -156,80 +156,80 @@ StringConvertResult FormatConvertImpl(const AbslCord& value, if (space_remaining > 0 && !is_left) sink->Append(space_remaining, ' '); - for (string_view piece : value.Chunks()) { - if (piece.size() > to_write) { - piece.remove_suffix(piece.size() - to_write); - to_write = 0; - } else { - to_write -= piece.size(); - } + for (string_view piece : value.Chunks()) { + if (piece.size() > to_write) { + piece.remove_suffix(piece.size() - to_write); + to_write = 0; + } else { + to_write -= piece.size(); + } sink->Append(piece); - if (to_write == 0) { - break; - } + if (to_write == 0) { + break; + } } if (space_remaining > 0 && is_left) sink->Append(space_remaining, ' '); return {true}; } -using IntegralConvertResult = ArgConvertResult<FormatConversionCharSetUnion( - FormatConversionCharSetInternal::c, - FormatConversionCharSetInternal::kNumeric, - FormatConversionCharSetInternal::kStar)>; -using FloatingConvertResult = - ArgConvertResult<FormatConversionCharSetInternal::kFloating>; +using IntegralConvertResult = ArgConvertResult<FormatConversionCharSetUnion( + FormatConversionCharSetInternal::c, + FormatConversionCharSetInternal::kNumeric, + FormatConversionCharSetInternal::kStar)>; +using FloatingConvertResult = + ArgConvertResult<FormatConversionCharSetInternal::kFloating>; // Floats. -FloatingConvertResult FormatConvertImpl(float v, FormatConversionSpecImpl conv, +FloatingConvertResult FormatConvertImpl(float v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); -FloatingConvertResult FormatConvertImpl(double v, FormatConversionSpecImpl conv, +FloatingConvertResult FormatConvertImpl(double v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); -FloatingConvertResult FormatConvertImpl(long double v, - FormatConversionSpecImpl conv, +FloatingConvertResult FormatConvertImpl(long double v, + FormatConversionSpecImpl conv, FormatSinkImpl* sink); // Chars. -IntegralConvertResult FormatConvertImpl(char v, FormatConversionSpecImpl conv, +IntegralConvertResult FormatConvertImpl(char v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); -IntegralConvertResult FormatConvertImpl(signed char v, - FormatConversionSpecImpl conv, +IntegralConvertResult FormatConvertImpl(signed char v, + FormatConversionSpecImpl conv, FormatSinkImpl* sink); -IntegralConvertResult FormatConvertImpl(unsigned char v, - FormatConversionSpecImpl conv, +IntegralConvertResult FormatConvertImpl(unsigned char v, + FormatConversionSpecImpl conv, FormatSinkImpl* sink); // Ints. IntegralConvertResult FormatConvertImpl(short v, // NOLINT - FormatConversionSpecImpl conv, + FormatConversionSpecImpl conv, FormatSinkImpl* sink); IntegralConvertResult FormatConvertImpl(unsigned short v, // NOLINT - FormatConversionSpecImpl conv, + FormatConversionSpecImpl conv, FormatSinkImpl* sink); -IntegralConvertResult FormatConvertImpl(int v, FormatConversionSpecImpl conv, +IntegralConvertResult FormatConvertImpl(int v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); -IntegralConvertResult FormatConvertImpl(unsigned v, - FormatConversionSpecImpl conv, +IntegralConvertResult FormatConvertImpl(unsigned v, + FormatConversionSpecImpl conv, FormatSinkImpl* sink); IntegralConvertResult FormatConvertImpl(long v, // NOLINT - FormatConversionSpecImpl conv, + FormatConversionSpecImpl conv, FormatSinkImpl* sink); IntegralConvertResult FormatConvertImpl(unsigned long v, // NOLINT - FormatConversionSpecImpl conv, + FormatConversionSpecImpl conv, FormatSinkImpl* sink); IntegralConvertResult FormatConvertImpl(long long v, // NOLINT - FormatConversionSpecImpl conv, + FormatConversionSpecImpl conv, FormatSinkImpl* sink); IntegralConvertResult FormatConvertImpl(unsigned long long v, // NOLINT - FormatConversionSpecImpl conv, + FormatConversionSpecImpl conv, FormatSinkImpl* sink); -IntegralConvertResult FormatConvertImpl(int128 v, FormatConversionSpecImpl conv, +IntegralConvertResult FormatConvertImpl(int128 v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); -IntegralConvertResult FormatConvertImpl(uint128 v, - FormatConversionSpecImpl conv, +IntegralConvertResult FormatConvertImpl(uint128 v, + FormatConversionSpecImpl conv, FormatSinkImpl* sink); template <typename T, enable_if_t<std::is_same<T, bool>::value, int> = 0> -IntegralConvertResult FormatConvertImpl(T v, FormatConversionSpecImpl conv, +IntegralConvertResult FormatConvertImpl(T v, FormatConversionSpecImpl conv, FormatSinkImpl* sink) { return FormatConvertImpl(static_cast<int>(v), conv, sink); } @@ -240,12 +240,12 @@ template <typename T> typename std::enable_if<std::is_enum<T>::value && !HasUserDefinedConvert<T>::value, IntegralConvertResult>::type -FormatConvertImpl(T v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); +FormatConvertImpl(T v, FormatConversionSpecImpl conv, FormatSinkImpl* sink); template <typename T> -StringConvertResult FormatConvertImpl(const StreamedWrapper<T>& v, - FormatConversionSpecImpl conv, - FormatSinkImpl* out) { +StringConvertResult FormatConvertImpl(const StreamedWrapper<T>& v, + FormatConversionSpecImpl conv, + FormatSinkImpl* out) { std::ostringstream oss; oss << v.v_; if (!oss) return {false}; @@ -256,24 +256,24 @@ StringConvertResult FormatConvertImpl(const StreamedWrapper<T>& v, // until after FormatCountCapture is fully defined. struct FormatCountCaptureHelper { template <class T = int> - static ArgConvertResult<FormatConversionCharSetInternal::n> ConvertHelper( - const FormatCountCapture& v, FormatConversionSpecImpl conv, - FormatSinkImpl* sink) { + static ArgConvertResult<FormatConversionCharSetInternal::n> ConvertHelper( + const FormatCountCapture& v, FormatConversionSpecImpl conv, + FormatSinkImpl* sink) { const absl::enable_if_t<sizeof(T) != 0, FormatCountCapture>& v2 = v; - if (conv.conversion_char() != - str_format_internal::FormatConversionCharInternal::n) { + if (conv.conversion_char() != + str_format_internal::FormatConversionCharInternal::n) { return {false}; - } + } *v2.p_ = static_cast<int>(sink->size()); return {true}; } }; template <class T = int> -ArgConvertResult<FormatConversionCharSetInternal::n> FormatConvertImpl( - const FormatCountCapture& v, FormatConversionSpecImpl conv, - FormatSinkImpl* sink) { +ArgConvertResult<FormatConversionCharSetInternal::n> FormatConvertImpl( + const FormatCountCapture& v, FormatConversionSpecImpl conv, + FormatSinkImpl* sink) { return FormatCountCaptureHelper::ConvertHelper(v, conv, sink); } @@ -282,13 +282,13 @@ ArgConvertResult<FormatConversionCharSetInternal::n> FormatConvertImpl( struct FormatArgImplFriend { template <typename Arg> static bool ToInt(Arg arg, int* out) { - // A value initialized FormatConversionSpecImpl has a `none` conv, which - // tells the dispatcher to run the `int` conversion. + // A value initialized FormatConversionSpecImpl has a `none` conv, which + // tells the dispatcher to run the `int` conversion. return arg.dispatcher_(arg.data_, {}, out); } template <typename Arg> - static bool Convert(Arg arg, FormatConversionSpecImpl conv, + static bool Convert(Arg arg, FormatConversionSpecImpl conv, FormatSinkImpl* out) { return arg.dispatcher_(arg.data_, conv, out); } @@ -299,15 +299,15 @@ struct FormatArgImplFriend { } }; -template <typename Arg> -constexpr FormatConversionCharSet ArgumentToConv() { - return absl::str_format_internal::ExtractCharSet( - decltype(str_format_internal::FormatConvertImpl( - std::declval<const Arg&>(), - std::declval<const FormatConversionSpecImpl&>(), - std::declval<FormatSinkImpl*>())){}); -} - +template <typename Arg> +constexpr FormatConversionCharSet ArgumentToConv() { + return absl::str_format_internal::ExtractCharSet( + decltype(str_format_internal::FormatConvertImpl( + std::declval<const Arg&>(), + std::declval<const FormatConversionSpecImpl&>(), + std::declval<FormatSinkImpl*>())){}); +} + // A type-erased handle to a format argument. class FormatArgImpl { private: @@ -321,7 +321,7 @@ class FormatArgImpl { char buf[kInlinedSpace]; }; - using Dispatcher = bool (*)(Data, FormatConversionSpecImpl, void* out); + using Dispatcher = bool (*)(Data, FormatConversionSpecImpl, void* out); template <typename T> struct store_by_value @@ -463,20 +463,20 @@ class FormatArgImpl { } template <typename T> - static bool Dispatch(Data arg, FormatConversionSpecImpl spec, void* out) { + static bool Dispatch(Data arg, FormatConversionSpecImpl spec, void* out) { // A `none` conv indicates that we want the `int` conversion. - if (ABSL_PREDICT_FALSE(spec.conversion_char() == - FormatConversionCharInternal::kNone)) { + if (ABSL_PREDICT_FALSE(spec.conversion_char() == + FormatConversionCharInternal::kNone)) { return ToInt<T>(arg, static_cast<int*>(out), std::is_integral<T>(), std::is_enum<T>()); } - if (ABSL_PREDICT_FALSE(!Contains(ArgumentToConv<T>(), - spec.conversion_char()))) { - return false; - } + if (ABSL_PREDICT_FALSE(!Contains(ArgumentToConv<T>(), + spec.conversion_char()))) { + return false; + } return str_format_internal::FormatConvertImpl( - Manager<T>::Value(arg), spec, - static_cast<FormatSinkImpl*>(out)) + Manager<T>::Value(arg), spec, + static_cast<FormatSinkImpl*>(out)) .value; } @@ -484,9 +484,9 @@ class FormatArgImpl { Dispatcher dispatcher_; }; -#define ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(T, E) \ - E template bool FormatArgImpl::Dispatch<T>(Data, FormatConversionSpecImpl, \ - void*) +#define ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(T, E) \ + E template bool FormatArgImpl::Dispatch<T>(Data, FormatConversionSpecImpl, \ + void*) #define ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(...) \ ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(str_format_internal::VoidPtr, \ @@ -520,7 +520,7 @@ ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(extern); } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_ARG_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc index c988ba8fd2..34742bff72 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.cc @@ -1,17 +1,17 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. - +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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 "absl/strings/internal/str_format/bind.h" #include <cerrno> @@ -20,7 +20,7 @@ #include <string> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -80,21 +80,21 @@ inline bool ArgContext::Bind(const UnboundConversion* unbound, return false; } - FormatConversionSpecImplFriend::SetWidth(width, bound); - FormatConversionSpecImplFriend::SetPrecision(precision, bound); - - if (force_left) { + FormatConversionSpecImplFriend::SetWidth(width, bound); + FormatConversionSpecImplFriend::SetPrecision(precision, bound); + + if (force_left) { FormatConversionSpecImplFriend::SetFlags(unbound->flags | Flags::kLeft, bound); - } else { - FormatConversionSpecImplFriend::SetFlags(unbound->flags, bound); - } + } else { + FormatConversionSpecImplFriend::SetFlags(unbound->flags, bound); + } } else { - FormatConversionSpecImplFriend::SetFlags(unbound->flags, bound); - FormatConversionSpecImplFriend::SetWidth(-1, bound); - FormatConversionSpecImplFriend::SetPrecision(-1, bound); + FormatConversionSpecImplFriend::SetFlags(unbound->flags, bound); + FormatConversionSpecImplFriend::SetWidth(-1, bound); + FormatConversionSpecImplFriend::SetPrecision(-1, bound); } - FormatConversionSpecImplFriend::SetConversionChar(unbound->conv, bound); + FormatConversionSpecImplFriend::SetConversionChar(unbound->conv, bound); bound->set_arg(arg); return true; } @@ -156,11 +156,11 @@ class SummarizingConverter { UntypedFormatSpecImpl spec("%d"); std::ostringstream ss; - ss << "{" << Streamable(spec, {*bound.arg()}) << ":" - << FormatConversionSpecImplFriend::FlagsToString(bound); + ss << "{" << Streamable(spec, {*bound.arg()}) << ":" + << FormatConversionSpecImplFriend::FlagsToString(bound); if (bound.width() >= 0) ss << bound.width(); if (bound.precision() >= 0) ss << "." << bound.precision(); - ss << bound.conversion_char() << "}"; + ss << bound.conversion_char() << "}"; Append(ss.str()); return true; } @@ -254,5 +254,5 @@ int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl format, } } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h index b26cff6648..3d88a6f830 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/bind.h @@ -1,17 +1,17 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. - +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. + #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_ @@ -27,13 +27,13 @@ #include "absl/types/span.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN class UntypedFormatSpec; namespace str_format_internal { -class BoundConversion : public FormatConversionSpecImpl { +class BoundConversion : public FormatConversionSpecImpl { public: const FormatArgImpl* arg() const { return arg_; } void set_arg(const FormatArgImpl* a) { arg_ = a; } @@ -74,7 +74,7 @@ class UntypedFormatSpecImpl { size_t size_; }; -template <typename T, FormatConversionCharSet...> +template <typename T, FormatConversionCharSet...> struct MakeDependent { using type = T; }; @@ -82,19 +82,19 @@ struct MakeDependent { // Implicitly convertible from `const char*`, `string_view`, and the // `ExtendedParsedFormat` type. This abstraction allows all format functions to // operate on any without providing too many overloads. -template <FormatConversionCharSet... Args> +template <FormatConversionCharSet... Args> class FormatSpecTemplate : public MakeDependent<UntypedFormatSpec, Args...>::type { using Base = typename MakeDependent<UntypedFormatSpec, Args...>::type; public: -#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER +#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER - // Honeypot overload for when the string is not constexpr. + // Honeypot overload for when the string is not constexpr. // We use the 'unavailable' attribute to give a better compiler error than // just 'method is deleted'. FormatSpecTemplate(...) // NOLINT - __attribute__((unavailable("Format string is not constexpr."))); + __attribute__((unavailable("Format string is not constexpr."))); // Honeypot overload for when the format is constexpr and invalid. // We use the 'unavailable' attribute to give a better compiler error than @@ -119,11 +119,11 @@ class FormatSpecTemplate // Good format overload. FormatSpecTemplate(const char* s) // NOLINT - __attribute__((enable_if(ValidFormatImpl<Args...>(s), "bad format trap"))) + __attribute__((enable_if(ValidFormatImpl<Args...>(s), "bad format trap"))) : Base(s) {} FormatSpecTemplate(string_view s) // NOLINT - __attribute__((enable_if(ValidFormatImpl<Args...>(s), "bad format trap"))) + __attribute__((enable_if(ValidFormatImpl<Args...>(s), "bad format trap"))) : Base(s) {} #else // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER @@ -204,14 +204,14 @@ class StreamedWrapper { private: template <typename S> - friend ArgConvertResult<FormatConversionCharSetInternal::s> FormatConvertImpl( - const StreamedWrapper<S>& v, FormatConversionSpecImpl conv, - FormatSinkImpl* out); + friend ArgConvertResult<FormatConversionCharSetInternal::s> FormatConvertImpl( + const StreamedWrapper<S>& v, FormatConversionSpecImpl conv, + FormatSinkImpl* out); const T& v_; }; } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_BIND_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/checker.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/checker.h index 2a2601eccf..bfff09965f 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/checker.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/checker.h @@ -1,34 +1,34 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. - +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. + #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_ -#include "absl/base/attributes.h" +#include "absl/base/attributes.h" #include "absl/strings/internal/str_format/arg.h" #include "absl/strings/internal/str_format/extension.h" // Compile time check support for entry points. #ifndef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER -#if ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) +#if ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) #define ABSL_INTERNAL_ENABLE_FORMAT_CHECKER 1 -#endif // ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) +#endif // ABSL_HAVE_ATTRIBUTE(enable_if) && !defined(__native_client__) #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { constexpr bool AllOf() { return true; } @@ -38,7 +38,7 @@ constexpr bool AllOf(bool b, T... t) { return b && AllOf(t...); } -#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER +#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER constexpr bool ContainsChar(const char* chars, char c) { return *chars == c || (*chars && ContainsChar(chars + 1, c)); @@ -46,14 +46,14 @@ constexpr bool ContainsChar(const char* chars, char c) { // A constexpr compatible list of Convs. struct ConvList { - const FormatConversionCharSet* array; + const FormatConversionCharSet* array; int count; // We do the bound check here to avoid having to do it on the callers. - // Returning an empty FormatConversionCharSet has the same effect as - // short circuiting because it will never match any conversion. - constexpr FormatConversionCharSet operator[](int i) const { - return i < count ? array[i] : FormatConversionCharSet{}; + // Returning an empty FormatConversionCharSet has the same effect as + // short circuiting because it will never match any conversion. + constexpr FormatConversionCharSet operator[](int i) const { + return i < count ? array[i] : FormatConversionCharSet{}; } constexpr ConvList without_front() const { @@ -64,7 +64,7 @@ struct ConvList { template <size_t count> struct ConvListT { // Make sure the array has size > 0. - FormatConversionCharSet list[count ? count : 1]; + FormatConversionCharSet list[count ? count : 1]; }; constexpr char GetChar(string_view str, size_t index) { @@ -317,7 +317,7 @@ class FormatParser { ConvList args_; }; -template <FormatConversionCharSet... C> +template <FormatConversionCharSet... C> constexpr bool ValidFormatImpl(string_view format) { return FormatParser(format, {ConvListT<sizeof...(C)>{{C...}}.list, sizeof...(C)}) @@ -327,7 +327,7 @@ constexpr bool ValidFormatImpl(string_view format) { #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.cc index 484f6ebfc1..afc0a0bb56 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.cc @@ -20,7 +20,7 @@ #include <string> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { std::string FlagsToString(Flags v) { @@ -33,43 +33,43 @@ std::string FlagsToString(Flags v) { return s; } -#define ABSL_INTERNAL_X_VAL(id) \ - constexpr absl::FormatConversionChar FormatConversionCharInternal::id; -ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, ) -#undef ABSL_INTERNAL_X_VAL -// NOLINTNEXTLINE(readability-redundant-declaration) -constexpr absl::FormatConversionChar FormatConversionCharInternal::kNone; +#define ABSL_INTERNAL_X_VAL(id) \ + constexpr absl::FormatConversionChar FormatConversionCharInternal::id; +ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, ) +#undef ABSL_INTERNAL_X_VAL +// NOLINTNEXTLINE(readability-redundant-declaration) +constexpr absl::FormatConversionChar FormatConversionCharInternal::kNone; -#define ABSL_INTERNAL_CHAR_SET_CASE(c) \ - constexpr FormatConversionCharSet FormatConversionCharSetInternal::c; -ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) -#undef ABSL_INTERNAL_CHAR_SET_CASE +#define ABSL_INTERNAL_CHAR_SET_CASE(c) \ + constexpr FormatConversionCharSet FormatConversionCharSetInternal::c; +ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) +#undef ABSL_INTERNAL_CHAR_SET_CASE -// NOLINTNEXTLINE(readability-redundant-declaration) -constexpr FormatConversionCharSet FormatConversionCharSetInternal::kStar; -// NOLINTNEXTLINE(readability-redundant-declaration) -constexpr FormatConversionCharSet FormatConversionCharSetInternal::kIntegral; -// NOLINTNEXTLINE(readability-redundant-declaration) -constexpr FormatConversionCharSet FormatConversionCharSetInternal::kFloating; -// NOLINTNEXTLINE(readability-redundant-declaration) -constexpr FormatConversionCharSet FormatConversionCharSetInternal::kNumeric; -// NOLINTNEXTLINE(readability-redundant-declaration) -constexpr FormatConversionCharSet FormatConversionCharSetInternal::kPointer; - -bool FormatSinkImpl::PutPaddedString(string_view value, int width, - int precision, bool left) { +// NOLINTNEXTLINE(readability-redundant-declaration) +constexpr FormatConversionCharSet FormatConversionCharSetInternal::kStar; +// NOLINTNEXTLINE(readability-redundant-declaration) +constexpr FormatConversionCharSet FormatConversionCharSetInternal::kIntegral; +// NOLINTNEXTLINE(readability-redundant-declaration) +constexpr FormatConversionCharSet FormatConversionCharSetInternal::kFloating; +// NOLINTNEXTLINE(readability-redundant-declaration) +constexpr FormatConversionCharSet FormatConversionCharSetInternal::kNumeric; +// NOLINTNEXTLINE(readability-redundant-declaration) +constexpr FormatConversionCharSet FormatConversionCharSetInternal::kPointer; + +bool FormatSinkImpl::PutPaddedString(string_view value, int width, + int precision, bool left) { size_t space_remaining = 0; - if (width >= 0) space_remaining = width; - size_t n = value.size(); - if (precision >= 0) n = std::min(n, static_cast<size_t>(precision)); - string_view shown(value.data(), n); + if (width >= 0) space_remaining = width; + size_t n = value.size(); + if (precision >= 0) n = std::min(n, static_cast<size_t>(precision)); + string_view shown(value.data(), n); space_remaining = Excess(shown.size(), space_remaining); - if (!left) Append(space_remaining, ' '); + if (!left) Append(space_remaining, ' '); Append(shown); - if (left) Append(space_remaining, ' '); + if (left) Append(space_remaining, ' '); return true; } } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h index 55cbb56d0a..760cda3778 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/extension.h @@ -17,23 +17,23 @@ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_ #include <limits.h> - + #include <cstddef> #include <cstring> #include <ostream> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/base/port.h" -#include "absl/meta/type_traits.h" +#include "absl/meta/type_traits.h" #include "absl/strings/internal/str_format/output.h" #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN - -enum class FormatConversionChar : uint8_t; -enum class FormatConversionCharSet : uint64_t; +ABSL_NAMESPACE_BEGIN +enum class FormatConversionChar : uint8_t; +enum class FormatConversionCharSet : uint64_t; + namespace str_format_internal { class FormatRawSinkImpl { @@ -107,7 +107,7 @@ class FormatSinkImpl { size_t size() const { return size_; } // Put 'v' to 'sink' with specified width, precision, and left flag. - bool PutPaddedString(string_view v, int width, int precision, bool left); + bool PutPaddedString(string_view v, int width, int precision, bool left); template <typename T> T Wrap() { @@ -156,9 +156,9 @@ inline std::ostream& operator<<(std::ostream& os, Flags v) { } // clang-format off -#define ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) \ +#define ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) \ /* text */ \ - X_VAL(c) X_SEP X_VAL(s) X_SEP \ + X_VAL(c) X_SEP X_VAL(s) X_SEP \ /* ints */ \ X_VAL(d) X_SEP X_VAL(i) X_SEP X_VAL(o) X_SEP \ X_VAL(u) X_SEP X_VAL(x) X_SEP X_VAL(X) X_SEP \ @@ -169,108 +169,108 @@ inline std::ostream& operator<<(std::ostream& os, Flags v) { X_VAL(n) X_SEP X_VAL(p) // clang-format on -// This type should not be referenced, it exists only to provide labels -// internally that match the values declared in FormatConversionChar in -// str_format.h. This is meant to allow internal libraries to use the same -// declared interface type as the public interface -// (absl::StrFormatConversionChar) while keeping the definition in a public -// header. -// Internal libraries should use the form -// `FormatConversionCharInternal::c`, `FormatConversionCharInternal::kNone` for -// comparisons. Use in switch statements is not recommended due to a bug in how -// gcc 4.9 -Wswitch handles declared but undefined enums. -struct FormatConversionCharInternal { - FormatConversionCharInternal() = delete; - - private: - // clang-format off - enum class Enum : uint8_t { - c, s, // text +// This type should not be referenced, it exists only to provide labels +// internally that match the values declared in FormatConversionChar in +// str_format.h. This is meant to allow internal libraries to use the same +// declared interface type as the public interface +// (absl::StrFormatConversionChar) while keeping the definition in a public +// header. +// Internal libraries should use the form +// `FormatConversionCharInternal::c`, `FormatConversionCharInternal::kNone` for +// comparisons. Use in switch statements is not recommended due to a bug in how +// gcc 4.9 -Wswitch handles declared but undefined enums. +struct FormatConversionCharInternal { + FormatConversionCharInternal() = delete; + + private: + // clang-format off + enum class Enum : uint8_t { + c, s, // text d, i, o, u, x, X, // int f, F, e, E, g, G, a, A, // float n, p, // misc - kNone + kNone }; - // clang-format on + // clang-format on public: -#define ABSL_INTERNAL_X_VAL(id) \ - static constexpr FormatConversionChar id = \ - static_cast<FormatConversionChar>(Enum::id); - ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, ) -#undef ABSL_INTERNAL_X_VAL - static constexpr FormatConversionChar kNone = - static_cast<FormatConversionChar>(Enum::kNone); -}; -// clang-format on - -inline FormatConversionChar FormatConversionCharFromChar(char c) { - switch (c) { -#define ABSL_INTERNAL_X_VAL(id) \ - case #id[0]: \ - return FormatConversionCharInternal::id; - ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, ) -#undef ABSL_INTERNAL_X_VAL +#define ABSL_INTERNAL_X_VAL(id) \ + static constexpr FormatConversionChar id = \ + static_cast<FormatConversionChar>(Enum::id); + ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, ) +#undef ABSL_INTERNAL_X_VAL + static constexpr FormatConversionChar kNone = + static_cast<FormatConversionChar>(Enum::kNone); +}; +// clang-format on + +inline FormatConversionChar FormatConversionCharFromChar(char c) { + switch (c) { +#define ABSL_INTERNAL_X_VAL(id) \ + case #id[0]: \ + return FormatConversionCharInternal::id; + ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, ) +#undef ABSL_INTERNAL_X_VAL } - return FormatConversionCharInternal::kNone; -} - -inline bool FormatConversionCharIsUpper(FormatConversionChar c) { - if (c == FormatConversionCharInternal::X || - c == FormatConversionCharInternal::F || - c == FormatConversionCharInternal::E || - c == FormatConversionCharInternal::G || - c == FormatConversionCharInternal::A) { - return true; - } else { - return false; + return FormatConversionCharInternal::kNone; +} + +inline bool FormatConversionCharIsUpper(FormatConversionChar c) { + if (c == FormatConversionCharInternal::X || + c == FormatConversionCharInternal::F || + c == FormatConversionCharInternal::E || + c == FormatConversionCharInternal::G || + c == FormatConversionCharInternal::A) { + return true; + } else { + return false; } -} - -inline bool FormatConversionCharIsFloat(FormatConversionChar c) { - if (c == FormatConversionCharInternal::a || - c == FormatConversionCharInternal::e || - c == FormatConversionCharInternal::f || - c == FormatConversionCharInternal::g || - c == FormatConversionCharInternal::A || - c == FormatConversionCharInternal::E || - c == FormatConversionCharInternal::F || - c == FormatConversionCharInternal::G) { - return true; - } else { - return false; +} + +inline bool FormatConversionCharIsFloat(FormatConversionChar c) { + if (c == FormatConversionCharInternal::a || + c == FormatConversionCharInternal::e || + c == FormatConversionCharInternal::f || + c == FormatConversionCharInternal::g || + c == FormatConversionCharInternal::A || + c == FormatConversionCharInternal::E || + c == FormatConversionCharInternal::F || + c == FormatConversionCharInternal::G) { + return true; + } else { + return false; } -} - -inline char FormatConversionCharToChar(FormatConversionChar c) { - if (c == FormatConversionCharInternal::kNone) { - return '\0'; - -#define ABSL_INTERNAL_X_VAL(e) \ - } else if (c == FormatConversionCharInternal::e) { \ - return #e[0]; -#define ABSL_INTERNAL_X_SEP - ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, - ABSL_INTERNAL_X_SEP) - } else { - return '\0'; +} + +inline char FormatConversionCharToChar(FormatConversionChar c) { + if (c == FormatConversionCharInternal::kNone) { + return '\0'; + +#define ABSL_INTERNAL_X_VAL(e) \ + } else if (c == FormatConversionCharInternal::e) { \ + return #e[0]; +#define ABSL_INTERNAL_X_SEP + ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_X_VAL, + ABSL_INTERNAL_X_SEP) + } else { + return '\0'; } -#undef ABSL_INTERNAL_X_VAL -#undef ABSL_INTERNAL_X_SEP -} +#undef ABSL_INTERNAL_X_VAL +#undef ABSL_INTERNAL_X_SEP +} -// The associated char. -inline std::ostream& operator<<(std::ostream& os, FormatConversionChar v) { - char c = FormatConversionCharToChar(v); - if (!c) c = '?'; - return os << c; -} +// The associated char. +inline std::ostream& operator<<(std::ostream& os, FormatConversionChar v) { + char c = FormatConversionCharToChar(v); + if (!c) c = '?'; + return os << c; +} -struct FormatConversionSpecImplFriend; +struct FormatConversionSpecImplFriend; -class FormatConversionSpecImpl { - public: - // Width and precison are not specified, no flags are set. +class FormatConversionSpecImpl { + public: + // Width and precison are not specified, no flags are set. bool is_basic() const { return flags_ == Flags::kBasic; } bool has_left_flag() const { return FlagsContains(flags_, Flags::kLeft); } bool has_show_pos_flag() const { @@ -282,10 +282,10 @@ class FormatConversionSpecImpl { bool has_alt_flag() const { return FlagsContains(flags_, Flags::kAlt); } bool has_zero_flag() const { return FlagsContains(flags_, Flags::kZero); } - FormatConversionChar conversion_char() const { + FormatConversionChar conversion_char() const { // Keep this field first in the struct . It generates better code when // accessing it when ConversionSpec is passed by value in registers. - static_assert(offsetof(FormatConversionSpecImpl, conv_) == 0, ""); + static_assert(offsetof(FormatConversionSpecImpl, conv_) == 0, ""); return conv_; } @@ -296,96 +296,96 @@ class FormatConversionSpecImpl { // negative value. int precision() const { return precision_; } - template <typename T> - T Wrap() { - return T(*this); - } + template <typename T> + T Wrap() { + return T(*this); + } private: - friend struct str_format_internal::FormatConversionSpecImplFriend; - FormatConversionChar conv_ = FormatConversionCharInternal::kNone; + friend struct str_format_internal::FormatConversionSpecImplFriend; + FormatConversionChar conv_ = FormatConversionCharInternal::kNone; Flags flags_; int width_; int precision_; }; -struct FormatConversionSpecImplFriend final { - static void SetFlags(Flags f, FormatConversionSpecImpl* conv) { - conv->flags_ = f; - } - static void SetConversionChar(FormatConversionChar c, - FormatConversionSpecImpl* conv) { - conv->conv_ = c; - } - static void SetWidth(int w, FormatConversionSpecImpl* conv) { - conv->width_ = w; - } - static void SetPrecision(int p, FormatConversionSpecImpl* conv) { - conv->precision_ = p; - } - static std::string FlagsToString(const FormatConversionSpecImpl& spec) { +struct FormatConversionSpecImplFriend final { + static void SetFlags(Flags f, FormatConversionSpecImpl* conv) { + conv->flags_ = f; + } + static void SetConversionChar(FormatConversionChar c, + FormatConversionSpecImpl* conv) { + conv->conv_ = c; + } + static void SetWidth(int w, FormatConversionSpecImpl* conv) { + conv->width_ = w; + } + static void SetPrecision(int p, FormatConversionSpecImpl* conv) { + conv->precision_ = p; + } + static std::string FlagsToString(const FormatConversionSpecImpl& spec) { return str_format_internal::FlagsToString(spec.flags_); - } -}; - -// Type safe OR operator. -// We need this for two reasons: -// 1. operator| on enums makes them decay to integers and the result is an -// integer. We need the result to stay as an enum. -// 2. We use "enum class" which would not work even if we accepted the decay. -constexpr FormatConversionCharSet FormatConversionCharSetUnion( - FormatConversionCharSet a) { - return a; -} - -template <typename... CharSet> -constexpr FormatConversionCharSet FormatConversionCharSetUnion( - FormatConversionCharSet a, CharSet... rest) { - return static_cast<FormatConversionCharSet>( - static_cast<uint64_t>(a) | - static_cast<uint64_t>(FormatConversionCharSetUnion(rest...))); -} - -constexpr uint64_t FormatConversionCharToConvInt(FormatConversionChar c) { - return uint64_t{1} << (1 + static_cast<uint8_t>(c)); -} - -constexpr uint64_t FormatConversionCharToConvInt(char conv) { + } +}; + +// Type safe OR operator. +// We need this for two reasons: +// 1. operator| on enums makes them decay to integers and the result is an +// integer. We need the result to stay as an enum. +// 2. We use "enum class" which would not work even if we accepted the decay. +constexpr FormatConversionCharSet FormatConversionCharSetUnion( + FormatConversionCharSet a) { + return a; +} + +template <typename... CharSet> +constexpr FormatConversionCharSet FormatConversionCharSetUnion( + FormatConversionCharSet a, CharSet... rest) { + return static_cast<FormatConversionCharSet>( + static_cast<uint64_t>(a) | + static_cast<uint64_t>(FormatConversionCharSetUnion(rest...))); +} + +constexpr uint64_t FormatConversionCharToConvInt(FormatConversionChar c) { + return uint64_t{1} << (1 + static_cast<uint8_t>(c)); +} + +constexpr uint64_t FormatConversionCharToConvInt(char conv) { return -#define ABSL_INTERNAL_CHAR_SET_CASE(c) \ - conv == #c[0] \ - ? FormatConversionCharToConvInt(FormatConversionCharInternal::c) \ - : - ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) -#undef ABSL_INTERNAL_CHAR_SET_CASE +#define ABSL_INTERNAL_CHAR_SET_CASE(c) \ + conv == #c[0] \ + ? FormatConversionCharToConvInt(FormatConversionCharInternal::c) \ + : + ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) +#undef ABSL_INTERNAL_CHAR_SET_CASE conv == '*' ? 1 : 0; } -constexpr FormatConversionCharSet FormatConversionCharToConvValue(char conv) { - return static_cast<FormatConversionCharSet>( - FormatConversionCharToConvInt(conv)); -} - -struct FormatConversionCharSetInternal { -#define ABSL_INTERNAL_CHAR_SET_CASE(c) \ - static constexpr FormatConversionCharSet c = \ - FormatConversionCharToConvValue(#c[0]); - ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) -#undef ABSL_INTERNAL_CHAR_SET_CASE - +constexpr FormatConversionCharSet FormatConversionCharToConvValue(char conv) { + return static_cast<FormatConversionCharSet>( + FormatConversionCharToConvInt(conv)); +} + +struct FormatConversionCharSetInternal { +#define ABSL_INTERNAL_CHAR_SET_CASE(c) \ + static constexpr FormatConversionCharSet c = \ + FormatConversionCharToConvValue(#c[0]); + ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, ) +#undef ABSL_INTERNAL_CHAR_SET_CASE + // Used for width/precision '*' specification. - static constexpr FormatConversionCharSet kStar = - FormatConversionCharToConvValue('*'); - - static constexpr FormatConversionCharSet kIntegral = - FormatConversionCharSetUnion(d, i, u, o, x, X); - static constexpr FormatConversionCharSet kFloating = - FormatConversionCharSetUnion(a, e, f, g, A, E, F, G); - static constexpr FormatConversionCharSet kNumeric = - FormatConversionCharSetUnion(kIntegral, kFloating); - static constexpr FormatConversionCharSet kPointer = p; + static constexpr FormatConversionCharSet kStar = + FormatConversionCharToConvValue('*'); + + static constexpr FormatConversionCharSet kIntegral = + FormatConversionCharSetUnion(d, i, u, o, x, X); + static constexpr FormatConversionCharSet kFloating = + FormatConversionCharSetUnion(a, e, f, g, A, E, F, G); + static constexpr FormatConversionCharSet kNumeric = + FormatConversionCharSetUnion(kIntegral, kFloating); + static constexpr FormatConversionCharSet kPointer = p; }; // Type safe OR operator. @@ -393,44 +393,44 @@ struct FormatConversionCharSetInternal { // 1. operator| on enums makes them decay to integers and the result is an // integer. We need the result to stay as an enum. // 2. We use "enum class" which would not work even if we accepted the decay. -constexpr FormatConversionCharSet operator|(FormatConversionCharSet a, - FormatConversionCharSet b) { - return FormatConversionCharSetUnion(a, b); +constexpr FormatConversionCharSet operator|(FormatConversionCharSet a, + FormatConversionCharSet b) { + return FormatConversionCharSetUnion(a, b); } -// Overloaded conversion functions to support absl::ParsedFormat. +// Overloaded conversion functions to support absl::ParsedFormat. // Get a conversion with a single character in it. -constexpr FormatConversionCharSet ToFormatConversionCharSet(char c) { - return static_cast<FormatConversionCharSet>( - FormatConversionCharToConvValue(c)); +constexpr FormatConversionCharSet ToFormatConversionCharSet(char c) { + return static_cast<FormatConversionCharSet>( + FormatConversionCharToConvValue(c)); } -// Get a conversion with a single character in it. -constexpr FormatConversionCharSet ToFormatConversionCharSet( - FormatConversionCharSet c) { - return c; -} - -template <typename T> -void ToFormatConversionCharSet(T) = delete; - +// Get a conversion with a single character in it. +constexpr FormatConversionCharSet ToFormatConversionCharSet( + FormatConversionCharSet c) { + return c; +} + +template <typename T> +void ToFormatConversionCharSet(T) = delete; + // Checks whether `c` exists in `set`. -constexpr bool Contains(FormatConversionCharSet set, char c) { - return (static_cast<uint64_t>(set) & - static_cast<uint64_t>(FormatConversionCharToConvValue(c))) != 0; +constexpr bool Contains(FormatConversionCharSet set, char c) { + return (static_cast<uint64_t>(set) & + static_cast<uint64_t>(FormatConversionCharToConvValue(c))) != 0; } // Checks whether all the characters in `c` are contained in `set` -constexpr bool Contains(FormatConversionCharSet set, - FormatConversionCharSet c) { +constexpr bool Contains(FormatConversionCharSet set, + FormatConversionCharSet c) { return (static_cast<uint64_t>(set) & static_cast<uint64_t>(c)) == static_cast<uint64_t>(c); } -// Checks whether all the characters in `c` are contained in `set` -constexpr bool Contains(FormatConversionCharSet set, FormatConversionChar c) { - return (static_cast<uint64_t>(set) & FormatConversionCharToConvInt(c)) != 0; -} +// Checks whether all the characters in `c` are contained in `set` +constexpr bool Contains(FormatConversionCharSet set, FormatConversionChar c) { + return (static_cast<uint64_t>(set) & FormatConversionCharToConvInt(c)) != 0; +} // Return capacity - used, clipped to a minimum of 0. inline size_t Excess(size_t used, size_t capacity) { @@ -439,7 +439,7 @@ inline size_t Excess(size_t used, size_t capacity) { } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc index b1c4068475..1d151dd9bf 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc @@ -1,944 +1,944 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. - +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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 "absl/strings/internal/str_format/float_conversion.h" #include <string.h> - + #include <algorithm> #include <cassert> #include <cmath> -#include <limits> +#include <limits> #include <string> -#include "absl/base/attributes.h" +#include "absl/base/attributes.h" #include "absl/base/config.h" -#include "absl/base/optimization.h" -#include "absl/functional/function_ref.h" -#include "absl/meta/type_traits.h" +#include "absl/base/optimization.h" +#include "absl/functional/function_ref.h" +#include "absl/meta/type_traits.h" #include "absl/numeric/bits.h" -#include "absl/numeric/int128.h" +#include "absl/numeric/int128.h" #include "absl/numeric/internal/representation.h" -#include "absl/strings/numbers.h" -#include "absl/types/optional.h" -#include "absl/types/span.h" +#include "absl/strings/numbers.h" +#include "absl/types/optional.h" +#include "absl/types/span.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { using ::absl::numeric_internal::IsDoubleDouble; -// The code below wants to avoid heap allocations. -// To do so it needs to allocate memory on the stack. -// `StackArray` will allocate memory on the stack in the form of a uint32_t -// array and call the provided callback with said memory. -// It will allocate memory in increments of 512 bytes. We could allocate the -// largest needed unconditionally, but that is more than we need in most of -// cases. This way we use less stack in the common cases. -class StackArray { - using Func = absl::FunctionRef<void(absl::Span<uint32_t>)>; - static constexpr size_t kStep = 512 / sizeof(uint32_t); - // 5 steps is 2560 bytes, which is enough to hold a long double with the - // largest/smallest exponents. - // The operations below will static_assert their particular maximum. - static constexpr size_t kNumSteps = 5; - - // We do not want this function to be inlined. - // Otherwise the caller will allocate the stack space unnecessarily for all - // the variants even though it only calls one. - template <size_t steps> - ABSL_ATTRIBUTE_NOINLINE static void RunWithCapacityImpl(Func f) { - uint32_t values[steps * kStep]{}; - f(absl::MakeSpan(values)); - } - - public: - static constexpr size_t kMaxCapacity = kStep * kNumSteps; - - static void RunWithCapacity(size_t capacity, Func f) { - assert(capacity <= kMaxCapacity); - const size_t step = (capacity + kStep - 1) / kStep; - assert(step <= kNumSteps); - switch (step) { - case 1: - return RunWithCapacityImpl<1>(f); - case 2: - return RunWithCapacityImpl<2>(f); - case 3: - return RunWithCapacityImpl<3>(f); - case 4: - return RunWithCapacityImpl<4>(f); - case 5: - return RunWithCapacityImpl<5>(f); - } - - assert(false && "Invalid capacity"); - } -}; - -// Calculates `10 * (*v) + carry` and stores the result in `*v` and returns -// the carry. -template <typename Int> -inline Int MultiplyBy10WithCarry(Int *v, Int carry) { - using BiggerInt = absl::conditional_t<sizeof(Int) == 4, uint64_t, uint128>; - BiggerInt tmp = 10 * static_cast<BiggerInt>(*v) + carry; - *v = static_cast<Int>(tmp); - return static_cast<Int>(tmp >> (sizeof(Int) * 8)); -} - -// Calculates `(2^64 * carry + *v) / 10`. -// Stores the quotient in `*v` and returns the remainder. -// Requires: `0 <= carry <= 9` -inline uint64_t DivideBy10WithCarry(uint64_t *v, uint64_t carry) { - constexpr uint64_t divisor = 10; - // 2^64 / divisor = chunk_quotient + chunk_remainder / divisor - constexpr uint64_t chunk_quotient = (uint64_t{1} << 63) / (divisor / 2); - constexpr uint64_t chunk_remainder = uint64_t{} - chunk_quotient * divisor; - - const uint64_t mod = *v % divisor; - const uint64_t next_carry = chunk_remainder * carry + mod; - *v = *v / divisor + carry * chunk_quotient + next_carry / divisor; - return next_carry % divisor; -} - +// The code below wants to avoid heap allocations. +// To do so it needs to allocate memory on the stack. +// `StackArray` will allocate memory on the stack in the form of a uint32_t +// array and call the provided callback with said memory. +// It will allocate memory in increments of 512 bytes. We could allocate the +// largest needed unconditionally, but that is more than we need in most of +// cases. This way we use less stack in the common cases. +class StackArray { + using Func = absl::FunctionRef<void(absl::Span<uint32_t>)>; + static constexpr size_t kStep = 512 / sizeof(uint32_t); + // 5 steps is 2560 bytes, which is enough to hold a long double with the + // largest/smallest exponents. + // The operations below will static_assert their particular maximum. + static constexpr size_t kNumSteps = 5; + + // We do not want this function to be inlined. + // Otherwise the caller will allocate the stack space unnecessarily for all + // the variants even though it only calls one. + template <size_t steps> + ABSL_ATTRIBUTE_NOINLINE static void RunWithCapacityImpl(Func f) { + uint32_t values[steps * kStep]{}; + f(absl::MakeSpan(values)); + } + + public: + static constexpr size_t kMaxCapacity = kStep * kNumSteps; + + static void RunWithCapacity(size_t capacity, Func f) { + assert(capacity <= kMaxCapacity); + const size_t step = (capacity + kStep - 1) / kStep; + assert(step <= kNumSteps); + switch (step) { + case 1: + return RunWithCapacityImpl<1>(f); + case 2: + return RunWithCapacityImpl<2>(f); + case 3: + return RunWithCapacityImpl<3>(f); + case 4: + return RunWithCapacityImpl<4>(f); + case 5: + return RunWithCapacityImpl<5>(f); + } + + assert(false && "Invalid capacity"); + } +}; + +// Calculates `10 * (*v) + carry` and stores the result in `*v` and returns +// the carry. +template <typename Int> +inline Int MultiplyBy10WithCarry(Int *v, Int carry) { + using BiggerInt = absl::conditional_t<sizeof(Int) == 4, uint64_t, uint128>; + BiggerInt tmp = 10 * static_cast<BiggerInt>(*v) + carry; + *v = static_cast<Int>(tmp); + return static_cast<Int>(tmp >> (sizeof(Int) * 8)); +} + +// Calculates `(2^64 * carry + *v) / 10`. +// Stores the quotient in `*v` and returns the remainder. +// Requires: `0 <= carry <= 9` +inline uint64_t DivideBy10WithCarry(uint64_t *v, uint64_t carry) { + constexpr uint64_t divisor = 10; + // 2^64 / divisor = chunk_quotient + chunk_remainder / divisor + constexpr uint64_t chunk_quotient = (uint64_t{1} << 63) / (divisor / 2); + constexpr uint64_t chunk_remainder = uint64_t{} - chunk_quotient * divisor; + + const uint64_t mod = *v % divisor; + const uint64_t next_carry = chunk_remainder * carry + mod; + *v = *v / divisor + carry * chunk_quotient + next_carry / divisor; + return next_carry % divisor; +} + using MaxFloatType = typename std::conditional<IsDoubleDouble(), double, long double>::type; -// Generates the decimal representation for an integer of the form `v * 2^exp`, -// where `v` and `exp` are both positive integers. -// It generates the digits from the left (ie the most significant digit first) -// to allow for direct printing into the sink. -// +// Generates the decimal representation for an integer of the form `v * 2^exp`, +// where `v` and `exp` are both positive integers. +// It generates the digits from the left (ie the most significant digit first) +// to allow for direct printing into the sink. +// // Requires `0 <= exp` and `exp <= numeric_limits<MaxFloatType>::max_exponent`. -class BinaryToDecimal { - static constexpr int ChunksNeeded(int exp) { - // We will left shift a uint128 by `exp` bits, so we need `128+exp` total - // bits. Round up to 32. - // See constructor for details about adding `10%` to the value. - return (128 + exp + 31) / 32 * 11 / 10; - } - - public: - // Run the conversion for `v * 2^exp` and call `f(binary_to_decimal)`. - // This function will allocate enough stack space to perform the conversion. - static void RunConversion(uint128 v, int exp, - absl::FunctionRef<void(BinaryToDecimal)> f) { - assert(exp > 0); +class BinaryToDecimal { + static constexpr int ChunksNeeded(int exp) { + // We will left shift a uint128 by `exp` bits, so we need `128+exp` total + // bits. Round up to 32. + // See constructor for details about adding `10%` to the value. + return (128 + exp + 31) / 32 * 11 / 10; + } + + public: + // Run the conversion for `v * 2^exp` and call `f(binary_to_decimal)`. + // This function will allocate enough stack space to perform the conversion. + static void RunConversion(uint128 v, int exp, + absl::FunctionRef<void(BinaryToDecimal)> f) { + assert(exp > 0); assert(exp <= std::numeric_limits<MaxFloatType>::max_exponent); - static_assert( + static_assert( static_cast<int>(StackArray::kMaxCapacity) >= ChunksNeeded(std::numeric_limits<MaxFloatType>::max_exponent), - ""); - - StackArray::RunWithCapacity( - ChunksNeeded(exp), - [=](absl::Span<uint32_t> input) { f(BinaryToDecimal(input, v, exp)); }); - } - - int TotalDigits() const { - return static_cast<int>((decimal_end_ - decimal_start_) * kDigitsPerChunk + - CurrentDigits().size()); - } - - // See the current block of digits. - absl::string_view CurrentDigits() const { - return absl::string_view(digits_ + kDigitsPerChunk - size_, size_); - } - - // Advance the current view of digits. - // Returns `false` when no more digits are available. - bool AdvanceDigits() { - if (decimal_start_ >= decimal_end_) return false; - - uint32_t w = data_[decimal_start_++]; - for (size_ = 0; size_ < kDigitsPerChunk; w /= 10) { - digits_[kDigitsPerChunk - ++size_] = w % 10 + '0'; - } - return true; - } - - private: - BinaryToDecimal(absl::Span<uint32_t> data, uint128 v, int exp) : data_(data) { - // We need to print the digits directly into the sink object without - // buffering them all first. To do this we need two things: - // - to know the total number of digits to do padding when necessary - // - to generate the decimal digits from the left. - // - // In order to do this, we do a two pass conversion. - // On the first pass we convert the binary representation of the value into - // a decimal representation in which each uint32_t chunk holds up to 9 - // decimal digits. In the second pass we take each decimal-holding-uint32_t - // value and generate the ascii decimal digits into `digits_`. - // - // The binary and decimal representations actually share the same memory - // region. As we go converting the chunks from binary to decimal we free - // them up and reuse them for the decimal representation. One caveat is that - // the decimal representation is around 7% less efficient in space than the - // binary one. We allocate an extra 10% memory to account for this. See - // ChunksNeeded for this calculation. - int chunk_index = exp / 32; - decimal_start_ = decimal_end_ = ChunksNeeded(exp); - const int offset = exp % 32; - // Left shift v by exp bits. - data_[chunk_index] = static_cast<uint32_t>(v << offset); - for (v >>= (32 - offset); v; v >>= 32) - data_[++chunk_index] = static_cast<uint32_t>(v); - - while (chunk_index >= 0) { - // While we have more than one chunk available, go in steps of 1e9. - // `data_[chunk_index]` holds the highest non-zero binary chunk, so keep - // the variable updated. - uint32_t carry = 0; - for (int i = chunk_index; i >= 0; --i) { - uint64_t tmp = uint64_t{data_[i]} + (uint64_t{carry} << 32); - data_[i] = static_cast<uint32_t>(tmp / uint64_t{1000000000}); - carry = static_cast<uint32_t>(tmp % uint64_t{1000000000}); - } - - // If the highest chunk is now empty, remove it from view. - if (data_[chunk_index] == 0) --chunk_index; - - --decimal_start_; - assert(decimal_start_ != chunk_index); - data_[decimal_start_] = carry; - } - - // Fill the first set of digits. The first chunk might not be complete, so - // handle differently. - for (uint32_t first = data_[decimal_start_++]; first != 0; first /= 10) { - digits_[kDigitsPerChunk - ++size_] = first % 10 + '0'; - } - } - - private: - static constexpr int kDigitsPerChunk = 9; - - int decimal_start_; - int decimal_end_; - - char digits_[kDigitsPerChunk]; - int size_ = 0; - - absl::Span<uint32_t> data_; -}; - -// Converts a value of the form `x * 2^-exp` into a sequence of decimal digits. -// Requires `-exp < 0` and + ""); + + StackArray::RunWithCapacity( + ChunksNeeded(exp), + [=](absl::Span<uint32_t> input) { f(BinaryToDecimal(input, v, exp)); }); + } + + int TotalDigits() const { + return static_cast<int>((decimal_end_ - decimal_start_) * kDigitsPerChunk + + CurrentDigits().size()); + } + + // See the current block of digits. + absl::string_view CurrentDigits() const { + return absl::string_view(digits_ + kDigitsPerChunk - size_, size_); + } + + // Advance the current view of digits. + // Returns `false` when no more digits are available. + bool AdvanceDigits() { + if (decimal_start_ >= decimal_end_) return false; + + uint32_t w = data_[decimal_start_++]; + for (size_ = 0; size_ < kDigitsPerChunk; w /= 10) { + digits_[kDigitsPerChunk - ++size_] = w % 10 + '0'; + } + return true; + } + + private: + BinaryToDecimal(absl::Span<uint32_t> data, uint128 v, int exp) : data_(data) { + // We need to print the digits directly into the sink object without + // buffering them all first. To do this we need two things: + // - to know the total number of digits to do padding when necessary + // - to generate the decimal digits from the left. + // + // In order to do this, we do a two pass conversion. + // On the first pass we convert the binary representation of the value into + // a decimal representation in which each uint32_t chunk holds up to 9 + // decimal digits. In the second pass we take each decimal-holding-uint32_t + // value and generate the ascii decimal digits into `digits_`. + // + // The binary and decimal representations actually share the same memory + // region. As we go converting the chunks from binary to decimal we free + // them up and reuse them for the decimal representation. One caveat is that + // the decimal representation is around 7% less efficient in space than the + // binary one. We allocate an extra 10% memory to account for this. See + // ChunksNeeded for this calculation. + int chunk_index = exp / 32; + decimal_start_ = decimal_end_ = ChunksNeeded(exp); + const int offset = exp % 32; + // Left shift v by exp bits. + data_[chunk_index] = static_cast<uint32_t>(v << offset); + for (v >>= (32 - offset); v; v >>= 32) + data_[++chunk_index] = static_cast<uint32_t>(v); + + while (chunk_index >= 0) { + // While we have more than one chunk available, go in steps of 1e9. + // `data_[chunk_index]` holds the highest non-zero binary chunk, so keep + // the variable updated. + uint32_t carry = 0; + for (int i = chunk_index; i >= 0; --i) { + uint64_t tmp = uint64_t{data_[i]} + (uint64_t{carry} << 32); + data_[i] = static_cast<uint32_t>(tmp / uint64_t{1000000000}); + carry = static_cast<uint32_t>(tmp % uint64_t{1000000000}); + } + + // If the highest chunk is now empty, remove it from view. + if (data_[chunk_index] == 0) --chunk_index; + + --decimal_start_; + assert(decimal_start_ != chunk_index); + data_[decimal_start_] = carry; + } + + // Fill the first set of digits. The first chunk might not be complete, so + // handle differently. + for (uint32_t first = data_[decimal_start_++]; first != 0; first /= 10) { + digits_[kDigitsPerChunk - ++size_] = first % 10 + '0'; + } + } + + private: + static constexpr int kDigitsPerChunk = 9; + + int decimal_start_; + int decimal_end_; + + char digits_[kDigitsPerChunk]; + int size_ = 0; + + absl::Span<uint32_t> data_; +}; + +// Converts a value of the form `x * 2^-exp` into a sequence of decimal digits. +// Requires `-exp < 0` and // `-exp >= limits<MaxFloatType>::min_exponent - limits<MaxFloatType>::digits`. -class FractionalDigitGenerator { - public: - // Run the conversion for `v * 2^exp` and call `f(generator)`. - // This function will allocate enough stack space to perform the conversion. - static void RunConversion( - uint128 v, int exp, absl::FunctionRef<void(FractionalDigitGenerator)> f) { +class FractionalDigitGenerator { + public: + // Run the conversion for `v * 2^exp` and call `f(generator)`. + // This function will allocate enough stack space to perform the conversion. + static void RunConversion( + uint128 v, int exp, absl::FunctionRef<void(FractionalDigitGenerator)> f) { using Limits = std::numeric_limits<MaxFloatType>; - assert(-exp < 0); - assert(-exp >= Limits::min_exponent - 128); - static_assert(StackArray::kMaxCapacity >= - (Limits::digits + 128 - Limits::min_exponent + 31) / 32, - ""); - StackArray::RunWithCapacity((Limits::digits + exp + 31) / 32, - [=](absl::Span<uint32_t> input) { - f(FractionalDigitGenerator(input, v, exp)); - }); - } - - // Returns true if there are any more non-zero digits left. - bool HasMoreDigits() const { return next_digit_ != 0 || chunk_index_ >= 0; } - - // Returns true if the remainder digits are greater than 5000... - bool IsGreaterThanHalf() const { - return next_digit_ > 5 || (next_digit_ == 5 && chunk_index_ >= 0); - } - // Returns true if the remainder digits are exactly 5000... - bool IsExactlyHalf() const { return next_digit_ == 5 && chunk_index_ < 0; } - - struct Digits { - int digit_before_nine; - int num_nines; - }; - - // Get the next set of digits. - // They are composed by a non-9 digit followed by a runs of zero or more 9s. - Digits GetDigits() { - Digits digits{next_digit_, 0}; - - next_digit_ = GetOneDigit(); - while (next_digit_ == 9) { - ++digits.num_nines; - next_digit_ = GetOneDigit(); - } - - return digits; - } - - private: - // Return the next digit. - int GetOneDigit() { - if (chunk_index_ < 0) return 0; - - uint32_t carry = 0; - for (int i = chunk_index_; i >= 0; --i) { - carry = MultiplyBy10WithCarry(&data_[i], carry); - } - // If the lowest chunk is now empty, remove it from view. - if (data_[chunk_index_] == 0) --chunk_index_; - return carry; - } - - FractionalDigitGenerator(absl::Span<uint32_t> data, uint128 v, int exp) - : chunk_index_(exp / 32), data_(data) { - const int offset = exp % 32; - // Right shift `v` by `exp` bits. - data_[chunk_index_] = static_cast<uint32_t>(v << (32 - offset)); - v >>= offset; - // Make sure we don't overflow the data. We already calculated that - // non-zero bits fit, so we might not have space for leading zero bits. - for (int pos = chunk_index_; v; v >>= 32) - data_[--pos] = static_cast<uint32_t>(v); - - // Fill next_digit_, as GetDigits expects it to be populated always. - next_digit_ = GetOneDigit(); - } - - int next_digit_; - int chunk_index_; - absl::Span<uint32_t> data_; -}; - -// Count the number of leading zero bits. + assert(-exp < 0); + assert(-exp >= Limits::min_exponent - 128); + static_assert(StackArray::kMaxCapacity >= + (Limits::digits + 128 - Limits::min_exponent + 31) / 32, + ""); + StackArray::RunWithCapacity((Limits::digits + exp + 31) / 32, + [=](absl::Span<uint32_t> input) { + f(FractionalDigitGenerator(input, v, exp)); + }); + } + + // Returns true if there are any more non-zero digits left. + bool HasMoreDigits() const { return next_digit_ != 0 || chunk_index_ >= 0; } + + // Returns true if the remainder digits are greater than 5000... + bool IsGreaterThanHalf() const { + return next_digit_ > 5 || (next_digit_ == 5 && chunk_index_ >= 0); + } + // Returns true if the remainder digits are exactly 5000... + bool IsExactlyHalf() const { return next_digit_ == 5 && chunk_index_ < 0; } + + struct Digits { + int digit_before_nine; + int num_nines; + }; + + // Get the next set of digits. + // They are composed by a non-9 digit followed by a runs of zero or more 9s. + Digits GetDigits() { + Digits digits{next_digit_, 0}; + + next_digit_ = GetOneDigit(); + while (next_digit_ == 9) { + ++digits.num_nines; + next_digit_ = GetOneDigit(); + } + + return digits; + } + + private: + // Return the next digit. + int GetOneDigit() { + if (chunk_index_ < 0) return 0; + + uint32_t carry = 0; + for (int i = chunk_index_; i >= 0; --i) { + carry = MultiplyBy10WithCarry(&data_[i], carry); + } + // If the lowest chunk is now empty, remove it from view. + if (data_[chunk_index_] == 0) --chunk_index_; + return carry; + } + + FractionalDigitGenerator(absl::Span<uint32_t> data, uint128 v, int exp) + : chunk_index_(exp / 32), data_(data) { + const int offset = exp % 32; + // Right shift `v` by `exp` bits. + data_[chunk_index_] = static_cast<uint32_t>(v << (32 - offset)); + v >>= offset; + // Make sure we don't overflow the data. We already calculated that + // non-zero bits fit, so we might not have space for leading zero bits. + for (int pos = chunk_index_; v; v >>= 32) + data_[--pos] = static_cast<uint32_t>(v); + + // Fill next_digit_, as GetDigits expects it to be populated always. + next_digit_ = GetOneDigit(); + } + + int next_digit_; + int chunk_index_; + absl::Span<uint32_t> data_; +}; + +// Count the number of leading zero bits. int LeadingZeros(uint64_t v) { return countl_zero(v); } -int LeadingZeros(uint128 v) { - auto high = static_cast<uint64_t>(v >> 64); - auto low = static_cast<uint64_t>(v); +int LeadingZeros(uint128 v) { + auto high = static_cast<uint64_t>(v >> 64); + auto low = static_cast<uint64_t>(v); return high != 0 ? countl_zero(high) : 64 + countl_zero(low); -} - -// Round up the text digits starting at `p`. -// The buffer must have an extra digit that is known to not need rounding. -// This is done below by having an extra '0' digit on the left. -void RoundUp(char *p) { - while (*p == '9' || *p == '.') { - if (*p == '9') *p = '0'; - --p; - } - ++*p; -} - -// Check the previous digit and round up or down to follow the round-to-even -// policy. -void RoundToEven(char *p) { - if (*p == '.') --p; - if (*p % 2 == 1) RoundUp(p); -} - -// Simple integral decimal digit printing for values that fit in 64-bits. -// Returns the pointer to the last written digit. -char *PrintIntegralDigitsFromRightFast(uint64_t v, char *p) { - do { - *--p = DivideBy10WithCarry(&v, 0) + '0'; - } while (v != 0); - return p; -} - -// Simple integral decimal digit printing for values that fit in 128-bits. -// Returns the pointer to the last written digit. -char *PrintIntegralDigitsFromRightFast(uint128 v, char *p) { - auto high = static_cast<uint64_t>(v >> 64); - auto low = static_cast<uint64_t>(v); - - while (high != 0) { - uint64_t carry = DivideBy10WithCarry(&high, 0); - carry = DivideBy10WithCarry(&low, carry); - *--p = carry + '0'; - } - return PrintIntegralDigitsFromRightFast(low, p); -} - -// Simple fractional decimal digit printing for values that fir in 64-bits after -// shifting. -// Performs rounding if necessary to fit within `precision`. -// Returns the pointer to one after the last character written. -char *PrintFractionalDigitsFast(uint64_t v, char *start, int exp, - int precision) { - char *p = start; - v <<= (64 - exp); - while (precision > 0) { - if (!v) return p; - *p++ = MultiplyBy10WithCarry(&v, uint64_t{0}) + '0'; - --precision; - } - - // We need to round. - if (v < 0x8000000000000000) { - // We round down, so nothing to do. - } else if (v > 0x8000000000000000) { - // We round up. - RoundUp(p - 1); - } else { - RoundToEven(p - 1); - } - - assert(precision == 0); - // Precision can only be zero here. - return p; -} - -// Simple fractional decimal digit printing for values that fir in 128-bits -// after shifting. -// Performs rounding if necessary to fit within `precision`. -// Returns the pointer to one after the last character written. -char *PrintFractionalDigitsFast(uint128 v, char *start, int exp, - int precision) { - char *p = start; - v <<= (128 - exp); - auto high = static_cast<uint64_t>(v >> 64); - auto low = static_cast<uint64_t>(v); - - // While we have digits to print and `low` is not empty, do the long - // multiplication. - while (precision > 0 && low != 0) { - uint64_t carry = MultiplyBy10WithCarry(&low, uint64_t{0}); - carry = MultiplyBy10WithCarry(&high, carry); - - *p++ = carry + '0'; - --precision; - } - - // Now `low` is empty, so use a faster approach for the rest of the digits. - // This block is pretty much the same as the main loop for the 64-bit case - // above. - while (precision > 0) { - if (!high) return p; - *p++ = MultiplyBy10WithCarry(&high, uint64_t{0}) + '0'; - --precision; - } - - // We need to round. - if (high < 0x8000000000000000) { - // We round down, so nothing to do. - } else if (high > 0x8000000000000000 || low != 0) { - // We round up. - RoundUp(p - 1); - } else { - RoundToEven(p - 1); - } - - assert(precision == 0); - // Precision can only be zero here. - return p; -} - -struct FormatState { - char sign_char; - int precision; - const FormatConversionSpecImpl &conv; - FormatSinkImpl *sink; - - // In `alt` mode (flag #) we keep the `.` even if there are no fractional - // digits. In non-alt mode, we strip it. - bool ShouldPrintDot() const { return precision != 0 || conv.has_alt_flag(); } -}; - -struct Padding { - int left_spaces; - int zeros; - int right_spaces; -}; - -Padding ExtraWidthToPadding(size_t total_size, const FormatState &state) { - if (state.conv.width() < 0 || - static_cast<size_t>(state.conv.width()) <= total_size) { - return {0, 0, 0}; - } - int missing_chars = state.conv.width() - total_size; - if (state.conv.has_left_flag()) { - return {0, 0, missing_chars}; - } else if (state.conv.has_zero_flag()) { - return {0, missing_chars, 0}; - } else { - return {missing_chars, 0, 0}; - } -} - -void FinalPrint(const FormatState &state, absl::string_view data, - int padding_offset, int trailing_zeros, - absl::string_view data_postfix) { - if (state.conv.width() < 0) { - // No width specified. Fast-path. - if (state.sign_char != '\0') state.sink->Append(1, state.sign_char); - state.sink->Append(data); - state.sink->Append(trailing_zeros, '0'); - state.sink->Append(data_postfix); - return; - } - - auto padding = ExtraWidthToPadding((state.sign_char != '\0' ? 1 : 0) + - data.size() + data_postfix.size() + - static_cast<size_t>(trailing_zeros), - state); - - state.sink->Append(padding.left_spaces, ' '); - if (state.sign_char != '\0') state.sink->Append(1, state.sign_char); - // Padding in general needs to be inserted somewhere in the middle of `data`. - state.sink->Append(data.substr(0, padding_offset)); - state.sink->Append(padding.zeros, '0'); - state.sink->Append(data.substr(padding_offset)); - state.sink->Append(trailing_zeros, '0'); - state.sink->Append(data_postfix); - state.sink->Append(padding.right_spaces, ' '); -} - -// Fastpath %f formatter for when the shifted value fits in a simple integral -// type. -// Prints `v*2^exp` with the options from `state`. -template <typename Int> -void FormatFFast(Int v, int exp, const FormatState &state) { - constexpr int input_bits = sizeof(Int) * 8; - - static constexpr size_t integral_size = - /* in case we need to round up an extra digit */ 1 + - /* decimal digits for uint128 */ 40 + 1; - char buffer[integral_size + /* . */ 1 + /* max digits uint128 */ 128]; - buffer[integral_size] = '.'; - char *const integral_digits_end = buffer + integral_size; - char *integral_digits_start; - char *const fractional_digits_start = buffer + integral_size + 1; - char *fractional_digits_end = fractional_digits_start; - - if (exp >= 0) { - const int total_bits = input_bits - LeadingZeros(v) + exp; - integral_digits_start = - total_bits <= 64 - ? PrintIntegralDigitsFromRightFast(static_cast<uint64_t>(v) << exp, - integral_digits_end) - : PrintIntegralDigitsFromRightFast(static_cast<uint128>(v) << exp, - integral_digits_end); - } else { - exp = -exp; - - integral_digits_start = PrintIntegralDigitsFromRightFast( - exp < input_bits ? v >> exp : 0, integral_digits_end); - // PrintFractionalDigits may pull a carried 1 all the way up through the - // integral portion. - integral_digits_start[-1] = '0'; - - fractional_digits_end = - exp <= 64 ? PrintFractionalDigitsFast(v, fractional_digits_start, exp, - state.precision) - : PrintFractionalDigitsFast(static_cast<uint128>(v), - fractional_digits_start, exp, - state.precision); - // There was a carry, so include the first digit too. - if (integral_digits_start[-1] != '0') --integral_digits_start; - } - - size_t size = fractional_digits_end - integral_digits_start; - - // In `alt` mode (flag #) we keep the `.` even if there are no fractional - // digits. In non-alt mode, we strip it. - if (!state.ShouldPrintDot()) --size; - FinalPrint(state, absl::string_view(integral_digits_start, size), - /*padding_offset=*/0, - static_cast<int>(state.precision - (fractional_digits_end - - fractional_digits_start)), - /*data_postfix=*/""); -} - -// Slow %f formatter for when the shifted value does not fit in a uint128, and -// `exp > 0`. -// Prints `v*2^exp` with the options from `state`. -// This one is guaranteed to not have fractional digits, so we don't have to -// worry about anything after the `.`. -void FormatFPositiveExpSlow(uint128 v, int exp, const FormatState &state) { - BinaryToDecimal::RunConversion(v, exp, [&](BinaryToDecimal btd) { - const size_t total_digits = - btd.TotalDigits() + - (state.ShouldPrintDot() ? static_cast<size_t>(state.precision) + 1 : 0); - - const auto padding = ExtraWidthToPadding( - total_digits + (state.sign_char != '\0' ? 1 : 0), state); - - state.sink->Append(padding.left_spaces, ' '); - if (state.sign_char != '\0') state.sink->Append(1, state.sign_char); - state.sink->Append(padding.zeros, '0'); - - do { - state.sink->Append(btd.CurrentDigits()); - } while (btd.AdvanceDigits()); - - if (state.ShouldPrintDot()) state.sink->Append(1, '.'); - state.sink->Append(state.precision, '0'); - state.sink->Append(padding.right_spaces, ' '); - }); -} - -// Slow %f formatter for when the shifted value does not fit in a uint128, and -// `exp < 0`. -// Prints `v*2^exp` with the options from `state`. -// This one is guaranteed to be < 1.0, so we don't have to worry about integral -// digits. -void FormatFNegativeExpSlow(uint128 v, int exp, const FormatState &state) { - const size_t total_digits = - /* 0 */ 1 + - (state.ShouldPrintDot() ? static_cast<size_t>(state.precision) + 1 : 0); - auto padding = - ExtraWidthToPadding(total_digits + (state.sign_char ? 1 : 0), state); - padding.zeros += 1; - state.sink->Append(padding.left_spaces, ' '); - if (state.sign_char != '\0') state.sink->Append(1, state.sign_char); - state.sink->Append(padding.zeros, '0'); - - if (state.ShouldPrintDot()) state.sink->Append(1, '.'); - - // Print digits - int digits_to_go = state.precision; - - FractionalDigitGenerator::RunConversion( - v, exp, [&](FractionalDigitGenerator digit_gen) { - // There are no digits to print here. - if (state.precision == 0) return; - - // We go one digit at a time, while keeping track of runs of nines. - // The runs of nines are used to perform rounding when necessary. - - while (digits_to_go > 0 && digit_gen.HasMoreDigits()) { - auto digits = digit_gen.GetDigits(); - - // Now we have a digit and a run of nines. - // See if we can print them all. - if (digits.num_nines + 1 < digits_to_go) { - // We don't have to round yet, so print them. - state.sink->Append(1, digits.digit_before_nine + '0'); - state.sink->Append(digits.num_nines, '9'); - digits_to_go -= digits.num_nines + 1; - - } else { - // We can't print all the nines, see where we have to truncate. - - bool round_up = false; - if (digits.num_nines + 1 > digits_to_go) { - // We round up at a nine. No need to print them. - round_up = true; - } else { - // We can fit all the nines, but truncate just after it. - if (digit_gen.IsGreaterThanHalf()) { - round_up = true; - } else if (digit_gen.IsExactlyHalf()) { - // Round to even - round_up = - digits.num_nines != 0 || digits.digit_before_nine % 2 == 1; - } - } - - if (round_up) { - state.sink->Append(1, digits.digit_before_nine + '1'); - --digits_to_go; - // The rest will be zeros. - } else { - state.sink->Append(1, digits.digit_before_nine + '0'); - state.sink->Append(digits_to_go - 1, '9'); - digits_to_go = 0; - } - return; - } - } - }); - - state.sink->Append(digits_to_go, '0'); - state.sink->Append(padding.right_spaces, ' '); -} - -template <typename Int> -void FormatF(Int mantissa, int exp, const FormatState &state) { - if (exp >= 0) { - const int total_bits = sizeof(Int) * 8 - LeadingZeros(mantissa) + exp; - - // Fallback to the slow stack-based approach if we can't do it in a 64 or - // 128 bit state. - if (ABSL_PREDICT_FALSE(total_bits > 128)) { - return FormatFPositiveExpSlow(mantissa, exp, state); - } - } else { - // Fallback to the slow stack-based approach if we can't do it in a 64 or - // 128 bit state. - if (ABSL_PREDICT_FALSE(exp < -128)) { - return FormatFNegativeExpSlow(mantissa, -exp, state); - } - } - return FormatFFast(mantissa, exp, state); -} - -// Grab the group of four bits (nibble) from `n`. E.g., nibble 1 corresponds to -// bits 4-7. -template <typename Int> -uint8_t GetNibble(Int n, int nibble_index) { - constexpr Int mask_low_nibble = Int{0xf}; - int shift = nibble_index * 4; - n &= mask_low_nibble << shift; - return static_cast<uint8_t>((n >> shift) & 0xf); -} - -// Add one to the given nibble, applying carry to higher nibbles. Returns true -// if overflow, false otherwise. -template <typename Int> -bool IncrementNibble(int nibble_index, Int *n) { - constexpr int kShift = sizeof(Int) * 8 - 1; - constexpr int kNumNibbles = sizeof(Int) * 8 / 4; - Int before = *n >> kShift; - // Here we essentially want to take the number 1 and move it into the requsted - // nibble, then add it to *n to effectively increment the nibble. However, - // ASan will complain if we try to shift the 1 beyond the limits of the Int, - // i.e., if the nibble_index is out of range. So therefore we check for this - // and if we are out of range we just add 0 which leaves *n unchanged, which - // seems like the reasonable thing to do in that case. - *n += ((nibble_index >= kNumNibbles) ? 0 : (Int{1} << (nibble_index * 4))); - Int after = *n >> kShift; - return (before && !after) || (nibble_index >= kNumNibbles); -} - -// Return a mask with 1's in the given nibble and all lower nibbles. -template <typename Int> -Int MaskUpToNibbleInclusive(int nibble_index) { - constexpr int kNumNibbles = sizeof(Int) * 8 / 4; - static const Int ones = ~Int{0}; - return ones >> std::max(0, 4 * (kNumNibbles - nibble_index - 1)); -} - -// Return a mask with 1's below the given nibble. -template <typename Int> -Int MaskUpToNibbleExclusive(int nibble_index) { - return nibble_index <= 0 ? 0 : MaskUpToNibbleInclusive<Int>(nibble_index - 1); -} - -template <typename Int> -Int MoveToNibble(uint8_t nibble, int nibble_index) { - return Int{nibble} << (4 * nibble_index); -} - -// Given mantissa size, find optimal # of mantissa bits to put in initial digit. -// -// In the hex representation we keep a single hex digit to the left of the dot. -// However, the question as to how many bits of the mantissa should be put into -// that hex digit in theory is arbitrary, but in practice it is optimal to -// choose based on the size of the mantissa. E.g., for a `double`, there are 53 -// mantissa bits, so that means that we should put 1 bit to the left of the dot, -// thereby leaving 52 bits to the right, which is evenly divisible by four and -// thus all fractional digits represent actual precision. For a `long double`, -// on the other hand, there are 64 bits of mantissa, thus we can use all four -// bits for the initial hex digit and still have a number left over (60) that is -// a multiple of four. Once again, the goal is to have all fractional digits -// represent real precision. -template <typename Float> -constexpr int HexFloatLeadingDigitSizeInBits() { - return std::numeric_limits<Float>::digits % 4 > 0 - ? std::numeric_limits<Float>::digits % 4 - : 4; -} - -// This function captures the rounding behavior of glibc for hex float -// representations. E.g. when rounding 0x1.ab800000 to a precision of .2 -// ("%.2a") glibc will round up because it rounds toward the even number (since -// 0xb is an odd number, it will round up to 0xc). However, when rounding at a -// point that is not followed by 800000..., it disregards the parity and rounds -// up if > 8 and rounds down if < 8. -template <typename Int> -bool HexFloatNeedsRoundUp(Int mantissa, int final_nibble_displayed, - uint8_t leading) { - // If the last nibble (hex digit) to be displayed is the lowest on in the - // mantissa then that means that we don't have any further nibbles to inform - // rounding, so don't round. - if (final_nibble_displayed <= 0) { - return false; - } - int rounding_nibble_idx = final_nibble_displayed - 1; - constexpr int kTotalNibbles = sizeof(Int) * 8 / 4; - assert(final_nibble_displayed <= kTotalNibbles); - Int mantissa_up_to_rounding_nibble_inclusive = - mantissa & MaskUpToNibbleInclusive<Int>(rounding_nibble_idx); - Int eight = MoveToNibble<Int>(8, rounding_nibble_idx); - if (mantissa_up_to_rounding_nibble_inclusive != eight) { - return mantissa_up_to_rounding_nibble_inclusive > eight; - } - // Nibble in question == 8. - uint8_t round_if_odd = (final_nibble_displayed == kTotalNibbles) - ? leading - : GetNibble(mantissa, final_nibble_displayed); - return round_if_odd % 2 == 1; -} - -// Stores values associated with a Float type needed by the FormatA -// implementation in order to avoid templatizing that function by the Float -// type. -struct HexFloatTypeParams { - template <typename Float> - explicit HexFloatTypeParams(Float) - : min_exponent(std::numeric_limits<Float>::min_exponent - 1), - leading_digit_size_bits(HexFloatLeadingDigitSizeInBits<Float>()) { - assert(leading_digit_size_bits >= 1 && leading_digit_size_bits <= 4); - } - - int min_exponent; - int leading_digit_size_bits; -}; - -// Hex Float Rounding. First check if we need to round; if so, then we do that -// by manipulating (incrementing) the mantissa, that way we can later print the -// mantissa digits by iterating through them in the same way regardless of -// whether a rounding happened. -template <typename Int> -void FormatARound(bool precision_specified, const FormatState &state, - uint8_t *leading, Int *mantissa, int *exp) { - constexpr int kTotalNibbles = sizeof(Int) * 8 / 4; - // Index of the last nibble that we could display given precision. - int final_nibble_displayed = - precision_specified ? std::max(0, (kTotalNibbles - state.precision)) : 0; - if (HexFloatNeedsRoundUp(*mantissa, final_nibble_displayed, *leading)) { - // Need to round up. - bool overflow = IncrementNibble(final_nibble_displayed, mantissa); - *leading += (overflow ? 1 : 0); - if (ABSL_PREDICT_FALSE(*leading > 15)) { - // We have overflowed the leading digit. This would mean that we would - // need two hex digits to the left of the dot, which is not allowed. So - // adjust the mantissa and exponent so that the result is always 1.0eXXX. - *leading = 1; - *mantissa = 0; - *exp += 4; - } - } - // Now that we have handled a possible round-up we can go ahead and zero out - // all the nibbles of the mantissa that we won't need. - if (precision_specified) { - *mantissa &= ~MaskUpToNibbleExclusive<Int>(final_nibble_displayed); - } -} - -template <typename Int> -void FormatANormalize(const HexFloatTypeParams float_traits, uint8_t *leading, - Int *mantissa, int *exp) { - constexpr int kIntBits = sizeof(Int) * 8; - static const Int kHighIntBit = Int{1} << (kIntBits - 1); - const int kLeadDigitBitsCount = float_traits.leading_digit_size_bits; - // Normalize mantissa so that highest bit set is in MSB position, unless we - // get interrupted by the exponent threshold. - while (*mantissa && !(*mantissa & kHighIntBit)) { - if (ABSL_PREDICT_FALSE(*exp - 1 < float_traits.min_exponent)) { - *mantissa >>= (float_traits.min_exponent - *exp); - *exp = float_traits.min_exponent; - return; - } - *mantissa <<= 1; - --*exp; - } - // Extract bits for leading digit then shift them away leaving the - // fractional part. - *leading = - static_cast<uint8_t>(*mantissa >> (kIntBits - kLeadDigitBitsCount)); - *exp -= (*mantissa != 0) ? kLeadDigitBitsCount : *exp; - *mantissa <<= kLeadDigitBitsCount; -} - -template <typename Int> -void FormatA(const HexFloatTypeParams float_traits, Int mantissa, int exp, - bool uppercase, const FormatState &state) { - // Int properties. - constexpr int kIntBits = sizeof(Int) * 8; - constexpr int kTotalNibbles = sizeof(Int) * 8 / 4; - // Did the user specify a precision explicitly? - const bool precision_specified = state.conv.precision() >= 0; - - // ========== Normalize/Denormalize ========== - exp += kIntBits; // make all digits fractional digits. - // This holds the (up to four) bits of leading digit, i.e., the '1' in the - // number 0x1.e6fp+2. It's always > 0 unless number is zero or denormal. - uint8_t leading = 0; - FormatANormalize(float_traits, &leading, &mantissa, &exp); - - // =============== Rounding ================== - // Check if we need to round; if so, then we do that by manipulating - // (incrementing) the mantissa before beginning to print characters. - FormatARound(precision_specified, state, &leading, &mantissa, &exp); - - // ============= Format Result =============== - // This buffer holds the "0x1.ab1de3" portion of "0x1.ab1de3pe+2". Compute the - // size with long double which is the largest of the floats. - constexpr size_t kBufSizeForHexFloatRepr = +} + +// Round up the text digits starting at `p`. +// The buffer must have an extra digit that is known to not need rounding. +// This is done below by having an extra '0' digit on the left. +void RoundUp(char *p) { + while (*p == '9' || *p == '.') { + if (*p == '9') *p = '0'; + --p; + } + ++*p; +} + +// Check the previous digit and round up or down to follow the round-to-even +// policy. +void RoundToEven(char *p) { + if (*p == '.') --p; + if (*p % 2 == 1) RoundUp(p); +} + +// Simple integral decimal digit printing for values that fit in 64-bits. +// Returns the pointer to the last written digit. +char *PrintIntegralDigitsFromRightFast(uint64_t v, char *p) { + do { + *--p = DivideBy10WithCarry(&v, 0) + '0'; + } while (v != 0); + return p; +} + +// Simple integral decimal digit printing for values that fit in 128-bits. +// Returns the pointer to the last written digit. +char *PrintIntegralDigitsFromRightFast(uint128 v, char *p) { + auto high = static_cast<uint64_t>(v >> 64); + auto low = static_cast<uint64_t>(v); + + while (high != 0) { + uint64_t carry = DivideBy10WithCarry(&high, 0); + carry = DivideBy10WithCarry(&low, carry); + *--p = carry + '0'; + } + return PrintIntegralDigitsFromRightFast(low, p); +} + +// Simple fractional decimal digit printing for values that fir in 64-bits after +// shifting. +// Performs rounding if necessary to fit within `precision`. +// Returns the pointer to one after the last character written. +char *PrintFractionalDigitsFast(uint64_t v, char *start, int exp, + int precision) { + char *p = start; + v <<= (64 - exp); + while (precision > 0) { + if (!v) return p; + *p++ = MultiplyBy10WithCarry(&v, uint64_t{0}) + '0'; + --precision; + } + + // We need to round. + if (v < 0x8000000000000000) { + // We round down, so nothing to do. + } else if (v > 0x8000000000000000) { + // We round up. + RoundUp(p - 1); + } else { + RoundToEven(p - 1); + } + + assert(precision == 0); + // Precision can only be zero here. + return p; +} + +// Simple fractional decimal digit printing for values that fir in 128-bits +// after shifting. +// Performs rounding if necessary to fit within `precision`. +// Returns the pointer to one after the last character written. +char *PrintFractionalDigitsFast(uint128 v, char *start, int exp, + int precision) { + char *p = start; + v <<= (128 - exp); + auto high = static_cast<uint64_t>(v >> 64); + auto low = static_cast<uint64_t>(v); + + // While we have digits to print and `low` is not empty, do the long + // multiplication. + while (precision > 0 && low != 0) { + uint64_t carry = MultiplyBy10WithCarry(&low, uint64_t{0}); + carry = MultiplyBy10WithCarry(&high, carry); + + *p++ = carry + '0'; + --precision; + } + + // Now `low` is empty, so use a faster approach for the rest of the digits. + // This block is pretty much the same as the main loop for the 64-bit case + // above. + while (precision > 0) { + if (!high) return p; + *p++ = MultiplyBy10WithCarry(&high, uint64_t{0}) + '0'; + --precision; + } + + // We need to round. + if (high < 0x8000000000000000) { + // We round down, so nothing to do. + } else if (high > 0x8000000000000000 || low != 0) { + // We round up. + RoundUp(p - 1); + } else { + RoundToEven(p - 1); + } + + assert(precision == 0); + // Precision can only be zero here. + return p; +} + +struct FormatState { + char sign_char; + int precision; + const FormatConversionSpecImpl &conv; + FormatSinkImpl *sink; + + // In `alt` mode (flag #) we keep the `.` even if there are no fractional + // digits. In non-alt mode, we strip it. + bool ShouldPrintDot() const { return precision != 0 || conv.has_alt_flag(); } +}; + +struct Padding { + int left_spaces; + int zeros; + int right_spaces; +}; + +Padding ExtraWidthToPadding(size_t total_size, const FormatState &state) { + if (state.conv.width() < 0 || + static_cast<size_t>(state.conv.width()) <= total_size) { + return {0, 0, 0}; + } + int missing_chars = state.conv.width() - total_size; + if (state.conv.has_left_flag()) { + return {0, 0, missing_chars}; + } else if (state.conv.has_zero_flag()) { + return {0, missing_chars, 0}; + } else { + return {missing_chars, 0, 0}; + } +} + +void FinalPrint(const FormatState &state, absl::string_view data, + int padding_offset, int trailing_zeros, + absl::string_view data_postfix) { + if (state.conv.width() < 0) { + // No width specified. Fast-path. + if (state.sign_char != '\0') state.sink->Append(1, state.sign_char); + state.sink->Append(data); + state.sink->Append(trailing_zeros, '0'); + state.sink->Append(data_postfix); + return; + } + + auto padding = ExtraWidthToPadding((state.sign_char != '\0' ? 1 : 0) + + data.size() + data_postfix.size() + + static_cast<size_t>(trailing_zeros), + state); + + state.sink->Append(padding.left_spaces, ' '); + if (state.sign_char != '\0') state.sink->Append(1, state.sign_char); + // Padding in general needs to be inserted somewhere in the middle of `data`. + state.sink->Append(data.substr(0, padding_offset)); + state.sink->Append(padding.zeros, '0'); + state.sink->Append(data.substr(padding_offset)); + state.sink->Append(trailing_zeros, '0'); + state.sink->Append(data_postfix); + state.sink->Append(padding.right_spaces, ' '); +} + +// Fastpath %f formatter for when the shifted value fits in a simple integral +// type. +// Prints `v*2^exp` with the options from `state`. +template <typename Int> +void FormatFFast(Int v, int exp, const FormatState &state) { + constexpr int input_bits = sizeof(Int) * 8; + + static constexpr size_t integral_size = + /* in case we need to round up an extra digit */ 1 + + /* decimal digits for uint128 */ 40 + 1; + char buffer[integral_size + /* . */ 1 + /* max digits uint128 */ 128]; + buffer[integral_size] = '.'; + char *const integral_digits_end = buffer + integral_size; + char *integral_digits_start; + char *const fractional_digits_start = buffer + integral_size + 1; + char *fractional_digits_end = fractional_digits_start; + + if (exp >= 0) { + const int total_bits = input_bits - LeadingZeros(v) + exp; + integral_digits_start = + total_bits <= 64 + ? PrintIntegralDigitsFromRightFast(static_cast<uint64_t>(v) << exp, + integral_digits_end) + : PrintIntegralDigitsFromRightFast(static_cast<uint128>(v) << exp, + integral_digits_end); + } else { + exp = -exp; + + integral_digits_start = PrintIntegralDigitsFromRightFast( + exp < input_bits ? v >> exp : 0, integral_digits_end); + // PrintFractionalDigits may pull a carried 1 all the way up through the + // integral portion. + integral_digits_start[-1] = '0'; + + fractional_digits_end = + exp <= 64 ? PrintFractionalDigitsFast(v, fractional_digits_start, exp, + state.precision) + : PrintFractionalDigitsFast(static_cast<uint128>(v), + fractional_digits_start, exp, + state.precision); + // There was a carry, so include the first digit too. + if (integral_digits_start[-1] != '0') --integral_digits_start; + } + + size_t size = fractional_digits_end - integral_digits_start; + + // In `alt` mode (flag #) we keep the `.` even if there are no fractional + // digits. In non-alt mode, we strip it. + if (!state.ShouldPrintDot()) --size; + FinalPrint(state, absl::string_view(integral_digits_start, size), + /*padding_offset=*/0, + static_cast<int>(state.precision - (fractional_digits_end - + fractional_digits_start)), + /*data_postfix=*/""); +} + +// Slow %f formatter for when the shifted value does not fit in a uint128, and +// `exp > 0`. +// Prints `v*2^exp` with the options from `state`. +// This one is guaranteed to not have fractional digits, so we don't have to +// worry about anything after the `.`. +void FormatFPositiveExpSlow(uint128 v, int exp, const FormatState &state) { + BinaryToDecimal::RunConversion(v, exp, [&](BinaryToDecimal btd) { + const size_t total_digits = + btd.TotalDigits() + + (state.ShouldPrintDot() ? static_cast<size_t>(state.precision) + 1 : 0); + + const auto padding = ExtraWidthToPadding( + total_digits + (state.sign_char != '\0' ? 1 : 0), state); + + state.sink->Append(padding.left_spaces, ' '); + if (state.sign_char != '\0') state.sink->Append(1, state.sign_char); + state.sink->Append(padding.zeros, '0'); + + do { + state.sink->Append(btd.CurrentDigits()); + } while (btd.AdvanceDigits()); + + if (state.ShouldPrintDot()) state.sink->Append(1, '.'); + state.sink->Append(state.precision, '0'); + state.sink->Append(padding.right_spaces, ' '); + }); +} + +// Slow %f formatter for when the shifted value does not fit in a uint128, and +// `exp < 0`. +// Prints `v*2^exp` with the options from `state`. +// This one is guaranteed to be < 1.0, so we don't have to worry about integral +// digits. +void FormatFNegativeExpSlow(uint128 v, int exp, const FormatState &state) { + const size_t total_digits = + /* 0 */ 1 + + (state.ShouldPrintDot() ? static_cast<size_t>(state.precision) + 1 : 0); + auto padding = + ExtraWidthToPadding(total_digits + (state.sign_char ? 1 : 0), state); + padding.zeros += 1; + state.sink->Append(padding.left_spaces, ' '); + if (state.sign_char != '\0') state.sink->Append(1, state.sign_char); + state.sink->Append(padding.zeros, '0'); + + if (state.ShouldPrintDot()) state.sink->Append(1, '.'); + + // Print digits + int digits_to_go = state.precision; + + FractionalDigitGenerator::RunConversion( + v, exp, [&](FractionalDigitGenerator digit_gen) { + // There are no digits to print here. + if (state.precision == 0) return; + + // We go one digit at a time, while keeping track of runs of nines. + // The runs of nines are used to perform rounding when necessary. + + while (digits_to_go > 0 && digit_gen.HasMoreDigits()) { + auto digits = digit_gen.GetDigits(); + + // Now we have a digit and a run of nines. + // See if we can print them all. + if (digits.num_nines + 1 < digits_to_go) { + // We don't have to round yet, so print them. + state.sink->Append(1, digits.digit_before_nine + '0'); + state.sink->Append(digits.num_nines, '9'); + digits_to_go -= digits.num_nines + 1; + + } else { + // We can't print all the nines, see where we have to truncate. + + bool round_up = false; + if (digits.num_nines + 1 > digits_to_go) { + // We round up at a nine. No need to print them. + round_up = true; + } else { + // We can fit all the nines, but truncate just after it. + if (digit_gen.IsGreaterThanHalf()) { + round_up = true; + } else if (digit_gen.IsExactlyHalf()) { + // Round to even + round_up = + digits.num_nines != 0 || digits.digit_before_nine % 2 == 1; + } + } + + if (round_up) { + state.sink->Append(1, digits.digit_before_nine + '1'); + --digits_to_go; + // The rest will be zeros. + } else { + state.sink->Append(1, digits.digit_before_nine + '0'); + state.sink->Append(digits_to_go - 1, '9'); + digits_to_go = 0; + } + return; + } + } + }); + + state.sink->Append(digits_to_go, '0'); + state.sink->Append(padding.right_spaces, ' '); +} + +template <typename Int> +void FormatF(Int mantissa, int exp, const FormatState &state) { + if (exp >= 0) { + const int total_bits = sizeof(Int) * 8 - LeadingZeros(mantissa) + exp; + + // Fallback to the slow stack-based approach if we can't do it in a 64 or + // 128 bit state. + if (ABSL_PREDICT_FALSE(total_bits > 128)) { + return FormatFPositiveExpSlow(mantissa, exp, state); + } + } else { + // Fallback to the slow stack-based approach if we can't do it in a 64 or + // 128 bit state. + if (ABSL_PREDICT_FALSE(exp < -128)) { + return FormatFNegativeExpSlow(mantissa, -exp, state); + } + } + return FormatFFast(mantissa, exp, state); +} + +// Grab the group of four bits (nibble) from `n`. E.g., nibble 1 corresponds to +// bits 4-7. +template <typename Int> +uint8_t GetNibble(Int n, int nibble_index) { + constexpr Int mask_low_nibble = Int{0xf}; + int shift = nibble_index * 4; + n &= mask_low_nibble << shift; + return static_cast<uint8_t>((n >> shift) & 0xf); +} + +// Add one to the given nibble, applying carry to higher nibbles. Returns true +// if overflow, false otherwise. +template <typename Int> +bool IncrementNibble(int nibble_index, Int *n) { + constexpr int kShift = sizeof(Int) * 8 - 1; + constexpr int kNumNibbles = sizeof(Int) * 8 / 4; + Int before = *n >> kShift; + // Here we essentially want to take the number 1 and move it into the requsted + // nibble, then add it to *n to effectively increment the nibble. However, + // ASan will complain if we try to shift the 1 beyond the limits of the Int, + // i.e., if the nibble_index is out of range. So therefore we check for this + // and if we are out of range we just add 0 which leaves *n unchanged, which + // seems like the reasonable thing to do in that case. + *n += ((nibble_index >= kNumNibbles) ? 0 : (Int{1} << (nibble_index * 4))); + Int after = *n >> kShift; + return (before && !after) || (nibble_index >= kNumNibbles); +} + +// Return a mask with 1's in the given nibble and all lower nibbles. +template <typename Int> +Int MaskUpToNibbleInclusive(int nibble_index) { + constexpr int kNumNibbles = sizeof(Int) * 8 / 4; + static const Int ones = ~Int{0}; + return ones >> std::max(0, 4 * (kNumNibbles - nibble_index - 1)); +} + +// Return a mask with 1's below the given nibble. +template <typename Int> +Int MaskUpToNibbleExclusive(int nibble_index) { + return nibble_index <= 0 ? 0 : MaskUpToNibbleInclusive<Int>(nibble_index - 1); +} + +template <typename Int> +Int MoveToNibble(uint8_t nibble, int nibble_index) { + return Int{nibble} << (4 * nibble_index); +} + +// Given mantissa size, find optimal # of mantissa bits to put in initial digit. +// +// In the hex representation we keep a single hex digit to the left of the dot. +// However, the question as to how many bits of the mantissa should be put into +// that hex digit in theory is arbitrary, but in practice it is optimal to +// choose based on the size of the mantissa. E.g., for a `double`, there are 53 +// mantissa bits, so that means that we should put 1 bit to the left of the dot, +// thereby leaving 52 bits to the right, which is evenly divisible by four and +// thus all fractional digits represent actual precision. For a `long double`, +// on the other hand, there are 64 bits of mantissa, thus we can use all four +// bits for the initial hex digit and still have a number left over (60) that is +// a multiple of four. Once again, the goal is to have all fractional digits +// represent real precision. +template <typename Float> +constexpr int HexFloatLeadingDigitSizeInBits() { + return std::numeric_limits<Float>::digits % 4 > 0 + ? std::numeric_limits<Float>::digits % 4 + : 4; +} + +// This function captures the rounding behavior of glibc for hex float +// representations. E.g. when rounding 0x1.ab800000 to a precision of .2 +// ("%.2a") glibc will round up because it rounds toward the even number (since +// 0xb is an odd number, it will round up to 0xc). However, when rounding at a +// point that is not followed by 800000..., it disregards the parity and rounds +// up if > 8 and rounds down if < 8. +template <typename Int> +bool HexFloatNeedsRoundUp(Int mantissa, int final_nibble_displayed, + uint8_t leading) { + // If the last nibble (hex digit) to be displayed is the lowest on in the + // mantissa then that means that we don't have any further nibbles to inform + // rounding, so don't round. + if (final_nibble_displayed <= 0) { + return false; + } + int rounding_nibble_idx = final_nibble_displayed - 1; + constexpr int kTotalNibbles = sizeof(Int) * 8 / 4; + assert(final_nibble_displayed <= kTotalNibbles); + Int mantissa_up_to_rounding_nibble_inclusive = + mantissa & MaskUpToNibbleInclusive<Int>(rounding_nibble_idx); + Int eight = MoveToNibble<Int>(8, rounding_nibble_idx); + if (mantissa_up_to_rounding_nibble_inclusive != eight) { + return mantissa_up_to_rounding_nibble_inclusive > eight; + } + // Nibble in question == 8. + uint8_t round_if_odd = (final_nibble_displayed == kTotalNibbles) + ? leading + : GetNibble(mantissa, final_nibble_displayed); + return round_if_odd % 2 == 1; +} + +// Stores values associated with a Float type needed by the FormatA +// implementation in order to avoid templatizing that function by the Float +// type. +struct HexFloatTypeParams { + template <typename Float> + explicit HexFloatTypeParams(Float) + : min_exponent(std::numeric_limits<Float>::min_exponent - 1), + leading_digit_size_bits(HexFloatLeadingDigitSizeInBits<Float>()) { + assert(leading_digit_size_bits >= 1 && leading_digit_size_bits <= 4); + } + + int min_exponent; + int leading_digit_size_bits; +}; + +// Hex Float Rounding. First check if we need to round; if so, then we do that +// by manipulating (incrementing) the mantissa, that way we can later print the +// mantissa digits by iterating through them in the same way regardless of +// whether a rounding happened. +template <typename Int> +void FormatARound(bool precision_specified, const FormatState &state, + uint8_t *leading, Int *mantissa, int *exp) { + constexpr int kTotalNibbles = sizeof(Int) * 8 / 4; + // Index of the last nibble that we could display given precision. + int final_nibble_displayed = + precision_specified ? std::max(0, (kTotalNibbles - state.precision)) : 0; + if (HexFloatNeedsRoundUp(*mantissa, final_nibble_displayed, *leading)) { + // Need to round up. + bool overflow = IncrementNibble(final_nibble_displayed, mantissa); + *leading += (overflow ? 1 : 0); + if (ABSL_PREDICT_FALSE(*leading > 15)) { + // We have overflowed the leading digit. This would mean that we would + // need two hex digits to the left of the dot, which is not allowed. So + // adjust the mantissa and exponent so that the result is always 1.0eXXX. + *leading = 1; + *mantissa = 0; + *exp += 4; + } + } + // Now that we have handled a possible round-up we can go ahead and zero out + // all the nibbles of the mantissa that we won't need. + if (precision_specified) { + *mantissa &= ~MaskUpToNibbleExclusive<Int>(final_nibble_displayed); + } +} + +template <typename Int> +void FormatANormalize(const HexFloatTypeParams float_traits, uint8_t *leading, + Int *mantissa, int *exp) { + constexpr int kIntBits = sizeof(Int) * 8; + static const Int kHighIntBit = Int{1} << (kIntBits - 1); + const int kLeadDigitBitsCount = float_traits.leading_digit_size_bits; + // Normalize mantissa so that highest bit set is in MSB position, unless we + // get interrupted by the exponent threshold. + while (*mantissa && !(*mantissa & kHighIntBit)) { + if (ABSL_PREDICT_FALSE(*exp - 1 < float_traits.min_exponent)) { + *mantissa >>= (float_traits.min_exponent - *exp); + *exp = float_traits.min_exponent; + return; + } + *mantissa <<= 1; + --*exp; + } + // Extract bits for leading digit then shift them away leaving the + // fractional part. + *leading = + static_cast<uint8_t>(*mantissa >> (kIntBits - kLeadDigitBitsCount)); + *exp -= (*mantissa != 0) ? kLeadDigitBitsCount : *exp; + *mantissa <<= kLeadDigitBitsCount; +} + +template <typename Int> +void FormatA(const HexFloatTypeParams float_traits, Int mantissa, int exp, + bool uppercase, const FormatState &state) { + // Int properties. + constexpr int kIntBits = sizeof(Int) * 8; + constexpr int kTotalNibbles = sizeof(Int) * 8 / 4; + // Did the user specify a precision explicitly? + const bool precision_specified = state.conv.precision() >= 0; + + // ========== Normalize/Denormalize ========== + exp += kIntBits; // make all digits fractional digits. + // This holds the (up to four) bits of leading digit, i.e., the '1' in the + // number 0x1.e6fp+2. It's always > 0 unless number is zero or denormal. + uint8_t leading = 0; + FormatANormalize(float_traits, &leading, &mantissa, &exp); + + // =============== Rounding ================== + // Check if we need to round; if so, then we do that by manipulating + // (incrementing) the mantissa before beginning to print characters. + FormatARound(precision_specified, state, &leading, &mantissa, &exp); + + // ============= Format Result =============== + // This buffer holds the "0x1.ab1de3" portion of "0x1.ab1de3pe+2". Compute the + // size with long double which is the largest of the floats. + constexpr size_t kBufSizeForHexFloatRepr = 2 // 0x + std::numeric_limits<MaxFloatType>::digits / 4 // number of hex digits + 1 // round up + 1; // "." (dot) - char digits_buffer[kBufSizeForHexFloatRepr]; - char *digits_iter = digits_buffer; - const char *const digits = - static_cast<const char *>("0123456789ABCDEF0123456789abcdef") + - (uppercase ? 0 : 16); - - // =============== Hex Prefix ================ - *digits_iter++ = '0'; - *digits_iter++ = uppercase ? 'X' : 'x'; - - // ========== Non-Fractional Digit =========== - *digits_iter++ = digits[leading]; - - // ================== Dot ==================== - // There are three reasons we might need a dot. Keep in mind that, at this - // point, the mantissa holds only the fractional part. - if ((precision_specified && state.precision > 0) || - (!precision_specified && mantissa > 0) || state.conv.has_alt_flag()) { - *digits_iter++ = '.'; - } - - // ============ Fractional Digits ============ - int digits_emitted = 0; - while (mantissa > 0) { - *digits_iter++ = digits[GetNibble(mantissa, kTotalNibbles - 1)]; - mantissa <<= 4; - ++digits_emitted; - } - int trailing_zeros = - precision_specified ? state.precision - digits_emitted : 0; - assert(trailing_zeros >= 0); - auto digits_result = string_view(digits_buffer, digits_iter - digits_buffer); - - // =============== Exponent ================== - constexpr size_t kBufSizeForExpDecRepr = - numbers_internal::kFastToBufferSize // requred for FastIntToBuffer - + 1 // 'p' or 'P' - + 1; // '+' or '-' - char exp_buffer[kBufSizeForExpDecRepr]; - exp_buffer[0] = uppercase ? 'P' : 'p'; - exp_buffer[1] = exp >= 0 ? '+' : '-'; - numbers_internal::FastIntToBuffer(exp < 0 ? -exp : exp, exp_buffer + 2); - - // ============ Assemble Result ============== - FinalPrint(state, // - digits_result, // 0xN.NNN... - 2, // offset in `data` to start padding if needed. - trailing_zeros, // num remaining mantissa padding zeros - exp_buffer); // exponent -} - -char *CopyStringTo(absl::string_view v, char *out) { + char digits_buffer[kBufSizeForHexFloatRepr]; + char *digits_iter = digits_buffer; + const char *const digits = + static_cast<const char *>("0123456789ABCDEF0123456789abcdef") + + (uppercase ? 0 : 16); + + // =============== Hex Prefix ================ + *digits_iter++ = '0'; + *digits_iter++ = uppercase ? 'X' : 'x'; + + // ========== Non-Fractional Digit =========== + *digits_iter++ = digits[leading]; + + // ================== Dot ==================== + // There are three reasons we might need a dot. Keep in mind that, at this + // point, the mantissa holds only the fractional part. + if ((precision_specified && state.precision > 0) || + (!precision_specified && mantissa > 0) || state.conv.has_alt_flag()) { + *digits_iter++ = '.'; + } + + // ============ Fractional Digits ============ + int digits_emitted = 0; + while (mantissa > 0) { + *digits_iter++ = digits[GetNibble(mantissa, kTotalNibbles - 1)]; + mantissa <<= 4; + ++digits_emitted; + } + int trailing_zeros = + precision_specified ? state.precision - digits_emitted : 0; + assert(trailing_zeros >= 0); + auto digits_result = string_view(digits_buffer, digits_iter - digits_buffer); + + // =============== Exponent ================== + constexpr size_t kBufSizeForExpDecRepr = + numbers_internal::kFastToBufferSize // requred for FastIntToBuffer + + 1 // 'p' or 'P' + + 1; // '+' or '-' + char exp_buffer[kBufSizeForExpDecRepr]; + exp_buffer[0] = uppercase ? 'P' : 'p'; + exp_buffer[1] = exp >= 0 ? '+' : '-'; + numbers_internal::FastIntToBuffer(exp < 0 ? -exp : exp, exp_buffer + 2); + + // ============ Assemble Result ============== + FinalPrint(state, // + digits_result, // 0xN.NNN... + 2, // offset in `data` to start padding if needed. + trailing_zeros, // num remaining mantissa padding zeros + exp_buffer); // exponent +} + +char *CopyStringTo(absl::string_view v, char *out) { std::memcpy(out, v.data(), v.size()); return out + v.size(); } template <typename Float> -bool FallbackToSnprintf(const Float v, const FormatConversionSpecImpl &conv, +bool FallbackToSnprintf(const Float v, const FormatConversionSpecImpl &conv, FormatSinkImpl *sink) { int w = conv.width() >= 0 ? conv.width() : 0; int p = conv.precision() >= 0 ? conv.precision() : -1; @@ -946,22 +946,22 @@ bool FallbackToSnprintf(const Float v, const FormatConversionSpecImpl &conv, { char *fp = fmt; *fp++ = '%'; - fp = CopyStringTo(FormatConversionSpecImplFriend::FlagsToString(conv), fp); + fp = CopyStringTo(FormatConversionSpecImplFriend::FlagsToString(conv), fp); fp = CopyStringTo("*.*", fp); if (std::is_same<long double, Float>()) { *fp++ = 'L'; } - *fp++ = FormatConversionCharToChar(conv.conversion_char()); + *fp++ = FormatConversionCharToChar(conv.conversion_char()); *fp = 0; assert(fp < fmt + sizeof(fmt)); } std::string space(512, '\0'); - absl::string_view result; + absl::string_view result; while (true) { int n = snprintf(&space[0], space.size(), fmt, w, p, v); if (n < 0) return false; if (static_cast<size_t>(n) < space.size()) { - result = absl::string_view(space.data(), n); + result = absl::string_view(space.data(), n); break; } space.resize(n + 1); @@ -1014,24 +1014,24 @@ enum class FormatStyle { Fixed, Precision }; // Otherwise, return false. template <typename Float> bool ConvertNonNumericFloats(char sign_char, Float v, - const FormatConversionSpecImpl &conv, - FormatSinkImpl *sink) { + const FormatConversionSpecImpl &conv, + FormatSinkImpl *sink) { char text[4], *ptr = text; - if (sign_char != '\0') *ptr++ = sign_char; + if (sign_char != '\0') *ptr++ = sign_char; if (std::isnan(v)) { - ptr = std::copy_n( - FormatConversionCharIsUpper(conv.conversion_char()) ? "NAN" : "nan", 3, - ptr); + ptr = std::copy_n( + FormatConversionCharIsUpper(conv.conversion_char()) ? "NAN" : "nan", 3, + ptr); } else if (std::isinf(v)) { - ptr = std::copy_n( - FormatConversionCharIsUpper(conv.conversion_char()) ? "INF" : "inf", 3, - ptr); + ptr = std::copy_n( + FormatConversionCharIsUpper(conv.conversion_char()) ? "INF" : "inf", 3, + ptr); } else { return false; } return sink->PutPaddedString(string_view(text, ptr - text), conv.width(), -1, - conv.has_left_flag()); + conv.has_left_flag()); } // Round up the last digit of the value. @@ -1091,12 +1091,12 @@ constexpr bool CanFitMantissa() { template <typename Float> struct Decomposed { - using MantissaType = - absl::conditional_t<std::is_same<long double, Float>::value, uint128, - uint64_t>; - static_assert(std::numeric_limits<Float>::digits <= sizeof(MantissaType) * 8, - ""); - MantissaType mantissa; + using MantissaType = + absl::conditional_t<std::is_same<long double, Float>::value, uint128, + uint64_t>; + static_assert(std::numeric_limits<Float>::digits <= sizeof(MantissaType) * 8, + ""); + MantissaType mantissa; int exponent; }; @@ -1107,8 +1107,8 @@ Decomposed<Float> Decompose(Float v) { Float m = std::frexp(v, &exp); m = std::ldexp(m, std::numeric_limits<Float>::digits); exp -= std::numeric_limits<Float>::digits; - - return {static_cast<typename Decomposed<Float>::MantissaType>(m), exp}; + + return {static_cast<typename Decomposed<Float>::MantissaType>(m), exp}; } // Print 'digits' as decimal. @@ -1277,32 +1277,32 @@ bool FloatToBuffer(Decomposed<Float> decomposed, int precision, Buffer *out, return false; } -void WriteBufferToSink(char sign_char, absl::string_view str, - const FormatConversionSpecImpl &conv, - FormatSinkImpl *sink) { +void WriteBufferToSink(char sign_char, absl::string_view str, + const FormatConversionSpecImpl &conv, + FormatSinkImpl *sink) { int left_spaces = 0, zeros = 0, right_spaces = 0; int missing_chars = conv.width() >= 0 ? std::max(conv.width() - static_cast<int>(str.size()) - static_cast<int>(sign_char != 0), 0) : 0; - if (conv.has_left_flag()) { + if (conv.has_left_flag()) { right_spaces = missing_chars; - } else if (conv.has_zero_flag()) { + } else if (conv.has_zero_flag()) { zeros = missing_chars; } else { left_spaces = missing_chars; } sink->Append(left_spaces, ' '); - if (sign_char != '\0') sink->Append(1, sign_char); + if (sign_char != '\0') sink->Append(1, sign_char); sink->Append(zeros, '0'); sink->Append(str); sink->Append(right_spaces, ' '); } template <typename Float> -bool FloatToSink(const Float v, const FormatConversionSpecImpl &conv, +bool FloatToSink(const Float v, const FormatConversionSpecImpl &conv, FormatSinkImpl *sink) { // Print the sign or the sign column. Float abs_v = v; @@ -1310,9 +1310,9 @@ bool FloatToSink(const Float v, const FormatConversionSpecImpl &conv, if (std::signbit(abs_v)) { sign_char = '-'; abs_v = -abs_v; - } else if (conv.has_show_pos_flag()) { + } else if (conv.has_show_pos_flag()) { sign_char = '+'; - } else if (conv.has_sign_col_flag()) { + } else if (conv.has_sign_col_flag()) { sign_char = ' '; } @@ -1329,95 +1329,95 @@ bool FloatToSink(const Float v, const FormatConversionSpecImpl &conv, Buffer buffer; - FormatConversionChar c = conv.conversion_char(); - - if (c == FormatConversionCharInternal::f || - c == FormatConversionCharInternal::F) { - FormatF(decomposed.mantissa, decomposed.exponent, - {sign_char, precision, conv, sink}); - return true; - } else if (c == FormatConversionCharInternal::e || - c == FormatConversionCharInternal::E) { - if (!FloatToBuffer<FormatStyle::Precision>(decomposed, precision, &buffer, - &exp)) { - return FallbackToSnprintf(v, conv, sink); - } - if (!conv.has_alt_flag() && buffer.back() == '.') buffer.pop_back(); - PrintExponent( - exp, FormatConversionCharIsUpper(conv.conversion_char()) ? 'E' : 'e', - &buffer); - } else if (c == FormatConversionCharInternal::g || - c == FormatConversionCharInternal::G) { - precision = std::max(0, precision - 1); - if (!FloatToBuffer<FormatStyle::Precision>(decomposed, precision, &buffer, - &exp)) { - return FallbackToSnprintf(v, conv, sink); - } - if (precision + 1 > exp && exp >= -4) { - if (exp < 0) { - // Have 1.23456, needs 0.00123456 - // Move the first digit - buffer.begin[1] = *buffer.begin; - // Add some zeros - for (; exp < -1; ++exp) *buffer.begin-- = '0'; - *buffer.begin-- = '.'; - *buffer.begin = '0'; - } else if (exp > 0) { - // Have 1.23456, needs 1234.56 - // Move the '.' exp positions to the right. - std::rotate(buffer.begin + 1, buffer.begin + 2, buffer.begin + exp + 2); + FormatConversionChar c = conv.conversion_char(); + + if (c == FormatConversionCharInternal::f || + c == FormatConversionCharInternal::F) { + FormatF(decomposed.mantissa, decomposed.exponent, + {sign_char, precision, conv, sink}); + return true; + } else if (c == FormatConversionCharInternal::e || + c == FormatConversionCharInternal::E) { + if (!FloatToBuffer<FormatStyle::Precision>(decomposed, precision, &buffer, + &exp)) { + return FallbackToSnprintf(v, conv, sink); + } + if (!conv.has_alt_flag() && buffer.back() == '.') buffer.pop_back(); + PrintExponent( + exp, FormatConversionCharIsUpper(conv.conversion_char()) ? 'E' : 'e', + &buffer); + } else if (c == FormatConversionCharInternal::g || + c == FormatConversionCharInternal::G) { + precision = std::max(0, precision - 1); + if (!FloatToBuffer<FormatStyle::Precision>(decomposed, precision, &buffer, + &exp)) { + return FallbackToSnprintf(v, conv, sink); + } + if (precision + 1 > exp && exp >= -4) { + if (exp < 0) { + // Have 1.23456, needs 0.00123456 + // Move the first digit + buffer.begin[1] = *buffer.begin; + // Add some zeros + for (; exp < -1; ++exp) *buffer.begin-- = '0'; + *buffer.begin-- = '.'; + *buffer.begin = '0'; + } else if (exp > 0) { + // Have 1.23456, needs 1234.56 + // Move the '.' exp positions to the right. + std::rotate(buffer.begin + 1, buffer.begin + 2, buffer.begin + exp + 2); } - exp = 0; - } - if (!conv.has_alt_flag()) { - while (buffer.back() == '0') buffer.pop_back(); - if (buffer.back() == '.') buffer.pop_back(); - } - if (exp) { - PrintExponent( - exp, FormatConversionCharIsUpper(conv.conversion_char()) ? 'E' : 'e', - &buffer); - } - } else if (c == FormatConversionCharInternal::a || - c == FormatConversionCharInternal::A) { - bool uppercase = (c == FormatConversionCharInternal::A); - FormatA(HexFloatTypeParams(Float{}), decomposed.mantissa, - decomposed.exponent, uppercase, {sign_char, precision, conv, sink}); - return true; - } else { - return false; + exp = 0; + } + if (!conv.has_alt_flag()) { + while (buffer.back() == '0') buffer.pop_back(); + if (buffer.back() == '.') buffer.pop_back(); + } + if (exp) { + PrintExponent( + exp, FormatConversionCharIsUpper(conv.conversion_char()) ? 'E' : 'e', + &buffer); + } + } else if (c == FormatConversionCharInternal::a || + c == FormatConversionCharInternal::A) { + bool uppercase = (c == FormatConversionCharInternal::A); + FormatA(HexFloatTypeParams(Float{}), decomposed.mantissa, + decomposed.exponent, uppercase, {sign_char, precision, conv, sink}); + return true; + } else { + return false; } WriteBufferToSink(sign_char, - absl::string_view(buffer.begin, buffer.end - buffer.begin), - conv, sink); + absl::string_view(buffer.begin, buffer.end - buffer.begin), + conv, sink); return true; } } // namespace -bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv, +bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv, FormatSinkImpl *sink) { if (IsDoubleDouble()) { // This is the `double-double` representation of `long double`. We do not // handle it natively. Fallback to snprintf. - return FallbackToSnprintf(v, conv, sink); - } - + return FallbackToSnprintf(v, conv, sink); + } + return FloatToSink(v, conv, sink); } -bool ConvertFloatImpl(float v, const FormatConversionSpecImpl &conv, +bool ConvertFloatImpl(float v, const FormatConversionSpecImpl &conv, FormatSinkImpl *sink) { - return FloatToSink(static_cast<double>(v), conv, sink); + return FloatToSink(static_cast<double>(v), conv, sink); } -bool ConvertFloatImpl(double v, const FormatConversionSpecImpl &conv, +bool ConvertFloatImpl(double v, const FormatConversionSpecImpl &conv, FormatSinkImpl *sink) { return FloatToSink(v, conv, sink); } } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.h index 71100e7142..5d44c4b5e9 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/float_conversion.h @@ -1,37 +1,37 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. - +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. + #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_ #include "absl/strings/internal/str_format/extension.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { -bool ConvertFloatImpl(float v, const FormatConversionSpecImpl &conv, +bool ConvertFloatImpl(float v, const FormatConversionSpecImpl &conv, FormatSinkImpl *sink); -bool ConvertFloatImpl(double v, const FormatConversionSpecImpl &conv, +bool ConvertFloatImpl(double v, const FormatConversionSpecImpl &conv, FormatSinkImpl *sink); -bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv, +bool ConvertFloatImpl(long double v, const FormatConversionSpecImpl &conv, FormatSinkImpl *sink); } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_FLOAT_CONVERSION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/output.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/output.cc index c4b2470613..f96aa1ecaa 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/output.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/output.cc @@ -18,7 +18,7 @@ #include <cstring> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { namespace { @@ -68,5 +68,5 @@ void FILERawSink::Write(string_view v) { } } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/output.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/output.h index 8030dae00f..3eb18ccd47 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/output.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/output.h @@ -29,7 +29,7 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { // RawSink implementation that writes into a char* buffer. @@ -82,15 +82,15 @@ inline void AbslFormatFlush(BufferRawSink* sink, string_view v) { sink->Write(v); } -// This is a SFINAE to get a better compiler error message when the type -// is not supported. +// This is a SFINAE to get a better compiler error message when the type +// is not supported. template <typename T> -auto InvokeFlush(T* out, string_view s) -> decltype(AbslFormatFlush(out, s)) { - AbslFormatFlush(out, s); +auto InvokeFlush(T* out, string_view s) -> decltype(AbslFormatFlush(out, s)) { + AbslFormatFlush(out, s); } } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_OUTPUT_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.cc index 2c9c07dacc..b7ace91c1b 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.cc @@ -1,17 +1,17 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. - +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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 "absl/strings/internal/str_format/parser.h" #include <assert.h> @@ -28,12 +28,12 @@ #include <unordered_set> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { -using CC = FormatConversionCharInternal; -using LM = LengthMod; - +using CC = FormatConversionCharInternal; +using LM = LengthMod; + // Abbreviations to fit in the table below. constexpr auto f_sign = Flags::kSignCol; constexpr auto f_alt = Flags::kAlt; @@ -209,11 +209,11 @@ const char *ConsumeConversion(const char *pos, const char *const end, using str_format_internal::LengthMod; LengthMod length_mod = tag.as_length(); ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); - if (c == 'h' && length_mod == LengthMod::h) { - conv->length_mod = LengthMod::hh; + if (c == 'h' && length_mod == LengthMod::h) { + conv->length_mod = LengthMod::hh; ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); - } else if (c == 'l' && length_mod == LengthMod::l) { - conv->length_mod = LengthMod::ll; + } else if (c == 'l' && length_mod == LengthMod::l) { + conv->length_mod = LengthMod::ll; ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR(); } else { conv->length_mod = length_mod; @@ -232,32 +232,32 @@ const char *ConsumeConversion(const char *pos, const char *const end, } // namespace -std::string LengthModToString(LengthMod v) { - switch (v) { - case LengthMod::h: - return "h"; - case LengthMod::hh: - return "hh"; - case LengthMod::l: - return "l"; - case LengthMod::ll: - return "ll"; - case LengthMod::L: - return "L"; - case LengthMod::j: - return "j"; - case LengthMod::z: - return "z"; - case LengthMod::t: - return "t"; - case LengthMod::q: - return "q"; - case LengthMod::none: - return ""; - } - return ""; -} - +std::string LengthModToString(LengthMod v) { + switch (v) { + case LengthMod::h: + return "h"; + case LengthMod::hh: + return "hh"; + case LengthMod::l: + return "l"; + case LengthMod::ll: + return "ll"; + case LengthMod::L: + return "L"; + case LengthMod::j: + return "j"; + case LengthMod::z: + return "z"; + case LengthMod::t: + return "t"; + case LengthMod::q: + return "q"; + case LengthMod::none: + return ""; + } + return ""; +} + const char *ConsumeUnboundConversion(const char *p, const char *end, UnboundConversion *conv, int *next_arg) { if (*next_arg < 0) return ConsumeConversion<true>(p, end, conv, next_arg); @@ -299,17 +299,17 @@ struct ParsedFormatBase::ParsedFormatConsumer { char* data_pos; }; -ParsedFormatBase::ParsedFormatBase( - string_view format, bool allow_ignored, - std::initializer_list<FormatConversionCharSet> convs) +ParsedFormatBase::ParsedFormatBase( + string_view format, bool allow_ignored, + std::initializer_list<FormatConversionCharSet> convs) : data_(format.empty() ? nullptr : new char[format.size()]) { has_error_ = !ParseFormatString(format, ParsedFormatConsumer(this)) || !MatchesConversions(allow_ignored, convs); } bool ParsedFormatBase::MatchesConversions( - bool allow_ignored, - std::initializer_list<FormatConversionCharSet> convs) const { + bool allow_ignored, + std::initializer_list<FormatConversionCharSet> convs) const { std::unordered_set<int> used; auto add_if_valid_conv = [&](int pos, char c) { if (static_cast<size_t>(pos) > convs.size() || @@ -327,13 +327,13 @@ bool ParsedFormatBase::MatchesConversions( if (conv.width.is_from_arg() && !add_if_valid_conv(conv.width.get_from_arg(), '*')) return false; - if (!add_if_valid_conv(conv.arg_position, - FormatConversionCharToChar(conv.conv))) - return false; + if (!add_if_valid_conv(conv.arg_position, + FormatConversionCharToChar(conv.conv))) + return false; } return used.size() == convs.size() || allow_ignored; } } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h index ad8646edff..c0db5b4335 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_format/parser.h @@ -1,17 +1,17 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. - +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. + #ifndef ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_ @@ -20,25 +20,25 @@ #include <stdlib.h> #include <cassert> -#include <cstdint> +#include <cstdint> #include <initializer_list> #include <iosfwd> #include <iterator> #include <memory> -#include <string> +#include <string> #include <vector> #include "absl/strings/internal/str_format/checker.h" #include "absl/strings/internal/str_format/extension.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace str_format_internal { -enum class LengthMod : std::uint8_t { h, hh, l, ll, L, j, z, t, q, none }; - -std::string LengthModToString(LengthMod v); - +enum class LengthMod : std::uint8_t { h, hh, l, ll, L, j, z, t, q, none }; + +std::string LengthModToString(LengthMod v); + // The analyzed properties of a single specified conversion. struct UnboundConversion { UnboundConversion() {} @@ -77,8 +77,8 @@ struct UnboundConversion { InputValue precision; Flags flags = Flags::kBasic; - LengthMod length_mod = LengthMod::none; - FormatConversionChar conv = FormatConversionCharInternal::kNone; + LengthMod length_mod = LengthMod::none; + FormatConversionChar conv = FormatConversionCharInternal::kNone; }; // Consume conversion spec prefix (not including '%') of [p, end) if valid. @@ -91,12 +91,12 @@ const char* ConsumeUnboundConversion(const char* p, const char* end, // Helper tag class for the table below. // It allows fast `char -> ConversionChar/LengthMod/Flags` checking and -// conversions. +// conversions. class ConvTag { public: - constexpr ConvTag(FormatConversionChar conversion_char) // NOLINT + constexpr ConvTag(FormatConversionChar conversion_char) // NOLINT : tag_(static_cast<uint8_t>(conversion_char)) {} - constexpr ConvTag(LengthMod length_mod) // NOLINT + constexpr ConvTag(LengthMod length_mod) // NOLINT : tag_(0x80 | static_cast<uint8_t>(length_mod)) {} constexpr ConvTag(Flags flags) // NOLINT : tag_(0xc0 | static_cast<uint8_t>(flags)) {} @@ -106,11 +106,11 @@ class ConvTag { bool is_length() const { return (tag_ & 0xC0) == 0x80; } bool is_flags() const { return (tag_ & 0xE0) == 0xC0; } - FormatConversionChar as_conv() const { + FormatConversionChar as_conv() const { assert(is_conv()); assert(!is_length()); assert(!is_flags()); - return static_cast<FormatConversionChar>(tag_); + return static_cast<FormatConversionChar>(tag_); } LengthMod as_length() const { assert(!is_conv()); @@ -165,7 +165,7 @@ bool ParseFormatString(string_view src, Consumer consumer) { auto tag = GetTagForChar(percent[1]); if (tag.is_conv()) { if (ABSL_PREDICT_FALSE(next_arg < 0)) { - // This indicates an error in the format string. + // This indicates an error in the format string. // The only way to get `next_arg < 0` here is to have a positional // argument first which sets next_arg to -1 and then a non-positional // argument. @@ -208,9 +208,9 @@ constexpr bool EnsureConstexpr(string_view s) { class ParsedFormatBase { public: - explicit ParsedFormatBase( - string_view format, bool allow_ignored, - std::initializer_list<FormatConversionCharSet> convs); + explicit ParsedFormatBase( + string_view format, bool allow_ignored, + std::initializer_list<FormatConversionCharSet> convs); ParsedFormatBase(const ParsedFormatBase& other) { *this = other; } @@ -257,9 +257,9 @@ class ParsedFormatBase { private: // Returns whether the conversions match and if !allow_ignored it verifies // that all conversions are used by the format. - bool MatchesConversions( - bool allow_ignored, - std::initializer_list<FormatConversionCharSet> convs) const; + bool MatchesConversions( + bool allow_ignored, + std::initializer_list<FormatConversionCharSet> convs) const; struct ParsedFormatConsumer; @@ -304,14 +304,14 @@ class ParsedFormatBase { // This is the only API that allows the user to pass a runtime specified format // string. These factory functions will return NULL if the format does not match // the conversions requested by the user. -template <FormatConversionCharSet... C> +template <FormatConversionCharSet... C> class ExtendedParsedFormat : public str_format_internal::ParsedFormatBase { public: explicit ExtendedParsedFormat(string_view format) -#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER +#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER __attribute__(( enable_if(str_format_internal::EnsureConstexpr(format), - "Format string is not constexpr."), + "Format string is not constexpr."), enable_if(str_format_internal::ValidFormatImpl<C...>(format), "Format specified does not match the template arguments."))) #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER @@ -351,7 +351,7 @@ class ExtendedParsedFormat : public str_format_internal::ParsedFormatBase { : ParsedFormatBase(s, allow_ignored, {C...}) {} }; } // namespace str_format_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_FORMAT_PARSER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_join_internal.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_join_internal.h index 31dbf672f0..86219f2016 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_join_internal.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_join_internal.h @@ -43,7 +43,7 @@ #include "absl/strings/str_cat.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // @@ -308,7 +308,7 @@ std::string JoinRange(const Range& range, absl::string_view separator) { } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_JOIN_INTERNAL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/str_split_internal.h b/contrib/restricted/abseil-cpp/absl/strings/internal/str_split_internal.h index e766421617..a7229b6873 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/str_split_internal.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/str_split_internal.h @@ -47,7 +47,7 @@ #endif // _GLIBCXX_DEBUG namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // This class is implicitly constructible from everything that absl::string_view @@ -318,7 +318,7 @@ class Splitter { Container operator()(const Splitter& splitter) const { Container c; auto it = std::inserter(c, c.end()); - for (const auto& sp : splitter) { + for (const auto& sp : splitter) { *it++ = ValueType(sp); } return c; @@ -424,7 +424,7 @@ class Splitter { }; } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_STR_SPLIT_INTERNAL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/utf8.cc b/contrib/restricted/abseil-cpp/absl/strings/internal/utf8.cc index 8fd8edc1ec..66a2ca9496 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/utf8.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/utf8.cc @@ -17,7 +17,7 @@ #include "absl/strings/internal/utf8.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { size_t EncodeUTF8Char(char *buffer, char32_t utf8_char) { @@ -49,5 +49,5 @@ size_t EncodeUTF8Char(char *buffer, char32_t utf8_char) { } } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/internal/utf8.h b/contrib/restricted/abseil-cpp/absl/strings/internal/utf8.h index 32fb1093be..38ce7b97d8 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/internal/utf8.h +++ b/contrib/restricted/abseil-cpp/absl/strings/internal/utf8.h @@ -20,10 +20,10 @@ #include <cstddef> #include <cstdint> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // For Unicode code points 0 through 0x10FFFF, EncodeUTF8Char writes @@ -44,7 +44,7 @@ enum { kMaxEncodedUTF8Size = 4 }; size_t EncodeUTF8Char(char *buffer, char32_t utf8_char); } // namespace strings_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_INTERNAL_UTF8_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/match.cc b/contrib/restricted/abseil-cpp/absl/strings/match.cc index 2d67250970..c77d0ad322 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/match.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/match.cc @@ -17,7 +17,7 @@ #include "absl/strings/internal/memutil.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN bool EqualsIgnoreCase(absl::string_view piece1, absl::string_view piece2) noexcept { @@ -39,5 +39,5 @@ bool EndsWithIgnoreCase(absl::string_view text, EqualsIgnoreCase(text.substr(text.size() - suffix.size()), suffix); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/match.h b/contrib/restricted/abseil-cpp/absl/strings/match.h index 038cbb3fa8..d83d31ea1d 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/match.h +++ b/contrib/restricted/abseil-cpp/absl/strings/match.h @@ -20,7 +20,7 @@ // This file contains simple utilities for performing string matching checks. // All of these function parameters are specified as `absl::string_view`, // meaning that these functions can accept `std::string`, `absl::string_view` or -// NUL-terminated C-style strings. +// NUL-terminated C-style strings. // // Examples: // std::string s = "foo"; @@ -38,7 +38,7 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // StrContains() // @@ -94,7 +94,7 @@ bool StartsWithIgnoreCase(absl::string_view text, bool EndsWithIgnoreCase(absl::string_view text, absl::string_view suffix) noexcept; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_MATCH_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/numbers.cc b/contrib/restricted/abseil-cpp/absl/strings/numbers.cc index cbd84c918b..43550e3c4b 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/numbers.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/numbers.cc @@ -30,7 +30,7 @@ #include <memory> #include <utility> -#include "absl/base/attributes.h" +#include "absl/base/attributes.h" #include "absl/base/internal/raw_logging.h" #include "absl/numeric/bits.h" #include "absl/strings/ascii.h" @@ -41,7 +41,7 @@ #include "absl/strings/str_cat.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN bool SimpleAtof(absl::string_view str, float* out) { *out = 0.0; @@ -730,8 +730,8 @@ inline bool safe_parse_sign_and_base(absl::string_view* text /*inout*/, // commonly used bases. template <typename IntType> struct LookupTables { - ABSL_CONST_INIT static const IntType kVmaxOverBase[]; - ABSL_CONST_INIT static const IntType kVminOverBase[]; + ABSL_CONST_INIT static const IntType kVmaxOverBase[]; + ABSL_CONST_INIT static const IntType kVminOverBase[]; }; // An array initializer macro for X/base where base in [0, 36]. @@ -755,49 +755,49 @@ struct LookupTables { // } // See https://godbolt.org/z/aneYsb // -// uint128& operator/=(uint128) is not constexpr, so hardcode the resulting -// array to avoid a static initializer. +// uint128& operator/=(uint128) is not constexpr, so hardcode the resulting +// array to avoid a static initializer. template<> -const uint128 LookupTables<uint128>::kVmaxOverBase[] = { - 0, - 0, - MakeUint128(9223372036854775807u, 18446744073709551615u), - MakeUint128(6148914691236517205u, 6148914691236517205u), - MakeUint128(4611686018427387903u, 18446744073709551615u), - MakeUint128(3689348814741910323u, 3689348814741910323u), - MakeUint128(3074457345618258602u, 12297829382473034410u), - MakeUint128(2635249153387078802u, 5270498306774157604u), - MakeUint128(2305843009213693951u, 18446744073709551615u), - MakeUint128(2049638230412172401u, 14347467612885206812u), - MakeUint128(1844674407370955161u, 11068046444225730969u), - MakeUint128(1676976733973595601u, 8384883669867978007u), - MakeUint128(1537228672809129301u, 6148914691236517205u), - MakeUint128(1418980313362273201u, 4256940940086819603u), - MakeUint128(1317624576693539401u, 2635249153387078802u), - MakeUint128(1229782938247303441u, 1229782938247303441u), - MakeUint128(1152921504606846975u, 18446744073709551615u), - MakeUint128(1085102592571150095u, 1085102592571150095u), - MakeUint128(1024819115206086200u, 16397105843297379214u), - MakeUint128(970881267037344821u, 16504981539634861972u), - MakeUint128(922337203685477580u, 14757395258967641292u), - MakeUint128(878416384462359600u, 14054662151397753612u), - MakeUint128(838488366986797800u, 13415813871788764811u), - MakeUint128(802032351030850070u, 4812194106185100421u), - MakeUint128(768614336404564650u, 12297829382473034410u), - MakeUint128(737869762948382064u, 11805916207174113034u), - MakeUint128(709490156681136600u, 11351842506898185609u), - MakeUint128(683212743470724133u, 17080318586768103348u), - MakeUint128(658812288346769700u, 10540996613548315209u), - MakeUint128(636094623231363848u, 15266270957552732371u), - MakeUint128(614891469123651720u, 9838263505978427528u), - MakeUint128(595056260442243600u, 9520900167075897608u), - MakeUint128(576460752303423487u, 18446744073709551615u), - MakeUint128(558992244657865200u, 8943875914525843207u), - MakeUint128(542551296285575047u, 9765923333140350855u), - MakeUint128(527049830677415760u, 8432797290838652167u), - MakeUint128(512409557603043100u, 8198552921648689607u), -}; - +const uint128 LookupTables<uint128>::kVmaxOverBase[] = { + 0, + 0, + MakeUint128(9223372036854775807u, 18446744073709551615u), + MakeUint128(6148914691236517205u, 6148914691236517205u), + MakeUint128(4611686018427387903u, 18446744073709551615u), + MakeUint128(3689348814741910323u, 3689348814741910323u), + MakeUint128(3074457345618258602u, 12297829382473034410u), + MakeUint128(2635249153387078802u, 5270498306774157604u), + MakeUint128(2305843009213693951u, 18446744073709551615u), + MakeUint128(2049638230412172401u, 14347467612885206812u), + MakeUint128(1844674407370955161u, 11068046444225730969u), + MakeUint128(1676976733973595601u, 8384883669867978007u), + MakeUint128(1537228672809129301u, 6148914691236517205u), + MakeUint128(1418980313362273201u, 4256940940086819603u), + MakeUint128(1317624576693539401u, 2635249153387078802u), + MakeUint128(1229782938247303441u, 1229782938247303441u), + MakeUint128(1152921504606846975u, 18446744073709551615u), + MakeUint128(1085102592571150095u, 1085102592571150095u), + MakeUint128(1024819115206086200u, 16397105843297379214u), + MakeUint128(970881267037344821u, 16504981539634861972u), + MakeUint128(922337203685477580u, 14757395258967641292u), + MakeUint128(878416384462359600u, 14054662151397753612u), + MakeUint128(838488366986797800u, 13415813871788764811u), + MakeUint128(802032351030850070u, 4812194106185100421u), + MakeUint128(768614336404564650u, 12297829382473034410u), + MakeUint128(737869762948382064u, 11805916207174113034u), + MakeUint128(709490156681136600u, 11351842506898185609u), + MakeUint128(683212743470724133u, 17080318586768103348u), + MakeUint128(658812288346769700u, 10540996613548315209u), + MakeUint128(636094623231363848u, 15266270957552732371u), + MakeUint128(614891469123651720u, 9838263505978427528u), + MakeUint128(595056260442243600u, 9520900167075897608u), + MakeUint128(576460752303423487u, 18446744073709551615u), + MakeUint128(558992244657865200u, 8943875914525843207u), + MakeUint128(542551296285575047u, 9765923333140350855u), + MakeUint128(527049830677415760u, 8432797290838652167u), + MakeUint128(512409557603043100u, 8198552921648689607u), +}; + // This kVmaxOverBase generated with // for (int base = 2; base < 37; ++base) { // absl::int128 max = std::numeric_limits<absl::int128>::max(); @@ -922,8 +922,8 @@ inline bool safe_parse_positive_int(absl::string_view text, int base, assert(base >= 0); assert(vmax >= static_cast<IntType>(base)); const IntType vmax_over_base = LookupTables<IntType>::kVmaxOverBase[base]; - assert(base < 2 || - std::numeric_limits<IntType>::max() / base == vmax_over_base); + assert(base < 2 || + std::numeric_limits<IntType>::max() / base == vmax_over_base); const char* start = text.data(); const char* end = start + text.size(); // loop over digits @@ -957,8 +957,8 @@ inline bool safe_parse_negative_int(absl::string_view text, int base, assert(vmin < 0); assert(vmin <= 0 - base); IntType vmin_over_base = LookupTables<IntType>::kVminOverBase[base]; - assert(base < 2 || - std::numeric_limits<IntType>::min() / base == vmin_over_base); + assert(base < 2 || + std::numeric_limits<IntType>::min() / base == vmin_over_base); // 2003 c++ standard [expr.mul] // "... the sign of the remainder is implementation-defined." // Although (vmin/base)*base + vmin%base is always vmin. @@ -1024,10 +1024,10 @@ inline bool safe_uint_internal(absl::string_view text, IntType* value_p, namespace numbers_internal { // Digit conversion. -ABSL_CONST_INIT ABSL_DLL const char kHexChar[] = - "0123456789abcdef"; +ABSL_CONST_INIT ABSL_DLL const char kHexChar[] = + "0123456789abcdef"; -ABSL_CONST_INIT ABSL_DLL const char kHexTable[513] = +ABSL_CONST_INIT ABSL_DLL const char kHexTable[513] = "000102030405060708090a0b0c0d0e0f" "101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f" @@ -1045,7 +1045,7 @@ ABSL_CONST_INIT ABSL_DLL const char kHexTable[513] = "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; -ABSL_CONST_INIT ABSL_DLL const char two_ASCII_digits[100][2] = { +ABSL_CONST_INIT ABSL_DLL const char two_ASCII_digits[100][2] = { {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'}, {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'}, {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'}, @@ -1089,5 +1089,5 @@ bool safe_strtou128_base(absl::string_view text, uint128* value, int base) { } } // namespace numbers_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/numbers.h b/contrib/restricted/abseil-cpp/absl/strings/numbers.h index 899e623c8c..6cdaa73db0 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/numbers.h +++ b/contrib/restricted/abseil-cpp/absl/strings/numbers.h @@ -39,7 +39,7 @@ #include <string> #include <type_traits> -#include "absl/base/config.h" +#include "absl/base/config.h" #ifdef __SSE4_2__ // TODO(jorg): Remove this when we figure out the right way // to swap bytes on SSE 4.2 that works with the compilers @@ -55,24 +55,24 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // SimpleAtoi() // -// Converts the given string (optionally followed or preceded by ASCII -// whitespace) into an integer value, returning `true` if successful. The string -// must reflect a base-10 integer whose value falls within the range of the -// integer type (optionally preceded by a `+` or `-`). If any errors are -// encountered, this function returns `false`, leaving `out` in an unspecified -// state. +// Converts the given string (optionally followed or preceded by ASCII +// whitespace) into an integer value, returning `true` if successful. The string +// must reflect a base-10 integer whose value falls within the range of the +// integer type (optionally preceded by a `+` or `-`). If any errors are +// encountered, this function returns `false`, leaving `out` in an unspecified +// state. template <typename int_type> ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view str, int_type* out); // SimpleAtof() // // Converts the given string (optionally followed or preceded by ASCII -// whitespace) into a float, which may be rounded on overflow or underflow, -// returning `true` if successful. +// whitespace) into a float, which may be rounded on overflow or underflow, +// returning `true` if successful. // See https://en.cppreference.com/w/c/string/byte/strtof for details about the // allowed formats for `str`, except SimpleAtof() is locale-independent and will // always use the "C" locale. If any errors are encountered, this function @@ -82,8 +82,8 @@ ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* out); // SimpleAtod() // // Converts the given string (optionally followed or preceded by ASCII -// whitespace) into a double, which may be rounded on overflow or underflow, -// returning `true` if successful. +// whitespace) into a double, which may be rounded on overflow or underflow, +// returning `true` if successful. // See https://en.cppreference.com/w/c/string/byte/strtof for details about the // allowed formats for `str`, except SimpleAtod is locale-independent and will // always use the "C" locale. If any errors are encountered, this function @@ -119,21 +119,21 @@ ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str, ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str, absl::uint128* out); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl // End of public API. Implementation details follow. namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace numbers_internal { // Digit conversion. -ABSL_DLL extern const char kHexChar[17]; // 0123456789abcdef -ABSL_DLL extern const char - kHexTable[513]; // 000102030405060708090a0b0c0d0e0f1011... -ABSL_DLL extern const char - two_ASCII_digits[100][2]; // 00, 01, 02, 03... +ABSL_DLL extern const char kHexChar[17]; // 0123456789abcdef +ABSL_DLL extern const char + kHexTable[513]; // 000102030405060708090a0b0c0d0e0f1011... +ABSL_DLL extern const char + two_ASCII_digits[100][2]; // 00, 01, 02, 03... // Writes a two-character representation of 'i' to 'buf'. 'i' must be in the // range 0 <= i < 100, and buf must have space for two characters. Example: @@ -298,7 +298,7 @@ ABSL_MUST_USE_RESULT inline bool SimpleHexAtoi(absl::string_view str, return numbers_internal::safe_strtou128_base(str, out, 16); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_NUMBERS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_cat.cc b/contrib/restricted/abseil-cpp/absl/strings/str_cat.cc index f4a77493a4..5bd867d918 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/str_cat.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/str_cat.cc @@ -25,7 +25,7 @@ #include "absl/strings/numbers.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN AlphaNum::AlphaNum(Hex hex) { static_assert(numbers_internal::kFastToBufferSize >= 32, @@ -141,12 +141,12 @@ namespace strings_internal { std::string CatPieces(std::initializer_list<absl::string_view> pieces) { std::string result; size_t total_size = 0; - for (const absl::string_view& piece : pieces) total_size += piece.size(); + for (const absl::string_view& piece : pieces) total_size += piece.size(); strings_internal::STLStringResizeUninitialized(&result, total_size); char* const begin = &result[0]; char* out = begin; - for (const absl::string_view& piece : pieces) { + for (const absl::string_view& piece : pieces) { const size_t this_size = piece.size(); if (this_size != 0) { memcpy(out, piece.data(), this_size); @@ -170,7 +170,7 @@ void AppendPieces(std::string* dest, std::initializer_list<absl::string_view> pieces) { size_t old_size = dest->size(); size_t total_size = old_size; - for (const absl::string_view& piece : pieces) { + for (const absl::string_view& piece : pieces) { ASSERT_NO_OVERLAP(*dest, piece); total_size += piece.size(); } @@ -178,7 +178,7 @@ void AppendPieces(std::string* dest, char* const begin = &(*dest)[0]; char* out = begin + old_size; - for (const absl::string_view& piece : pieces) { + for (const absl::string_view& piece : pieces) { const size_t this_size = piece.size(); if (this_size != 0) { memcpy(out, piece.data(), this_size); @@ -242,5 +242,5 @@ void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, assert(out == begin + dest->size()); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_cat.h b/contrib/restricted/abseil-cpp/absl/strings/str_cat.h index a8a85c7322..3253bb0077 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/str_cat.h +++ b/contrib/restricted/abseil-cpp/absl/strings/str_cat.h @@ -64,7 +64,7 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { // AlphaNumBuffer allows a way to pass a string to StrCat without having to do @@ -253,7 +253,7 @@ class AlphaNum { const std::basic_string<char, std::char_traits<char>, Allocator>& str) : piece_(str) {} - // Use string literals ":" instead of character literals ':'. + // Use string literals ":" instead of character literals ':'. AlphaNum(char c) = delete; // NOLINT(runtime/explicit) AlphaNum(const AlphaNum&) = delete; @@ -402,7 +402,7 @@ SixDigits(double d) { return result; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STR_CAT_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_format.h b/contrib/restricted/abseil-cpp/absl/strings/str_format.h index 4b05c70c23..d7a2a90d9f 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/str_format.h +++ b/contrib/restricted/abseil-cpp/absl/strings/str_format.h @@ -19,7 +19,7 @@ // // The `str_format` library is a typesafe replacement for the family of // `printf()` string formatting routines within the `<cstdio>` standard library -// header. Like the `printf` family, `str_format` uses a "format string" to +// header. Like the `printf` family, `str_format` uses a "format string" to // perform argument substitutions based on types. See the `FormatSpec` section // below for format string documentation. // @@ -57,7 +57,7 @@ // arbitrary sink types: // // * A generic `Format()` function to write outputs to arbitrary sink types, -// which must implement a `FormatRawSink` interface. +// which must implement a `FormatRawSink` interface. // // * A `FormatUntyped()` function that is similar to `Format()` except it is // loosely typed. `FormatUntyped()` is not a template and does not perform @@ -65,7 +65,7 @@ // boolean from a runtime check. // // In addition, the `str_format` library provides extension points for -// augmenting formatting to new types. See "StrFormat Extensions" below. +// augmenting formatting to new types. See "StrFormat Extensions" below. #ifndef ABSL_STRINGS_STR_FORMAT_H_ #define ABSL_STRINGS_STR_FORMAT_H_ @@ -80,7 +80,7 @@ #include "absl/strings/internal/str_format/parser.h" // IWYU pragma: export namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // UntypedFormatSpec // @@ -253,8 +253,8 @@ class FormatCountCapture { // argument, etc. template <typename... Args> -using FormatSpec = str_format_internal::FormatSpecTemplate< - str_format_internal::ArgumentToConv<Args>()...>; +using FormatSpec = str_format_internal::FormatSpecTemplate< + str_format_internal::ArgumentToConv<Args>()...>; // ParsedFormat // @@ -281,36 +281,36 @@ using FormatSpec = str_format_internal::FormatSpecTemplate< // } else { // ... error case ... // } - -#if defined(__cpp_nontype_template_parameter_auto) -// If C++17 is available, an 'extended' format is also allowed that can specify -// multiple conversion characters per format argument, using a combination of -// `absl::FormatConversionCharSet` enum values (logically a set union) -// via the `|` operator. (Single character-based arguments are still accepted, -// but cannot be combined). Some common conversions also have predefined enum -// values, such as `absl::FormatConversionCharSet::kIntegral`. -// -// Example: -// // Extended format supports multiple conversion characters per argument, -// // specified via a combination of `FormatConversionCharSet` enums. -// using MyFormat = absl::ParsedFormat<absl::FormatConversionCharSet::d | -// absl::FormatConversionCharSet::x>; -// MyFormat GetFormat(bool use_hex) { -// if (use_hex) return MyFormat("foo %x bar"); -// return MyFormat("foo %d bar"); -// } -// // `format` can be used with any value that supports 'd' and 'x', -// // like `int`. -// auto format = GetFormat(use_hex); -// value = StringF(format, i); -template <auto... Conv> -using ParsedFormat = absl::str_format_internal::ExtendedParsedFormat< - absl::str_format_internal::ToFormatConversionCharSet(Conv)...>; -#else + +#if defined(__cpp_nontype_template_parameter_auto) +// If C++17 is available, an 'extended' format is also allowed that can specify +// multiple conversion characters per format argument, using a combination of +// `absl::FormatConversionCharSet` enum values (logically a set union) +// via the `|` operator. (Single character-based arguments are still accepted, +// but cannot be combined). Some common conversions also have predefined enum +// values, such as `absl::FormatConversionCharSet::kIntegral`. +// +// Example: +// // Extended format supports multiple conversion characters per argument, +// // specified via a combination of `FormatConversionCharSet` enums. +// using MyFormat = absl::ParsedFormat<absl::FormatConversionCharSet::d | +// absl::FormatConversionCharSet::x>; +// MyFormat GetFormat(bool use_hex) { +// if (use_hex) return MyFormat("foo %x bar"); +// return MyFormat("foo %d bar"); +// } +// // `format` can be used with any value that supports 'd' and 'x', +// // like `int`. +// auto format = GetFormat(use_hex); +// value = StringF(format, i); +template <auto... Conv> +using ParsedFormat = absl::str_format_internal::ExtendedParsedFormat< + absl::str_format_internal::ToFormatConversionCharSet(Conv)...>; +#else template <char... Conv> using ParsedFormat = str_format_internal::ExtendedParsedFormat< - absl::str_format_internal::ToFormatConversionCharSet(Conv)...>; -#endif // defined(__cpp_nontype_template_parameter_auto) + absl::str_format_internal::ToFormatConversionCharSet(Conv)...>; +#endif // defined(__cpp_nontype_template_parameter_auto) // StrFormat() // @@ -427,7 +427,7 @@ int FPrintF(std::FILE* output, const FormatSpec<Args...>& format, // type-safe); prefer `absl::SNPrintF()` over `std::snprintf()`. // // In particular, a successful call to `absl::SNPrintF()` writes at most `size` -// bytes of the formatted output to `output`, including a NUL-terminator, and +// bytes of the formatted output to `output`, including a NUL-terminator, and // returns the number of bytes that would have been written if truncation did // not occur. In the event of an error, a negative value is returned and `errno` // is set. @@ -457,16 +457,16 @@ int SNPrintF(char* output, std::size_t size, const FormatSpec<Args...>& format, // // FormatRawSink is a type erased wrapper around arbitrary sink objects // specifically used as an argument to `Format()`. -// -// All the object has to do define an overload of `AbslFormatFlush()` for the -// sink, usually by adding a ADL-based free function in the same namespace as -// the sink: -// -// void AbslFormatFlush(MySink* dest, absl::string_view part); -// -// where `dest` is the pointer passed to `absl::Format()`. The function should -// append `part` to `dest`. -// +// +// All the object has to do define an overload of `AbslFormatFlush()` for the +// sink, usually by adding a ADL-based free function in the same namespace as +// the sink: +// +// void AbslFormatFlush(MySink* dest, absl::string_view part); +// +// where `dest` is the pointer passed to `absl::Format()`. The function should +// append `part` to `dest`. +// // FormatRawSink does not own the passed sink object. The passed object must // outlive the FormatRawSink. class FormatRawSink { @@ -490,13 +490,13 @@ class FormatRawSink { // `absl::FormatRawSink` interface), using a format string and zero or more // additional arguments. // -// By default, `std::string`, `std::ostream`, and `absl::Cord` are supported as -// destination objects. If a `std::string` is used the formatted string is -// appended to it. +// By default, `std::string`, `std::ostream`, and `absl::Cord` are supported as +// destination objects. If a `std::string` is used the formatted string is +// appended to it. // -// `absl::Format()` is a generic version of `absl::StrAppendFormat()`, for -// custom sinks. The format string, like format strings for `StrFormat()`, is -// checked at compile-time. +// `absl::Format()` is a generic version of `absl::StrAppendFormat()`, for +// custom sinks. The format string, like format strings for `StrFormat()`, is +// checked at compile-time. // // On failure, this function returns `false` and the state of the sink is // unspecified. @@ -566,247 +566,247 @@ ABSL_MUST_USE_RESULT inline bool FormatUntyped( str_format_internal::UntypedFormatSpecImpl::Extract(format), args); } -//------------------------------------------------------------------------------ -// StrFormat Extensions -//------------------------------------------------------------------------------ -// -// AbslFormatConvert() -// -// The StrFormat library provides a customization API for formatting -// user-defined types using absl::StrFormat(). The API relies on detecting an -// overload in the user-defined type's namespace of a free (non-member) -// `AbslFormatConvert()` function, usually as a friend definition with the -// following signature: -// -// absl::FormatConvertResult<...> AbslFormatConvert( -// const X& value, -// const absl::FormatConversionSpec& spec, -// absl::FormatSink *sink); -// -// An `AbslFormatConvert()` overload for a type should only be declared in the -// same file and namespace as said type. -// -// The abstractions within this definition include: -// -// * An `absl::FormatConversionSpec` to specify the fields to pull from a -// user-defined type's format string -// * An `absl::FormatSink` to hold the converted string data during the -// conversion process. -// * An `absl::FormatConvertResult` to hold the status of the returned -// formatting operation -// -// The return type encodes all the conversion characters that your -// AbslFormatConvert() routine accepts. The return value should be {true}. -// A return value of {false} will result in `StrFormat()` returning -// an empty string. This result will be propagated to the result of -// `FormatUntyped`. -// -// Example: -// -// struct Point { -// // To add formatting support to `Point`, we simply need to add a free -// // (non-member) function `AbslFormatConvert()`. This method interprets -// // `spec` to print in the request format. The allowed conversion characters -// // can be restricted via the type of the result, in this example -// // string and integral formatting are allowed (but not, for instance -// // floating point characters like "%f"). You can add such a free function -// // using a friend declaration within the body of the class: -// friend absl::FormatConvertResult<absl::FormatConversionCharSet::kString | -// absl::FormatConversionCharSet::kIntegral> -// AbslFormatConvert(const Point& p, const absl::FormatConversionSpec& spec, -// absl::FormatSink* s) { -// if (spec.conversion_char() == absl::FormatConversionChar::s) { -// s->Append(absl::StrCat("x=", p.x, " y=", p.y)); -// } else { -// s->Append(absl::StrCat(p.x, ",", p.y)); -// } -// return {true}; -// } -// -// int x; -// int y; -// }; - -// clang-format off - -// FormatConversionChar -// -// Specifies the formatting character provided in the format string -// passed to `StrFormat()`. -enum class FormatConversionChar : uint8_t { - c, s, // text - d, i, o, u, x, X, // int - f, F, e, E, g, G, a, A, // float - n, p // misc -}; -// clang-format on - -// FormatConversionSpec -// -// Specifies modifications to the conversion of the format string, through use -// of one or more format flags in the source format string. -class FormatConversionSpec { - public: - // FormatConversionSpec::is_basic() - // - // Indicates that width and precision are not specified, and no additional - // flags are set for this conversion character in the format string. - bool is_basic() const { return impl_.is_basic(); } - - // FormatConversionSpec::has_left_flag() - // - // Indicates whether the result should be left justified for this conversion - // character in the format string. This flag is set through use of a '-' - // character in the format string. E.g. "%-s" - bool has_left_flag() const { return impl_.has_left_flag(); } - - // FormatConversionSpec::has_show_pos_flag() - // - // Indicates whether a sign column is prepended to the result for this - // conversion character in the format string, even if the result is positive. - // This flag is set through use of a '+' character in the format string. - // E.g. "%+d" - bool has_show_pos_flag() const { return impl_.has_show_pos_flag(); } - - // FormatConversionSpec::has_sign_col_flag() - // - // Indicates whether a mandatory sign column is added to the result for this - // conversion character. This flag is set through use of a space character - // (' ') in the format string. E.g. "% i" - bool has_sign_col_flag() const { return impl_.has_sign_col_flag(); } - - // FormatConversionSpec::has_alt_flag() - // - // Indicates whether an "alternate" format is applied to the result for this - // conversion character. Alternative forms depend on the type of conversion - // character, and unallowed alternatives are undefined. This flag is set - // through use of a '#' character in the format string. E.g. "%#h" - bool has_alt_flag() const { return impl_.has_alt_flag(); } - - // FormatConversionSpec::has_zero_flag() - // - // Indicates whether zeroes should be prepended to the result for this - // conversion character instead of spaces. This flag is set through use of the - // '0' character in the format string. E.g. "%0f" - bool has_zero_flag() const { return impl_.has_zero_flag(); } - - // FormatConversionSpec::conversion_char() - // - // Returns the underlying conversion character. - FormatConversionChar conversion_char() const { - return impl_.conversion_char(); - } - - // FormatConversionSpec::width() - // - // Returns the specified width (indicated through use of a non-zero integer - // value or '*' character) of the conversion character. If width is - // unspecified, it returns a negative value. - int width() const { return impl_.width(); } - - // FormatConversionSpec::precision() - // - // Returns the specified precision (through use of the '.' character followed - // by a non-zero integer value or '*' character) of the conversion character. - // If precision is unspecified, it returns a negative value. - int precision() const { return impl_.precision(); } - - private: - explicit FormatConversionSpec( - str_format_internal::FormatConversionSpecImpl impl) - : impl_(impl) {} - - friend str_format_internal::FormatConversionSpecImpl; - - absl::str_format_internal::FormatConversionSpecImpl impl_; -}; - -// Type safe OR operator for FormatConversionCharSet to allow accepting multiple -// conversion chars in custom format converters. -constexpr FormatConversionCharSet operator|(FormatConversionCharSet a, - FormatConversionCharSet b) { - return static_cast<FormatConversionCharSet>(static_cast<uint64_t>(a) | - static_cast<uint64_t>(b)); -} - -// FormatConversionCharSet -// -// Specifies the _accepted_ conversion types as a template parameter to -// FormatConvertResult for custom implementations of `AbslFormatConvert`. -// Note the helper predefined alias definitions (kIntegral, etc.) below. -enum class FormatConversionCharSet : uint64_t { - // text - c = str_format_internal::FormatConversionCharToConvInt('c'), - s = str_format_internal::FormatConversionCharToConvInt('s'), - // integer - d = str_format_internal::FormatConversionCharToConvInt('d'), - i = str_format_internal::FormatConversionCharToConvInt('i'), - o = str_format_internal::FormatConversionCharToConvInt('o'), - u = str_format_internal::FormatConversionCharToConvInt('u'), - x = str_format_internal::FormatConversionCharToConvInt('x'), - X = str_format_internal::FormatConversionCharToConvInt('X'), - // Float - f = str_format_internal::FormatConversionCharToConvInt('f'), - F = str_format_internal::FormatConversionCharToConvInt('F'), - e = str_format_internal::FormatConversionCharToConvInt('e'), - E = str_format_internal::FormatConversionCharToConvInt('E'), - g = str_format_internal::FormatConversionCharToConvInt('g'), - G = str_format_internal::FormatConversionCharToConvInt('G'), - a = str_format_internal::FormatConversionCharToConvInt('a'), - A = str_format_internal::FormatConversionCharToConvInt('A'), - // misc - n = str_format_internal::FormatConversionCharToConvInt('n'), - p = str_format_internal::FormatConversionCharToConvInt('p'), - - // Used for width/precision '*' specification. - kStar = static_cast<uint64_t>( - absl::str_format_internal::FormatConversionCharSetInternal::kStar), - // Some predefined values: - kIntegral = d | i | u | o | x | X, - kFloating = a | e | f | g | A | E | F | G, - kNumeric = kIntegral | kFloating, - kString = s, - kPointer = p, -}; - -// FormatSink -// -// An abstraction to which conversions write their string data. -// -class FormatSink { - public: - // Appends `count` copies of `ch`. - void Append(size_t count, char ch) { sink_->Append(count, ch); } - - void Append(string_view v) { sink_->Append(v); } - - // Appends the first `precision` bytes of `v`. If this is less than - // `width`, spaces will be appended first (if `left` is false), or - // after (if `left` is true) to ensure the total amount appended is - // at least `width`. - bool PutPaddedString(string_view v, int width, int precision, bool left) { - return sink_->PutPaddedString(v, width, precision, left); - } - - private: - friend str_format_internal::FormatSinkImpl; - explicit FormatSink(str_format_internal::FormatSinkImpl* s) : sink_(s) {} - str_format_internal::FormatSinkImpl* sink_; -}; - -// FormatConvertResult -// -// Indicates whether a call to AbslFormatConvert() was successful. -// This return type informs the StrFormat extension framework (through -// ADL but using the return type) of what conversion characters are supported. -// It is strongly discouraged to return {false}, as this will result in an -// empty string in StrFormat. -template <FormatConversionCharSet C> -struct FormatConvertResult { - bool value; -}; - -ABSL_NAMESPACE_END +//------------------------------------------------------------------------------ +// StrFormat Extensions +//------------------------------------------------------------------------------ +// +// AbslFormatConvert() +// +// The StrFormat library provides a customization API for formatting +// user-defined types using absl::StrFormat(). The API relies on detecting an +// overload in the user-defined type's namespace of a free (non-member) +// `AbslFormatConvert()` function, usually as a friend definition with the +// following signature: +// +// absl::FormatConvertResult<...> AbslFormatConvert( +// const X& value, +// const absl::FormatConversionSpec& spec, +// absl::FormatSink *sink); +// +// An `AbslFormatConvert()` overload for a type should only be declared in the +// same file and namespace as said type. +// +// The abstractions within this definition include: +// +// * An `absl::FormatConversionSpec` to specify the fields to pull from a +// user-defined type's format string +// * An `absl::FormatSink` to hold the converted string data during the +// conversion process. +// * An `absl::FormatConvertResult` to hold the status of the returned +// formatting operation +// +// The return type encodes all the conversion characters that your +// AbslFormatConvert() routine accepts. The return value should be {true}. +// A return value of {false} will result in `StrFormat()` returning +// an empty string. This result will be propagated to the result of +// `FormatUntyped`. +// +// Example: +// +// struct Point { +// // To add formatting support to `Point`, we simply need to add a free +// // (non-member) function `AbslFormatConvert()`. This method interprets +// // `spec` to print in the request format. The allowed conversion characters +// // can be restricted via the type of the result, in this example +// // string and integral formatting are allowed (but not, for instance +// // floating point characters like "%f"). You can add such a free function +// // using a friend declaration within the body of the class: +// friend absl::FormatConvertResult<absl::FormatConversionCharSet::kString | +// absl::FormatConversionCharSet::kIntegral> +// AbslFormatConvert(const Point& p, const absl::FormatConversionSpec& spec, +// absl::FormatSink* s) { +// if (spec.conversion_char() == absl::FormatConversionChar::s) { +// s->Append(absl::StrCat("x=", p.x, " y=", p.y)); +// } else { +// s->Append(absl::StrCat(p.x, ",", p.y)); +// } +// return {true}; +// } +// +// int x; +// int y; +// }; + +// clang-format off + +// FormatConversionChar +// +// Specifies the formatting character provided in the format string +// passed to `StrFormat()`. +enum class FormatConversionChar : uint8_t { + c, s, // text + d, i, o, u, x, X, // int + f, F, e, E, g, G, a, A, // float + n, p // misc +}; +// clang-format on + +// FormatConversionSpec +// +// Specifies modifications to the conversion of the format string, through use +// of one or more format flags in the source format string. +class FormatConversionSpec { + public: + // FormatConversionSpec::is_basic() + // + // Indicates that width and precision are not specified, and no additional + // flags are set for this conversion character in the format string. + bool is_basic() const { return impl_.is_basic(); } + + // FormatConversionSpec::has_left_flag() + // + // Indicates whether the result should be left justified for this conversion + // character in the format string. This flag is set through use of a '-' + // character in the format string. E.g. "%-s" + bool has_left_flag() const { return impl_.has_left_flag(); } + + // FormatConversionSpec::has_show_pos_flag() + // + // Indicates whether a sign column is prepended to the result for this + // conversion character in the format string, even if the result is positive. + // This flag is set through use of a '+' character in the format string. + // E.g. "%+d" + bool has_show_pos_flag() const { return impl_.has_show_pos_flag(); } + + // FormatConversionSpec::has_sign_col_flag() + // + // Indicates whether a mandatory sign column is added to the result for this + // conversion character. This flag is set through use of a space character + // (' ') in the format string. E.g. "% i" + bool has_sign_col_flag() const { return impl_.has_sign_col_flag(); } + + // FormatConversionSpec::has_alt_flag() + // + // Indicates whether an "alternate" format is applied to the result for this + // conversion character. Alternative forms depend on the type of conversion + // character, and unallowed alternatives are undefined. This flag is set + // through use of a '#' character in the format string. E.g. "%#h" + bool has_alt_flag() const { return impl_.has_alt_flag(); } + + // FormatConversionSpec::has_zero_flag() + // + // Indicates whether zeroes should be prepended to the result for this + // conversion character instead of spaces. This flag is set through use of the + // '0' character in the format string. E.g. "%0f" + bool has_zero_flag() const { return impl_.has_zero_flag(); } + + // FormatConversionSpec::conversion_char() + // + // Returns the underlying conversion character. + FormatConversionChar conversion_char() const { + return impl_.conversion_char(); + } + + // FormatConversionSpec::width() + // + // Returns the specified width (indicated through use of a non-zero integer + // value or '*' character) of the conversion character. If width is + // unspecified, it returns a negative value. + int width() const { return impl_.width(); } + + // FormatConversionSpec::precision() + // + // Returns the specified precision (through use of the '.' character followed + // by a non-zero integer value or '*' character) of the conversion character. + // If precision is unspecified, it returns a negative value. + int precision() const { return impl_.precision(); } + + private: + explicit FormatConversionSpec( + str_format_internal::FormatConversionSpecImpl impl) + : impl_(impl) {} + + friend str_format_internal::FormatConversionSpecImpl; + + absl::str_format_internal::FormatConversionSpecImpl impl_; +}; + +// Type safe OR operator for FormatConversionCharSet to allow accepting multiple +// conversion chars in custom format converters. +constexpr FormatConversionCharSet operator|(FormatConversionCharSet a, + FormatConversionCharSet b) { + return static_cast<FormatConversionCharSet>(static_cast<uint64_t>(a) | + static_cast<uint64_t>(b)); +} + +// FormatConversionCharSet +// +// Specifies the _accepted_ conversion types as a template parameter to +// FormatConvertResult for custom implementations of `AbslFormatConvert`. +// Note the helper predefined alias definitions (kIntegral, etc.) below. +enum class FormatConversionCharSet : uint64_t { + // text + c = str_format_internal::FormatConversionCharToConvInt('c'), + s = str_format_internal::FormatConversionCharToConvInt('s'), + // integer + d = str_format_internal::FormatConversionCharToConvInt('d'), + i = str_format_internal::FormatConversionCharToConvInt('i'), + o = str_format_internal::FormatConversionCharToConvInt('o'), + u = str_format_internal::FormatConversionCharToConvInt('u'), + x = str_format_internal::FormatConversionCharToConvInt('x'), + X = str_format_internal::FormatConversionCharToConvInt('X'), + // Float + f = str_format_internal::FormatConversionCharToConvInt('f'), + F = str_format_internal::FormatConversionCharToConvInt('F'), + e = str_format_internal::FormatConversionCharToConvInt('e'), + E = str_format_internal::FormatConversionCharToConvInt('E'), + g = str_format_internal::FormatConversionCharToConvInt('g'), + G = str_format_internal::FormatConversionCharToConvInt('G'), + a = str_format_internal::FormatConversionCharToConvInt('a'), + A = str_format_internal::FormatConversionCharToConvInt('A'), + // misc + n = str_format_internal::FormatConversionCharToConvInt('n'), + p = str_format_internal::FormatConversionCharToConvInt('p'), + + // Used for width/precision '*' specification. + kStar = static_cast<uint64_t>( + absl::str_format_internal::FormatConversionCharSetInternal::kStar), + // Some predefined values: + kIntegral = d | i | u | o | x | X, + kFloating = a | e | f | g | A | E | F | G, + kNumeric = kIntegral | kFloating, + kString = s, + kPointer = p, +}; + +// FormatSink +// +// An abstraction to which conversions write their string data. +// +class FormatSink { + public: + // Appends `count` copies of `ch`. + void Append(size_t count, char ch) { sink_->Append(count, ch); } + + void Append(string_view v) { sink_->Append(v); } + + // Appends the first `precision` bytes of `v`. If this is less than + // `width`, spaces will be appended first (if `left` is false), or + // after (if `left` is true) to ensure the total amount appended is + // at least `width`. + bool PutPaddedString(string_view v, int width, int precision, bool left) { + return sink_->PutPaddedString(v, width, precision, left); + } + + private: + friend str_format_internal::FormatSinkImpl; + explicit FormatSink(str_format_internal::FormatSinkImpl* s) : sink_(s) {} + str_format_internal::FormatSinkImpl* sink_; +}; + +// FormatConvertResult +// +// Indicates whether a call to AbslFormatConvert() was successful. +// This return type informs the StrFormat extension framework (through +// ADL but using the return type) of what conversion characters are supported. +// It is strongly discouraged to return {false}, as this will result in an +// empty string in StrFormat. +template <FormatConversionCharSet C> +struct FormatConvertResult { + bool value; +}; + +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STR_FORMAT_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_join.h b/contrib/restricted/abseil-cpp/absl/strings/str_join.h index 33534536cf..5f388b5000 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/str_join.h +++ b/contrib/restricted/abseil-cpp/absl/strings/str_join.h @@ -60,7 +60,7 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // Concept: Formatter @@ -287,7 +287,7 @@ std::string StrJoin(const std::tuple<T...>& value, return strings_internal::JoinAlgorithm(value, separator, AlphaNumFormatter()); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STR_JOIN_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_replace.cc b/contrib/restricted/abseil-cpp/absl/strings/str_replace.cc index 2bd5fa9821..73c72a46a1 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/str_replace.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/str_replace.cc @@ -17,7 +17,7 @@ #include "absl/strings/str_cat.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace strings_internal { using FixedMapping = @@ -78,5 +78,5 @@ int StrReplaceAll(strings_internal::FixedMapping replacements, return StrReplaceAll<strings_internal::FixedMapping>(replacements, target); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_replace.h b/contrib/restricted/abseil-cpp/absl/strings/str_replace.h index 273c707735..00dd1b85cf 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/str_replace.h +++ b/contrib/restricted/abseil-cpp/absl/strings/str_replace.h @@ -46,7 +46,7 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // StrReplaceAll() // @@ -213,7 +213,7 @@ int StrReplaceAll(const StrToStrMapping& replacements, std::string* target) { return substitutions; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STR_REPLACE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_split.cc b/contrib/restricted/abseil-cpp/absl/strings/str_split.cc index e08c26b6bb..e421049bc2 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/str_split.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/str_split.cc @@ -27,7 +27,7 @@ #include "absl/strings/ascii.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { @@ -42,7 +42,7 @@ absl::string_view GenericFind(absl::string_view text, absl::string_view delimiter, size_t pos, FindPolicy find_policy) { if (delimiter.empty() && text.length() > 0) { - // Special case for empty string delimiters: always return a zero-length + // Special case for empty string delimiters: always return a zero-length // absl::string_view referring to the item at position 1 past pos. return absl::string_view(text.data() + pos + 1, 0); } @@ -127,7 +127,7 @@ absl::string_view ByLength::Find(absl::string_view text, size_t pos) const { pos = std::min(pos, text.size()); // truncate `pos` absl::string_view substr = text.substr(pos); - // If the string is shorter than the chunk size we say we + // If the string is shorter than the chunk size we say we // "can't find the delimiter" so this will be the last chunk. if (substr.length() <= static_cast<size_t>(length_)) return absl::string_view(text.data() + text.size(), 0); @@ -135,5 +135,5 @@ absl::string_view ByLength::Find(absl::string_view text, return absl::string_view(substr.data() + length_, 0); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_split.h b/contrib/restricted/abseil-cpp/absl/strings/str_split.h index bfbca422a8..092edff75f 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/str_split.h +++ b/contrib/restricted/abseil-cpp/absl/strings/str_split.h @@ -44,13 +44,13 @@ #include <vector> #include "absl/base/internal/raw_logging.h" -#include "absl/base/macros.h" +#include "absl/base/macros.h" #include "absl/strings/internal/str_split_internal.h" #include "absl/strings/string_view.h" #include "absl/strings/strip.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN //------------------------------------------------------------------------------ // Delimiters @@ -542,7 +542,7 @@ StrSplit(StringType&& text, Delimiter d, Predicate p) { std::move(text), DelimiterType(d), std::move(p)); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STR_SPLIT_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/string_view.cc b/contrib/restricted/abseil-cpp/absl/strings/string_view.cc index d596e08cde..2e62545317 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/string_view.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/string_view.cc @@ -24,7 +24,7 @@ #include "absl/strings/internal/memutil.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { void WritePadding(std::ostream& o, size_t pad) { @@ -224,7 +224,7 @@ constexpr string_view::size_type string_view::npos; ABSL_STRING_VIEW_SELECTANY constexpr string_view::size_type string_view::kMaxSize; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_STRING_VIEW diff --git a/contrib/restricted/abseil-cpp/absl/strings/string_view.h b/contrib/restricted/abseil-cpp/absl/strings/string_view.h index 65e74ccb1d..bc2b853a07 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/string_view.h +++ b/contrib/restricted/abseil-cpp/absl/strings/string_view.h @@ -28,29 +28,29 @@ #define ABSL_STRINGS_STRING_VIEW_H_ #include <algorithm> -#include <cassert> -#include <cstddef> -#include <cstring> -#include <iosfwd> -#include <iterator> -#include <limits> -#include <string> - +#include <cassert> +#include <cstddef> +#include <cstring> +#include <iosfwd> +#include <iterator> +#include <limits> +#include <string> + #include "absl/base/attributes.h" #include "absl/base/config.h" -#include "absl/base/internal/throw_delegate.h" -#include "absl/base/macros.h" -#include "absl/base/optimization.h" -#include "absl/base/port.h" +#include "absl/base/internal/throw_delegate.h" +#include "absl/base/macros.h" +#include "absl/base/optimization.h" +#include "absl/base/port.h" #ifdef ABSL_USES_STD_STRING_VIEW #include <string_view> // IWYU pragma: export namespace absl { -ABSL_NAMESPACE_BEGIN -using string_view = std::string_view; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_BEGIN +using string_view = std::string_view; +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_STRING_VIEW @@ -71,7 +71,7 @@ ABSL_NAMESPACE_END #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // absl::string_view // @@ -120,22 +120,22 @@ ABSL_NAMESPACE_BEGIN // example, when splitting a string, `std::vector<absl::string_view>` is a // natural data type for the output. // -// For another example, a Cord is a non-contiguous, potentially very -// long string-like object. The Cord class has an interface that iteratively -// provides string_view objects that point to the successive pieces of a Cord -// object. -// -// When constructed from a source which is NUL-terminated, the `string_view` -// itself will not include the NUL-terminator unless a specific size (including -// the NUL) is passed to the constructor. As a result, common idioms that work -// on NUL-terminated strings do not work on `string_view` objects. If you write +// For another example, a Cord is a non-contiguous, potentially very +// long string-like object. The Cord class has an interface that iteratively +// provides string_view objects that point to the successive pieces of a Cord +// object. +// +// When constructed from a source which is NUL-terminated, the `string_view` +// itself will not include the NUL-terminator unless a specific size (including +// the NUL) is passed to the constructor. As a result, common idioms that work +// on NUL-terminated strings do not work on `string_view` objects. If you write // code that scans a `string_view`, you must check its length rather than test // for nul, for example. Note, however, that nuls may still be embedded within // a `string_view` explicitly. // // You may create a null `string_view` in two ways: // -// absl::string_view sv; +// absl::string_view sv; // absl::string_view sv(nullptr, 0); // // For the above, `sv.data() == nullptr`, `sv.length() == 0`, and @@ -197,7 +197,7 @@ class string_view { // code bloat. : string_view(str.data(), str.size(), SkipCheckLengthTag{}) {} - // Implicit constructor of a `string_view` from NUL-terminated `str`. When + // Implicit constructor of a `string_view` from NUL-terminated `str`. When // accepting possibly null strings, use `absl::NullSafeStringView(str)` // instead (see below). // The length check is skipped since it is unnecessary and causes code bloat. @@ -296,9 +296,9 @@ class string_view { // // Returns the ith element of the `string_view` using the array operator. // Note that this operator does not perform any bounds checking. - constexpr const_reference operator[](size_type i) const { - return ABSL_HARDENING_ASSERT(i < size()), ptr_[i]; - } + constexpr const_reference operator[](size_type i) const { + return ABSL_HARDENING_ASSERT(i < size()), ptr_[i]; + } // string_view::at() // @@ -316,24 +316,24 @@ class string_view { // string_view::front() // // Returns the first element of a `string_view`. - constexpr const_reference front() const { - return ABSL_HARDENING_ASSERT(!empty()), ptr_[0]; - } + constexpr const_reference front() const { + return ABSL_HARDENING_ASSERT(!empty()), ptr_[0]; + } // string_view::back() // // Returns the last element of a `string_view`. - constexpr const_reference back() const { - return ABSL_HARDENING_ASSERT(!empty()), ptr_[size() - 1]; - } + constexpr const_reference back() const { + return ABSL_HARDENING_ASSERT(!empty()), ptr_[size() - 1]; + } // string_view::data() // // Returns a pointer to the underlying character array (which is of course // stored elsewhere). Note that `string_view::data()` may contain embedded nul - // characters, but the returned buffer may or may not be NUL-terminated; - // therefore, do not pass `data()` to a routine that expects a NUL-terminated - // string. + // characters, but the returned buffer may or may not be NUL-terminated; + // therefore, do not pass `data()` to a routine that expects a NUL-terminated + // string. constexpr const_pointer data() const noexcept { return ptr_; } // Modifiers @@ -341,9 +341,9 @@ class string_view { // string_view::remove_prefix() // // Removes the first `n` characters from the `string_view`. Note that the - // underlying string is not changed, only the view. + // underlying string is not changed, only the view. ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_prefix(size_type n) { - ABSL_HARDENING_ASSERT(n <= length_); + ABSL_HARDENING_ASSERT(n <= length_); ptr_ += n; length_ -= n; } @@ -351,9 +351,9 @@ class string_view { // string_view::remove_suffix() // // Removes the last `n` characters from the `string_view`. Note that the - // underlying string is not changed, only the view. + // underlying string is not changed, only the view. ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_suffix(size_type n) { - ABSL_HARDENING_ASSERT(n <= length_); + ABSL_HARDENING_ASSERT(n <= length_); length_ -= n; } @@ -396,13 +396,13 @@ class string_view { // Returns a "substring" of the `string_view` (at offset `pos` and length // `n`) as another string_view. This function throws `std::out_of_bounds` if // `pos > size`. - // Use absl::ClippedSubstr if you need a truncating substr operation. + // Use absl::ClippedSubstr if you need a truncating substr operation. constexpr string_view substr(size_type pos = 0, size_type n = npos) const { - return ABSL_PREDICT_FALSE(pos > length_) - ? (base_internal::ThrowStdOutOfRange( - "absl::string_view::substr"), - string_view()) - : string_view(ptr_ + pos, Min(n, length_ - pos)); + return ABSL_PREDICT_FALSE(pos > length_) + ? (base_internal::ThrowStdOutOfRange( + "absl::string_view::substr"), + string_view()) + : string_view(ptr_ + pos, Min(n, length_ - pos)); } // string_view::compare() @@ -412,11 +412,11 @@ class string_view { // than `x`, 0 if `*this` is equal to `x`, and a positive value if `*this` // is greater than `x`. constexpr int compare(string_view x) const noexcept { - return CompareImpl(length_, x.length_, - Min(length_, x.length_) == 0 - ? 0 - : ABSL_INTERNAL_STRING_VIEW_MEMCMP( - ptr_, x.ptr_, Min(length_, x.length_))); + return CompareImpl(length_, x.length_, + Min(length_, x.length_) == 0 + ? 0 + : ABSL_INTERNAL_STRING_VIEW_MEMCMP( + ptr_, x.ptr_, Min(length_, x.length_))); } // Overload of `string_view::compare()` for comparing a substring of the @@ -437,13 +437,13 @@ class string_view { constexpr int compare(const char* s) const { return compare(string_view(s)); } // Overload of `string_view::compare()` for comparing a substring of the - // `string_view` and a different string C-style string `s`. + // `string_view` and a different string C-style string `s`. constexpr int compare(size_type pos1, size_type count1, const char* s) const { return substr(pos1, count1).compare(string_view(s)); } // Overload of `string_view::compare()` for comparing a substring of the - // `string_view` and a substring of a different C-style string `s`. + // `string_view` and a substring of a different C-style string `s`. constexpr int compare(size_type pos1, size_type count1, const char* s, size_type count2) const { return substr(pos1, count1).compare(string_view(s, count2)); @@ -608,7 +608,7 @@ class string_view { (std::numeric_limits<difference_type>::max)(); static constexpr size_type CheckLengthInternal(size_type len) { - return ABSL_HARDENING_ASSERT(len <= kMaxSize), len; + return ABSL_HARDENING_ASSERT(len <= kMaxSize), len; } static constexpr size_type StrlenInternal(const char* str) { @@ -629,15 +629,15 @@ class string_view { #endif } - static constexpr size_t Min(size_type length_a, size_type length_b) { - return length_a < length_b ? length_a : length_b; - } - + static constexpr size_t Min(size_type length_a, size_type length_b) { + return length_a < length_b ? length_a : length_b; + } + static constexpr int CompareImpl(size_type length_a, size_type length_b, int compare_result) { return compare_result == 0 ? static_cast<int>(length_a > length_b) - static_cast<int>(length_a < length_b) - : (compare_result < 0 ? -1 : 1); + : (compare_result < 0 ? -1 : 1); } const char* ptr_; @@ -676,7 +676,7 @@ constexpr bool operator>=(string_view x, string_view y) noexcept { // IO Insertion Operator std::ostream& operator<<(std::ostream& o, string_view piece); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #undef ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR @@ -685,7 +685,7 @@ ABSL_NAMESPACE_END #endif // ABSL_USES_STD_STRING_VIEW namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ClippedSubstr() // @@ -702,11 +702,11 @@ inline string_view ClippedSubstr(string_view s, size_t pos, // Creates an `absl::string_view` from a pointer `p` even if it's null-valued. // This function should be used where an `absl::string_view` can be created from // a possibly-null pointer. -constexpr string_view NullSafeStringView(const char* p) { +constexpr string_view NullSafeStringView(const char* p) { return p ? string_view(p) : string_view(); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STRING_VIEW_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/strip.h b/contrib/restricted/abseil-cpp/absl/strings/strip.h index 111872ca54..5dfa716942 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/strip.h +++ b/contrib/restricted/abseil-cpp/absl/strings/strip.h @@ -30,7 +30,7 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ConsumePrefix() // @@ -85,7 +85,7 @@ ABSL_MUST_USE_RESULT inline absl::string_view StripSuffix( return str; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_STRIP_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/substitute.cc b/contrib/restricted/abseil-cpp/absl/strings/substitute.cc index 8980b198c2..bc625d4082 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/substitute.cc +++ b/contrib/restricted/abseil-cpp/absl/strings/substitute.cc @@ -23,7 +23,7 @@ #include "absl/strings/string_view.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace substitute_internal { void SubstituteAndAppendArray(std::string* output, absl::string_view format, @@ -36,7 +36,7 @@ void SubstituteAndAppendArray(std::string* output, absl::string_view format, if (i + 1 >= format.size()) { #ifndef NDEBUG ABSL_RAW_LOG(FATAL, - "Invalid absl::Substitute() format string: \"%s\".", + "Invalid absl::Substitute() format string: \"%s\".", absl::CEscape(format).c_str()); #endif return; @@ -46,8 +46,8 @@ void SubstituteAndAppendArray(std::string* output, absl::string_view format, #ifndef NDEBUG ABSL_RAW_LOG( FATAL, - "Invalid absl::Substitute() format string: asked for \"$" - "%d\", but only %d args were given. Full format string was: " + "Invalid absl::Substitute() format string: asked for \"$" + "%d\", but only %d args were given. Full format string was: " "\"%s\".", index, static_cast<int>(num_args), absl::CEscape(format).c_str()); #endif @@ -61,7 +61,7 @@ void SubstituteAndAppendArray(std::string* output, absl::string_view format, } else { #ifndef NDEBUG ABSL_RAW_LOG(FATAL, - "Invalid absl::Substitute() format string: \"%s\".", + "Invalid absl::Substitute() format string: \"%s\".", absl::CEscape(format).c_str()); #endif return; @@ -73,7 +73,7 @@ void SubstituteAndAppendArray(std::string* output, absl::string_view format, if (size == 0) return; - // Build the string. + // Build the string. size_t original_size = output->size(); strings_internal::STLStringResizeUninitializedAmortized(output, original_size + size); @@ -168,5 +168,5 @@ Arg::Arg(Dec dec) { } } // namespace substitute_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/strings/substitute.h b/contrib/restricted/abseil-cpp/absl/strings/substitute.h index 151c56f543..c928c0979e 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/substitute.h +++ b/contrib/restricted/abseil-cpp/absl/strings/substitute.h @@ -50,7 +50,7 @@ // // Supported types: // * absl::string_view, std::string, const char* (null is equivalent to "") -// * int32_t, int64_t, uint32_t, uint64_t +// * int32_t, int64_t, uint32_t, uint64_t // * float, double // * bool (Printed as "true" or "false") // * pointer types other than char* (Printed as "0x<lower case hex string>", @@ -86,7 +86,7 @@ #include "absl/strings/strip.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace substitute_internal { // Arg @@ -99,7 +99,7 @@ namespace substitute_internal { // This class has implicit constructors. class Arg { public: - // Overloads for string-y things + // Overloads for string-y things // // Explicitly overload `const char*` so the compiler doesn't cast to `bool`. Arg(const char* value) // NOLINT(runtime/explicit) @@ -120,9 +120,9 @@ class Arg { // representation. However, we can't really know, so we make the caller decide // what to do. Arg(char value) // NOLINT(runtime/explicit) - : piece_(scratch_, 1) { - scratch_[0] = value; - } + : piece_(scratch_, 1) { + scratch_[0] = value; + } Arg(short value) // NOLINT(*) : piece_(scratch_, numbers_internal::FastIntToBuffer(value, scratch_) - scratch_) {} @@ -192,12 +192,12 @@ void SubstituteAndAppendArray(std::string* output, absl::string_view format, #if defined(ABSL_BAD_CALL_IF) constexpr int CalculateOneBit(const char* format) { - // Returns: - // * 2^N for '$N' when N is in [0-9] - // * 0 for correct '$' escaping: '$$'. - // * -1 otherwise. - return (*format < '0' || *format > '9') ? (*format == '$' ? 0 : -1) - : (1 << (*format - '0')); + // Returns: + // * 2^N for '$N' when N is in [0-9] + // * 0 for correct '$' escaping: '$$'. + // * -1 otherwise. + return (*format < '0' || *format > '9') ? (*format == '$' ? 0 : -1) + : (1 << (*format - '0')); } constexpr const char* SkipNumber(const char* format) { @@ -205,11 +205,11 @@ constexpr const char* SkipNumber(const char* format) { } constexpr int PlaceholderBitmask(const char* format) { - return !*format - ? 0 - : *format != '$' ? PlaceholderBitmask(format + 1) - : (CalculateOneBit(format + 1) | - PlaceholderBitmask(SkipNumber(format + 1))); + return !*format + ? 0 + : *format != '$' ? PlaceholderBitmask(format + 1) + : (CalculateOneBit(format + 1) | + PlaceholderBitmask(SkipNumber(format + 1))); } #endif // ABSL_BAD_CALL_IF @@ -715,7 +715,7 @@ std::string Substitute( "contains an unescaped $ character (use $$ instead)"); #endif // ABSL_BAD_CALL_IF -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_STRINGS_SUBSTITUTE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/strings/ya.make b/contrib/restricted/abseil-cpp/absl/strings/ya.make index bc11193f12..52364d460e 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/ya.make +++ b/contrib/restricted/abseil-cpp/absl/strings/ya.make @@ -8,16 +8,16 @@ LICENSE(Apache-2.0) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -PEERDIR( +PEERDIR( contrib/restricted/abseil-cpp/absl/base - contrib/restricted/abseil-cpp/absl/base/internal/raw_logging + contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate - contrib/restricted/abseil-cpp/absl/base/log_severity + contrib/restricted/abseil-cpp/absl/base/log_severity contrib/restricted/abseil-cpp/absl/numeric contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal -) - +) + ADDINCL( GLOBAL contrib/restricted/abseil-cpp ) @@ -26,14 +26,14 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCS( ascii.cc charconv.cc - escaping.cc + escaping.cc internal/charconv_bigint.cc internal/charconv_parse.cc internal/memutil.cc diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/barrier.cc b/contrib/restricted/abseil-cpp/absl/synchronization/barrier.cc index 0dfd795e7b..c9fd3a201c 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/barrier.cc +++ b/contrib/restricted/abseil-cpp/absl/synchronization/barrier.cc @@ -18,7 +18,7 @@ #include "absl/synchronization/mutex.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // Return whether int *arg is zero. static bool IsZero(void *arg) { @@ -48,5 +48,5 @@ bool Barrier::Block() { return this->num_to_exit_ == 0; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/barrier.h b/contrib/restricted/abseil-cpp/absl/synchronization/barrier.h index d8e754406f..0fc25f561c 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/barrier.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/barrier.h @@ -23,7 +23,7 @@ #include "absl/synchronization/mutex.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // Barrier // @@ -74,6 +74,6 @@ class Barrier { int num_to_exit_ ABSL_GUARDED_BY(lock_); }; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_BARRIER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc b/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc index d2f82da3bb..345efa93fe 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc +++ b/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.cc @@ -19,7 +19,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { @@ -63,5 +63,5 @@ void BlockingCounter::Wait() { // after we return from this method. } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h b/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h index 1908fdb1d9..53799a9892 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/blocking_counter.h @@ -26,7 +26,7 @@ #include "absl/synchronization/mutex.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // BlockingCounter // @@ -95,7 +95,7 @@ class BlockingCounter { bool done_ ABSL_GUARDED_BY(lock_); }; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_BLOCKING_COUNTER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc b/contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc index 53a71b342b..49550a531f 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc @@ -27,14 +27,14 @@ #include "absl/synchronization/internal/per_thread_sem.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { // ThreadIdentity storage is persistent, we maintain a free-list of previously // released ThreadIdentity objects. -ABSL_CONST_INIT static base_internal::SpinLock freelist_lock( - absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY); -ABSL_CONST_INIT static base_internal::ThreadIdentity* thread_identity_freelist; +ABSL_CONST_INIT static base_internal::SpinLock freelist_lock( + absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY); +ABSL_CONST_INIT static base_internal::ThreadIdentity* thread_identity_freelist; // A per-thread destructor for reclaiming associated ThreadIdentity objects. // Since we must preserve their storage we cache them for re-use. @@ -134,7 +134,7 @@ base_internal::ThreadIdentity* CreateThreadIdentity() { } } // namespace synchronization_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_LOW_LEVEL_ALLOC_MISSING diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.h b/contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.h index e121f68377..2d363223a4 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/create_thread_identity.h @@ -29,7 +29,7 @@ #include "absl/base/port.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { // Allocates and attaches a ThreadIdentity object for the calling thread. @@ -54,7 +54,7 @@ inline base_internal::ThreadIdentity* GetOrCreateCurrentThreadIdentity() { } } // namespace synchronization_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_INTERNAL_CREATE_THREAD_IDENTITY_H_ diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/futex.h b/contrib/restricted/abseil-cpp/absl/synchronization/internal/futex.h index 06fbd6d072..40eae732f6 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/futex.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/futex.h @@ -1,43 +1,43 @@ -// Copyright 2020 The Abseil Authors. -// -// 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 -// -// https://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. -#ifndef ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_ -#define ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_ - -#include "absl/base/config.h" - -#ifdef _WIN32 -#include <windows.h> -#else -#include <sys/time.h> -#include <unistd.h> -#endif - -#ifdef __linux__ -#include <linux/futex.h> -#include <sys/syscall.h> -#endif - -#include <errno.h> -#include <stdio.h> -#include <time.h> - -#include <atomic> -#include <cstdint> - -#include "absl/base/optimization.h" -#include "absl/synchronization/internal/kernel_timeout.h" - +// Copyright 2020 The Abseil Authors. +// +// 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 +// +// https://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. +#ifndef ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_ +#define ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_ + +#include "absl/base/config.h" + +#ifdef _WIN32 +#include <windows.h> +#else +#include <sys/time.h> +#include <unistd.h> +#endif + +#ifdef __linux__ +#include <linux/futex.h> +#include <sys/syscall.h> +#endif + +#include <errno.h> +#include <stdio.h> +#include <time.h> + +#include <atomic> +#include <cstdint> + +#include "absl/base/optimization.h" +#include "absl/synchronization/internal/kernel_timeout.h" + #ifdef ABSL_INTERNAL_HAVE_FUTEX #error ABSL_INTERNAL_HAVE_FUTEX may not be set on the command line #elif defined(__BIONIC__) @@ -51,104 +51,104 @@ #ifdef ABSL_INTERNAL_HAVE_FUTEX -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace synchronization_internal { - -// Some Android headers are missing these definitions even though they -// support these futex operations. -#ifdef __BIONIC__ -#ifndef SYS_futex -#define SYS_futex __NR_futex -#endif -#ifndef FUTEX_WAIT_BITSET -#define FUTEX_WAIT_BITSET 9 -#endif -#ifndef FUTEX_PRIVATE_FLAG -#define FUTEX_PRIVATE_FLAG 128 -#endif -#ifndef FUTEX_CLOCK_REALTIME -#define FUTEX_CLOCK_REALTIME 256 -#endif -#ifndef FUTEX_BITSET_MATCH_ANY -#define FUTEX_BITSET_MATCH_ANY 0xFFFFFFFF -#endif -#endif - -#if defined(__NR_futex_time64) && !defined(SYS_futex_time64) -#define SYS_futex_time64 __NR_futex_time64 -#endif - -#if defined(SYS_futex_time64) && !defined(SYS_futex) -#define SYS_futex SYS_futex_time64 -#endif - -class FutexImpl { - public: - static int WaitUntil(std::atomic<int32_t> *v, int32_t val, - KernelTimeout t) { - int err = 0; - if (t.has_timeout()) { - // https://locklessinc.com/articles/futex_cheat_sheet/ - // Unlike FUTEX_WAIT, FUTEX_WAIT_BITSET uses absolute time. - struct timespec abs_timeout = t.MakeAbsTimespec(); - // Atomically check that the futex value is still 0, and if it - // is, sleep until abs_timeout or until woken by FUTEX_WAKE. - err = syscall( - SYS_futex, reinterpret_cast<int32_t *>(v), - FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME, val, - &abs_timeout, nullptr, FUTEX_BITSET_MATCH_ANY); - } else { - // Atomically check that the futex value is still 0, and if it - // is, sleep until woken by FUTEX_WAKE. - err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v), - FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, nullptr); - } - if (ABSL_PREDICT_FALSE(err != 0)) { - err = -errno; - } - return err; - } - - static int WaitBitsetAbsoluteTimeout(std::atomic<int32_t> *v, int32_t val, - int32_t bits, - const struct timespec *abstime) { - int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v), - FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG, val, abstime, - nullptr, bits); - if (ABSL_PREDICT_FALSE(err != 0)) { - err = -errno; - } - return err; - } - - static int Wake(std::atomic<int32_t> *v, int32_t count) { - int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v), - FUTEX_WAKE | FUTEX_PRIVATE_FLAG, count); - if (ABSL_PREDICT_FALSE(err < 0)) { - err = -errno; - } - return err; - } - - // FUTEX_WAKE_BITSET - static int WakeBitset(std::atomic<int32_t> *v, int32_t count, int32_t bits) { - int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v), - FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG, count, nullptr, - nullptr, bits); - if (ABSL_PREDICT_FALSE(err < 0)) { - err = -errno; - } - return err; - } -}; - -class Futex : public FutexImpl {}; - -} // namespace synchronization_internal -ABSL_NAMESPACE_END -} // namespace absl - +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace synchronization_internal { + +// Some Android headers are missing these definitions even though they +// support these futex operations. +#ifdef __BIONIC__ +#ifndef SYS_futex +#define SYS_futex __NR_futex +#endif +#ifndef FUTEX_WAIT_BITSET +#define FUTEX_WAIT_BITSET 9 +#endif +#ifndef FUTEX_PRIVATE_FLAG +#define FUTEX_PRIVATE_FLAG 128 +#endif +#ifndef FUTEX_CLOCK_REALTIME +#define FUTEX_CLOCK_REALTIME 256 +#endif +#ifndef FUTEX_BITSET_MATCH_ANY +#define FUTEX_BITSET_MATCH_ANY 0xFFFFFFFF +#endif +#endif + +#if defined(__NR_futex_time64) && !defined(SYS_futex_time64) +#define SYS_futex_time64 __NR_futex_time64 +#endif + +#if defined(SYS_futex_time64) && !defined(SYS_futex) +#define SYS_futex SYS_futex_time64 +#endif + +class FutexImpl { + public: + static int WaitUntil(std::atomic<int32_t> *v, int32_t val, + KernelTimeout t) { + int err = 0; + if (t.has_timeout()) { + // https://locklessinc.com/articles/futex_cheat_sheet/ + // Unlike FUTEX_WAIT, FUTEX_WAIT_BITSET uses absolute time. + struct timespec abs_timeout = t.MakeAbsTimespec(); + // Atomically check that the futex value is still 0, and if it + // is, sleep until abs_timeout or until woken by FUTEX_WAKE. + err = syscall( + SYS_futex, reinterpret_cast<int32_t *>(v), + FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME, val, + &abs_timeout, nullptr, FUTEX_BITSET_MATCH_ANY); + } else { + // Atomically check that the futex value is still 0, and if it + // is, sleep until woken by FUTEX_WAKE. + err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v), + FUTEX_WAIT | FUTEX_PRIVATE_FLAG, val, nullptr); + } + if (ABSL_PREDICT_FALSE(err != 0)) { + err = -errno; + } + return err; + } + + static int WaitBitsetAbsoluteTimeout(std::atomic<int32_t> *v, int32_t val, + int32_t bits, + const struct timespec *abstime) { + int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v), + FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG, val, abstime, + nullptr, bits); + if (ABSL_PREDICT_FALSE(err != 0)) { + err = -errno; + } + return err; + } + + static int Wake(std::atomic<int32_t> *v, int32_t count) { + int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v), + FUTEX_WAKE | FUTEX_PRIVATE_FLAG, count); + if (ABSL_PREDICT_FALSE(err < 0)) { + err = -errno; + } + return err; + } + + // FUTEX_WAKE_BITSET + static int WakeBitset(std::atomic<int32_t> *v, int32_t count, int32_t bits) { + int err = syscall(SYS_futex, reinterpret_cast<int32_t *>(v), + FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG, count, nullptr, + nullptr, bits); + if (ABSL_PREDICT_FALSE(err < 0)) { + err = -errno; + } + return err; + } +}; + +class Futex : public FutexImpl {}; + +} // namespace synchronization_internal +ABSL_NAMESPACE_END +} // namespace absl + #endif // ABSL_INTERNAL_HAVE_FUTEX -#endif // ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_ +#endif // ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_ diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/graphcycles.cc b/contrib/restricted/abseil-cpp/absl/synchronization/internal/graphcycles.cc index 27fec21681..a6dab02da1 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/graphcycles.cc +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/graphcycles.cc @@ -45,16 +45,16 @@ // Do not use STL. This module does not use standard memory allocation. namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { namespace { // Avoid LowLevelAlloc's default arena since it calls malloc hooks in // which people are doing things like acquiring Mutexes. -ABSL_CONST_INIT static absl::base_internal::SpinLock arena_mu( - absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY); -ABSL_CONST_INIT static base_internal::LowLevelAlloc::Arena* arena; +ABSL_CONST_INIT static absl::base_internal::SpinLock arena_mu( + absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY); +ABSL_CONST_INIT static base_internal::LowLevelAlloc::Arena* arena; static void InitArenaIfNecessary() { arena_mu.Lock(); @@ -692,7 +692,7 @@ int GraphCycles::GetStackTrace(GraphId id, void*** ptr) { } } // namespace synchronization_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_LOW_LEVEL_ALLOC_MISSING diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/graphcycles.h b/contrib/restricted/abseil-cpp/absl/synchronization/internal/graphcycles.h index ceba33e4de..7a723ac04f 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/graphcycles.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/graphcycles.h @@ -40,10 +40,10 @@ #include <cstdint> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { // Opaque identifier for a graph node. @@ -135,7 +135,7 @@ class GraphCycles { }; } // namespace synchronization_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/kernel_timeout.h b/contrib/restricted/abseil-cpp/absl/synchronization/internal/kernel_timeout.h index bbd4d2d70f..338aaf512b 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/kernel_timeout.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/kernel_timeout.h @@ -26,7 +26,7 @@ #define ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_ #include <time.h> - + #include <algorithm> #include <limits> @@ -35,7 +35,7 @@ #include "absl/time/time.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { class Futex; @@ -58,10 +58,10 @@ class KernelTimeout { bool has_timeout() const { return ns_ != 0; } - // Convert to parameter for sem_timedwait/futex/similar. Only for approved - // users. Do not call if !has_timeout. - struct timespec MakeAbsTimespec(); - + // Convert to parameter for sem_timedwait/futex/similar. Only for approved + // users. Do not call if !has_timeout. + struct timespec MakeAbsTimespec(); + private: // internal rep, not user visible: ns after unix epoch. // zero = no timeout. @@ -125,32 +125,32 @@ class KernelTimeout { friend class Waiter; }; -inline struct timespec KernelTimeout::MakeAbsTimespec() { - int64_t n = ns_; - static const int64_t kNanosPerSecond = 1000 * 1000 * 1000; - if (n == 0) { - ABSL_RAW_LOG( - ERROR, "Tried to create a timespec from a non-timeout; never do this."); - // But we'll try to continue sanely. no-timeout ~= saturated timeout. - n = (std::numeric_limits<int64_t>::max)(); - } - - // Kernel APIs validate timespecs as being at or after the epoch, - // despite the kernel time type being signed. However, no one can - // tell the difference between a timeout at or before the epoch (since - // all such timeouts have expired!) - if (n < 0) n = 0; - - struct timespec abstime; - int64_t seconds = (std::min)(n / kNanosPerSecond, - int64_t{(std::numeric_limits<time_t>::max)()}); - abstime.tv_sec = static_cast<time_t>(seconds); - abstime.tv_nsec = static_cast<decltype(abstime.tv_nsec)>(n % kNanosPerSecond); - return abstime; -} - +inline struct timespec KernelTimeout::MakeAbsTimespec() { + int64_t n = ns_; + static const int64_t kNanosPerSecond = 1000 * 1000 * 1000; + if (n == 0) { + ABSL_RAW_LOG( + ERROR, "Tried to create a timespec from a non-timeout; never do this."); + // But we'll try to continue sanely. no-timeout ~= saturated timeout. + n = (std::numeric_limits<int64_t>::max)(); + } + + // Kernel APIs validate timespecs as being at or after the epoch, + // despite the kernel time type being signed. However, no one can + // tell the difference between a timeout at or before the epoch (since + // all such timeouts have expired!) + if (n < 0) n = 0; + + struct timespec abstime; + int64_t seconds = (std::min)(n / kNanosPerSecond, + int64_t{(std::numeric_limits<time_t>::max)()}); + abstime.tv_sec = static_cast<time_t>(seconds); + abstime.tv_nsec = static_cast<decltype(abstime.tv_nsec)>(n % kNanosPerSecond); + return abstime; +} + } // namespace synchronization_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_ diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc b/contrib/restricted/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc index a6031787e0..40e232de25 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc @@ -25,7 +25,7 @@ #include "absl/synchronization/internal/waiter.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { void PerThreadSem::SetThreadBlockedCounter(std::atomic<int> *counter) { @@ -63,7 +63,7 @@ void PerThreadSem::Tick(base_internal::ThreadIdentity *identity) { } } // namespace synchronization_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl extern "C" { diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/per_thread_sem.h b/contrib/restricted/abseil-cpp/absl/synchronization/internal/per_thread_sem.h index 7beae8ef1d..c94a16f82b 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/per_thread_sem.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/per_thread_sem.h @@ -32,7 +32,7 @@ #include "absl/synchronization/internal/kernel_timeout.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN class Mutex; @@ -78,7 +78,7 @@ class PerThreadSem { // !t.has_timeout() => Wait(t) will return true. static inline bool Wait(KernelTimeout t); - // Permitted callers. + // Permitted callers. friend class PerThreadSemTest; friend class absl::Mutex; friend absl::base_internal::ThreadIdentity* CreateThreadIdentity(); @@ -86,7 +86,7 @@ class PerThreadSem { }; } // namespace synchronization_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl // In some build configurations we pass --detect-odr-violations to the diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/thread_pool.h b/contrib/restricted/abseil-cpp/absl/synchronization/internal/thread_pool.h index 0cb96dacde..762d74ffce 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/thread_pool.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/thread_pool.h @@ -26,7 +26,7 @@ #include "absl/synchronization/mutex.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { // A simple ThreadPool implementation for tests. @@ -87,7 +87,7 @@ class ThreadPool { }; } // namespace synchronization_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_INTERNAL_THREAD_POOL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/waiter.cc b/contrib/restricted/abseil-cpp/absl/synchronization/internal/waiter.cc index 28ef311e4a..9bee8284da 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/waiter.cc +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/waiter.cc @@ -48,9 +48,9 @@ #include "absl/base/optimization.h" #include "absl/synchronization/internal/kernel_timeout.h" - + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { static void MaybeBecomeIdle() { @@ -82,7 +82,7 @@ bool Waiter::Wait(KernelTimeout t) { while (true) { int32_t x = futex_.load(std::memory_order_relaxed); - while (x != 0) { + while (x != 0) { if (!futex_.compare_exchange_weak(x, x - 1, std::memory_order_acquire, std::memory_order_relaxed)) { @@ -258,7 +258,7 @@ bool Waiter::Wait(KernelTimeout t) { bool first_pass = true; while (true) { int x = wakeups_.load(std::memory_order_relaxed); - while (x != 0) { + while (x != 0) { if (!wakeups_.compare_exchange_weak(x, x - 1, std::memory_order_acquire, std::memory_order_relaxed)) { @@ -312,29 +312,29 @@ class Waiter::WinHelper { return reinterpret_cast<CONDITION_VARIABLE *>(&w->cv_storage_); } - static_assert(sizeof(SRWLOCK) == sizeof(void *), - "`mu_storage_` does not have the same size as SRWLOCK"); - static_assert(alignof(SRWLOCK) == alignof(void *), - "`mu_storage_` does not have the same alignment as SRWLOCK"); - - static_assert(sizeof(CONDITION_VARIABLE) == sizeof(void *), - "`ABSL_CONDITION_VARIABLE_STORAGE` does not have the same size " - "as `CONDITION_VARIABLE`"); + static_assert(sizeof(SRWLOCK) == sizeof(void *), + "`mu_storage_` does not have the same size as SRWLOCK"); + static_assert(alignof(SRWLOCK) == alignof(void *), + "`mu_storage_` does not have the same alignment as SRWLOCK"); + + static_assert(sizeof(CONDITION_VARIABLE) == sizeof(void *), + "`ABSL_CONDITION_VARIABLE_STORAGE` does not have the same size " + "as `CONDITION_VARIABLE`"); static_assert( - alignof(CONDITION_VARIABLE) == alignof(void *), - "`cv_storage_` does not have the same alignment as `CONDITION_VARIABLE`"); + alignof(CONDITION_VARIABLE) == alignof(void *), + "`cv_storage_` does not have the same alignment as `CONDITION_VARIABLE`"); // The SRWLOCK and CONDITION_VARIABLE types must be trivially constructible // and destructible because we never call their constructors or destructors. static_assert(std::is_trivially_constructible<SRWLOCK>::value, - "The `SRWLOCK` type must be trivially constructible"); - static_assert( - std::is_trivially_constructible<CONDITION_VARIABLE>::value, - "The `CONDITION_VARIABLE` type must be trivially constructible"); + "The `SRWLOCK` type must be trivially constructible"); + static_assert( + std::is_trivially_constructible<CONDITION_VARIABLE>::value, + "The `CONDITION_VARIABLE` type must be trivially constructible"); static_assert(std::is_trivially_destructible<SRWLOCK>::value, - "The `SRWLOCK` type must be trivially destructible"); + "The `SRWLOCK` type must be trivially destructible"); static_assert(std::is_trivially_destructible<CONDITION_VARIABLE>::value, - "The `CONDITION_VARIABLE` type must be trivially destructible"); + "The `CONDITION_VARIABLE` type must be trivially destructible"); }; class LockHolder { @@ -424,5 +424,5 @@ void Waiter::InternalCondVarPoke() { #endif } // namespace synchronization_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/waiter.h b/contrib/restricted/abseil-cpp/absl/synchronization/internal/waiter.h index be3df180d4..e3415fb11d 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/waiter.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/waiter.h @@ -58,7 +58,7 @@ #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace synchronization_internal { // Waiter is an OS-specific semaphore. @@ -96,8 +96,8 @@ class Waiter { } // How many periods to remain idle before releasing resources -#ifndef ABSL_HAVE_THREAD_SANITIZER - static constexpr int kIdlePeriods = 60; +#ifndef ABSL_HAVE_THREAD_SANITIZER + static constexpr int kIdlePeriods = 60; #else // Memory consumption under ThreadSanitizer is a serious concern, // so we release resources sooner. The value of 1 leads to 1 to 2 second @@ -136,10 +136,10 @@ class Waiter { // REQUIRES: WinHelper::GetLock(this) must be held. void InternalCondVarPoke(); - // We can't include Windows.h in our headers, so we use aligned charachter - // buffers to define the storage of SRWLOCK and CONDITION_VARIABLE. - alignas(void*) unsigned char mu_storage_[sizeof(void*)]; - alignas(void*) unsigned char cv_storage_[sizeof(void*)]; + // We can't include Windows.h in our headers, so we use aligned charachter + // buffers to define the storage of SRWLOCK and CONDITION_VARIABLE. + alignas(void*) unsigned char mu_storage_[sizeof(void*)]; + alignas(void*) unsigned char cv_storage_[sizeof(void*)]; int waiter_count_; int wakeup_count_; @@ -149,7 +149,7 @@ class Waiter { }; } // namespace synchronization_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_INTERNAL_WAITER_H_ diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/internal/ya.make b/contrib/restricted/abseil-cpp/absl/synchronization/internal/ya.make index 40f72cf665..6207943f1a 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/internal/ya.make +++ b/contrib/restricted/abseil-cpp/absl/synchronization/internal/ya.make @@ -24,10 +24,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCS( graphcycles.cc ) diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc b/contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc index 76ad41fe16..a429496e9b 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc +++ b/contrib/restricted/abseil-cpp/absl/synchronization/mutex.cc @@ -39,7 +39,7 @@ #include <thread> // NOLINT(build/c++11) #include "absl/base/attributes.h" -#include "absl/base/call_once.h" +#include "absl/base/call_once.h" #include "absl/base/config.h" #include "absl/base/dynamic_annotations.h" #include "absl/base/internal/atomic_hook.h" @@ -60,7 +60,7 @@ using absl::base_internal::CurrentThreadIdentityIfPresent; using absl::base_internal::PerThreadSynch; -using absl::base_internal::SchedulingGuard; +using absl::base_internal::SchedulingGuard; using absl::base_internal::ThreadIdentity; using absl::synchronization_internal::GetOrCreateCurrentThreadIdentity; using absl::synchronization_internal::GraphCycles; @@ -76,11 +76,11 @@ ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalMutexYield)() { } // extern "C" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { -#if defined(ABSL_HAVE_THREAD_SANITIZER) +#if defined(ABSL_HAVE_THREAD_SANITIZER) constexpr OnDeadlockCycle kDeadlockDetectionDefault = OnDeadlockCycle::kIgnore; #else constexpr OnDeadlockCycle kDeadlockDetectionDefault = OnDeadlockCycle::kAbort; @@ -90,16 +90,16 @@ ABSL_CONST_INIT std::atomic<OnDeadlockCycle> synch_deadlock_detection( kDeadlockDetectionDefault); ABSL_CONST_INIT std::atomic<bool> synch_check_invariants(false); -ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES -absl::base_internal::AtomicHook<void (*)(int64_t wait_cycles)> +ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES +absl::base_internal::AtomicHook<void (*)(int64_t wait_cycles)> submit_profile_data; -ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook<void (*)( - const char *msg, const void *obj, int64_t wait_cycles)> - mutex_tracer; -ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES - absl::base_internal::AtomicHook<void (*)(const char *msg, const void *cv)> - cond_var_tracer; -ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook< +ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook<void (*)( + const char *msg, const void *obj, int64_t wait_cycles)> + mutex_tracer; +ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES + absl::base_internal::AtomicHook<void (*)(const char *msg, const void *cv)> + cond_var_tracer; +ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook< bool (*)(const void *pc, char *out, int out_size)> symbolizer(absl::Symbolize); @@ -131,15 +131,15 @@ namespace { // See the comment in GetMutexGlobals() for more information. enum DelayMode { AGGRESSIVE, GENTLE }; -struct ABSL_CACHELINE_ALIGNED MutexGlobals { - absl::once_flag once; - int spinloop_iterations = 0; +struct ABSL_CACHELINE_ALIGNED MutexGlobals { + absl::once_flag once; + int spinloop_iterations = 0; int32_t mutex_sleep_limit[2] = {}; -}; - +}; + const MutexGlobals &GetMutexGlobals() { - ABSL_CONST_INIT static MutexGlobals data; - absl::base_internal::LowLevelCallOnce(&data.once, [&]() { + ABSL_CONST_INIT static MutexGlobals data; + absl::base_internal::LowLevelCallOnce(&data.once, [&]() { const int num_cpus = absl::base_internal::NumCPUs(); data.spinloop_iterations = num_cpus > 1 ? 1500 : 0; // If this a uniprocessor, only yield/sleep. Otherwise, if the mode is @@ -154,36 +154,36 @@ const MutexGlobals &GetMutexGlobals() { data.mutex_sleep_limit[AGGRESSIVE] = 0; data.mutex_sleep_limit[GENTLE] = 0; } - }); - return data; -} + }); + return data; +} } // namespace - -namespace synchronization_internal { + +namespace synchronization_internal { // Returns the Mutex delay on iteration `c` depending on the given `mode`. // The returned value should be used as `c` for the next call to `MutexDelay`. -int MutexDelay(int32_t c, int mode) { +int MutexDelay(int32_t c, int mode) { const int32_t limit = GetMutexGlobals().mutex_sleep_limit[mode]; if (c < limit) { - // Spin. - c++; + // Spin. + c++; } else { - SchedulingGuard::ScopedEnable enable_rescheduling; + SchedulingGuard::ScopedEnable enable_rescheduling; ABSL_TSAN_MUTEX_PRE_DIVERT(nullptr, 0); - if (c == limit) { - // Yield once. + if (c == limit) { + // Yield once. ABSL_INTERNAL_C_SYMBOL(AbslInternalMutexYield)(); c++; - } else { - // Then wait. + } else { + // Then wait. absl::SleepFor(absl::Microseconds(10)); c = 0; } ABSL_TSAN_MUTEX_POST_DIVERT(nullptr, 0); } - return c; + return c; } -} // namespace synchronization_internal +} // namespace synchronization_internal // --------------------------Generic atomic ops // Ensure that "(*pv & bits) == bits" by doing an atomic update of "*pv" to @@ -221,12 +221,12 @@ static void AtomicClearBits(std::atomic<intptr_t>* pv, intptr_t bits, //------------------------------------------------------------------ // Data for doing deadlock detection. -ABSL_CONST_INIT static absl::base_internal::SpinLock deadlock_graph_mu( - absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY); +ABSL_CONST_INIT static absl::base_internal::SpinLock deadlock_graph_mu( + absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY); -// Graph used to detect deadlocks. -ABSL_CONST_INIT static GraphCycles *deadlock_graph - ABSL_GUARDED_BY(deadlock_graph_mu) ABSL_PT_GUARDED_BY(deadlock_graph_mu); +// Graph used to detect deadlocks. +ABSL_CONST_INIT static GraphCycles *deadlock_graph + ABSL_GUARDED_BY(deadlock_graph_mu) ABSL_PT_GUARDED_BY(deadlock_graph_mu); //------------------------------------------------------------------ // An event mechanism for debugging mutex use. @@ -287,12 +287,12 @@ static const struct { {0, "SignalAll on "}, }; -ABSL_CONST_INIT static absl::base_internal::SpinLock synch_event_mu( - absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY); +ABSL_CONST_INIT static absl::base_internal::SpinLock synch_event_mu( + absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY); // Hash table size; should be prime > 2. // Can't be too small, as it's used for deadlock detection information. -static constexpr uint32_t kNSynchEvent = 1031; +static constexpr uint32_t kNSynchEvent = 1031; static struct SynchEvent { // this is a trivial hash table for the events // struct is freed when refcount reaches 0 @@ -312,7 +312,7 @@ static struct SynchEvent { // this is a trivial hash table for the events bool log; // logging turned on // Constant after initialization - char name[1]; // actually longer---NUL-terminated string + char name[1]; // actually longer---NUL-terminated string } * synch_event[kNSynchEvent] ABSL_GUARDED_BY(synch_event_mu); // Ensure that the object at "addr" has a SynchEvent struct associated with it, @@ -503,7 +503,7 @@ struct SynchWaitParams { std::atomic<intptr_t> *cv_word; int64_t contention_start_cycles; // Time (in cycles) when this thread started - // to contend for the mutex. + // to contend for the mutex. }; struct SynchLocksHeld { @@ -1064,7 +1064,7 @@ static PerThreadSynch *DequeueAllWakeable(PerThreadSynch *head, // Try to remove thread s from the list of waiters on this mutex. // Does nothing if s is not on the waiter list. void Mutex::TryRemove(PerThreadSynch *s) { - SchedulingGuard::ScopedDisable disable_rescheduling; + SchedulingGuard::ScopedDisable disable_rescheduling; intptr_t v = mu_.load(std::memory_order_relaxed); // acquire spinlock & lock if ((v & (kMuWait | kMuSpin | kMuWriter | kMuReader)) == kMuWait && @@ -1131,7 +1131,7 @@ ABSL_XRAY_LOG_ARGS(1) void Mutex::Block(PerThreadSynch *s) { this->TryRemove(s); int c = 0; while (s->next != nullptr) { - c = synchronization_internal::MutexDelay(c, GENTLE); + c = synchronization_internal::MutexDelay(c, GENTLE); this->TryRemove(s); } if (kDebugMode) { @@ -1452,19 +1452,19 @@ void Mutex::AssertNotHeld() const { // Attempt to acquire *mu, and return whether successful. The implementation // may spin for a short while if the lock cannot be acquired immediately. static bool TryAcquireWithSpinning(std::atomic<intptr_t>* mu) { - int c = GetMutexGlobals().spinloop_iterations; + int c = GetMutexGlobals().spinloop_iterations; do { // do/while somewhat faster on AMD intptr_t v = mu->load(std::memory_order_relaxed); - if ((v & (kMuReader|kMuEvent)) != 0) { - return false; // a reader or tracing -> give up + if ((v & (kMuReader|kMuEvent)) != 0) { + return false; // a reader or tracing -> give up } else if (((v & kMuWriter) == 0) && // no holder -> try to acquire mu->compare_exchange_strong(v, kMuWriter | v, std::memory_order_acquire, std::memory_order_relaxed)) { - return true; + return true; } - } while (--c > 0); - return false; + } while (--c > 0); + return false; } ABSL_XRAY_LOG_ARGS(1) void Mutex::Lock() { @@ -1763,8 +1763,8 @@ static const intptr_t ignore_waiting_writers[] = { }; // Internal version of LockWhen(). See LockSlowWithDeadline() -ABSL_ATTRIBUTE_NOINLINE void Mutex::LockSlow(MuHow how, const Condition *cond, - int flags) { +ABSL_ATTRIBUTE_NOINLINE void Mutex::LockSlow(MuHow how, const Condition *cond, + int flags) { ABSL_RAW_CHECK( this->LockSlowWithDeadline(how, cond, KernelTimeout::Never(), flags), "condition untrue on return from LockSlow"); @@ -1829,9 +1829,9 @@ static inline bool EvalConditionIgnored(Mutex *mu, const Condition *cond) { // So we "divert" (which un-ignores both memory accesses and synchronization) // and then separately turn on ignores of memory accesses. ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0); - ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN(); + ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN(); bool res = cond->Eval(); - ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END(); + ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END(); ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0); static_cast<void>(mu); // Prevent unused param warning in non-TSAN builds. return res; @@ -1912,7 +1912,7 @@ static void CheckForMutexCorruption(intptr_t v, const char* label) { } void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) { - SchedulingGuard::ScopedDisable disable_rescheduling; + SchedulingGuard::ScopedDisable disable_rescheduling; int c = 0; intptr_t v = mu_.load(std::memory_order_relaxed); if ((v & kMuEvent) != 0) { @@ -2014,8 +2014,8 @@ void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) { ABSL_RAW_CHECK( waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors, "detected illegal recursion into Mutex code"); - // delay, then try again - c = synchronization_internal::MutexDelay(c, GENTLE); + // delay, then try again + c = synchronization_internal::MutexDelay(c, GENTLE); } ABSL_RAW_CHECK( waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors, @@ -2032,8 +2032,8 @@ void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) { // which holds the lock but is not runnable because its condition is false // or it is in the process of blocking on a condition variable; it must requeue // itself on the mutex/condvar to wait for its condition to become true. -ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams *waitp) { - SchedulingGuard::ScopedDisable disable_rescheduling; +ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams *waitp) { + SchedulingGuard::ScopedDisable disable_rescheduling; intptr_t v = mu_.load(std::memory_order_relaxed); this->AssertReaderHeld(); CheckForMutexCorruption(v, "Unlock"); @@ -2310,8 +2310,8 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams *waitp) { mu_.store(nv, std::memory_order_release); break; // out of for(;;)-loop } - // aggressive here; no one can proceed till we do - c = synchronization_internal::MutexDelay(c, AGGRESSIVE); + // aggressive here; no one can proceed till we do + c = synchronization_internal::MutexDelay(c, AGGRESSIVE); } // end of for(;;)-loop if (wake_list != kPerThreadSynchNull) { @@ -2323,8 +2323,8 @@ ABSL_ATTRIBUTE_NOINLINE void Mutex::UnlockSlow(SynchWaitParams *waitp) { if (!cond_waiter) { // Sample lock contention events only if the (first) waiter was trying to // acquire the lock, not waiting on a condition variable or Condition. - int64_t wait_cycles = - base_internal::CycleClock::Now() - enqueue_timestamp; + int64_t wait_cycles = + base_internal::CycleClock::Now() - enqueue_timestamp; mutex_tracer("slow release", this, wait_cycles); ABSL_TSAN_MUTEX_PRE_DIVERT(this, 0); submit_profile_data(enqueue_timestamp); @@ -2351,7 +2351,7 @@ void Mutex::Trans(MuHow how) { // It will later acquire the mutex with high probability. Otherwise, we // enqueue thread w on this mutex. void Mutex::Fer(PerThreadSynch *w) { - SchedulingGuard::ScopedDisable disable_rescheduling; + SchedulingGuard::ScopedDisable disable_rescheduling; int c = 0; ABSL_RAW_CHECK(w->waitp->cond == nullptr, "Mutex::Fer while waiting on Condition"); @@ -2401,7 +2401,7 @@ void Mutex::Fer(PerThreadSynch *w) { return; } } - c = synchronization_internal::MutexDelay(c, GENTLE); + c = synchronization_internal::MutexDelay(c, GENTLE); } } @@ -2450,7 +2450,7 @@ CondVar::~CondVar() { // Remove thread s from the list of waiters on this condition variable. void CondVar::Remove(PerThreadSynch *s) { - SchedulingGuard::ScopedDisable disable_rescheduling; + SchedulingGuard::ScopedDisable disable_rescheduling; intptr_t v; int c = 0; for (v = cv_.load(std::memory_order_relaxed);; @@ -2479,8 +2479,8 @@ void CondVar::Remove(PerThreadSynch *s) { std::memory_order_release); return; } else { - // try again after a delay - c = synchronization_internal::MutexDelay(c, GENTLE); + // try again after a delay + c = synchronization_internal::MutexDelay(c, GENTLE); } } } @@ -2513,7 +2513,7 @@ static void CondVarEnqueue(SynchWaitParams *waitp) { !cv_word->compare_exchange_weak(v, v | kCvSpin, std::memory_order_acquire, std::memory_order_relaxed)) { - c = synchronization_internal::MutexDelay(c, GENTLE); + c = synchronization_internal::MutexDelay(c, GENTLE); v = cv_word->load(std::memory_order_relaxed); } ABSL_RAW_CHECK(waitp->thread->waitp == nullptr, "waiting when shouldn't be"); @@ -2612,7 +2612,7 @@ void CondVar::Wakeup(PerThreadSynch *w) { } void CondVar::Signal() { - SchedulingGuard::ScopedDisable disable_rescheduling; + SchedulingGuard::ScopedDisable disable_rescheduling; ABSL_TSAN_MUTEX_PRE_SIGNAL(nullptr, 0); intptr_t v; int c = 0; @@ -2645,7 +2645,7 @@ void CondVar::Signal() { ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0); return; } else { - c = synchronization_internal::MutexDelay(c, GENTLE); + c = synchronization_internal::MutexDelay(c, GENTLE); } } ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0); @@ -2682,8 +2682,8 @@ void CondVar::SignalAll () { ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0); return; } else { - // try again after a delay - c = synchronization_internal::MutexDelay(c, GENTLE); + // try again after a delay + c = synchronization_internal::MutexDelay(c, GENTLE); } } ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0); @@ -2696,7 +2696,7 @@ void ReleasableMutexLock::Release() { this->mu_ = nullptr; } -#ifdef ABSL_HAVE_THREAD_SANITIZER +#ifdef ABSL_HAVE_THREAD_SANITIZER extern "C" void __tsan_read1(void *addr); #else #define __tsan_read1(addr) // do nothing if TSan not enabled @@ -2747,5 +2747,5 @@ bool Condition::GuaranteedEqual(const Condition *a, const Condition *b) { a->arg_ == b->arg_ && a->method_ == b->method_; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/mutex.h b/contrib/restricted/abseil-cpp/absl/synchronization/mutex.h index 38338f24df..111eea4c77 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/mutex.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/mutex.h @@ -74,7 +74,7 @@ #include "absl/time/time.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN class Condition; struct SynchWaitParams; @@ -323,16 +323,16 @@ class ABSL_LOCKABLE Mutex { // Mutex::AwaitWithTimeout() // Mutex::AwaitWithDeadline() // - // Unlocks this `Mutex` and blocks until simultaneously: + // Unlocks this `Mutex` and blocks until simultaneously: // - either `cond` is true or the {timeout has expired, deadline has passed} // and // - this `Mutex` can be reacquired, // then reacquire this `Mutex` in the same mode in which it was previously // held, returning `true` iff `cond` is `true` on return. // - // If the condition is initially `true`, the implementation *may* skip the - // release/re-acquire step and return immediately. - // + // If the condition is initially `true`, the implementation *may* skip the + // release/re-acquire step and return immediately. + // // Deadlines in the past are equivalent to an immediate deadline. // Negative timeouts are equivalent to a zero timeout. // @@ -701,11 +701,11 @@ class Condition { // return processed_ >= current; // }; // mu_.Await(Condition(&reached)); - // - // NOTE: never use "mu_.AssertHeld()" instead of "mu_.AssertReaderHeld()" in - // the lambda as it may be called when the mutex is being unlocked from a - // scope holding only a reader lock, which will make the assertion not - // fulfilled and crash the binary. + // + // NOTE: never use "mu_.AssertHeld()" instead of "mu_.AssertReaderHeld()" in + // the lambda as it may be called when the mutex is being unlocked from a + // scope holding only a reader lock, which will make the assertion not + // fulfilled and crash the binary. // See class comment for performance advice. In particular, if there // might be more than one waiter for the same condition, make sure @@ -790,8 +790,8 @@ class Condition { // class CondVar { public: - // A `CondVar` allocated on the heap or on the stack can use the this - // constructor. + // A `CondVar` allocated on the heap or on the stack can use the this + // constructor. CondVar(); ~CondVar(); @@ -1005,7 +1005,7 @@ void RegisterMutexProfiler(void (*fn)(int64_t wait_timestamp)); // // This has the same memory ordering concerns as RegisterMutexProfiler() above. void RegisterMutexTracer(void (*fn)(const char *msg, const void *obj, - int64_t wait_cycles)); + int64_t wait_cycles)); // TODO(gfalcon): Combine RegisterMutexProfiler() and RegisterMutexTracer() // into a single interface, since they are only ever called in pairs. @@ -1027,7 +1027,7 @@ void RegisterCondVarTracer(void (*fn)(const char *msg, const void *cv)); // // 'pc' is the program counter being symbolized, 'out' is the buffer to write // into, and 'out_size' is the size of the buffer. This function can return -// false if symbolizing failed, or true if a NUL-terminated symbol was written +// false if symbolizing failed, or true if a NUL-terminated symbol was written // to 'out.' // // This has the same memory ordering concerns as RegisterMutexProfiler() above. @@ -1066,7 +1066,7 @@ enum class OnDeadlockCycle { // the manner chosen here. void SetMutexDeadlockDetectionMode(OnDeadlockCycle mode); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl // In some build configurations we pass --detect-odr-violations to the diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/notification.cc b/contrib/restricted/abseil-cpp/absl/synchronization/notification.cc index e91b903822..1439d41380 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/notification.cc +++ b/contrib/restricted/abseil-cpp/absl/synchronization/notification.cc @@ -22,7 +22,7 @@ #include "absl/time/time.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN void Notification::Notify() { MutexLock l(&this->mutex_); @@ -74,5 +74,5 @@ bool Notification::WaitForNotificationWithDeadline(absl::Time deadline) const { return notified; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/notification.h b/contrib/restricted/abseil-cpp/absl/synchronization/notification.h index 9a354ca2c0..ebf0105223 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/notification.h +++ b/contrib/restricted/abseil-cpp/absl/synchronization/notification.h @@ -57,7 +57,7 @@ #include "absl/time/time.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // Notification @@ -117,7 +117,7 @@ class Notification { std::atomic<bool> notified_yet_; // written under mutex_ }; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_SYNCHRONIZATION_NOTIFICATION_H_ diff --git a/contrib/restricted/abseil-cpp/absl/synchronization/ya.make b/contrib/restricted/abseil-cpp/absl/synchronization/ya.make index 06f72b69e9..91926a20aa 100644 --- a/contrib/restricted/abseil-cpp/absl/synchronization/ya.make +++ b/contrib/restricted/abseil-cpp/absl/synchronization/ya.make @@ -36,10 +36,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCS( barrier.cc blocking_counter.cc diff --git a/contrib/restricted/abseil-cpp/absl/time/civil_time.cc b/contrib/restricted/abseil-cpp/absl/time/civil_time.cc index 6a231edb2d..b03132c959 100644 --- a/contrib/restricted/abseil-cpp/absl/time/civil_time.cc +++ b/contrib/restricted/abseil-cpp/absl/time/civil_time.cc @@ -21,7 +21,7 @@ #include "absl/time/time.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { @@ -45,7 +45,7 @@ template <typename CivilT> bool ParseYearAnd(string_view fmt, string_view s, CivilT* c) { // Civil times support a larger year range than absl::Time, so we need to // parse the year separately, normalize it, then use absl::ParseTime on the - // normalized string. + // normalized string. const std::string ss = std::string(s); // TODO(absl-team): Avoid conversion. const char* const np = ss.c_str(); char* endp; @@ -80,7 +80,7 @@ bool ParseAs(string_view s, CivilT2* c) { template <typename CivilT> bool ParseLenient(string_view s, CivilT* c) { - // A fastpath for when the given string data parses exactly into the given + // A fastpath for when the given string data parses exactly into the given // type T (e.g., s="YYYY-MM-DD" and CivilT=CivilDay). if (ParseCivilTime(s, c)) return true; // Try parsing as each of the 6 types, trying the most common types first @@ -96,26 +96,26 @@ bool ParseLenient(string_view s, CivilT* c) { } // namespace std::string FormatCivilTime(CivilSecond c) { - return FormatYearAnd("-%m-%d%ET%H:%M:%S", c); + return FormatYearAnd("-%m-%d%ET%H:%M:%S", c); } std::string FormatCivilTime(CivilMinute c) { - return FormatYearAnd("-%m-%d%ET%H:%M", c); + return FormatYearAnd("-%m-%d%ET%H:%M", c); } std::string FormatCivilTime(CivilHour c) { - return FormatYearAnd("-%m-%d%ET%H", c); + return FormatYearAnd("-%m-%d%ET%H", c); } std::string FormatCivilTime(CivilDay c) { return FormatYearAnd("-%m-%d", c); } std::string FormatCivilTime(CivilMonth c) { return FormatYearAnd("-%m", c); } std::string FormatCivilTime(CivilYear c) { return FormatYearAnd("", c); } bool ParseCivilTime(string_view s, CivilSecond* c) { - return ParseYearAnd("-%m-%d%ET%H:%M:%S", s, c); + return ParseYearAnd("-%m-%d%ET%H:%M:%S", s, c); } bool ParseCivilTime(string_view s, CivilMinute* c) { - return ParseYearAnd("-%m-%d%ET%H:%M", s, c); + return ParseYearAnd("-%m-%d%ET%H:%M", s, c); } bool ParseCivilTime(string_view s, CivilHour* c) { - return ParseYearAnd("-%m-%d%ET%H", s, c); + return ParseYearAnd("-%m-%d%ET%H", s, c); } bool ParseCivilTime(string_view s, CivilDay* c) { return ParseYearAnd("-%m-%d", s, c); @@ -169,5 +169,5 @@ std::ostream& operator<<(std::ostream& os, CivilSecond s) { } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/civil_time.h b/contrib/restricted/abseil-cpp/absl/time/civil_time.h index bb46004434..bced90191f 100644 --- a/contrib/restricted/abseil-cpp/absl/time/civil_time.h +++ b/contrib/restricted/abseil-cpp/absl/time/civil_time.h @@ -76,7 +76,7 @@ #include "absl/time/internal/cctz/include/cctz/civil_time.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { struct second_tag : cctz::detail::second_tag {}; @@ -532,7 +532,7 @@ std::ostream& operator<<(std::ostream& os, CivilSecond s); } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_CIVIL_TIME_H_ diff --git a/contrib/restricted/abseil-cpp/absl/time/civil_time/ya.make b/contrib/restricted/abseil-cpp/absl/time/civil_time/ya.make index d6d6000692..5797933193 100644 --- a/contrib/restricted/abseil-cpp/absl/time/civil_time/ya.make +++ b/contrib/restricted/abseil-cpp/absl/time/civil_time/ya.make @@ -16,10 +16,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/time/internal/cctz/src) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/time/clock.cc b/contrib/restricted/abseil-cpp/absl/time/clock.cc index 7b204c4ee0..40ac6e7a54 100644 --- a/contrib/restricted/abseil-cpp/absl/time/clock.cc +++ b/contrib/restricted/abseil-cpp/absl/time/clock.cc @@ -35,7 +35,7 @@ #include "absl/base/thread_annotations.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN Time Now() { // TODO(bww): Get a timespec instead so we don't have to divide. int64_t n = absl::GetCurrentTimeNanos(); @@ -45,7 +45,7 @@ Time Now() { } return time_internal::FromUnixDuration(absl::Nanoseconds(n)); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl // Decide if we should use the fast GetCurrentTimeNanos() algorithm @@ -74,9 +74,9 @@ ABSL_NAMESPACE_END #if !ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS namespace absl { -ABSL_NAMESPACE_BEGIN -int64_t GetCurrentTimeNanos() { return GET_CURRENT_TIME_NANOS_FROM_SYSTEM(); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_BEGIN +int64_t GetCurrentTimeNanos() { return GET_CURRENT_TIME_NANOS_FROM_SYSTEM(); } +ABSL_NAMESPACE_END } // namespace absl #else // Use the cyclecounter-based implementation below. @@ -87,7 +87,7 @@ ABSL_NAMESPACE_END #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { // This is a friend wrapper around UnscaledCycleClock::Now() // (needed to access UnscaledCycleClock). @@ -535,12 +535,12 @@ static uint64_t UpdateLastSample(uint64_t now_cycles, uint64_t now_ns, return estimated_base_ns; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { // Returns the maximum duration that SleepOnce() can sleep for. @@ -568,7 +568,7 @@ void SleepOnce(absl::Duration to_sleep) { } } // namespace -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl extern "C" { diff --git a/contrib/restricted/abseil-cpp/absl/time/clock.h b/contrib/restricted/abseil-cpp/absl/time/clock.h index 5fe244d638..0f9b555800 100644 --- a/contrib/restricted/abseil-cpp/absl/time/clock.h +++ b/contrib/restricted/abseil-cpp/absl/time/clock.h @@ -26,7 +26,7 @@ #include "absl/time/time.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // Now() // @@ -50,7 +50,7 @@ int64_t GetCurrentTimeNanos(); // * Returns immediately when passed a nonpositive duration. void SleepFor(absl::Duration duration); -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl // ----------------------------------------------------------------------------- diff --git a/contrib/restricted/abseil-cpp/absl/time/duration.cc b/contrib/restricted/abseil-cpp/absl/time/duration.cc index 4443109a51..4aae128bad 100644 --- a/contrib/restricted/abseil-cpp/absl/time/duration.cc +++ b/contrib/restricted/abseil-cpp/absl/time/duration.cc @@ -67,14 +67,14 @@ #include <string> #include "absl/base/casts.h" -#include "absl/base/macros.h" +#include "absl/base/macros.h" #include "absl/numeric/int128.h" -#include "absl/strings/string_view.h" -#include "absl/strings/strip.h" +#include "absl/strings/string_view.h" +#include "absl/strings/strip.h" #include "absl/time/time.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { @@ -356,7 +356,7 @@ namespace time_internal { // the remainder. If it does not saturate, the remainder remain accurate, // but the returned quotient will over/underflow int64_t and should not be used. int64_t IDivDuration(bool satq, const Duration num, const Duration den, - Duration* rem) { + Duration* rem) { int64_t q = 0; if (IDivFastPath(num, den, &q, rem)) { return q; @@ -711,17 +711,17 @@ char* Format64(char* ep, int width, int64_t v) { // fractional digits, because it is in the noise of what a Duration can // represent. struct DisplayUnit { - absl::string_view abbr; + absl::string_view abbr; int prec; double pow10; }; -ABSL_CONST_INIT const DisplayUnit kDisplayNano = {"ns", 2, 1e2}; -ABSL_CONST_INIT const DisplayUnit kDisplayMicro = {"us", 5, 1e5}; -ABSL_CONST_INIT const DisplayUnit kDisplayMilli = {"ms", 8, 1e8}; -ABSL_CONST_INIT const DisplayUnit kDisplaySec = {"s", 11, 1e11}; -ABSL_CONST_INIT const DisplayUnit kDisplayMin = {"m", -1, 0.0}; // prec ignored -ABSL_CONST_INIT const DisplayUnit kDisplayHour = {"h", -1, - 0.0}; // prec ignored +ABSL_CONST_INIT const DisplayUnit kDisplayNano = {"ns", 2, 1e2}; +ABSL_CONST_INIT const DisplayUnit kDisplayMicro = {"us", 5, 1e5}; +ABSL_CONST_INIT const DisplayUnit kDisplayMilli = {"ms", 8, 1e8}; +ABSL_CONST_INIT const DisplayUnit kDisplaySec = {"s", 11, 1e11}; +ABSL_CONST_INIT const DisplayUnit kDisplayMin = {"m", -1, 0.0}; // prec ignored +ABSL_CONST_INIT const DisplayUnit kDisplayHour = {"h", -1, + 0.0}; // prec ignored void AppendNumberUnit(std::string* out, int64_t n, DisplayUnit unit) { char buf[sizeof("2562047788015216")]; // hours in max duration @@ -729,16 +729,16 @@ void AppendNumberUnit(std::string* out, int64_t n, DisplayUnit unit) { char* bp = Format64(ep, 0, n); if (*bp != '0' || bp + 1 != ep) { out->append(bp, ep - bp); - out->append(unit.abbr.data(), unit.abbr.size()); + out->append(unit.abbr.data(), unit.abbr.size()); } } // Note: unit.prec is limited to double's digits10 value (typically 15) so it // always fits in buf[]. void AppendNumberUnit(std::string* out, double n, DisplayUnit unit) { - constexpr int kBufferSize = std::numeric_limits<double>::digits10; - const int prec = std::min(kBufferSize, unit.prec); - char buf[kBufferSize]; // also large enough to hold integer part + constexpr int kBufferSize = std::numeric_limits<double>::digits10; + const int prec = std::min(kBufferSize, unit.prec); + char buf[kBufferSize]; // also large enough to hold integer part char* ep = buf + sizeof(buf); double d = 0; int64_t frac_part = Round(std::modf(n, &d) * unit.pow10); @@ -752,7 +752,7 @@ void AppendNumberUnit(std::string* out, double n, DisplayUnit unit) { while (ep[-1] == '0') --ep; out->append(bp, ep - bp); } - out->append(unit.abbr.data(), unit.abbr.size()); + out->append(unit.abbr.data(), unit.abbr.size()); } } @@ -763,8 +763,8 @@ void AppendNumberUnit(std::string* out, double n, DisplayUnit unit) { // form "72h3m0.5s". Leading zero units are omitted. As a special // case, durations less than one second format use a smaller unit // (milli-, micro-, or nanoseconds) to ensure that the leading digit -// is non-zero. -// Unlike Go, we format the zero duration as 0, with no unit. +// is non-zero. +// Unlike Go, we format the zero duration as 0, with no unit. std::string FormatDuration(Duration d) { const Duration min_duration = Seconds(kint64min); if (d == min_duration) { @@ -805,27 +805,27 @@ namespace { // A helper for ParseDuration() that parses a leading number from the given // string and stores the result in *int_part/*frac_part/*frac_scale. The // given string pointer is modified to point to the first unconsumed char. -bool ConsumeDurationNumber(const char** dpp, const char* ep, int64_t* int_part, +bool ConsumeDurationNumber(const char** dpp, const char* ep, int64_t* int_part, int64_t* frac_part, int64_t* frac_scale) { *int_part = 0; *frac_part = 0; *frac_scale = 1; // invariant: *frac_part < *frac_scale const char* start = *dpp; - for (; *dpp != ep; *dpp += 1) { + for (; *dpp != ep; *dpp += 1) { const int d = **dpp - '0'; // contiguous digits - if (d < 0 || 10 <= d) break; - + if (d < 0 || 10 <= d) break; + if (*int_part > kint64max / 10) return false; *int_part *= 10; if (*int_part > kint64max - d) return false; *int_part += d; } const bool int_part_empty = (*dpp == start); - if (*dpp == ep || **dpp != '.') return !int_part_empty; - - for (*dpp += 1; *dpp != ep; *dpp += 1) { + if (*dpp == ep || **dpp != '.') return !int_part_empty; + + for (*dpp += 1; *dpp != ep; *dpp += 1) { const int d = **dpp - '0'; // contiguous digits - if (d < 0 || 10 <= d) break; + if (d < 0 || 10 <= d) break; if (*frac_scale <= kint64max / 10) { *frac_part *= 10; *frac_part += d; @@ -839,55 +839,55 @@ bool ConsumeDurationNumber(const char** dpp, const char* ep, int64_t* int_part, // ns, us, ms, s, m, h) from the given string and stores the resulting unit // in "*unit". The given string pointer is modified to point to the first // unconsumed char. -bool ConsumeDurationUnit(const char** start, const char* end, Duration* unit) { - size_t size = end - *start; - switch (size) { - case 0: - return false; - default: - switch (**start) { - case 'n': - if (*(*start + 1) == 's') { - *start += 2; - *unit = Nanoseconds(1); - return true; - } - break; - case 'u': - if (*(*start + 1) == 's') { - *start += 2; - *unit = Microseconds(1); - return true; - } - break; - case 'm': - if (*(*start + 1) == 's') { - *start += 2; - *unit = Milliseconds(1); - return true; - } - break; - default: - break; - } - ABSL_FALLTHROUGH_INTENDED; - case 1: - switch (**start) { - case 's': - *unit = Seconds(1); - *start += 1; - return true; - case 'm': - *unit = Minutes(1); - *start += 1; - return true; - case 'h': - *unit = Hours(1); - *start += 1; - return true; - default: - return false; - } +bool ConsumeDurationUnit(const char** start, const char* end, Duration* unit) { + size_t size = end - *start; + switch (size) { + case 0: + return false; + default: + switch (**start) { + case 'n': + if (*(*start + 1) == 's') { + *start += 2; + *unit = Nanoseconds(1); + return true; + } + break; + case 'u': + if (*(*start + 1) == 's') { + *start += 2; + *unit = Microseconds(1); + return true; + } + break; + case 'm': + if (*(*start + 1) == 's') { + *start += 2; + *unit = Milliseconds(1); + return true; + } + break; + default: + break; + } + ABSL_FALLTHROUGH_INTENDED; + case 1: + switch (**start) { + case 's': + *unit = Seconds(1); + *start += 1; + return true; + case 'm': + *unit = Minutes(1); + *start += 1; + return true; + case 'h': + *unit = Hours(1); + *start += 1; + return true; + default: + return false; + } } } @@ -898,38 +898,38 @@ bool ConsumeDurationUnit(const char** start, const char* end, Duration* unit) { // a possibly signed sequence of decimal numbers, each with optional // fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". // Valid time units are "ns", "us" "ms", "s", "m", "h". -bool ParseDuration(absl::string_view dur_sv, Duration* d) { +bool ParseDuration(absl::string_view dur_sv, Duration* d) { int sign = 1; - if (absl::ConsumePrefix(&dur_sv, "-")) { - sign = -1; - } else { - absl::ConsumePrefix(&dur_sv, "+"); + if (absl::ConsumePrefix(&dur_sv, "-")) { + sign = -1; + } else { + absl::ConsumePrefix(&dur_sv, "+"); } - if (dur_sv.empty()) return false; + if (dur_sv.empty()) return false; - // Special case for a string of "0". - if (dur_sv == "0") { + // Special case for a string of "0". + if (dur_sv == "0") { *d = ZeroDuration(); return true; } - if (dur_sv == "inf") { + if (dur_sv == "inf") { *d = sign * InfiniteDuration(); return true; } - const char* start = dur_sv.data(); - const char* end = start + dur_sv.size(); - + const char* start = dur_sv.data(); + const char* end = start + dur_sv.size(); + Duration dur; - while (start != end) { + while (start != end) { int64_t int_part; int64_t frac_part; int64_t frac_scale; Duration unit; - if (!ConsumeDurationNumber(&start, end, &int_part, &frac_part, - &frac_scale) || - !ConsumeDurationUnit(&start, end, &unit)) { + if (!ConsumeDurationNumber(&start, end, &int_part, &frac_part, + &frac_scale) || + !ConsumeDurationUnit(&start, end, &unit)) { return false; } if (int_part != 0) dur += sign * int_part * unit; @@ -940,7 +940,7 @@ bool ParseDuration(absl::string_view dur_sv, Duration* d) { } bool AbslParseFlag(absl::string_view text, Duration* dst, std::string*) { - return ParseDuration(text, dst); + return ParseDuration(text, dst); } std::string AbslUnparseFlag(Duration d) { return FormatDuration(d); } @@ -950,5 +950,5 @@ bool ParseFlag(const std::string& text, Duration* dst, std::string* ) { std::string UnparseFlag(Duration d) { return FormatDuration(d); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/format.cc b/contrib/restricted/abseil-cpp/absl/time/format.cc index 4005fb704c..7a3e8fe1e1 100644 --- a/contrib/restricted/abseil-cpp/absl/time/format.cc +++ b/contrib/restricted/abseil-cpp/absl/time/format.cc @@ -13,25 +13,25 @@ // limitations under the License. #include <string.h> - + #include <cctype> #include <cstdint> -#include "absl/strings/match.h" -#include "absl/strings/string_view.h" +#include "absl/strings/match.h" +#include "absl/strings/string_view.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" #include "absl/time/time.h" namespace cctz = absl::time_internal::cctz; namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN -ABSL_DLL extern const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez"; -ABSL_DLL extern const char RFC3339_sec[] = "%Y-%m-%d%ET%H:%M:%S%Ez"; +ABSL_DLL extern const char RFC3339_full[] = "%Y-%m-%d%ET%H:%M:%E*S%Ez"; +ABSL_DLL extern const char RFC3339_sec[] = "%Y-%m-%d%ET%H:%M:%S%Ez"; -ABSL_DLL extern const char RFC1123_full[] = "%a, %d %b %E4Y %H:%M:%S %z"; -ABSL_DLL extern const char RFC1123_no_wday[] = "%d %b %E4Y %H:%M:%S %z"; +ABSL_DLL extern const char RFC1123_full[] = "%a, %d %b %E4Y %H:%M:%S %z"; +ABSL_DLL extern const char RFC1123_no_wday[] = "%d %b %E4Y %H:%M:%S %z"; namespace { @@ -71,12 +71,12 @@ absl::Time Join(const cctz_parts& parts) { } // namespace -std::string FormatTime(absl::string_view format, absl::Time t, +std::string FormatTime(absl::string_view format, absl::Time t, absl::TimeZone tz) { - if (t == absl::InfiniteFuture()) return std::string(kInfiniteFutureStr); - if (t == absl::InfinitePast()) return std::string(kInfinitePastStr); + if (t == absl::InfiniteFuture()) return std::string(kInfiniteFutureStr); + if (t == absl::InfinitePast()) return std::string(kInfinitePastStr); const auto parts = Split(t); - return cctz::detail::format(std::string(format), parts.sec, parts.fem, + return cctz::detail::format(std::string(format), parts.sec, parts.fem, cctz::time_zone(tz)); } @@ -88,50 +88,50 @@ std::string FormatTime(absl::Time t) { return absl::FormatTime(RFC3339_full, t, absl::LocalTimeZone()); } -bool ParseTime(absl::string_view format, absl::string_view input, +bool ParseTime(absl::string_view format, absl::string_view input, absl::Time* time, std::string* err) { return absl::ParseTime(format, input, absl::UTCTimeZone(), time, err); } // If the input string does not contain an explicit UTC offset, interpret // the fields with respect to the given TimeZone. -bool ParseTime(absl::string_view format, absl::string_view input, +bool ParseTime(absl::string_view format, absl::string_view input, absl::TimeZone tz, absl::Time* time, std::string* err) { - auto strip_leading_space = [](absl::string_view* sv) { - while (!sv->empty()) { - if (!std::isspace(sv->front())) return; - sv->remove_prefix(1); + auto strip_leading_space = [](absl::string_view* sv) { + while (!sv->empty()) { + if (!std::isspace(sv->front())) return; + sv->remove_prefix(1); } - }; - - // Portable toolchains means we don't get nice constexpr here. - struct Literal { - const char* name; - size_t size; - absl::Time value; - }; - static Literal literals[] = { - {kInfiniteFutureStr, strlen(kInfiniteFutureStr), InfiniteFuture()}, - {kInfinitePastStr, strlen(kInfinitePastStr), InfinitePast()}, - }; - strip_leading_space(&input); - for (const auto& lit : literals) { - if (absl::StartsWith(input, absl::string_view(lit.name, lit.size))) { - absl::string_view tail = input; - tail.remove_prefix(lit.size); - strip_leading_space(&tail); - if (tail.empty()) { - *time = lit.value; - return true; - } + }; + + // Portable toolchains means we don't get nice constexpr here. + struct Literal { + const char* name; + size_t size; + absl::Time value; + }; + static Literal literals[] = { + {kInfiniteFutureStr, strlen(kInfiniteFutureStr), InfiniteFuture()}, + {kInfinitePastStr, strlen(kInfinitePastStr), InfinitePast()}, + }; + strip_leading_space(&input); + for (const auto& lit : literals) { + if (absl::StartsWith(input, absl::string_view(lit.name, lit.size))) { + absl::string_view tail = input; + tail.remove_prefix(lit.size); + strip_leading_space(&tail); + if (tail.empty()) { + *time = lit.value; + return true; + } } } std::string error; cctz_parts parts; - const bool b = - cctz::detail::parse(std::string(format), std::string(input), - cctz::time_zone(tz), &parts.sec, &parts.fem, &error); + const bool b = + cctz::detail::parse(std::string(format), std::string(input), + cctz::time_zone(tz), &parts.sec, &parts.fem, &error); if (b) { *time = Join(parts); } else if (err != nullptr) { @@ -142,7 +142,7 @@ bool ParseTime(absl::string_view format, absl::string_view input, // Functions required to support absl::Time flags. bool AbslParseFlag(absl::string_view text, absl::Time* t, std::string* error) { - return absl::ParseTime(RFC3339_full, text, absl::UTCTimeZone(), t, error); + return absl::ParseTime(RFC3339_full, text, absl::UTCTimeZone(), t, error); } std::string AbslUnparseFlag(absl::Time t) { @@ -156,5 +156,5 @@ std::string UnparseFlag(absl::Time t) { return absl::FormatTime(RFC3339_full, t, absl::UTCTimeZone()); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h index d47ff86fe4..18bf6230ba 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time.h @@ -15,11 +15,11 @@ #ifndef ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_ #define ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_ -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/civil_time_detail.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -326,7 +326,7 @@ using detail::get_yearday; } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_CIVIL_TIME_H_ diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h index 8aadde57ca..a27ed73a96 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h @@ -20,8 +20,8 @@ #include <ostream> #include <type_traits> -#include "absl/base/config.h" - +#include "absl/base/config.h" + // Disable constexpr support unless we are in C++14 mode. #if __cpp_constexpr >= 201304 || (defined(_MSC_VER) && _MSC_VER >= 1910) #define CONSTEXPR_D constexpr // data @@ -34,7 +34,7 @@ #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -56,8 +56,8 @@ using second_t = std::int_fast8_t; // [0:59] // Normalized civil-time fields: Y-M-D HH:MM:SS. struct fields { - CONSTEXPR_M fields(year_t year, month_t month, day_t day, hour_t hour, - minute_t minute, second_t second) + CONSTEXPR_M fields(year_t year, month_t month, day_t day, hour_t hour, + minute_t minute, second_t second) : y(year), m(month), d(day), hh(hour), mm(minute), ss(second) {} std::int_least64_t y; std::int_least8_t m; @@ -104,69 +104,69 @@ CONSTEXPR_F int days_per_month(year_t y, month_t m) noexcept { return k_days_per_month[m] + (m == 2 && is_leap_year(y)); } -CONSTEXPR_F fields n_day(year_t y, month_t m, diff_t d, diff_t cd, hour_t hh, - minute_t mm, second_t ss) noexcept { - year_t ey = y % 400; - const year_t oey = ey; - ey += (cd / 146097) * 400; +CONSTEXPR_F fields n_day(year_t y, month_t m, diff_t d, diff_t cd, hour_t hh, + minute_t mm, second_t ss) noexcept { + year_t ey = y % 400; + const year_t oey = ey; + ey += (cd / 146097) * 400; cd %= 146097; if (cd < 0) { - ey -= 400; + ey -= 400; cd += 146097; } - ey += (d / 146097) * 400; + ey += (d / 146097) * 400; d = d % 146097 + cd; if (d > 0) { if (d > 146097) { - ey += 400; + ey += 400; d -= 146097; } } else { if (d > -365) { // We often hit the previous year when stepping a civil time backwards, // so special case it to avoid counting up by 100/4/1-year chunks. - ey -= 1; - d += days_per_year(ey, m); + ey -= 1; + d += days_per_year(ey, m); } else { - ey -= 400; + ey -= 400; d += 146097; } } if (d > 365) { - for (;;) { - int n = days_per_century(ey, m); - if (d <= n) break; + for (;;) { + int n = days_per_century(ey, m); + if (d <= n) break; d -= n; - ey += 100; + ey += 100; } - for (;;) { - int n = days_per_4years(ey, m); - if (d <= n) break; + for (;;) { + int n = days_per_4years(ey, m); + if (d <= n) break; d -= n; - ey += 4; + ey += 4; } - for (;;) { - int n = days_per_year(ey, m); - if (d <= n) break; + for (;;) { + int n = days_per_year(ey, m); + if (d <= n) break; d -= n; - ++ey; + ++ey; } } if (d > 28) { - for (;;) { - int n = days_per_month(ey, m); - if (d <= n) break; + for (;;) { + int n = days_per_month(ey, m); + if (d <= n) break; d -= n; if (++m > 12) { - ++ey; + ++ey; m = 1; } } } - return fields(y + (ey - oey), m, static_cast<day_t>(d), hh, mm, ss); + return fields(y + (ey - oey), m, static_cast<day_t>(d), hh, mm, ss); } -CONSTEXPR_F fields n_mon(year_t y, diff_t m, diff_t d, diff_t cd, hour_t hh, - minute_t mm, second_t ss) noexcept { +CONSTEXPR_F fields n_mon(year_t y, diff_t m, diff_t d, diff_t cd, hour_t hh, + minute_t mm, second_t ss) noexcept { if (m != 12) { y += m / 12; m %= 12; @@ -177,8 +177,8 @@ CONSTEXPR_F fields n_mon(year_t y, diff_t m, diff_t d, diff_t cd, hour_t hh, } return n_day(y, static_cast<month_t>(m), d, cd, hh, mm, ss); } -CONSTEXPR_F fields n_hour(year_t y, diff_t m, diff_t d, diff_t cd, diff_t hh, - minute_t mm, second_t ss) noexcept { +CONSTEXPR_F fields n_hour(year_t y, diff_t m, diff_t d, diff_t cd, diff_t hh, + minute_t mm, second_t ss) noexcept { cd += hh / 24; hh %= 24; if (hh < 0) { @@ -277,8 +277,8 @@ CONSTEXPR_F diff_t ymd_ord(year_t y, month_t m, day_t d) noexcept { // yet the difference between two such extreme values may actually be // small, so we take a little care to avoid overflow when possible by // exploiting the 146097-day cycle. -CONSTEXPR_F diff_t day_difference(year_t y1, month_t m1, day_t d1, year_t y2, - month_t m2, day_t d2) noexcept { +CONSTEXPR_F diff_t day_difference(year_t y1, month_t m1, day_t d1, year_t y2, + month_t m2, day_t d2) noexcept { const diff_t a_c4_off = y1 % 400; const diff_t b_c4_off = y2 % 400; diff_t c4_diff = (y1 - a_c4_off) - (y2 - b_c4_off); @@ -318,7 +318,7 @@ CONSTEXPR_F diff_t difference(second_tag, fields f1, fields f2) noexcept { //////////////////////////////////////////////////////////////////////// // Aligns the (normalized) fields struct to the indicated field. -CONSTEXPR_F fields align(second_tag, fields f) noexcept { return f; } +CONSTEXPR_F fields align(second_tag, fields f) noexcept { return f; } CONSTEXPR_F fields align(minute_tag, fields f) noexcept { return fields{f.y, f.m, f.d, f.hh, f.mm, 0}; } @@ -397,11 +397,11 @@ class civil_time { : civil_time(ct.f_) {} // Factories for the maximum/minimum representable civil_time. - static CONSTEXPR_F civil_time(max)() { + static CONSTEXPR_F civil_time(max)() { const auto max_year = (std::numeric_limits<std::int_least64_t>::max)(); return civil_time(max_year, 12, 31, 23, 59, 59); } - static CONSTEXPR_F civil_time(min)() { + static CONSTEXPR_F civil_time(min)() { const auto min_year = (std::numeric_limits<std::int_least64_t>::min)(); return civil_time(min_year, 1, 1, 0, 0, 0); } @@ -421,13 +421,13 @@ class civil_time { CONSTEXPR_M civil_time& operator-=(diff_t n) noexcept { return *this = *this - n; } - CONSTEXPR_M civil_time& operator++() noexcept { return *this += 1; } + CONSTEXPR_M civil_time& operator++() noexcept { return *this += 1; } CONSTEXPR_M civil_time operator++(int) noexcept { const civil_time a = *this; ++*this; return a; } - CONSTEXPR_M civil_time& operator--() noexcept { return *this -= 1; } + CONSTEXPR_M civil_time& operator--() noexcept { return *this -= 1; } CONSTEXPR_M civil_time operator--(int) noexcept { const civil_time a = *this; --*this; @@ -486,17 +486,17 @@ using civil_second = civil_time<second_tag>; template <typename T1, typename T2> CONSTEXPR_F bool operator<(const civil_time<T1>& lhs, const civil_time<T2>& rhs) noexcept { - return ( - lhs.year() < rhs.year() || - (lhs.year() == rhs.year() && - (lhs.month() < rhs.month() || - (lhs.month() == rhs.month() && - (lhs.day() < rhs.day() || (lhs.day() == rhs.day() && - (lhs.hour() < rhs.hour() || - (lhs.hour() == rhs.hour() && - (lhs.minute() < rhs.minute() || - (lhs.minute() == rhs.minute() && - (lhs.second() < rhs.second()))))))))))); + return ( + lhs.year() < rhs.year() || + (lhs.year() == rhs.year() && + (lhs.month() < rhs.month() || + (lhs.month() == rhs.month() && + (lhs.day() < rhs.day() || (lhs.day() == rhs.day() && + (lhs.hour() < rhs.hour() || + (lhs.hour() == rhs.hour() && + (lhs.minute() < rhs.minute() || + (lhs.minute() == rhs.minute() && + (lhs.second() < rhs.second()))))))))))); } template <typename T1, typename T2> CONSTEXPR_F bool operator<=(const civil_time<T1>& lhs, @@ -618,7 +618,7 @@ std::ostream& operator<<(std::ostream& os, weekday wd); } // namespace detail } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #undef CONSTEXPR_M diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h index 6e382dc6c9..bef00a51f1 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h @@ -26,11 +26,11 @@ #include <string> #include <utility> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/civil_time.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -186,20 +186,20 @@ class time_zone { bool next_transition(const time_point<seconds>& tp, civil_transition* trans) const; template <typename D> - bool next_transition(const time_point<D>& tp, civil_transition* trans) const { + bool next_transition(const time_point<D>& tp, civil_transition* trans) const { return next_transition(detail::split_seconds(tp).first, trans); } bool prev_transition(const time_point<seconds>& tp, civil_transition* trans) const; template <typename D> - bool prev_transition(const time_point<D>& tp, civil_transition* trans) const { + bool prev_transition(const time_point<D>& tp, civil_transition* trans) const { return prev_transition(detail::split_seconds(tp).first, trans); } // version() and description() provide additional information about the // time zone. The content of each of the returned strings is unspecified, // however, when the IANA Time Zone Database is the underlying data source - // the version() string will be in the familar form (e.g, "2018e") or + // the version() string will be in the familar form (e.g, "2018e") or // empty when unavailable. // // Note: These functions are for informational or testing purposes only. @@ -210,7 +210,7 @@ class time_zone { friend bool operator==(time_zone lhs, time_zone rhs) { return &lhs.effective_impl() == &rhs.effective_impl(); } - friend bool operator!=(time_zone lhs, time_zone rhs) { return !(lhs == rhs); } + friend bool operator!=(time_zone lhs, time_zone rhs) { return !(lhs == rhs); } template <typename H> friend H AbslHashValue(H h, time_zone tz) { @@ -296,7 +296,7 @@ bool join_seconds(const time_point<seconds>& sec, const femtoseconds&, // - %E#f - Fractional seconds with # digits of precision // - %E*f - Fractional seconds with full precision (a literal '*') // - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) -// - %ET - The RFC3339 "date-time" separator "T" +// - %ET - The RFC3339 "date-time" separator "T" // // Note that %E0S behaves like %S, and %E0f produces no characters. In // contrast %E*f always produces at least one digit, which may be '0'. @@ -326,8 +326,8 @@ inline std::string format(const std::string& fmt, const time_point<D>& tp, // returns the corresponding time_point. Uses strftime()-like formatting // options, with the same extensions as cctz::format(), but with the // exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez -// and %E*z also accept the same inputs, which (along with %z) includes -// 'z' and 'Z' as synonyms for +00:00. %ET accepts either 'T' or 't'. +// and %E*z also accept the same inputs, which (along with %z) includes +// 'z' and 'Z' as synonyms for +00:00. %ET accepts either 'T' or 't'. // // %Y consumes as many numeric characters as it can, so the matching data // should always be terminated with a non-numeric. %E4Y always consumes @@ -453,7 +453,7 @@ inline bool join_seconds(const time_point<seconds>& sec, const femtoseconds&, } // namespace detail } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/zone_info_source.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/zone_info_source.h index 012eb4ec30..558d5c1fcd 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/zone_info_source.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/include/cctz/zone_info_source.h @@ -20,10 +20,10 @@ #include <memory> #include <string> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -33,21 +33,21 @@ class ZoneInfoSource { virtual ~ZoneInfoSource(); virtual std::size_t Read(void* ptr, std::size_t size) = 0; // like fread() - virtual int Skip(std::size_t offset) = 0; // like fseek() + virtual int Skip(std::size_t offset) = 0; // like fseek() // Until the zoneinfo data supports versioning information, we provide // a way for a ZoneInfoSource to indicate it out-of-band. The default - // implementation returns an empty string. + // implementation returns an empty string. virtual std::string Version() const; }; } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz_extension { @@ -57,8 +57,8 @@ namespace cctz_extension { using ZoneInfoSourceFactory = std::unique_ptr<absl::time_internal::cctz::ZoneInfoSource> (*)( const std::string&, - const std::function<std::unique_ptr< - absl::time_internal::cctz::ZoneInfoSource>(const std::string&)>&); + const std::function<std::unique_ptr< + absl::time_internal::cctz::ZoneInfoSource>(const std::string&)>&); // The user can control the mapping of zone names to zoneinfo data by // providing a definition for cctz_extension::zone_info_source_factory. @@ -96,7 +96,7 @@ extern ZoneInfoSourceFactory zone_info_source_factory; } // namespace cctz_extension } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_ZONE_INFO_SOURCE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/civil_time_detail.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/civil_time_detail.cc index 0b07e397e5..94f06f9e03 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/civil_time_detail.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/civil_time_detail.cc @@ -18,10 +18,10 @@ #include <ostream> #include <sstream> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { namespace detail { @@ -90,5 +90,5 @@ std::ostream& operator<<(std::ostream& os, weekday wd) { } // namespace detail } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc index f2b3294ef7..a8fd9c71cd 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc @@ -20,10 +20,10 @@ #include <cstring> #include <string> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -62,9 +62,9 @@ bool FixedOffsetFromName(const std::string& name, seconds* offset) { const char* const ep = kFixedZonePrefix + prefix_len; if (name.size() != prefix_len + 9) // <prefix>+99:99:99 return false; - if (!std::equal(kFixedZonePrefix, ep, name.begin())) return false; + if (!std::equal(kFixedZonePrefix, ep, name.begin())) return false; const char* np = name.data() + prefix_len; - if (np[0] != '+' && np[0] != '-') return false; + if (np[0] != '+' && np[0] != '-') return false; if (np[3] != ':' || np[6] != ':') // see note below about large offsets return false; @@ -89,29 +89,29 @@ std::string FixedOffsetToName(const seconds& offset) { // offsets and to (somewhat) limit the total number of zones. return "UTC"; } - int offset_seconds = static_cast<int>(offset.count()); - const char sign = (offset_seconds < 0 ? '-' : '+'); - int offset_minutes = offset_seconds / 60; - offset_seconds %= 60; + int offset_seconds = static_cast<int>(offset.count()); + const char sign = (offset_seconds < 0 ? '-' : '+'); + int offset_minutes = offset_seconds / 60; + offset_seconds %= 60; if (sign == '-') { - if (offset_seconds > 0) { - offset_seconds -= 60; - offset_minutes += 1; + if (offset_seconds > 0) { + offset_seconds -= 60; + offset_minutes += 1; } - offset_seconds = -offset_seconds; - offset_minutes = -offset_minutes; + offset_seconds = -offset_seconds; + offset_minutes = -offset_minutes; } - int offset_hours = offset_minutes / 60; - offset_minutes %= 60; + int offset_hours = offset_minutes / 60; + offset_minutes %= 60; const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1; char buf[prefix_len + sizeof("-24:00:00")]; char* ep = std::copy(kFixedZonePrefix, kFixedZonePrefix + prefix_len, buf); *ep++ = sign; - ep = Format02d(ep, offset_hours); + ep = Format02d(ep, offset_hours); *ep++ = ':'; - ep = Format02d(ep, offset_minutes); + ep = Format02d(ep, offset_minutes); *ep++ = ':'; - ep = Format02d(ep, offset_seconds); + ep = Format02d(ep, offset_seconds); *ep++ = '\0'; assert(ep == buf + sizeof(buf)); return buf; @@ -136,5 +136,5 @@ std::string FixedOffsetToAbbr(const seconds& offset) { } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.h index e74a0bbd9d..d237a7bce6 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.h @@ -17,11 +17,11 @@ #include <string> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -46,7 +46,7 @@ std::string FixedOffsetToAbbr(const seconds& offset); } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_FIXED_H_ diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc index d8cb047425..4dc047560e 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc @@ -13,18 +13,18 @@ // limitations under the License. #if !defined(HAS_STRPTIME) -#if !defined(_MSC_VER) && !defined(__MINGW32__) -#define HAS_STRPTIME 1 // assume everyone has strptime() except windows -#endif +#if !defined(_MSC_VER) && !defined(__MINGW32__) +#define HAS_STRPTIME 1 // assume everyone has strptime() except windows #endif +#endif #if defined(HAS_STRPTIME) && HAS_STRPTIME -#if !defined(_XOPEN_SOURCE) -#define _XOPEN_SOURCE // Definedness suffices for strptime. -#endif +#if !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE // Definedness suffices for strptime. #endif +#endif -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" // Include time.h directly since, by C++ standards, ctime doesn't have to @@ -49,7 +49,7 @@ #include "time_zone_if.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { namespace detail { @@ -67,48 +67,48 @@ char* strptime(const char* s, const char* fmt, std::tm* tm) { } #endif -// Convert a cctz::weekday to a tm_wday value (0-6, Sunday = 0). -int ToTmWday(weekday wd) { - switch (wd) { - case weekday::sunday: - return 0; - case weekday::monday: - return 1; - case weekday::tuesday: - return 2; - case weekday::wednesday: - return 3; - case weekday::thursday: - return 4; - case weekday::friday: - return 5; - case weekday::saturday: - return 6; - } - return 0; /*NOTREACHED*/ -} - -// Convert a tm_wday value (0-6, Sunday = 0) to a cctz::weekday. -weekday FromTmWday(int tm_wday) { - switch (tm_wday) { - case 0: - return weekday::sunday; - case 1: - return weekday::monday; - case 2: - return weekday::tuesday; - case 3: - return weekday::wednesday; - case 4: - return weekday::thursday; - case 5: - return weekday::friday; - case 6: - return weekday::saturday; - } - return weekday::sunday; /*NOTREACHED*/ -} - +// Convert a cctz::weekday to a tm_wday value (0-6, Sunday = 0). +int ToTmWday(weekday wd) { + switch (wd) { + case weekday::sunday: + return 0; + case weekday::monday: + return 1; + case weekday::tuesday: + return 2; + case weekday::wednesday: + return 3; + case weekday::thursday: + return 4; + case weekday::friday: + return 5; + case weekday::saturday: + return 6; + } + return 0; /*NOTREACHED*/ +} + +// Convert a tm_wday value (0-6, Sunday = 0) to a cctz::weekday. +weekday FromTmWday(int tm_wday) { + switch (tm_wday) { + case 0: + return weekday::sunday; + case 1: + return weekday::monday; + case 2: + return weekday::tuesday; + case 3: + return weekday::wednesday; + case 4: + return weekday::thursday; + case 5: + return weekday::friday; + case 6: + return weekday::saturday; + } + return weekday::sunday; /*NOTREACHED*/ +} + std::tm ToTM(const time_zone::absolute_lookup& al) { std::tm tm{}; tm.tm_sec = al.cs.second(); @@ -126,19 +126,19 @@ std::tm ToTM(const time_zone::absolute_lookup& al) { tm.tm_year = static_cast<int>(al.cs.year() - 1900); } - tm.tm_wday = ToTmWday(get_weekday(al.cs)); + tm.tm_wday = ToTmWday(get_weekday(al.cs)); tm.tm_yday = get_yearday(al.cs) - 1; tm.tm_isdst = al.is_dst ? 1 : 0; return tm; } -// Returns the week of the year [0:53] given a civil day and the day on -// which weeks are defined to start. -int ToWeek(const civil_day& cd, weekday week_start) { - const civil_day d(cd.year() % 400, cd.month(), cd.day()); - return static_cast<int>((d - prev_weekday(civil_year(d), week_start)) / 7); -} - +// Returns the week of the year [0:53] given a civil day and the day on +// which weeks are defined to start. +int ToWeek(const civil_day& cd, weekday week_start) { + const civil_day d(cd.year() % 400, cd.month(), cd.day()); + return static_cast<int>((d - prev_weekday(civil_year(d), week_start)) / 7); +} + const char kDigits[] = "0123456789"; // Formats a 64-bit integer in the given field width. Note that it is up @@ -216,7 +216,7 @@ void FormatTM(std::string* out, const std::string& fmt, const std::tm& tm) { // strftime(3) returns the number of characters placed in the output // array (which may be 0 characters). It also returns 0 to indicate // an error, like the array wasn't large enough. To accommodate this, - // the following code grows the buffer size from 2x the format string + // the following code grows the buffer size from 2x the format string // length up to 32x. for (std::size_t i = 2; i != 32; i *= 2) { std::size_t buf_size = fmt.size() * i; @@ -317,7 +317,7 @@ const std::int_fast64_t kExp10[kDigits10_64 + 1] = { // - %E#S - Seconds with # digits of fractional precision // - %E*S - Seconds with full fractional precision (a literal '*') // - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) -// - %ET - The RFC3339 "date-time" separator "T" +// - %ET - The RFC3339 "date-time" separator "T" // // The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are // handled internally for performance reasons. strftime(3) is slow due to @@ -382,7 +382,7 @@ std::string format(const std::string& format, const time_point<seconds>& tp, if (cur == end || (cur - percent) % 2 == 0) continue; // Simple specifiers that we handle ourselves. - if (strchr("YmdeUuWwHMSzZs%", *cur)) { + if (strchr("YmdeUuWwHMSzZs%", *cur)) { if (cur - 1 != pending) { FormatTM(&result, std::string(pending, cur - 1), tm); } @@ -403,22 +403,22 @@ std::string format(const std::string& format, const time_point<seconds>& tp, if (*cur == 'e' && *bp == '0') *bp = ' '; // for Windows result.append(bp, static_cast<std::size_t>(ep - bp)); break; - case 'U': - bp = Format02d(ep, ToWeek(civil_day(al.cs), weekday::sunday)); - result.append(bp, static_cast<std::size_t>(ep - bp)); - break; - case 'u': - bp = Format64(ep, 0, tm.tm_wday ? tm.tm_wday : 7); - result.append(bp, static_cast<std::size_t>(ep - bp)); - break; - case 'W': - bp = Format02d(ep, ToWeek(civil_day(al.cs), weekday::monday)); - result.append(bp, static_cast<std::size_t>(ep - bp)); - break; - case 'w': - bp = Format64(ep, 0, tm.tm_wday); - result.append(bp, static_cast<std::size_t>(ep - bp)); - break; + case 'U': + bp = Format02d(ep, ToWeek(civil_day(al.cs), weekday::sunday)); + result.append(bp, static_cast<std::size_t>(ep - bp)); + break; + case 'u': + bp = Format64(ep, 0, tm.tm_wday ? tm.tm_wday : 7); + result.append(bp, static_cast<std::size_t>(ep - bp)); + break; + case 'W': + bp = Format02d(ep, ToWeek(civil_day(al.cs), weekday::monday)); + result.append(bp, static_cast<std::size_t>(ep - bp)); + break; + case 'w': + bp = Format64(ep, 0, tm.tm_wday); + result.append(bp, static_cast<std::size_t>(ep - bp)); + break; case 'H': bp = Format02d(ep, al.cs.hour()); result.append(bp, static_cast<std::size_t>(ep - bp)); @@ -492,14 +492,14 @@ std::string format(const std::string& format, const time_point<seconds>& tp, if (*cur != 'E' || ++cur == end) continue; // Format our extensions. - if (*cur == 'T') { - // Formats %ET. - if (cur - 2 != pending) { - FormatTM(&result, std::string(pending, cur - 2), tm); - } - result.append("T"); - pending = ++cur; - } else if (*cur == 'z') { + if (*cur == 'T') { + // Formats %ET. + if (cur - 2 != pending) { + FormatTM(&result, std::string(pending, cur - 2), tm); + } + result.append("T"); + pending = ++cur; + } else if (*cur == 'z') { // Formats %Ez. if (cur - 2 != pending) { FormatTM(&result, std::string(pending, cur - 2), tm); @@ -555,9 +555,9 @@ std::string format(const std::string& format, const time_point<seconds>& tp, bp = ep; if (n > 0) { if (n > kDigits10_64) n = kDigits10_64; - bp = Format64(bp, n, - (n > 15) ? fs.count() * kExp10[n - 15] - : fs.count() / kExp10[15 - n]); + bp = Format64(bp, n, + (n > 15) ? fs.count() * kExp10[n - 15] + : fs.count() / kExp10[15 - n]); if (*np == 'S') *--bp = '.'; } if (*np == 'S') bp = Format02d(bp, al.cs.second()); @@ -602,7 +602,7 @@ const char* ParseOffset(const char* dp, const char* mode, int* offset) { } else { dp = nullptr; } - } else if (first == 'Z' || first == 'z') { // Zulu + } else if (first == 'Z' || first == 'z') { // Zulu *offset = 0; } else { dp = nullptr; @@ -653,32 +653,32 @@ const char* ParseTM(const char* dp, const char* fmt, std::tm* tm) { return dp; } -// Sets year, tm_mon and tm_mday given the year, week_num, and tm_wday, -// and the day on which weeks are defined to start. Returns false if year -// would need to move outside its bounds. -bool FromWeek(int week_num, weekday week_start, year_t* year, std::tm* tm) { - const civil_year y(*year % 400); - civil_day cd = prev_weekday(y, week_start); // week 0 - cd = next_weekday(cd - 1, FromTmWday(tm->tm_wday)) + (week_num * 7); - if (const year_t shift = cd.year() - y.year()) { - if (shift > 0) { - if (*year > std::numeric_limits<year_t>::max() - shift) return false; - } else { - if (*year < std::numeric_limits<year_t>::min() - shift) return false; - } - *year += shift; - } - tm->tm_mon = cd.month() - 1; - tm->tm_mday = cd.day(); - return true; -} - +// Sets year, tm_mon and tm_mday given the year, week_num, and tm_wday, +// and the day on which weeks are defined to start. Returns false if year +// would need to move outside its bounds. +bool FromWeek(int week_num, weekday week_start, year_t* year, std::tm* tm) { + const civil_year y(*year % 400); + civil_day cd = prev_weekday(y, week_start); // week 0 + cd = next_weekday(cd - 1, FromTmWday(tm->tm_wday)) + (week_num * 7); + if (const year_t shift = cd.year() - y.year()) { + if (shift > 0) { + if (*year > std::numeric_limits<year_t>::max() - shift) return false; + } else { + if (*year < std::numeric_limits<year_t>::min() - shift) return false; + } + *year += shift; + } + tm->tm_mon = cd.month() - 1; + tm->tm_mday = cd.day(); + return true; +} + } // namespace // Uses strptime(3) to parse the given input. Supports the same extended // format specifiers as format(), although %E#S and %E*S are treated // identically (and similarly for %E#f and %E*f). %Ez and %E*z also accept -// the same inputs. %ET accepts either 'T' or 't'. +// the same inputs. %ET accepts either 'T' or 't'. // // The standard specifiers from RFC3339_* (%Y, %m, %d, %H, %M, and %S) are // handled internally so that we can normally avoid strptime() altogether @@ -722,8 +722,8 @@ bool parse(const std::string& format, const std::string& input, const char* fmt = format.c_str(); // NUL terminated bool twelve_hour = false; bool afternoon = false; - int week_num = -1; - weekday week_start = weekday::sunday; + int week_num = -1; + weekday week_start = weekday::sunday; bool saw_percent_s = false; std::int_fast64_t percent_s = 0; @@ -762,28 +762,28 @@ bool parse(const std::string& format, const std::string& input, case 'm': data = ParseInt(data, 2, 1, 12, &tm.tm_mon); if (data != nullptr) tm.tm_mon -= 1; - week_num = -1; + week_num = -1; continue; case 'd': case 'e': data = ParseInt(data, 2, 1, 31, &tm.tm_mday); - week_num = -1; - continue; - case 'U': - data = ParseInt(data, 0, 0, 53, &week_num); - week_start = weekday::sunday; - continue; - case 'W': - data = ParseInt(data, 0, 0, 53, &week_num); - week_start = weekday::monday; - continue; - case 'u': - data = ParseInt(data, 0, 1, 7, &tm.tm_wday); - if (data != nullptr) tm.tm_wday %= 7; - continue; - case 'w': - data = ParseInt(data, 0, 0, 6, &tm.tm_wday); + week_num = -1; continue; + case 'U': + data = ParseInt(data, 0, 0, 53, &week_num); + week_start = weekday::sunday; + continue; + case 'W': + data = ParseInt(data, 0, 0, 53, &week_num); + week_start = weekday::monday; + continue; + case 'u': + data = ParseInt(data, 0, 1, 7, &tm.tm_wday); + if (data != nullptr) tm.tm_wday %= 7; + continue; + case 'w': + data = ParseInt(data, 0, 0, 6, &tm.tm_wday); + continue; case 'H': data = ParseInt(data, 2, 0, 23, &tm.tm_hour); twelve_hour = false; @@ -813,9 +813,9 @@ bool parse(const std::string& format, const std::string& input, data = ParseZone(data, &zone); continue; case 's': - data = - ParseInt(data, 0, std::numeric_limits<std::int_fast64_t>::min(), - std::numeric_limits<std::int_fast64_t>::max(), &percent_s); + data = + ParseInt(data, 0, std::numeric_limits<std::int_fast64_t>::min(), + std::numeric_limits<std::int_fast64_t>::max(), &percent_s); if (data != nullptr) saw_percent_s = true; continue; case ':': @@ -832,15 +832,15 @@ bool parse(const std::string& format, const std::string& input, data = (*data == '%' ? data + 1 : nullptr); continue; case 'E': - if (fmt[0] == 'T') { - if (*data == 'T' || *data == 't') { - ++data; - ++fmt; - } else { - data = nullptr; - } - continue; - } + if (fmt[0] == 'T') { + if (*data == 'T' || *data == 't') { + ++data; + ++fmt; + } else { + data = nullptr; + } + continue; + } if (fmt[0] == 'z' || (fmt[0] == '*' && fmt[1] == 'z')) { data = ParseOffset(data, ":", &offset); if (data != nullptr) saw_offset = true; @@ -938,7 +938,7 @@ bool parse(const std::string& format, const std::string& input, // Skip any remaining whitespace. while (std::isspace(*data)) ++data; - // parse() must consume the entire input string. + // parse() must consume the entire input string. if (*data != '\0') { if (err != nullptr) *err = "Illegal trailing data in input string"; return false; @@ -973,14 +973,14 @@ bool parse(const std::string& format, const std::string& input, year += 1900; } - // Compute year, tm.tm_mon and tm.tm_mday if we parsed a week number. - if (week_num != -1) { - if (!FromWeek(week_num, week_start, &year, &tm)) { - if (err != nullptr) *err = "Out-of-range field"; - return false; - } - } - + // Compute year, tm.tm_mon and tm.tm_mday if we parsed a week number. + if (week_num != -1) { + if (!FromWeek(week_num, week_start, &year, &tm)) { + if (err != nullptr) *err = "Out-of-range field"; + return false; + } + } + const int month = tm.tm_mon + 1; civil_second cs(year, month, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); @@ -1025,5 +1025,5 @@ bool parse(const std::string& format, const std::string& input, } // namespace detail } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc index 0319b2f98e..6b985b588d 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc @@ -13,13 +13,13 @@ // limitations under the License. #include "time_zone_if.h" - -#include "absl/base/config.h" + +#include "absl/base/config.h" #include "time_zone_info.h" #include "time_zone_libc.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -41,5 +41,5 @@ TimeZoneIf::~TimeZoneIf() {} } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h index 7d3e42d3cd..79d71f09c2 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.h @@ -20,12 +20,12 @@ #include <memory> #include <string> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/civil_time.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -40,7 +40,7 @@ class TimeZoneIf { virtual time_zone::absolute_lookup BreakTime( const time_point<seconds>& tp) const = 0; - virtual time_zone::civil_lookup MakeTime(const civil_second& cs) const = 0; + virtual time_zone::civil_lookup MakeTime(const civil_second& cs) const = 0; virtual bool NextTransition(const time_point<seconds>& tp, time_zone::civil_transition* trans) const = 0; @@ -60,18 +60,18 @@ class TimeZoneIf { // (That is, that they share an epoch, which is required since C++20.) inline std::int_fast64_t ToUnixSeconds(const time_point<seconds>& tp) { return (tp - std::chrono::time_point_cast<seconds>( - std::chrono::system_clock::from_time_t(0))) - .count(); + std::chrono::system_clock::from_time_t(0))) + .count(); } inline time_point<seconds> FromUnixSeconds(std::int_fast64_t t) { return std::chrono::time_point_cast<seconds>( - std::chrono::system_clock::from_time_t(0)) + - seconds(t); + std::chrono::system_clock::from_time_t(0)) + + seconds(t); } } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IF_H_ diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc index f34e3aec84..f40b0220a1 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc @@ -15,17 +15,17 @@ #include "time_zone_impl.h" #include <deque> -#include <memory> +#include <memory> #include <mutex> #include <string> #include <unordered_map> #include <utility> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "time_zone_fixed.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -46,19 +46,19 @@ std::mutex& TimeZoneMutex() { } // namespace -time_zone time_zone::Impl::UTC() { return time_zone(UTCImpl()); } +time_zone time_zone::Impl::UTC() { return time_zone(UTCImpl()); } bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { - const Impl* const utc_impl = UTCImpl(); + const Impl* const utc_impl = UTCImpl(); - // Check for UTC (which is never a key in time_zone_map). + // Check for UTC (which is never a key in time_zone_map). auto offset = seconds::zero(); if (FixedOffsetFromName(name, &offset) && offset == seconds::zero()) { *tz = time_zone(utc_impl); return true; } - // Check whether the time zone has already been loaded. + // Check whether the time zone has already been loaded. { std::lock_guard<std::mutex> lock(TimeZoneMutex()); if (time_zone_map != nullptr) { @@ -70,15 +70,15 @@ bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { } } - // Load the new time zone (outside the lock). - std::unique_ptr<const Impl> new_impl(new Impl(name)); - - // Add the new time zone to the map. + // Load the new time zone (outside the lock). + std::unique_ptr<const Impl> new_impl(new Impl(name)); + + // Add the new time zone to the map. std::lock_guard<std::mutex> lock(TimeZoneMutex()); if (time_zone_map == nullptr) time_zone_map = new TimeZoneImplByName; const Impl*& impl = (*time_zone_map)[name]; - if (impl == nullptr) { // this thread won any load race - impl = new_impl->zone_ ? new_impl.release() : utc_impl; + if (impl == nullptr) { // this thread won any load race + impl = new_impl->zone_ ? new_impl.release() : utc_impl; } *tz = time_zone(impl); return impl != utc_impl; @@ -99,15 +99,15 @@ void time_zone::Impl::ClearTimeZoneMapTestOnly() { } } -time_zone::Impl::Impl(const std::string& name) - : name_(name), zone_(TimeZoneIf::Load(name_)) {} +time_zone::Impl::Impl(const std::string& name) + : name_(name), zone_(TimeZoneIf::Load(name_)) {} const time_zone::Impl* time_zone::Impl::UTCImpl() { - static const Impl* utc_impl = new Impl("UTC"); // never fails + static const Impl* utc_impl = new Impl("UTC"); // never fails return utc_impl; } } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h index 7d747ba966..356ed93581 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.h @@ -18,14 +18,14 @@ #include <memory> #include <string> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/civil_time.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" #include "time_zone_if.h" #include "time_zone_info.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -71,7 +71,7 @@ class time_zone::Impl { return zone_->PrevTransition(tp, trans); } - // Returns an implementation-defined version string for this time zone. + // Returns an implementation-defined version string for this time zone. std::string Version() const { return zone_->Version(); } // Returns an implementation-defined description of this time zone. @@ -87,7 +87,7 @@ class time_zone::Impl { } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_IMPL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc index 4f175d95fc..596df5a834 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc @@ -46,13 +46,13 @@ #include <string> #include <utility> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/civil_time.h" #include "time_zone_fixed.h" #include "time_zone_posix.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -68,8 +68,8 @@ const std::int_least32_t kDaysPerYear[2] = {365, 366}; // The day offsets of the beginning of each (1-based) month in non-leap and // leap years respectively (e.g., 335 days before December in a leap year). const std::int_least16_t kMonthOffsets[2][1 + 12 + 1] = { - {-1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, - {-1, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}, + {-1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, + {-1, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}, }; // We reject leap-second encoded zoneinfo and so assume 60-second minutes. @@ -80,31 +80,31 @@ const std::int_least64_t kSecsPer400Years = 146097LL * kSecsPerDay; // Like kDaysPerYear[] but scaled up by a factor of kSecsPerDay. const std::int_least32_t kSecsPerYear[2] = { - 365 * kSecsPerDay, - 366 * kSecsPerDay, + 365 * kSecsPerDay, + 366 * kSecsPerDay, }; -// Convert a cctz::weekday to a POSIX TZ weekday number (0==Sun, ..., 6=Sat). -inline int ToPosixWeekday(weekday wd) { - switch (wd) { - case weekday::sunday: - return 0; - case weekday::monday: - return 1; - case weekday::tuesday: - return 2; - case weekday::wednesday: - return 3; - case weekday::thursday: - return 4; - case weekday::friday: - return 5; - case weekday::saturday: - return 6; - } - return 0; /*NOTREACHED*/ -} - +// Convert a cctz::weekday to a POSIX TZ weekday number (0==Sun, ..., 6=Sat). +inline int ToPosixWeekday(weekday wd) { + switch (wd) { + case weekday::sunday: + return 0; + case weekday::monday: + return 1; + case weekday::tuesday: + return 2; + case weekday::wednesday: + return 3; + case weekday::thursday: + return 4; + case weekday::friday: + return 5; + case weekday::saturday: + return 6; + } + return 0; /*NOTREACHED*/ +} + // Single-byte, unsigned numeric values are encoded directly. inline std::uint_fast8_t Decode8(const char* cp) { return static_cast<std::uint_fast8_t>(*cp) & 0xff; @@ -196,8 +196,8 @@ inline time_zone::civil_lookup MakeRepeated(const Transition& tr, } inline civil_second YearShift(const civil_second& cs, year_t shift) { - return civil_second(cs.year() + shift, cs.month(), cs.day(), cs.hour(), - cs.minute(), cs.second()); + return civil_second(cs.year() + shift, cs.month(), cs.day(), cs.hour(), + cs.minute(), cs.second()); } } // namespace @@ -210,13 +210,13 @@ bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) { tt.is_dst = false; tt.abbr_index = 0; - // We temporarily add some redundant, contemporary (2015 through 2025) + // We temporarily add some redundant, contemporary (2015 through 2025) // transitions for performance reasons. See TimeZoneInfo::LocalTime(). // TODO: Fix the performance issue and remove the extra transitions. transitions_.clear(); transitions_.reserve(12); for (const std::int_fast64_t unix_time : { - -(1LL << 59), // a "first half" transition + -(1LL << 59), // a "first half" transition 1420070400LL, // 2015-01-01T00:00:00+00:00 1451606400LL, // 2016-01-01T00:00:00+00:00 1483228800LL, // 2017-01-01T00:00:00+00:00 @@ -226,8 +226,8 @@ bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) { 1609459200LL, // 2021-01-01T00:00:00+00:00 1640995200LL, // 2022-01-01T00:00:00+00:00 1672531200LL, // 2023-01-01T00:00:00+00:00 - 1704067200LL, // 2024-01-01T00:00:00+00:00 - 1735689600LL, // 2025-01-01T00:00:00+00:00 + 1704067200LL, // 2024-01-01T00:00:00+00:00 + 1735689600LL, // 2025-01-01T00:00:00+00:00 }) { Transition& tr(*transitions_.emplace(transitions_.end())); tr.unix_time = unix_time; @@ -238,7 +238,7 @@ bool TimeZoneInfo::ResetToBuiltinUTC(const seconds& offset) { default_transition_type_ = 0; abbreviations_ = FixedOffsetToAbbr(offset); - abbreviations_.append(1, '\0'); + abbreviations_.append(1, '\0'); future_spec_.clear(); // never needed for a fixed-offset zone extended_ = false; @@ -288,128 +288,128 @@ bool TimeZoneInfo::EquivTransitions(std::uint_fast8_t tt1_index, if (tt1_index == tt2_index) return true; const TransitionType& tt1(transition_types_[tt1_index]); const TransitionType& tt2(transition_types_[tt2_index]); - if (tt1.utc_offset != tt2.utc_offset) return false; + if (tt1.utc_offset != tt2.utc_offset) return false; if (tt1.is_dst != tt2.is_dst) return false; if (tt1.abbr_index != tt2.abbr_index) return false; return true; } -// Find/make a transition type with these attributes. -bool TimeZoneInfo::GetTransitionType(std::int_fast32_t utc_offset, bool is_dst, - const std::string& abbr, - std::uint_least8_t* index) { - std::size_t type_index = 0; - std::size_t abbr_index = abbreviations_.size(); - for (; type_index != transition_types_.size(); ++type_index) { - const TransitionType& tt(transition_types_[type_index]); - const char* tt_abbr = &abbreviations_[tt.abbr_index]; - if (tt_abbr == abbr) abbr_index = tt.abbr_index; - if (tt.utc_offset == utc_offset && tt.is_dst == is_dst) { - if (abbr_index == tt.abbr_index) break; // reuse - } - } - if (type_index > 255 || abbr_index > 255) { - // No index space (8 bits) available for a new type or abbreviation. - return false; - } - if (type_index == transition_types_.size()) { - TransitionType& tt(*transition_types_.emplace(transition_types_.end())); - tt.utc_offset = static_cast<std::int_least32_t>(utc_offset); - tt.is_dst = is_dst; - if (abbr_index == abbreviations_.size()) { - abbreviations_.append(abbr); - abbreviations_.append(1, '\0'); - } - tt.abbr_index = static_cast<std::uint_least8_t>(abbr_index); - } - *index = static_cast<std::uint_least8_t>(type_index); - return true; -} - +// Find/make a transition type with these attributes. +bool TimeZoneInfo::GetTransitionType(std::int_fast32_t utc_offset, bool is_dst, + const std::string& abbr, + std::uint_least8_t* index) { + std::size_t type_index = 0; + std::size_t abbr_index = abbreviations_.size(); + for (; type_index != transition_types_.size(); ++type_index) { + const TransitionType& tt(transition_types_[type_index]); + const char* tt_abbr = &abbreviations_[tt.abbr_index]; + if (tt_abbr == abbr) abbr_index = tt.abbr_index; + if (tt.utc_offset == utc_offset && tt.is_dst == is_dst) { + if (abbr_index == tt.abbr_index) break; // reuse + } + } + if (type_index > 255 || abbr_index > 255) { + // No index space (8 bits) available for a new type or abbreviation. + return false; + } + if (type_index == transition_types_.size()) { + TransitionType& tt(*transition_types_.emplace(transition_types_.end())); + tt.utc_offset = static_cast<std::int_least32_t>(utc_offset); + tt.is_dst = is_dst; + if (abbr_index == abbreviations_.size()) { + abbreviations_.append(abbr); + abbreviations_.append(1, '\0'); + } + tt.abbr_index = static_cast<std::uint_least8_t>(abbr_index); + } + *index = static_cast<std::uint_least8_t>(type_index); + return true; +} + // Use the POSIX-TZ-environment-variable-style string to handle times // in years after the last transition stored in the zoneinfo data. -bool TimeZoneInfo::ExtendTransitions() { +bool TimeZoneInfo::ExtendTransitions() { extended_ = false; - if (future_spec_.empty()) return true; // last transition prevails + if (future_spec_.empty()) return true; // last transition prevails PosixTimeZone posix; - if (!ParsePosixSpec(future_spec_, &posix)) return false; + if (!ParsePosixSpec(future_spec_, &posix)) return false; - // Find transition type for the future std specification. - std::uint_least8_t std_ti; - if (!GetTransitionType(posix.std_offset, false, posix.std_abbr, &std_ti)) - return false; + // Find transition type for the future std specification. + std::uint_least8_t std_ti; + if (!GetTransitionType(posix.std_offset, false, posix.std_abbr, &std_ti)) + return false; - if (posix.dst_abbr.empty()) { // std only - // The future specification should match the last transition, and - // that means that handling the future will fall out naturally. - return EquivTransitions(transitions_.back().type_index, std_ti); + if (posix.dst_abbr.empty()) { // std only + // The future specification should match the last transition, and + // that means that handling the future will fall out naturally. + return EquivTransitions(transitions_.back().type_index, std_ti); } - // Find transition type for the future dst specification. - std::uint_least8_t dst_ti; - if (!GetTransitionType(posix.dst_offset, true, posix.dst_abbr, &dst_ti)) - return false; + // Find transition type for the future dst specification. + std::uint_least8_t dst_ti; + if (!GetTransitionType(posix.dst_offset, true, posix.dst_abbr, &dst_ti)) + return false; // Extend the transitions for an additional 400 years using the // future specification. Years beyond those can be handled by // mapping back to a cycle-equivalent year within that range. - // We may need two additional transitions for the current year. - transitions_.reserve(transitions_.size() + 400 * 2 + 2); + // We may need two additional transitions for the current year. + transitions_.reserve(transitions_.size() + 400 * 2 + 2); extended_ = true; - const Transition& last(transitions_.back()); - const std::int_fast64_t last_time = last.unix_time; - const TransitionType& last_tt(transition_types_[last.type_index]); - last_year_ = LocalTime(last_time, last_tt).cs.year(); - bool leap_year = IsLeap(last_year_); - const civil_second jan1(last_year_); - std::int_fast64_t jan1_time = jan1 - civil_second(); - int jan1_weekday = ToPosixWeekday(get_weekday(jan1)); - - Transition dst = {0, dst_ti, civil_second(), civil_second()}; - Transition std = {0, std_ti, civil_second(), civil_second()}; - for (const year_t limit = last_year_ + 400;; ++last_year_) { - auto dst_trans_off = TransOffset(leap_year, jan1_weekday, posix.dst_start); - auto std_trans_off = TransOffset(leap_year, jan1_weekday, posix.dst_end); - dst.unix_time = jan1_time + dst_trans_off - posix.std_offset; - std.unix_time = jan1_time + std_trans_off - posix.dst_offset; - const auto* ta = dst.unix_time < std.unix_time ? &dst : &std; - const auto* tb = dst.unix_time < std.unix_time ? &std : &dst; - if (last_time < tb->unix_time) { - if (last_time < ta->unix_time) transitions_.push_back(*ta); - transitions_.push_back(*tb); - } - if (last_year_ == limit) break; + const Transition& last(transitions_.back()); + const std::int_fast64_t last_time = last.unix_time; + const TransitionType& last_tt(transition_types_[last.type_index]); + last_year_ = LocalTime(last_time, last_tt).cs.year(); + bool leap_year = IsLeap(last_year_); + const civil_second jan1(last_year_); + std::int_fast64_t jan1_time = jan1 - civil_second(); + int jan1_weekday = ToPosixWeekday(get_weekday(jan1)); + + Transition dst = {0, dst_ti, civil_second(), civil_second()}; + Transition std = {0, std_ti, civil_second(), civil_second()}; + for (const year_t limit = last_year_ + 400;; ++last_year_) { + auto dst_trans_off = TransOffset(leap_year, jan1_weekday, posix.dst_start); + auto std_trans_off = TransOffset(leap_year, jan1_weekday, posix.dst_end); + dst.unix_time = jan1_time + dst_trans_off - posix.std_offset; + std.unix_time = jan1_time + std_trans_off - posix.dst_offset; + const auto* ta = dst.unix_time < std.unix_time ? &dst : &std; + const auto* tb = dst.unix_time < std.unix_time ? &std : &dst; + if (last_time < tb->unix_time) { + if (last_time < ta->unix_time) transitions_.push_back(*ta); + transitions_.push_back(*tb); + } + if (last_year_ == limit) break; jan1_time += kSecsPerYear[leap_year]; jan1_weekday = (jan1_weekday + kDaysPerYear[leap_year]) % 7; - leap_year = !leap_year && IsLeap(last_year_ + 1); + leap_year = !leap_year && IsLeap(last_year_ + 1); } - - return true; + + return true; } -bool TimeZoneInfo::Load(ZoneInfoSource* zip) { +bool TimeZoneInfo::Load(ZoneInfoSource* zip) { // Read and validate the header. tzhead tzh; - if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh)) return false; + if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh)) return false; if (strncmp(tzh.tzh_magic, TZ_MAGIC, sizeof(tzh.tzh_magic)) != 0) return false; Header hdr; - if (!hdr.Build(tzh)) return false; + if (!hdr.Build(tzh)) return false; std::size_t time_len = 4; if (tzh.tzh_version[0] != '\0') { // Skip the 4-byte data. - if (zip->Skip(hdr.DataLength(time_len)) != 0) return false; + if (zip->Skip(hdr.DataLength(time_len)) != 0) return false; // Read and validate the header for the 8-byte data. - if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh)) return false; + if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh)) return false; if (strncmp(tzh.tzh_magic, TZ_MAGIC, sizeof(tzh.tzh_magic)) != 0) return false; - if (tzh.tzh_version[0] == '\0') return false; - if (!hdr.Build(tzh)) return false; + if (tzh.tzh_version[0] == '\0') return false; + if (!hdr.Build(tzh)) return false; time_len = 8; } - if (hdr.typecnt == 0) return false; + if (hdr.typecnt == 0) return false; if (hdr.leapcnt != 0) { // This code assumes 60-second minutes so we do not want // the leap-second encoded zoneinfo. We could reverse the @@ -417,17 +417,17 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { // so currently we simply reject such data. return false; } - if (hdr.ttisstdcnt != 0 && hdr.ttisstdcnt != hdr.typecnt) return false; - if (hdr.ttisutcnt != 0 && hdr.ttisutcnt != hdr.typecnt) return false; + if (hdr.ttisstdcnt != 0 && hdr.ttisstdcnt != hdr.typecnt) return false; + if (hdr.ttisutcnt != 0 && hdr.ttisutcnt != hdr.typecnt) return false; // Read the data into a local buffer. std::size_t len = hdr.DataLength(time_len); std::vector<char> tbuf(len); - if (zip->Read(tbuf.data(), len) != len) return false; + if (zip->Read(tbuf.data(), len) != len) return false; const char* bp = tbuf.data(); // Decode and validate the transitions. - transitions_.reserve(hdr.timecnt + 2); + transitions_.reserve(hdr.timecnt + 2); transitions_.resize(hdr.timecnt); for (std::size_t i = 0; i != hdr.timecnt; ++i) { transitions_[i].unix_time = (time_len == 4) ? Decode32(bp) : Decode64(bp); @@ -441,12 +441,12 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { bool seen_type_0 = false; for (std::size_t i = 0; i != hdr.timecnt; ++i) { transitions_[i].type_index = Decode8(bp++); - if (transitions_[i].type_index >= hdr.typecnt) return false; - if (transitions_[i].type_index == 0) seen_type_0 = true; + if (transitions_[i].type_index >= hdr.typecnt) return false; + if (transitions_[i].type_index == 0) seen_type_0 = true; } // Decode and validate the transition types. - transition_types_.reserve(hdr.typecnt + 2); + transition_types_.reserve(hdr.typecnt + 2); transition_types_.resize(hdr.typecnt); for (std::size_t i = 0; i != hdr.typecnt; ++i) { transition_types_[i].utc_offset = @@ -457,7 +457,7 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { bp += 4; transition_types_[i].is_dst = (Decode8(bp++) != 0); transition_types_[i].abbr_index = Decode8(bp++); - if (transition_types_[i].abbr_index >= hdr.charcnt) return false; + if (transition_types_[i].abbr_index >= hdr.charcnt) return false; } // Determine the before-first-transition type. @@ -466,14 +466,14 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { std::uint_fast8_t index = 0; if (transition_types_[0].is_dst) { index = transitions_[0].type_index; - while (index != 0 && transition_types_[index].is_dst) --index; + while (index != 0 && transition_types_[index].is_dst) --index; } - while (index != hdr.typecnt && transition_types_[index].is_dst) ++index; - if (index != hdr.typecnt) default_transition_type_ = index; + while (index != hdr.typecnt && transition_types_[index].is_dst) ++index; + if (index != hdr.typecnt) default_transition_type_ = index; } // Copy all the abbreviations. - abbreviations_.reserve(hdr.charcnt + 10); + abbreviations_.reserve(hdr.charcnt + 10); abbreviations_.assign(bp, hdr.charcnt); bp += hdr.charcnt; @@ -494,9 +494,9 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { unsigned char ch; // all non-EOF results are positive return (azip->Read(&ch, 1) == 1) ? ch : EOF; }; - if (get_char(zip) != '\n') return false; + if (get_char(zip) != '\n') return false; for (int c = get_char(zip); c != '\n'; c = get_char(zip)) { - if (c == EOF) return false; + if (c == EOF) return false; future_spec_.push_back(static_cast<char>(c)); } } @@ -505,7 +505,7 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { // If we did not find version information during the standard loading // process (as of tzh_version '3' that is unsupported), then ask the - // ZoneInfoSource for any out-of-bound version string it may be privy to. + // ZoneInfoSource for any out-of-bound version string it may be privy to. if (version_.empty()) { version_ = zip->Version(); } @@ -524,30 +524,30 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) { transitions_.resize(hdr.timecnt); // Ensure that there is always a transition in the first half of the - // time line (the second half is handled below) so that the signed - // difference between a civil_second and the civil_second of its - // previous transition is always representable, without overflow. + // time line (the second half is handled below) so that the signed + // difference between a civil_second and the civil_second of its + // previous transition is always representable, without overflow. if (transitions_.empty() || transitions_.front().unix_time >= 0) { Transition& tr(*transitions_.emplace(transitions_.begin())); - tr.unix_time = -(1LL << 59); // -18267312070-10-26T17:01:52+00:00 + tr.unix_time = -(1LL << 59); // -18267312070-10-26T17:01:52+00:00 tr.type_index = default_transition_type_; } // Extend the transitions using the future specification. - if (!ExtendTransitions()) return false; - - // Ensure that there is always a transition in the second half of the - // time line (the first half is handled above) so that the signed - // difference between a civil_second and the civil_second of its - // previous transition is always representable, without overflow. - const Transition& last(transitions_.back()); - if (last.unix_time < 0) { - const std::uint_fast8_t type_index = last.type_index; - Transition& tr(*transitions_.emplace(transitions_.end())); - tr.unix_time = 2147483647; // 2038-01-19T03:14:07+00:00 - tr.type_index = type_index; - } - + if (!ExtendTransitions()) return false; + + // Ensure that there is always a transition in the second half of the + // time line (the first half is handled above) so that the signed + // difference between a civil_second and the civil_second of its + // previous transition is always representable, without overflow. + const Transition& last(transitions_.back()); + if (last.unix_time < 0) { + const std::uint_fast8_t type_index = last.type_index; + Transition& tr(*transitions_.emplace(transitions_.end())); + tr.unix_time = 2147483647; // 2038-01-19T03:14:07+00:00 + tr.type_index = type_index; + } + // Compute the local civil time for each transition and the preceding // second. These will be used for reverse conversions in MakeTime(). const TransitionType* ttp = &transition_types_[default_transition_type_]; @@ -786,13 +786,13 @@ bool TimeZoneInfo::Load(const std::string& name) { // Find and use a ZoneInfoSource to load the named zone. auto zip = cctz_extension::zone_info_source_factory( - name, [](const std::string& n) -> std::unique_ptr<ZoneInfoSource> { - if (auto z = FileZoneInfoSource::Open(n)) return z; - if (auto z = AndroidZoneInfoSource::Open(n)) return z; + name, [](const std::string& n) -> std::unique_ptr<ZoneInfoSource> { + if (auto z = FileZoneInfoSource::Open(n)) return z; + if (auto z = AndroidZoneInfoSource::Open(n)) return z; if (auto z = FuchsiaZoneInfoSource::Open(n)) return z; return nullptr; }); - return zip != nullptr && Load(zip.get()); + return zip != nullptr && Load(zip.get()); } // BreakTime() translation for a particular transition type. @@ -801,13 +801,13 @@ time_zone::absolute_lookup TimeZoneInfo::LocalTime( // A civil time in "+offset" looks like (time+offset) in UTC. // Note: We perform two additions in the civil_second domain to // sidestep the chance of overflow in (unix_time + tt.utc_offset). - return {(civil_second() + unix_time) + tt.utc_offset, tt.utc_offset, - tt.is_dst, &abbreviations_[tt.abbr_index]}; + return {(civil_second() + unix_time) + tt.utc_offset, tt.utc_offset, + tt.is_dst, &abbreviations_[tt.abbr_index]}; } // BreakTime() translation for a particular transition. -time_zone::absolute_lookup TimeZoneInfo::LocalTime(std::int_fast64_t unix_time, - const Transition& tr) const { +time_zone::absolute_lookup TimeZoneInfo::LocalTime(std::int_fast64_t unix_time, + const Transition& tr) const { const TransitionType& tt = transition_types_[tr.type_index]; // Note: (unix_time - tr.unix_time) will never overflow as we // have ensured that there is always a "nearby" transition. @@ -950,7 +950,7 @@ time_zone::civil_lookup TimeZoneInfo::MakeTime(const civil_second& cs) const { return MakeUnique(tr->unix_time + (cs - tr->civil_sec)); } -std::string TimeZoneInfo::Version() const { return version_; } +std::string TimeZoneInfo::Version() const { return version_; } std::string TimeZoneInfo::Description() const { std::ostringstream oss; @@ -966,14 +966,14 @@ bool TimeZoneInfo::NextTransition(const time_point<seconds>& tp, const Transition* begin = &transitions_[0]; const Transition* end = begin + transitions_.size(); if (begin->unix_time <= -(1LL << 59)) { - // Do not report the BIG_BANG found in some zoneinfo data as it is - // really a sentinel, not a transition. See pre-2018f tz/zic.c. + // Do not report the BIG_BANG found in some zoneinfo data as it is + // really a sentinel, not a transition. See pre-2018f tz/zic.c. ++begin; } std::int_fast64_t unix_time = ToUnixSeconds(tp); const Transition target = {unix_time, 0, civil_second(), civil_second()}; - const Transition* tr = - std::upper_bound(begin, end, target, Transition::ByUnixTime()); + const Transition* tr = + std::upper_bound(begin, end, target, Transition::ByUnixTime()); for (; tr != end; ++tr) { // skip no-op transitions std::uint_fast8_t prev_type_index = (tr == begin) ? default_transition_type_ : tr[-1].type_index; @@ -992,8 +992,8 @@ bool TimeZoneInfo::PrevTransition(const time_point<seconds>& tp, const Transition* begin = &transitions_[0]; const Transition* end = begin + transitions_.size(); if (begin->unix_time <= -(1LL << 59)) { - // Do not report the BIG_BANG found in some zoneinfo data as it is - // really a sentinel, not a transition. See pre-2018f tz/zic.c. + // Do not report the BIG_BANG found in some zoneinfo data as it is + // really a sentinel, not a transition. See pre-2018f tz/zic.c. ++begin; } std::int_fast64_t unix_time = ToUnixSeconds(tp); @@ -1007,8 +1007,8 @@ bool TimeZoneInfo::PrevTransition(const time_point<seconds>& tp, unix_time += 1; // ceils } const Transition target = {unix_time, 0, civil_second(), civil_second()}; - const Transition* tr = - std::lower_bound(begin, end, target, Transition::ByUnixTime()); + const Transition* tr = + std::lower_bound(begin, end, target, Transition::ByUnixTime()); for (; tr != begin; --tr) { // skip no-op transitions std::uint_fast8_t prev_type_index = (tr - 1 == begin) ? default_transition_type_ : tr[-2].type_index; @@ -1023,5 +1023,5 @@ bool TimeZoneInfo::PrevTransition(const time_point<seconds>& tp, } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h index 2467ff559d..63b958a7e2 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.h @@ -21,7 +21,7 @@ #include <string> #include <vector> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/civil_time.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" #include "absl/time/internal/cctz/include/cctz/zone_info_source.h" @@ -29,7 +29,7 @@ #include "tzfile.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -74,7 +74,7 @@ class TimeZoneInfo : public TimeZoneIf { // TimeZoneIf implementations. time_zone::absolute_lookup BreakTime( const time_point<seconds>& tp) const override; - time_zone::civil_lookup MakeTime(const civil_second& cs) const override; + time_zone::civil_lookup MakeTime(const civil_second& cs) const override; bool NextTransition(const time_point<seconds>& tp, time_zone::civil_transition* trans) const override; bool PrevTransition(const time_point<seconds>& tp, @@ -83,7 +83,7 @@ class TimeZoneInfo : public TimeZoneIf { std::string Description() const override; private: - struct Header { // counts of: + struct Header { // counts of: std::size_t timecnt; // transition times std::size_t typecnt; // transition types std::size_t charcnt; // zone abbreviation characters @@ -95,14 +95,14 @@ class TimeZoneInfo : public TimeZoneIf { std::size_t DataLength(std::size_t time_len) const; }; - bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst, - const std::string& abbr, std::uint_least8_t* index); + bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst, + const std::string& abbr, std::uint_least8_t* index); bool EquivTransitions(std::uint_fast8_t tt1_index, std::uint_fast8_t tt2_index) const; - bool ExtendTransitions(); + bool ExtendTransitions(); bool ResetToBuiltinUTC(const seconds& offset); - bool Load(ZoneInfoSource* zip); + bool Load(ZoneInfoSource* zip); // Helpers for BreakTime() and MakeTime(). time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, @@ -114,7 +114,7 @@ class TimeZoneInfo : public TimeZoneIf { std::vector<Transition> transitions_; // ordered by unix_time and civil_sec std::vector<TransitionType> transition_types_; // distinct transition types - std::uint_fast8_t default_transition_type_; // for before first transition + std::uint_fast8_t default_transition_type_; // for before first transition std::string abbreviations_; // all the NUL-terminated abbreviations std::string version_; // the tzdata version if available @@ -131,7 +131,7 @@ class TimeZoneInfo : public TimeZoneIf { } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_INFO_H_ diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc index 887dd097c6..3148f2b4af 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc @@ -23,7 +23,7 @@ #include <limits> #include <utility> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/civil_time.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" @@ -34,7 +34,7 @@ extern long altzone; #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -92,7 +92,7 @@ auto tm_gmtoff(const T& tm) -> decltype(tm.__tm_gmtoff) { } #endif // tm_gmtoff #if defined(tm_zone) -auto tm_zone(const std::tm& tm) -> decltype(tm.tm_zone) { return tm.tm_zone; } +auto tm_zone(const std::tm& tm) -> decltype(tm.tm_zone) { return tm.tm_zone; } #elif defined(__tm_zone) auto tm_zone(const std::tm& tm) -> decltype(tm.__tm_zone) { return tm.__tm_zone; @@ -109,19 +109,19 @@ auto tm_zone(const T& tm) -> decltype(tm.__tm_zone) { #endif // tm_zone #endif -inline std::tm* gm_time(const std::time_t* timep, std::tm* result) { +inline std::tm* gm_time(const std::time_t* timep, std::tm* result) { #if defined(_WIN32) || defined(_WIN64) - return gmtime_s(result, timep) ? nullptr : result; + return gmtime_s(result, timep) ? nullptr : result; #else - return gmtime_r(timep, result); + return gmtime_r(timep, result); #endif } -inline std::tm* local_time(const std::time_t* timep, std::tm* result) { +inline std::tm* local_time(const std::time_t* timep, std::tm* result) { #if defined(_WIN32) || defined(_WIN64) - return localtime_s(result, timep) ? nullptr : result; + return localtime_s(result, timep) ? nullptr : result; #else - return localtime_r(timep, result); + return localtime_r(timep, result); #endif } @@ -159,8 +159,8 @@ std::time_t find_trans(std::time_t lo, std::time_t hi, int offset) { std::tm tm; while (lo + 1 != hi) { const std::time_t mid = lo + (hi - lo) / 2; - std::tm* tmp = local_time(&mid, &tm); - if (tmp != nullptr) { + std::tm* tmp = local_time(&mid, &tm); + if (tmp != nullptr) { if (tm_gmtoff(*tmp) == offset) { hi = mid; } else { @@ -170,8 +170,8 @@ std::time_t find_trans(std::time_t lo, std::time_t hi, int offset) { // If std::tm cannot hold some result we resort to a linear search, // ignoring all failed conversions. Slow, but never really happens. while (++lo != hi) { - tmp = local_time(&lo, &tm); - if (tmp != nullptr) { + tmp = local_time(&lo, &tm); + if (tmp != nullptr) { if (tm_gmtoff(*tmp) == offset) break; } } @@ -216,8 +216,8 @@ time_zone::absolute_lookup TimeZoneLibC::BreakTime( } const year_t year = tmp->tm_year + year_t{1900}; - al.cs = civil_second(year, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, - tmp->tm_min, tmp->tm_sec); + al.cs = civil_second(year, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, + tmp->tm_min, tmp->tm_sec); al.offset = static_cast<int>(tm_gmtoff(*tmp)); al.abbr = local_ ? tm_zone(*tmp) : "UTC"; // as expected by cctz al.is_dst = tmp->tm_isdst > 0; @@ -231,10 +231,10 @@ time_zone::civil_lookup TimeZoneLibC::MakeTime(const civil_second& cs) const { civil_second() + ToUnixSeconds(time_point<seconds>::min()); static const civil_second max_tp_cs = civil_second() + ToUnixSeconds(time_point<seconds>::max()); - const time_point<seconds> tp = (cs < min_tp_cs) ? time_point<seconds>::min() - : (cs > max_tp_cs) - ? time_point<seconds>::max() - : FromUnixSeconds(cs - civil_second()); + const time_point<seconds> tp = (cs < min_tp_cs) ? time_point<seconds>::min() + : (cs > max_tp_cs) + ? time_point<seconds>::max() + : FromUnixSeconds(cs - civil_second()); return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; } @@ -311,5 +311,5 @@ std::string TimeZoneLibC::Description() const { } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h index 1da9039a15..191d617d67 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.h @@ -17,11 +17,11 @@ #include <string> -#include "absl/base/config.h" +#include "absl/base/config.h" #include "time_zone_if.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -35,7 +35,7 @@ class TimeZoneLibC : public TimeZoneIf { // TimeZoneIf implementations. time_zone::absolute_lookup BreakTime( const time_point<seconds>& tp) const override; - time_zone::civil_lookup MakeTime(const civil_second& cs) const override; + time_zone::civil_lookup MakeTime(const civil_second& cs) const override; bool NextTransition(const time_point<seconds>& tp, time_zone::civil_transition* trans) const override; bool PrevTransition(const time_point<seconds>& tp, @@ -49,7 +49,7 @@ class TimeZoneLibC : public TimeZoneIf { } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_LIBC_H_ diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc index 55843c5e5b..a336f5b615 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "absl/base/config.h" +#include "absl/base/config.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" #if defined(__ANDROID__) @@ -24,7 +24,7 @@ #if defined(__APPLE__) #include <CoreFoundation/CFTimeZone.h> - + #include <vector> #endif @@ -43,7 +43,7 @@ #include "time_zone_impl.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -76,7 +76,7 @@ int __system_property_get(const char* name, char* value) { } // namespace #endif -std::string time_zone::name() const { return effective_impl().Name(); } +std::string time_zone::name() const { return effective_impl().Name(); } time_zone::absolute_lookup time_zone::lookup( const time_point<seconds>& tp) const { @@ -97,7 +97,7 @@ bool time_zone::prev_transition(const time_point<seconds>& tp, return effective_impl().PrevTransition(tp, trans); } -std::string time_zone::version() const { return effective_impl().Version(); } +std::string time_zone::version() const { return effective_impl().Version(); } std::string time_zone::description() const { return effective_impl().Description(); @@ -232,5 +232,5 @@ time_zone local_time_zone() { } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc index 5cdd09e89d..efb73f9698 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc @@ -19,10 +19,10 @@ #include <limits> #include <string> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -155,5 +155,5 @@ bool ParsePosixSpec(const std::string& spec, PosixTimeZone* res) { } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h index 0cf29055f5..63903230a6 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h @@ -55,10 +55,10 @@ #include <cstdint> #include <string> -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -126,7 +126,7 @@ bool ParsePosixSpec(const std::string& spec, PosixTimeZone* res); } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_INTERNAL_CCTZ_TIME_ZONE_POSIX_H_ diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/tzfile.h b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/tzfile.h index 31e8598257..1581e02940 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/tzfile.h @@ -22,15 +22,15 @@ */ #ifndef TZDIR -#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */ -#endif /* !defined TZDIR */ +#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */ +#endif /* !defined TZDIR */ #ifndef TZDEFAULT -#define TZDEFAULT "/etc/localtime" +#define TZDEFAULT "/etc/localtime" #endif /* !defined TZDEFAULT */ #ifndef TZDEFRULES -#define TZDEFRULES "posixrules" +#define TZDEFRULES "posixrules" #endif /* !defined TZDEFRULES */ /* See Internet RFC 8536 for more details about the following format. */ @@ -39,18 +39,18 @@ ** Each file begins with. . . */ -#define TZ_MAGIC "TZif" +#define TZ_MAGIC "TZif" struct tzhead { - char tzh_magic[4]; /* TZ_MAGIC */ + char tzh_magic[4]; /* TZ_MAGIC */ char tzh_version[1]; /* '\0' or '2'-'4' as of 2021 */ - char tzh_reserved[15]; /* reserved; must be zero */ - char tzh_ttisutcnt[4]; /* coded number of trans. time flags */ - char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ - char tzh_leapcnt[4]; /* coded number of leap seconds */ - char tzh_timecnt[4]; /* coded number of transition times */ - char tzh_typecnt[4]; /* coded number of local time types */ - char tzh_charcnt[4]; /* coded number of abbr. chars */ + char tzh_reserved[15]; /* reserved; must be zero */ + char tzh_ttisutcnt[4]; /* coded number of trans. time flags */ + char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ + char tzh_leapcnt[4]; /* coded number of leap seconds */ + char tzh_timecnt[4]; /* coded number of transition times */ + char tzh_typecnt[4]; /* coded number of local time types */ + char tzh_charcnt[4]; /* coded number of abbr. chars */ }; /* @@ -83,13 +83,13 @@ struct tzhead { ** If tzh_version is '2' or greater, the above is followed by a second instance ** of tzhead and a second instance of the data in which each coded transition ** time uses 8 rather than 4 chars, -** then a POSIX-TZ-environment-variable-style string for use in handling +** then a POSIX-TZ-environment-variable-style string for use in handling ** instants after the last transition time stored in the file ** (with nothing between the newlines if there is no POSIX representation for ** such instants). ** ** If tz_version is '3' or greater, the above is extended as follows. -** First, the POSIX TZ string's hour offset may range from -167 +** First, the POSIX TZ string's hour offset may range from -167 ** through 167 as compared to the POSIX-required 0 through 24. ** Second, its DST start time may be January 1 at 00:00 and its stop ** time December 31 at 24:00 plus the difference between DST and @@ -102,21 +102,21 @@ struct tzhead { */ #ifndef TZ_MAX_TIMES -#define TZ_MAX_TIMES 2000 +#define TZ_MAX_TIMES 2000 #endif /* !defined TZ_MAX_TIMES */ #ifndef TZ_MAX_TYPES /* This must be at least 17 for Europe/Samara and Europe/Vilnius. */ -#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ +#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ #endif /* !defined TZ_MAX_TYPES */ #ifndef TZ_MAX_CHARS -#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ +#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ /* (limited by what unsigned chars can hold) */ #endif /* !defined TZ_MAX_CHARS */ #ifndef TZ_MAX_LEAPS -#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ +#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ #endif /* !defined TZ_MAX_LEAPS */ #endif /* !defined TZFILE_H */ diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc index 5ab5a59ecf..840e968aad 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc @@ -14,10 +14,10 @@ #include "absl/time/internal/cctz/include/cctz/zone_info_source.h" -#include "absl/base/config.h" - +#include "absl/base/config.h" + namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { @@ -27,11 +27,11 @@ std::string ZoneInfoSource::Version() const { return std::string(); } } // namespace cctz } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz_extension { @@ -41,9 +41,9 @@ namespace { // defers to the fallback factory. std::unique_ptr<absl::time_internal::cctz::ZoneInfoSource> DefaultFactory( const std::string& name, - const std::function< - std::unique_ptr<absl::time_internal::cctz::ZoneInfoSource>( - const std::string& name)>& fallback_factory) { + const std::function< + std::unique_ptr<absl::time_internal::cctz::ZoneInfoSource>( + const std::string& name)>& fallback_factory) { return fallback_factory(name); } @@ -59,48 +59,48 @@ std::unique_ptr<absl::time_internal::cctz::ZoneInfoSource> DefaultFactory( // Windows linker cannot handle that. Nor does the MinGW compiler know how to // pass "#pragma comment(linker, ...)" to the Windows linker. #if (__has_attribute(weak) || defined(__GNUC__)) && !defined(__MINGW32__) -ZoneInfoSourceFactory zone_info_source_factory __attribute__((weak)) = - DefaultFactory; +ZoneInfoSourceFactory zone_info_source_factory __attribute__((weak)) = + DefaultFactory; #elif defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_LIBCPP_VERSION) extern ZoneInfoSourceFactory zone_info_source_factory; extern ZoneInfoSourceFactory default_factory; ZoneInfoSourceFactory default_factory = DefaultFactory; #if defined(_M_IX86) || defined(_M_ARM) -#pragma comment( \ - linker, \ - "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ - "@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ - "@@ZA=?default_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ - "@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ - "@@ZA") +#pragma comment( \ + linker, \ + "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@@ZA=?default_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@@ZA") #elif defined(_M_IA_64) || defined(_M_AMD64) || defined(_M_ARM64) -#pragma comment( \ - linker, \ - "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ - "@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ - "@@ZEA=?default_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ - "@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ - "@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ - "@@ZEA") +#pragma comment( \ + linker, \ + "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@@ZEA=?default_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@@ZEA") #else #error Unsupported MSVC platform #endif // _M_<PLATFORM> @@ -111,5 +111,5 @@ ZoneInfoSourceFactory zone_info_source_factory = DefaultFactory; } // namespace cctz_extension } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/get_current_time_chrono.inc b/contrib/restricted/abseil-cpp/absl/time/internal/get_current_time_chrono.inc index 5eeb6406aa..6160a8b0cb 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/get_current_time_chrono.inc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/get_current_time_chrono.inc @@ -16,7 +16,7 @@ #include <cstdint> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { static int64_t GetCurrentTimeNanosFromSystem() { @@ -27,5 +27,5 @@ static int64_t GetCurrentTimeNanosFromSystem() { } } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/get_current_time_posix.inc b/contrib/restricted/abseil-cpp/absl/time/internal/get_current_time_posix.inc index 42072000ae..3a92c45763 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/get_current_time_posix.inc +++ b/contrib/restricted/abseil-cpp/absl/time/internal/get_current_time_posix.inc @@ -7,7 +7,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { static int64_t GetCurrentTimeNanosFromSystem() { @@ -20,5 +20,5 @@ static int64_t GetCurrentTimeNanosFromSystem() { } } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/internal/test_util.h b/contrib/restricted/abseil-cpp/absl/time/internal/test_util.h index 5c4bf1f680..626ee92f6b 100644 --- a/contrib/restricted/abseil-cpp/absl/time/internal/test_util.h +++ b/contrib/restricted/abseil-cpp/absl/time/internal/test_util.h @@ -20,14 +20,14 @@ #include "absl/time/time.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace time_internal { // Loads the named timezone, but dies on any failure. absl::TimeZone LoadTimeZone(const std::string& name); } // namespace time_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_INTERNAL_TEST_UTIL_H_ diff --git a/contrib/restricted/abseil-cpp/absl/time/time.cc b/contrib/restricted/abseil-cpp/absl/time/time.cc index 1ec2026e25..398b024324 100644 --- a/contrib/restricted/abseil-cpp/absl/time/time.cc +++ b/contrib/restricted/abseil-cpp/absl/time/time.cc @@ -47,7 +47,7 @@ namespace cctz = absl::time_internal::cctz; namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace { @@ -60,10 +60,10 @@ inline cctz::time_point<cctz::seconds> unix_epoch() { inline int64_t FloorToUnit(absl::Duration d, absl::Duration unit) { absl::Duration rem; int64_t q = absl::IDivDuration(d, unit, &rem); - return (q > 0 || rem >= ZeroDuration() || - q == std::numeric_limits<int64_t>::min()) - ? q - : q - 1; + return (q > 0 || rem >= ZeroDuration() || + q == std::numeric_limits<int64_t>::min()) + ? q + : q - 1; } inline absl::Time::Breakdown InfiniteFutureBreakdown() { @@ -496,5 +496,5 @@ struct tm ToTM(absl::Time t, absl::TimeZone tz) { return tm; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl diff --git a/contrib/restricted/abseil-cpp/absl/time/time.h b/contrib/restricted/abseil-cpp/absl/time/time.h index 5abd815a79..6fb7207dde 100644 --- a/contrib/restricted/abseil-cpp/absl/time/time.h +++ b/contrib/restricted/abseil-cpp/absl/time/time.h @@ -89,7 +89,7 @@ struct timeval; #include "absl/time/internal/cctz/include/cctz/time_zone.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN class Duration; // Defined below class Time; // Defined below @@ -575,7 +575,7 @@ inline std::ostream& operator<<(std::ostream& os, Duration d) { // suffix. The valid suffixes are "ns", "us" "ms", "s", "m", and "h". // Simple examples include "300ms", "-1.5h", and "2h45m". Parses "0" as // `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`. -bool ParseDuration(absl::string_view dur_string, Duration* d); +bool ParseDuration(absl::string_view dur_string, Duration* d); // AbslParseFlag() // @@ -679,7 +679,7 @@ class Time { // Deprecated. Use `absl::TimeZone::CivilInfo`. struct Breakdown { - int64_t year; // year (e.g., 2013) + int64_t year; // year (e.g., 2013) int month; // month of year [1:12] int day; // day of month [1:31] int hour; // hour of day [0:23] @@ -1071,13 +1071,13 @@ class TimeZone { // Loads the named zone. May perform I/O on the initial load of the named // zone. If the name is invalid, or some other kind of error occurs, returns // `false` and `*tz` is set to the UTC time zone. -inline bool LoadTimeZone(absl::string_view name, TimeZone* tz) { +inline bool LoadTimeZone(absl::string_view name, TimeZone* tz) { if (name == "localtime") { *tz = TimeZone(time_internal::cctz::local_time_zone()); return true; } time_internal::cctz::time_zone cz; - const bool b = time_internal::cctz::load_time_zone(std::string(name), &cz); + const bool b = time_internal::cctz::load_time_zone(std::string(name), &cz); *tz = TimeZone(cz); return b; } @@ -1257,15 +1257,15 @@ struct tm ToTM(Time t, TimeZone tz); // time with UTC offset. Also note the use of "%Y": RFC3339 mandates that // years have exactly four digits, but we allow them to take their natural // width. -ABSL_DLL extern const char RFC3339_full[]; // %Y-%m-%d%ET%H:%M:%E*S%Ez -ABSL_DLL extern const char RFC3339_sec[]; // %Y-%m-%d%ET%H:%M:%S%Ez +ABSL_DLL extern const char RFC3339_full[]; // %Y-%m-%d%ET%H:%M:%E*S%Ez +ABSL_DLL extern const char RFC3339_sec[]; // %Y-%m-%d%ET%H:%M:%S%Ez // RFC1123_full // RFC1123_no_wday // // FormatTime()/ParseTime() format specifiers for RFC1123 date/time strings. -ABSL_DLL extern const char RFC1123_full[]; // %a, %d %b %E4Y %H:%M:%S %z -ABSL_DLL extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z +ABSL_DLL extern const char RFC1123_full[]; // %a, %d %b %E4Y %H:%M:%S %z +ABSL_DLL extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z // FormatTime() // @@ -1280,7 +1280,7 @@ ABSL_DLL extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z // - %E#f - Fractional seconds with # digits of precision // - %E*f - Fractional seconds with full precision (a literal '*') // - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) -// - %ET - The RFC3339 "date-time" separator "T" +// - %ET - The RFC3339 "date-time" separator "T" // // Note that %E0S behaves like %S, and %E0f produces no characters. In // contrast %E*f always produces at least one digit, which may be '0'. @@ -1304,7 +1304,7 @@ ABSL_DLL extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z // `absl::InfinitePast()`, the returned string will be exactly "infinite-past". // In both cases the given format string and `absl::TimeZone` are ignored. // -std::string FormatTime(absl::string_view format, Time t, TimeZone tz); +std::string FormatTime(absl::string_view format, Time t, TimeZone tz); // Convenience functions that format the given time using the RFC3339_full // format. The first overload uses the provided TimeZone, while the second @@ -1323,8 +1323,8 @@ inline std::ostream& operator<<(std::ostream& os, Time t) { // returns the corresponding `absl::Time`. Uses strftime()-like formatting // options, with the same extensions as FormatTime(), but with the // exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez -// and %E*z also accept the same inputs, which (along with %z) includes -// 'z' and 'Z' as synonyms for +00:00. %ET accepts either 'T' or 't'. +// and %E*z also accept the same inputs, which (along with %z) includes +// 'z' and 'Z' as synonyms for +00:00. %ET accepts either 'T' or 't'. // // %Y consumes as many numeric characters as it can, so the matching data // should always be terminated with a non-numeric. %E4Y always consumes @@ -1366,7 +1366,7 @@ inline std::ostream& operator<<(std::ostream& os, Time t) { // If the input string is "infinite-past", the returned `absl::Time` will be // `absl::InfinitePast()` and `true` will be returned. // -bool ParseTime(absl::string_view format, absl::string_view input, Time* time, +bool ParseTime(absl::string_view format, absl::string_view input, Time* time, std::string* err); // Like ParseTime() above, but if the format string does not contain a UTC @@ -1376,7 +1376,7 @@ bool ParseTime(absl::string_view format, absl::string_view input, Time* time, // of ambiguity or non-existence, in which case the "pre" time (as defined // by TimeZone::TimeInfo) is returned. For these reasons we recommend that // all date/time strings include a UTC offset so they're context independent. -bool ParseTime(absl::string_view format, absl::string_view input, TimeZone tz, +bool ParseTime(absl::string_view format, absl::string_view input, TimeZone tz, Time* time, std::string* err); // ============================================================================ @@ -1401,7 +1401,7 @@ constexpr Duration MakeDuration(int64_t hi, int64_t lo) { // it's positive and can be converted to int64_t without risk of UB. inline Duration MakePosDoubleDuration(double n) { const int64_t int_secs = static_cast<int64_t>(n); - const uint32_t ticks = static_cast<uint32_t>( + const uint32_t ticks = static_cast<uint32_t>( std::round((n - static_cast<double>(int_secs)) * kTicksPerSecond)); return ticks < kTicksPerSecond ? MakeDuration(int_secs, ticks) @@ -1529,10 +1529,10 @@ T ToChronoDuration(Duration d) { constexpr bool operator<(Duration lhs, Duration rhs) { return time_internal::GetRepHi(lhs) != time_internal::GetRepHi(rhs) ? time_internal::GetRepHi(lhs) < time_internal::GetRepHi(rhs) - : time_internal::GetRepHi(lhs) == (std::numeric_limits<int64_t>::min)() - ? time_internal::GetRepLo(lhs) + 1 < - time_internal::GetRepLo(rhs) + 1 - : time_internal::GetRepLo(lhs) < time_internal::GetRepLo(rhs); + : time_internal::GetRepHi(lhs) == (std::numeric_limits<int64_t>::min)() + ? time_internal::GetRepLo(lhs) + 1 < + time_internal::GetRepLo(rhs) + 1 + : time_internal::GetRepLo(lhs) < time_internal::GetRepLo(rhs); } constexpr bool operator==(Duration lhs, Duration rhs) { @@ -1610,7 +1610,7 @@ constexpr Time FromTimeT(time_t t) { return time_internal::FromUnixDuration(Seconds(t)); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TIME_TIME_H_ diff --git a/contrib/restricted/abseil-cpp/absl/time/time_zone/ya.make b/contrib/restricted/abseil-cpp/absl/time/time_zone/ya.make index 810a0b318c..04e1bb9005 100644 --- a/contrib/restricted/abseil-cpp/absl/time/time_zone/ya.make +++ b/contrib/restricted/abseil-cpp/absl/time/time_zone/ya.make @@ -20,10 +20,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/time/internal/cctz/src) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/time/ya.make b/contrib/restricted/abseil-cpp/absl/time/ya.make index feb835cc53..a70b2c1ee6 100644 --- a/contrib/restricted/abseil-cpp/absl/time/ya.make +++ b/contrib/restricted/abseil-cpp/absl/time/ya.make @@ -32,10 +32,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCS( civil_time.cc clock.cc diff --git a/contrib/restricted/abseil-cpp/absl/types/any.h b/contrib/restricted/abseil-cpp/absl/types/any.h index fc5a07469f..808a9b080e 100644 --- a/contrib/restricted/abseil-cpp/absl/types/any.h +++ b/contrib/restricted/abseil-cpp/absl/types/any.h @@ -47,9 +47,9 @@ // this abstraction, make sure that you should not instead be rewriting your // code to be more specific. // -// Abseil has also released an `absl::variant` type (a C++11 compatible version -// of the C++17 `std::variant`), which is generally preferred for use over -// `absl::any`. +// Abseil has also released an `absl::variant` type (a C++11 compatible version +// of the C++17 `std::variant`), which is generally preferred for use over +// `absl::any`. #ifndef ABSL_TYPES_ANY_H_ #define ABSL_TYPES_ANY_H_ @@ -61,12 +61,12 @@ #include <any> // IWYU pragma: export namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN using std::any; using std::any_cast; using std::bad_any_cast; using std::make_any; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_ANY @@ -80,7 +80,7 @@ ABSL_NAMESPACE_END #include <typeinfo> #include <utility> -#include "absl/base/internal/fast_type_id.h" +#include "absl/base/internal/fast_type_id.h" #include "absl/base/macros.h" #include "absl/meta/type_traits.h" #include "absl/types/bad_any_cast.h" @@ -94,7 +94,7 @@ ABSL_NAMESPACE_END #endif // !defined(__GNUC__) || defined(__GXX_RTTI) namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN class any; @@ -404,11 +404,11 @@ class any { using NormalizedType = typename std::remove_cv<typename std::remove_reference<T>::type>::type; - return base_internal::FastTypeId<NormalizedType>(); + return base_internal::FastTypeId<NormalizedType>(); } const void* GetObjTypeId() const { - return obj_ ? obj_->ObjTypeId() : base_internal::FastTypeId<void>(); + return obj_ ? obj_->ObjTypeId() : base_internal::FastTypeId<void>(); } // `absl::any` nonmember functions // @@ -518,7 +518,7 @@ T* any_cast(any* operand) noexcept { : nullptr; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #undef ABSL_ANY_DETAIL_HAS_RTTI diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_any_cast.cc b/contrib/restricted/abseil-cpp/absl/types/bad_any_cast.cc index b0592cc9bc..b19fec870a 100644 --- a/contrib/restricted/abseil-cpp/absl/types/bad_any_cast.cc +++ b/contrib/restricted/abseil-cpp/absl/types/bad_any_cast.cc @@ -22,7 +22,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN bad_any_cast::~bad_any_cast() = default; @@ -40,7 +40,7 @@ void ThrowBadAnyCast() { } } // namespace any_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_ANY diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_any_cast.h b/contrib/restricted/abseil-cpp/absl/types/bad_any_cast.h index 114cef80cd..666771f098 100644 --- a/contrib/restricted/abseil-cpp/absl/types/bad_any_cast.h +++ b/contrib/restricted/abseil-cpp/absl/types/bad_any_cast.h @@ -30,15 +30,15 @@ #include <any> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN using std::bad_any_cast; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_ANY namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // bad_any_cast @@ -67,7 +67,7 @@ namespace any_internal { [[noreturn]] void ThrowBadAnyCast(); } // namespace any_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_ANY diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_any_cast/ya.make b/contrib/restricted/abseil-cpp/absl/types/bad_any_cast/ya.make index aa13ee52f6..1558a678ff 100644 --- a/contrib/restricted/abseil-cpp/absl/types/bad_any_cast/ya.make +++ b/contrib/restricted/abseil-cpp/absl/types/bad_any_cast/ya.make @@ -21,10 +21,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/types) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.cc b/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.cc index 26aca70d9c..f53d617f38 100644 --- a/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.cc +++ b/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.cc @@ -22,7 +22,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN bad_optional_access::~bad_optional_access() = default; @@ -42,7 +42,7 @@ void throw_bad_optional_access() { } } // namespace optional_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_OPTIONAL diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.h b/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.h index 049e72ad9a..65ce9d55aa 100644 --- a/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.h +++ b/contrib/restricted/abseil-cpp/absl/types/bad_optional_access.h @@ -30,15 +30,15 @@ #include <optional> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN using std::bad_optional_access; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_OPTIONAL namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // bad_optional_access @@ -70,7 +70,7 @@ namespace optional_internal { [[noreturn]] ABSL_DLL void throw_bad_optional_access(); } // namespace optional_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_OPTIONAL diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_optional_access/ya.make b/contrib/restricted/abseil-cpp/absl/types/bad_optional_access/ya.make index 25b3cf1d53..63f0b44567 100644 --- a/contrib/restricted/abseil-cpp/absl/types/bad_optional_access/ya.make +++ b/contrib/restricted/abseil-cpp/absl/types/bad_optional_access/ya.make @@ -21,10 +21,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/types) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.cc b/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.cc index 3dc88cc09f..4dadfc5981 100644 --- a/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.cc +++ b/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.cc @@ -23,7 +23,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN ////////////////////////// // [variant.bad.access] // @@ -58,7 +58,7 @@ void Rethrow() { } } // namespace variant_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_VARIANT diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.h b/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.h index 8ab215e97d..f4e7372ac2 100644 --- a/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.h +++ b/contrib/restricted/abseil-cpp/absl/types/bad_variant_access.h @@ -30,15 +30,15 @@ #include <variant> namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN using std::bad_variant_access; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_VARIANT namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // bad_variant_access @@ -74,7 +74,7 @@ namespace variant_internal { [[noreturn]] ABSL_DLL void Rethrow(); } // namespace variant_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USES_STD_VARIANT diff --git a/contrib/restricted/abseil-cpp/absl/types/bad_variant_access/ya.make b/contrib/restricted/abseil-cpp/absl/types/bad_variant_access/ya.make index 4819f7f422..f3dc599b31 100644 --- a/contrib/restricted/abseil-cpp/absl/types/bad_variant_access/ya.make +++ b/contrib/restricted/abseil-cpp/absl/types/bad_variant_access/ya.make @@ -21,10 +21,10 @@ NO_COMPILER_WARNINGS() NO_UTIL() -CFLAGS( - -DNOMINMAX -) - +CFLAGS( + -DNOMINMAX +) + SRCDIR(contrib/restricted/abseil-cpp/absl/types) SRCS( diff --git a/contrib/restricted/abseil-cpp/absl/types/compare.h b/contrib/restricted/abseil-cpp/absl/types/compare.h index 19b076e7f1..bdb4b360c0 100644 --- a/contrib/restricted/abseil-cpp/absl/types/compare.h +++ b/contrib/restricted/abseil-cpp/absl/types/compare.h @@ -39,7 +39,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace compare_internal { using value_type = int8_t; @@ -86,8 +86,8 @@ enum class ncmp : value_type { unordered = -127 }; // incomplete types so they need to be defined after the types are complete. #ifdef __cpp_inline_variables -// A no-op expansion that can be followed by a semicolon at class level. -#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) static_assert(true, "") +// A no-op expansion that can be followed by a semicolon at class level. +#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) static_assert(true, "") #define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) \ static const type name @@ -100,8 +100,8 @@ enum class ncmp : value_type { unordered = -127 }; #define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) \ ABSL_CONST_INIT static const T name -// A no-op expansion that can be followed by a semicolon at class level. -#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) static_assert(true, "") +// A no-op expansion that can be followed by a semicolon at class level. +#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) static_assert(true, "") #define ABSL_COMPARE_INLINE_INIT(type, name, init) \ template <typename T> \ @@ -178,14 +178,14 @@ class weak_equality weak_equality v) noexcept { return 0 != v.value_; } - friend constexpr bool operator==(weak_equality v1, - weak_equality v2) noexcept { - return v1.value_ == v2.value_; - } - friend constexpr bool operator!=(weak_equality v1, - weak_equality v2) noexcept { - return v1.value_ != v2.value_; - } + friend constexpr bool operator==(weak_equality v1, + weak_equality v2) noexcept { + return v1.value_ == v2.value_; + } + friend constexpr bool operator!=(weak_equality v1, + weak_equality v2) noexcept { + return v1.value_ != v2.value_; + } private: compare_internal::value_type value_; @@ -229,14 +229,14 @@ class strong_equality strong_equality v) noexcept { return 0 != v.value_; } - friend constexpr bool operator==(strong_equality v1, - strong_equality v2) noexcept { - return v1.value_ == v2.value_; - } - friend constexpr bool operator!=(strong_equality v1, - strong_equality v2) noexcept { - return v1.value_ != v2.value_; - } + friend constexpr bool operator==(strong_equality v1, + strong_equality v2) noexcept { + return v1.value_ == v2.value_; + } + friend constexpr bool operator!=(strong_equality v1, + strong_equality v2) noexcept { + return v1.value_ != v2.value_; + } private: compare_internal::value_type value_; @@ -324,14 +324,14 @@ class partial_ordering partial_ordering v) noexcept { return v.is_ordered() && 0 >= v.value_; } - friend constexpr bool operator==(partial_ordering v1, - partial_ordering v2) noexcept { - return v1.value_ == v2.value_; - } - friend constexpr bool operator!=(partial_ordering v1, - partial_ordering v2) noexcept { - return v1.value_ != v2.value_; - } + friend constexpr bool operator==(partial_ordering v1, + partial_ordering v2) noexcept { + return v1.value_ == v2.value_; + } + friend constexpr bool operator!=(partial_ordering v1, + partial_ordering v2) noexcept { + return v1.value_ != v2.value_; + } private: compare_internal::value_type value_; @@ -416,14 +416,14 @@ class weak_ordering weak_ordering v) noexcept { return 0 >= v.value_; } - friend constexpr bool operator==(weak_ordering v1, - weak_ordering v2) noexcept { - return v1.value_ == v2.value_; - } - friend constexpr bool operator!=(weak_ordering v1, - weak_ordering v2) noexcept { - return v1.value_ != v2.value_; - } + friend constexpr bool operator==(weak_ordering v1, + weak_ordering v2) noexcept { + return v1.value_ == v2.value_; + } + friend constexpr bool operator!=(weak_ordering v1, + weak_ordering v2) noexcept { + return v1.value_ != v2.value_; + } private: compare_internal::value_type value_; @@ -515,14 +515,14 @@ class strong_ordering strong_ordering v) noexcept { return 0 >= v.value_; } - friend constexpr bool operator==(strong_ordering v1, - strong_ordering v2) noexcept { - return v1.value_ == v2.value_; - } - friend constexpr bool operator!=(strong_ordering v1, - strong_ordering v2) noexcept { - return v1.value_ != v2.value_; - } + friend constexpr bool operator==(strong_ordering v1, + strong_ordering v2) noexcept { + return v1.value_ == v2.value_; + } + friend constexpr bool operator!=(strong_ordering v1, + strong_ordering v2) noexcept { + return v1.value_ != v2.value_; + } private: compare_internal::value_type value_; @@ -594,7 +594,7 @@ constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare, } } // namespace compare_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TYPES_COMPARE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/conformance_aliases.h b/contrib/restricted/abseil-cpp/absl/types/internal/conformance_aliases.h index 0cc6884e30..a792770339 100644 --- a/contrib/restricted/abseil-cpp/absl/types/internal/conformance_aliases.h +++ b/contrib/restricted/abseil-cpp/absl/types/internal/conformance_aliases.h @@ -1,447 +1,447 @@ -// Copyright 2018 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// regularity_aliases.h -// ----------------------------------------------------------------------------- -// -// This file contains type aliases of common ConformanceProfiles and Archetypes -// so that they can be directly used by name without creating them from scratch. - -#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_ALIASES_H_ -#define ABSL_TYPES_INTERNAL_CONFORMANCE_ALIASES_H_ - -#include "absl/types/internal/conformance_archetype.h" -#include "absl/types/internal/conformance_profile.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace types_internal { - -// Creates both a Profile and a corresponding Archetype with root name "name". -#define ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(name, ...) \ - struct name##Profile : __VA_ARGS__ {}; \ - \ - using name##Archetype = ::absl::types_internal::Archetype<name##Profile>; \ - \ - template <class AbslInternalProfileTag> \ - using name##Archetype##_ = ::absl::types_internal::Archetype< \ - ::absl::types_internal::StrongProfileTypedef<name##Profile, \ - AbslInternalProfileTag>> - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasTrivialDefaultConstructor, - ConformanceProfile<default_constructible::trivial>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowDefaultConstructor, - ConformanceProfile<default_constructible::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasDefaultConstructor, ConformanceProfile<default_constructible::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasTrivialMoveConstructor, ConformanceProfile<default_constructible::maybe, - move_constructible::trivial>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowMoveConstructor, ConformanceProfile<default_constructible::maybe, - move_constructible::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasMoveConstructor, - ConformanceProfile<default_constructible::maybe, move_constructible::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasTrivialCopyConstructor, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::trivial>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowCopyConstructor, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasCopyConstructor, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasTrivialMoveAssign, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::trivial>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowMoveAssign, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasMoveAssign, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasTrivialCopyAssign, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::trivial>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowCopyAssign, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasCopyAssign, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasTrivialDestructor, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::trivial>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowDestructor, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasDestructor, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowEquality, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, - equality_comparable::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasEquality, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, - equality_comparable::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowInequality, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, - equality_comparable::maybe, - inequality_comparable::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasInequality, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, - equality_comparable::maybe, inequality_comparable::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowLessThan, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, - equality_comparable::maybe, inequality_comparable::maybe, - less_than_comparable::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasLessThan, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, - equality_comparable::maybe, inequality_comparable::maybe, - less_than_comparable::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowLessEqual, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, - equality_comparable::maybe, inequality_comparable::maybe, - less_than_comparable::maybe, - less_equal_comparable::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasLessEqual, - ConformanceProfile<default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, - equality_comparable::maybe, inequality_comparable::maybe, - less_than_comparable::maybe, - less_equal_comparable::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowGreaterEqual, - ConformanceProfile< - default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, - inequality_comparable::maybe, less_than_comparable::maybe, - less_equal_comparable::maybe, greater_equal_comparable::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasGreaterEqual, - ConformanceProfile< - default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, - inequality_comparable::maybe, less_than_comparable::maybe, - less_equal_comparable::maybe, greater_equal_comparable::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowGreaterThan, - ConformanceProfile< - default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, - inequality_comparable::maybe, less_than_comparable::maybe, - less_equal_comparable::maybe, greater_equal_comparable::maybe, - greater_than_comparable::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasGreaterThan, - ConformanceProfile< - default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, - inequality_comparable::maybe, less_than_comparable::maybe, - less_equal_comparable::maybe, greater_equal_comparable::maybe, - greater_than_comparable::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasNothrowSwap, - ConformanceProfile< - default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, - inequality_comparable::maybe, less_than_comparable::maybe, - less_equal_comparable::maybe, greater_equal_comparable::maybe, - greater_than_comparable::maybe, swappable::nothrow>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasSwap, - ConformanceProfile< - default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, - inequality_comparable::maybe, less_than_comparable::maybe, - less_equal_comparable::maybe, greater_equal_comparable::maybe, - greater_than_comparable::maybe, swappable::yes>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HasStdHashSpecialization, - ConformanceProfile< - default_constructible::maybe, move_constructible::maybe, - copy_constructible::maybe, move_assignable::maybe, - copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, - inequality_comparable::maybe, less_than_comparable::maybe, - less_equal_comparable::maybe, greater_equal_comparable::maybe, - greater_than_comparable::maybe, swappable::maybe, hashable::yes>); - -//////////////////////////////////////////////////////////////////////////////// -//// The remaining aliases are combinations of the previous aliases. //// -//////////////////////////////////////////////////////////////////////////////// - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - Equatable, CombineProfiles<HasEqualityProfile, HasInequalityProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - Comparable, - CombineProfiles<EquatableProfile, HasLessThanProfile, HasLessEqualProfile, - HasGreaterEqualProfile, HasGreaterThanProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - NothrowEquatable, - CombineProfiles<HasNothrowEqualityProfile, HasNothrowInequalityProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - NothrowComparable, - CombineProfiles<NothrowEquatableProfile, HasNothrowLessThanProfile, - HasNothrowLessEqualProfile, HasNothrowGreaterEqualProfile, - HasNothrowGreaterThanProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - Value, - CombineProfiles<HasNothrowMoveConstructorProfile, HasCopyConstructorProfile, - HasNothrowMoveAssignProfile, HasCopyAssignProfile, - HasNothrowDestructorProfile, HasNothrowSwapProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - EquatableValue, CombineProfiles<EquatableProfile, ValueProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - ComparableValue, CombineProfiles<ComparableProfile, ValueProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - DefaultConstructibleValue, - CombineProfiles<HasDefaultConstructorProfile, ValueProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - NothrowMoveConstructible, CombineProfiles<HasNothrowMoveConstructorProfile, - HasNothrowDestructorProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - EquatableNothrowMoveConstructible, - CombineProfiles<EquatableProfile, NothrowMoveConstructibleProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - ComparableNothrowMoveConstructible, - CombineProfiles<ComparableProfile, NothrowMoveConstructibleProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - DefaultConstructibleNothrowMoveConstructible, - CombineProfiles<HasDefaultConstructorProfile, - NothrowMoveConstructibleProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - CopyConstructible, - CombineProfiles<HasNothrowMoveConstructorProfile, HasCopyConstructorProfile, - HasNothrowDestructorProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - EquatableCopyConstructible, - CombineProfiles<EquatableProfile, CopyConstructibleProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - ComparableCopyConstructible, - CombineProfiles<ComparableProfile, CopyConstructibleProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - DefaultConstructibleCopyConstructible, - CombineProfiles<HasDefaultConstructorProfile, CopyConstructibleProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - NothrowMovable, - CombineProfiles<HasNothrowMoveConstructorProfile, - HasNothrowMoveAssignProfile, HasNothrowDestructorProfile, - HasNothrowSwapProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - EquatableNothrowMovable, - CombineProfiles<EquatableProfile, NothrowMovableProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - ComparableNothrowMovable, - CombineProfiles<ComparableProfile, NothrowMovableProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - DefaultConstructibleNothrowMovable, - CombineProfiles<HasDefaultConstructorProfile, NothrowMovableProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - TrivialSpecialMemberFunctions, - CombineProfiles<HasTrivialDefaultConstructorProfile, - HasTrivialMoveConstructorProfile, - HasTrivialCopyConstructorProfile, - HasTrivialMoveAssignProfile, HasTrivialCopyAssignProfile, - HasTrivialDestructorProfile, HasNothrowSwapProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - TriviallyComplete, - CombineProfiles<TrivialSpecialMemberFunctionsProfile, ComparableProfile, - HasStdHashSpecializationProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HashableNothrowMoveConstructible, - CombineProfiles<HasStdHashSpecializationProfile, - NothrowMoveConstructibleProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HashableCopyConstructible, - CombineProfiles<HasStdHashSpecializationProfile, CopyConstructibleProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HashableNothrowMovable, - CombineProfiles<HasStdHashSpecializationProfile, NothrowMovableProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - HashableValue, - CombineProfiles<HasStdHashSpecializationProfile, ValueProfile>); - -ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( - ComparableHashableValue, - CombineProfiles<HashableValueProfile, ComparableProfile>); - -// The "preferred" profiles that we support in Abseil. -template <template <class...> class Receiver> -using ExpandBasicProfiles = - Receiver<NothrowMoveConstructibleProfile, CopyConstructibleProfile, - NothrowMovableProfile, ValueProfile>; - -// The basic profiles except that they are also all Equatable. -template <template <class...> class Receiver> -using ExpandBasicEquatableProfiles = - Receiver<EquatableNothrowMoveConstructibleProfile, - EquatableCopyConstructibleProfile, EquatableNothrowMovableProfile, - EquatableValueProfile>; - -// The basic profiles except that they are also all Comparable. -template <template <class...> class Receiver> -using ExpandBasicComparableProfiles = - Receiver<ComparableNothrowMoveConstructibleProfile, - ComparableCopyConstructibleProfile, - ComparableNothrowMovableProfile, ComparableValueProfile>; - -// The basic profiles except that they are also all Hashable. -template <template <class...> class Receiver> -using ExpandBasicHashableProfiles = - Receiver<HashableNothrowMoveConstructibleProfile, - HashableCopyConstructibleProfile, HashableNothrowMovableProfile, - HashableValueProfile>; - -// The basic profiles except that they are also all DefaultConstructible. -template <template <class...> class Receiver> -using ExpandBasicDefaultConstructibleProfiles = - Receiver<DefaultConstructibleNothrowMoveConstructibleProfile, - DefaultConstructibleCopyConstructibleProfile, - DefaultConstructibleNothrowMovableProfile, - DefaultConstructibleValueProfile>; - -// The type profiles that we support in Abseil (all of the previous lists). -template <template <class...> class Receiver> -using ExpandSupportedProfiles = Receiver< - NothrowMoveConstructibleProfile, CopyConstructibleProfile, - NothrowMovableProfile, ValueProfile, - EquatableNothrowMoveConstructibleProfile, EquatableCopyConstructibleProfile, - EquatableNothrowMovableProfile, EquatableValueProfile, - ComparableNothrowMoveConstructibleProfile, - ComparableCopyConstructibleProfile, ComparableNothrowMovableProfile, - ComparableValueProfile, DefaultConstructibleNothrowMoveConstructibleProfile, - DefaultConstructibleCopyConstructibleProfile, - DefaultConstructibleNothrowMovableProfile, DefaultConstructibleValueProfile, - HashableNothrowMoveConstructibleProfile, HashableCopyConstructibleProfile, - HashableNothrowMovableProfile, HashableValueProfile>; - -// TODO(calabrese) Include types that have throwing move constructors, since in -// practice we still need to support them because of standard library types with -// (potentially) non-noexcept moves. - -} // namespace types_internal -ABSL_NAMESPACE_END -} // namespace absl - -#undef ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS - -#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_ALIASES_H_ +// Copyright 2018 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// regularity_aliases.h +// ----------------------------------------------------------------------------- +// +// This file contains type aliases of common ConformanceProfiles and Archetypes +// so that they can be directly used by name without creating them from scratch. + +#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_ALIASES_H_ +#define ABSL_TYPES_INTERNAL_CONFORMANCE_ALIASES_H_ + +#include "absl/types/internal/conformance_archetype.h" +#include "absl/types/internal/conformance_profile.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace types_internal { + +// Creates both a Profile and a corresponding Archetype with root name "name". +#define ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS(name, ...) \ + struct name##Profile : __VA_ARGS__ {}; \ + \ + using name##Archetype = ::absl::types_internal::Archetype<name##Profile>; \ + \ + template <class AbslInternalProfileTag> \ + using name##Archetype##_ = ::absl::types_internal::Archetype< \ + ::absl::types_internal::StrongProfileTypedef<name##Profile, \ + AbslInternalProfileTag>> + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasTrivialDefaultConstructor, + ConformanceProfile<default_constructible::trivial>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowDefaultConstructor, + ConformanceProfile<default_constructible::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasDefaultConstructor, ConformanceProfile<default_constructible::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasTrivialMoveConstructor, ConformanceProfile<default_constructible::maybe, + move_constructible::trivial>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowMoveConstructor, ConformanceProfile<default_constructible::maybe, + move_constructible::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasMoveConstructor, + ConformanceProfile<default_constructible::maybe, move_constructible::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasTrivialCopyConstructor, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::trivial>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowCopyConstructor, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasCopyConstructor, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasTrivialMoveAssign, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::trivial>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowMoveAssign, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasMoveAssign, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasTrivialCopyAssign, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::trivial>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowCopyAssign, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasCopyAssign, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasTrivialDestructor, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::trivial>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowDestructor, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasDestructor, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowEquality, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, + equality_comparable::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasEquality, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, + equality_comparable::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowInequality, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, + equality_comparable::maybe, + inequality_comparable::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasInequality, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, + equality_comparable::maybe, inequality_comparable::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowLessThan, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, + equality_comparable::maybe, inequality_comparable::maybe, + less_than_comparable::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasLessThan, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, + equality_comparable::maybe, inequality_comparable::maybe, + less_than_comparable::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowLessEqual, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, + equality_comparable::maybe, inequality_comparable::maybe, + less_than_comparable::maybe, + less_equal_comparable::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasLessEqual, + ConformanceProfile<default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, + equality_comparable::maybe, inequality_comparable::maybe, + less_than_comparable::maybe, + less_equal_comparable::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowGreaterEqual, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasGreaterEqual, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowGreaterThan, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::maybe, + greater_than_comparable::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasGreaterThan, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::maybe, + greater_than_comparable::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasNothrowSwap, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::maybe, + greater_than_comparable::maybe, swappable::nothrow>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasSwap, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::maybe, + greater_than_comparable::maybe, swappable::yes>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HasStdHashSpecialization, + ConformanceProfile< + default_constructible::maybe, move_constructible::maybe, + copy_constructible::maybe, move_assignable::maybe, + copy_assignable::maybe, destructible::maybe, equality_comparable::maybe, + inequality_comparable::maybe, less_than_comparable::maybe, + less_equal_comparable::maybe, greater_equal_comparable::maybe, + greater_than_comparable::maybe, swappable::maybe, hashable::yes>); + +//////////////////////////////////////////////////////////////////////////////// +//// The remaining aliases are combinations of the previous aliases. //// +//////////////////////////////////////////////////////////////////////////////// + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + Equatable, CombineProfiles<HasEqualityProfile, HasInequalityProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + Comparable, + CombineProfiles<EquatableProfile, HasLessThanProfile, HasLessEqualProfile, + HasGreaterEqualProfile, HasGreaterThanProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + NothrowEquatable, + CombineProfiles<HasNothrowEqualityProfile, HasNothrowInequalityProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + NothrowComparable, + CombineProfiles<NothrowEquatableProfile, HasNothrowLessThanProfile, + HasNothrowLessEqualProfile, HasNothrowGreaterEqualProfile, + HasNothrowGreaterThanProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + Value, + CombineProfiles<HasNothrowMoveConstructorProfile, HasCopyConstructorProfile, + HasNothrowMoveAssignProfile, HasCopyAssignProfile, + HasNothrowDestructorProfile, HasNothrowSwapProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + EquatableValue, CombineProfiles<EquatableProfile, ValueProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + ComparableValue, CombineProfiles<ComparableProfile, ValueProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + DefaultConstructibleValue, + CombineProfiles<HasDefaultConstructorProfile, ValueProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + NothrowMoveConstructible, CombineProfiles<HasNothrowMoveConstructorProfile, + HasNothrowDestructorProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + EquatableNothrowMoveConstructible, + CombineProfiles<EquatableProfile, NothrowMoveConstructibleProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + ComparableNothrowMoveConstructible, + CombineProfiles<ComparableProfile, NothrowMoveConstructibleProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + DefaultConstructibleNothrowMoveConstructible, + CombineProfiles<HasDefaultConstructorProfile, + NothrowMoveConstructibleProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + CopyConstructible, + CombineProfiles<HasNothrowMoveConstructorProfile, HasCopyConstructorProfile, + HasNothrowDestructorProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + EquatableCopyConstructible, + CombineProfiles<EquatableProfile, CopyConstructibleProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + ComparableCopyConstructible, + CombineProfiles<ComparableProfile, CopyConstructibleProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + DefaultConstructibleCopyConstructible, + CombineProfiles<HasDefaultConstructorProfile, CopyConstructibleProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + NothrowMovable, + CombineProfiles<HasNothrowMoveConstructorProfile, + HasNothrowMoveAssignProfile, HasNothrowDestructorProfile, + HasNothrowSwapProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + EquatableNothrowMovable, + CombineProfiles<EquatableProfile, NothrowMovableProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + ComparableNothrowMovable, + CombineProfiles<ComparableProfile, NothrowMovableProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + DefaultConstructibleNothrowMovable, + CombineProfiles<HasDefaultConstructorProfile, NothrowMovableProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + TrivialSpecialMemberFunctions, + CombineProfiles<HasTrivialDefaultConstructorProfile, + HasTrivialMoveConstructorProfile, + HasTrivialCopyConstructorProfile, + HasTrivialMoveAssignProfile, HasTrivialCopyAssignProfile, + HasTrivialDestructorProfile, HasNothrowSwapProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + TriviallyComplete, + CombineProfiles<TrivialSpecialMemberFunctionsProfile, ComparableProfile, + HasStdHashSpecializationProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HashableNothrowMoveConstructible, + CombineProfiles<HasStdHashSpecializationProfile, + NothrowMoveConstructibleProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HashableCopyConstructible, + CombineProfiles<HasStdHashSpecializationProfile, CopyConstructibleProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HashableNothrowMovable, + CombineProfiles<HasStdHashSpecializationProfile, NothrowMovableProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + HashableValue, + CombineProfiles<HasStdHashSpecializationProfile, ValueProfile>); + +ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS( + ComparableHashableValue, + CombineProfiles<HashableValueProfile, ComparableProfile>); + +// The "preferred" profiles that we support in Abseil. +template <template <class...> class Receiver> +using ExpandBasicProfiles = + Receiver<NothrowMoveConstructibleProfile, CopyConstructibleProfile, + NothrowMovableProfile, ValueProfile>; + +// The basic profiles except that they are also all Equatable. +template <template <class...> class Receiver> +using ExpandBasicEquatableProfiles = + Receiver<EquatableNothrowMoveConstructibleProfile, + EquatableCopyConstructibleProfile, EquatableNothrowMovableProfile, + EquatableValueProfile>; + +// The basic profiles except that they are also all Comparable. +template <template <class...> class Receiver> +using ExpandBasicComparableProfiles = + Receiver<ComparableNothrowMoveConstructibleProfile, + ComparableCopyConstructibleProfile, + ComparableNothrowMovableProfile, ComparableValueProfile>; + +// The basic profiles except that they are also all Hashable. +template <template <class...> class Receiver> +using ExpandBasicHashableProfiles = + Receiver<HashableNothrowMoveConstructibleProfile, + HashableCopyConstructibleProfile, HashableNothrowMovableProfile, + HashableValueProfile>; + +// The basic profiles except that they are also all DefaultConstructible. +template <template <class...> class Receiver> +using ExpandBasicDefaultConstructibleProfiles = + Receiver<DefaultConstructibleNothrowMoveConstructibleProfile, + DefaultConstructibleCopyConstructibleProfile, + DefaultConstructibleNothrowMovableProfile, + DefaultConstructibleValueProfile>; + +// The type profiles that we support in Abseil (all of the previous lists). +template <template <class...> class Receiver> +using ExpandSupportedProfiles = Receiver< + NothrowMoveConstructibleProfile, CopyConstructibleProfile, + NothrowMovableProfile, ValueProfile, + EquatableNothrowMoveConstructibleProfile, EquatableCopyConstructibleProfile, + EquatableNothrowMovableProfile, EquatableValueProfile, + ComparableNothrowMoveConstructibleProfile, + ComparableCopyConstructibleProfile, ComparableNothrowMovableProfile, + ComparableValueProfile, DefaultConstructibleNothrowMoveConstructibleProfile, + DefaultConstructibleCopyConstructibleProfile, + DefaultConstructibleNothrowMovableProfile, DefaultConstructibleValueProfile, + HashableNothrowMoveConstructibleProfile, HashableCopyConstructibleProfile, + HashableNothrowMovableProfile, HashableValueProfile>; + +// TODO(calabrese) Include types that have throwing move constructors, since in +// practice we still need to support them because of standard library types with +// (potentially) non-noexcept moves. + +} // namespace types_internal +ABSL_NAMESPACE_END +} // namespace absl + +#undef ABSL_INTERNAL_PROFILE_AND_ARCHETYPE_ALIAS + +#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_ALIASES_H_ diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/conformance_archetype.h b/contrib/restricted/abseil-cpp/absl/types/internal/conformance_archetype.h index 2349e0f726..f88d14b8ec 100644 --- a/contrib/restricted/abseil-cpp/absl/types/internal/conformance_archetype.h +++ b/contrib/restricted/abseil-cpp/absl/types/internal/conformance_archetype.h @@ -1,978 +1,978 @@ -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// conformance_archetype.h -// ----------------------------------------------------------------------------- -// -// This file contains a facility for generating "archetypes" of out of -// "Conformance Profiles" (see "conformance_profiles.h" for more information -// about Conformance Profiles). An archetype is a type that aims to support the -// bare minimum requirements of a given Conformance Profile. For instance, an -// archetype that corresponds to an ImmutableProfile has exactly a nothrow -// move-constructor, a potentially-throwing copy constructor, a nothrow -// destructor, with all other special-member-functions deleted. These archetypes -// are useful for testing to make sure that templates are able to work with the -// kinds of types that they claim to support (i.e. that they do not accidentally -// under-constrain), -// -// The main type template in this file is the Archetype template, which takes -// a Conformance Profile as a template argument and its instantiations are a -// minimum-conforming model of that profile. - -#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_ARCHETYPE_H_ -#define ABSL_TYPES_INTERNAL_CONFORMANCE_ARCHETYPE_H_ - -#include <cstddef> -#include <functional> -#include <type_traits> -#include <utility> - -#include "absl/meta/type_traits.h" -#include "absl/types/internal/conformance_profile.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace types_internal { - -// A minimum-conforming implementation of a type with properties specified in -// `Prof`, where `Prof` is a valid Conformance Profile. -template <class Prof, class /*Enabler*/ = void> -class Archetype; - -// Given an Archetype, obtain the properties of the profile associated with that -// archetype. -template <class Archetype> -struct PropertiesOfArchetype; - -template <class Prof> -struct PropertiesOfArchetype<Archetype<Prof>> { - using type = PropertiesOfT<Prof>; -}; - -template <class Archetype> -using PropertiesOfArchetypeT = typename PropertiesOfArchetype<Archetype>::type; - -// A metafunction to determine if a type is an `Archetype`. -template <class T> -struct IsArchetype : std::false_type {}; - -template <class Prof> -struct IsArchetype<Archetype<Prof>> : std::true_type {}; - -// A constructor tag type used when creating an Archetype with internal state. -struct MakeArchetypeState {}; - -// Data stored within an archetype that is copied/compared/hashed when the -// corresponding operations are used. -using ArchetypeState = std::size_t; - -//////////////////////////////////////////////////////////////////////////////// -// This section of the file defines a chain of base classes for Archetype, // -// where each base defines a specific special member function with the // -// appropriate properties (deleted, noexcept(false), noexcept, or trivial). // -//////////////////////////////////////////////////////////////////////////////// - -// The bottom-most base, which contains the state and the default constructor. -template <default_constructible DefaultConstructibleValue> -struct ArchetypeStateBase { - static_assert(DefaultConstructibleValue == default_constructible::yes || - DefaultConstructibleValue == default_constructible::nothrow, - ""); - - ArchetypeStateBase() noexcept( - DefaultConstructibleValue == - default_constructible:: - nothrow) /*Vacuous archetype_state initialization*/ {} - explicit ArchetypeStateBase(MakeArchetypeState, ArchetypeState state) noexcept - : archetype_state(state) {} - - ArchetypeState archetype_state; -}; - -template <> -struct ArchetypeStateBase<default_constructible::maybe> { - explicit ArchetypeStateBase() = delete; - explicit ArchetypeStateBase(MakeArchetypeState, ArchetypeState state) noexcept - : archetype_state(state) {} - - ArchetypeState archetype_state; -}; - -template <> -struct ArchetypeStateBase<default_constructible::trivial> { - ArchetypeStateBase() = default; - explicit ArchetypeStateBase(MakeArchetypeState, ArchetypeState state) noexcept - : archetype_state(state) {} - - ArchetypeState archetype_state; -}; - -// The move-constructor base -template <default_constructible DefaultConstructibleValue, - move_constructible MoveConstructibleValue> -struct ArchetypeMoveConstructor - : ArchetypeStateBase<DefaultConstructibleValue> { - static_assert(MoveConstructibleValue == move_constructible::yes || - MoveConstructibleValue == move_constructible::nothrow, - ""); - - explicit ArchetypeMoveConstructor(MakeArchetypeState, - ArchetypeState state) noexcept - : ArchetypeStateBase<DefaultConstructibleValue>(MakeArchetypeState(), - state) {} - - ArchetypeMoveConstructor() = default; - ArchetypeMoveConstructor(ArchetypeMoveConstructor&& other) noexcept( - MoveConstructibleValue == move_constructible::nothrow) - : ArchetypeStateBase<DefaultConstructibleValue>(MakeArchetypeState(), - other.archetype_state) {} - ArchetypeMoveConstructor(const ArchetypeMoveConstructor&) = default; - ArchetypeMoveConstructor& operator=(ArchetypeMoveConstructor&&) = default; - ArchetypeMoveConstructor& operator=(const ArchetypeMoveConstructor&) = - default; -}; - -template <default_constructible DefaultConstructibleValue> -struct ArchetypeMoveConstructor<DefaultConstructibleValue, - move_constructible::trivial> - : ArchetypeStateBase<DefaultConstructibleValue> { - explicit ArchetypeMoveConstructor(MakeArchetypeState, - ArchetypeState state) noexcept - : ArchetypeStateBase<DefaultConstructibleValue>(MakeArchetypeState(), - state) {} - - ArchetypeMoveConstructor() = default; -}; - -// The copy-constructor base -template <default_constructible DefaultConstructibleValue, - move_constructible MoveConstructibleValue, - copy_constructible CopyConstructibleValue> -struct ArchetypeCopyConstructor - : ArchetypeMoveConstructor<DefaultConstructibleValue, - MoveConstructibleValue> { - static_assert(CopyConstructibleValue == copy_constructible::yes || - CopyConstructibleValue == copy_constructible::nothrow, - ""); - explicit ArchetypeCopyConstructor(MakeArchetypeState, - ArchetypeState state) noexcept - : ArchetypeMoveConstructor<DefaultConstructibleValue, - MoveConstructibleValue>(MakeArchetypeState(), - state) {} - - ArchetypeCopyConstructor() = default; - ArchetypeCopyConstructor(ArchetypeCopyConstructor&&) = default; - ArchetypeCopyConstructor(const ArchetypeCopyConstructor& other) noexcept( - CopyConstructibleValue == copy_constructible::nothrow) - : ArchetypeMoveConstructor<DefaultConstructibleValue, - MoveConstructibleValue>( - MakeArchetypeState(), other.archetype_state) {} - ArchetypeCopyConstructor& operator=(ArchetypeCopyConstructor&&) = default; - ArchetypeCopyConstructor& operator=(const ArchetypeCopyConstructor&) = - default; -}; - -template <default_constructible DefaultConstructibleValue, - move_constructible MoveConstructibleValue> -struct ArchetypeCopyConstructor<DefaultConstructibleValue, - MoveConstructibleValue, - copy_constructible::maybe> - : ArchetypeMoveConstructor<DefaultConstructibleValue, - MoveConstructibleValue> { - explicit ArchetypeCopyConstructor(MakeArchetypeState, - ArchetypeState state) noexcept - : ArchetypeMoveConstructor<DefaultConstructibleValue, - MoveConstructibleValue>(MakeArchetypeState(), - state) {} - - ArchetypeCopyConstructor() = default; - ArchetypeCopyConstructor(ArchetypeCopyConstructor&&) = default; - ArchetypeCopyConstructor(const ArchetypeCopyConstructor&) = delete; - ArchetypeCopyConstructor& operator=(ArchetypeCopyConstructor&&) = default; - ArchetypeCopyConstructor& operator=(const ArchetypeCopyConstructor&) = - default; -}; - -template <default_constructible DefaultConstructibleValue, - move_constructible MoveConstructibleValue> -struct ArchetypeCopyConstructor<DefaultConstructibleValue, - MoveConstructibleValue, - copy_constructible::trivial> - : ArchetypeMoveConstructor<DefaultConstructibleValue, - MoveConstructibleValue> { - explicit ArchetypeCopyConstructor(MakeArchetypeState, - ArchetypeState state) noexcept - : ArchetypeMoveConstructor<DefaultConstructibleValue, - MoveConstructibleValue>(MakeArchetypeState(), - state) {} - - ArchetypeCopyConstructor() = default; -}; - -// The move-assign base -template <default_constructible DefaultConstructibleValue, - move_constructible MoveConstructibleValue, - copy_constructible CopyConstructibleValue, - move_assignable MoveAssignableValue> -struct ArchetypeMoveAssign - : ArchetypeCopyConstructor<DefaultConstructibleValue, - MoveConstructibleValue, CopyConstructibleValue> { - static_assert(MoveAssignableValue == move_assignable::yes || - MoveAssignableValue == move_assignable::nothrow, - ""); - explicit ArchetypeMoveAssign(MakeArchetypeState, - ArchetypeState state) noexcept - : ArchetypeCopyConstructor<DefaultConstructibleValue, - MoveConstructibleValue, - CopyConstructibleValue>(MakeArchetypeState(), - state) {} - - ArchetypeMoveAssign() = default; - ArchetypeMoveAssign(ArchetypeMoveAssign&&) = default; - ArchetypeMoveAssign(const ArchetypeMoveAssign&) = default; - ArchetypeMoveAssign& operator=(ArchetypeMoveAssign&& other) noexcept( - MoveAssignableValue == move_assignable::nothrow) { - this->archetype_state = other.archetype_state; - return *this; - } - - ArchetypeMoveAssign& operator=(const ArchetypeMoveAssign&) = default; -}; - -template <default_constructible DefaultConstructibleValue, - move_constructible MoveConstructibleValue, - copy_constructible CopyConstructibleValue> -struct ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, move_assignable::trivial> - : ArchetypeCopyConstructor<DefaultConstructibleValue, - MoveConstructibleValue, CopyConstructibleValue> { - explicit ArchetypeMoveAssign(MakeArchetypeState, - ArchetypeState state) noexcept - : ArchetypeCopyConstructor<DefaultConstructibleValue, - MoveConstructibleValue, - CopyConstructibleValue>(MakeArchetypeState(), - state) {} - - ArchetypeMoveAssign() = default; -}; - -// The copy-assign base -template <default_constructible DefaultConstructibleValue, - move_constructible MoveConstructibleValue, - copy_constructible CopyConstructibleValue, - move_assignable MoveAssignableValue, - copy_assignable CopyAssignableValue> -struct ArchetypeCopyAssign - : ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue> { - static_assert(CopyAssignableValue == copy_assignable::yes || - CopyAssignableValue == copy_assignable::nothrow, - ""); - explicit ArchetypeCopyAssign(MakeArchetypeState, - ArchetypeState state) noexcept - : ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue>( - MakeArchetypeState(), state) {} - - ArchetypeCopyAssign() = default; - ArchetypeCopyAssign(ArchetypeCopyAssign&&) = default; - ArchetypeCopyAssign(const ArchetypeCopyAssign&) = default; - ArchetypeCopyAssign& operator=(ArchetypeCopyAssign&&) = default; - - ArchetypeCopyAssign& operator=(const ArchetypeCopyAssign& other) noexcept( - CopyAssignableValue == copy_assignable::nothrow) { - this->archetype_state = other.archetype_state; - return *this; - } -}; - -template <default_constructible DefaultConstructibleValue, - move_constructible MoveConstructibleValue, - copy_constructible CopyConstructibleValue, - move_assignable MoveAssignableValue> -struct ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue, - copy_assignable::maybe> - : ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue> { - explicit ArchetypeCopyAssign(MakeArchetypeState, - ArchetypeState state) noexcept - : ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue>( - MakeArchetypeState(), state) {} - - ArchetypeCopyAssign() = default; - ArchetypeCopyAssign(ArchetypeCopyAssign&&) = default; - ArchetypeCopyAssign(const ArchetypeCopyAssign&) = default; - ArchetypeCopyAssign& operator=(ArchetypeCopyAssign&&) = default; - ArchetypeCopyAssign& operator=(const ArchetypeCopyAssign&) = delete; -}; - -template <default_constructible DefaultConstructibleValue, - move_constructible MoveConstructibleValue, - copy_constructible CopyConstructibleValue, - move_assignable MoveAssignableValue> -struct ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue, - copy_assignable::trivial> - : ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue> { - explicit ArchetypeCopyAssign(MakeArchetypeState, - ArchetypeState state) noexcept - : ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue>( - MakeArchetypeState(), state) {} - - ArchetypeCopyAssign() = default; -}; - -// The destructor base -template <default_constructible DefaultConstructibleValue, - move_constructible MoveConstructibleValue, - copy_constructible CopyConstructibleValue, - move_assignable MoveAssignableValue, - copy_assignable CopyAssignableValue, destructible DestructibleValue> -struct ArchetypeDestructor - : ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue, - CopyAssignableValue> { - static_assert(DestructibleValue == destructible::yes || - DestructibleValue == destructible::nothrow, - ""); - - explicit ArchetypeDestructor(MakeArchetypeState, - ArchetypeState state) noexcept - : ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue, - CopyAssignableValue>(MakeArchetypeState(), state) {} - - ArchetypeDestructor() = default; - ArchetypeDestructor(ArchetypeDestructor&&) = default; - ArchetypeDestructor(const ArchetypeDestructor&) = default; - ArchetypeDestructor& operator=(ArchetypeDestructor&&) = default; - ArchetypeDestructor& operator=(const ArchetypeDestructor&) = default; - ~ArchetypeDestructor() noexcept(DestructibleValue == destructible::nothrow) {} -}; - -template <default_constructible DefaultConstructibleValue, - move_constructible MoveConstructibleValue, - copy_constructible CopyConstructibleValue, - move_assignable MoveAssignableValue, - copy_assignable CopyAssignableValue> -struct ArchetypeDestructor<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue, - CopyAssignableValue, destructible::trivial> - : ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue, - CopyAssignableValue> { - explicit ArchetypeDestructor(MakeArchetypeState, - ArchetypeState state) noexcept - : ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue, - CopyConstructibleValue, MoveAssignableValue, - CopyAssignableValue>(MakeArchetypeState(), state) {} - - ArchetypeDestructor() = default; -}; - -// An alias to the top of the chain of bases for special-member functions. -// NOTE: move_constructible::maybe, move_assignable::maybe, and -// destructible::maybe are handled in the top-level type by way of SFINAE. -// Because of this, we never instantiate the base classes with -// move_constructible::maybe, move_assignable::maybe, or destructible::maybe so -// that we minimize the number of different possible type-template -// instantiations. -template <default_constructible DefaultConstructibleValue, - move_constructible MoveConstructibleValue, - copy_constructible CopyConstructibleValue, - move_assignable MoveAssignableValue, - copy_assignable CopyAssignableValue, destructible DestructibleValue> -using ArchetypeSpecialMembersBase = ArchetypeDestructor< - DefaultConstructibleValue, - MoveConstructibleValue != move_constructible::maybe - ? MoveConstructibleValue - : move_constructible::nothrow, - CopyConstructibleValue, - MoveAssignableValue != move_assignable::maybe ? MoveAssignableValue - : move_assignable::nothrow, - CopyAssignableValue, - DestructibleValue != destructible::maybe ? DestructibleValue - : destructible::nothrow>; - -// A function that is used to create an archetype with some associated state. -template <class Arch> -Arch MakeArchetype(ArchetypeState state) noexcept { - static_assert(IsArchetype<Arch>::value, - "The explicit template argument to MakeArchetype is required " - "to be an Archetype."); - return Arch(MakeArchetypeState(), state); -} - -// This is used to conditionally delete "copy" and "move" constructors in a way -// that is consistent with what the ConformanceProfile requires and that also -// strictly enforces the arguments to the copy/move to not come from implicit -// conversions when dealing with the Archetype. -template <class Prof, class T> -constexpr bool ShouldDeleteConstructor() { - return !((PropertiesOfT<Prof>::move_constructible_support != - move_constructible::maybe && - std::is_same<T, Archetype<Prof>>::value) || - (PropertiesOfT<Prof>::copy_constructible_support != - copy_constructible::maybe && - (std::is_same<T, const Archetype<Prof>&>::value || - std::is_same<T, Archetype<Prof>&>::value || - std::is_same<T, const Archetype<Prof>>::value))); -} - -// This is used to conditionally delete "copy" and "move" assigns in a way -// that is consistent with what the ConformanceProfile requires and that also -// strictly enforces the arguments to the copy/move to not come from implicit -// conversions when dealing with the Archetype. -template <class Prof, class T> -constexpr bool ShouldDeleteAssign() { - return !( - (PropertiesOfT<Prof>::move_assignable_support != move_assignable::maybe && - std::is_same<T, Archetype<Prof>>::value) || - (PropertiesOfT<Prof>::copy_assignable_support != copy_assignable::maybe && - (std::is_same<T, const Archetype<Prof>&>::value || - std::is_same<T, Archetype<Prof>&>::value || - std::is_same<T, const Archetype<Prof>>::value))); -} - -// TODO(calabrese) Inherit from a chain of secondary bases to pull in the -// associated functions of other concepts. -template <class Prof, class Enabler> -class Archetype : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support> { - static_assert(std::is_same<Enabler, void>::value, - "An explicit type must not be passed as the second template " - "argument to 'Archetype`."); - - // The cases mentioned in these static_asserts are expected to be handled in - // the partial template specializations of Archetype that follow this - // definition. - static_assert(PropertiesOfT<Prof>::destructible_support != - destructible::maybe, - ""); - static_assert(PropertiesOfT<Prof>::move_constructible_support != - move_constructible::maybe || - PropertiesOfT<Prof>::copy_constructible_support == - copy_constructible::maybe, - ""); - static_assert(PropertiesOfT<Prof>::move_assignable_support != - move_assignable::maybe || - PropertiesOfT<Prof>::copy_assignable_support == - copy_assignable::maybe, - ""); - - public: - Archetype() = default; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> - Archetype(T&&) = delete; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteAssign<Prof, T>()>::type* = nullptr> - Archetype& operator=(T&&) = delete; - - using ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>::archetype_state; - - private: - explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), - state) {} - - friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; -}; - -template <class Prof> -class Archetype<Prof, typename std::enable_if< - PropertiesOfT<Prof>::move_constructible_support != - move_constructible::maybe && - PropertiesOfT<Prof>::move_assignable_support == - move_assignable::maybe && - PropertiesOfT<Prof>::destructible_support != - destructible::maybe>::type> - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support> { - public: - Archetype() = default; - Archetype(Archetype&&) = default; - Archetype(const Archetype&) = default; - Archetype& operator=(Archetype&&) = delete; - Archetype& operator=(const Archetype&) = default; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> - Archetype(T&&) = delete; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteAssign<Prof, T>()>::type* = nullptr> - Archetype& operator=(T&&) = delete; - - using ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>::archetype_state; - - private: - explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), - state) {} - - friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; -}; - -template <class Prof> -class Archetype<Prof, typename std::enable_if< - PropertiesOfT<Prof>::move_constructible_support == - move_constructible::maybe && - PropertiesOfT<Prof>::move_assignable_support == - move_assignable::maybe && - PropertiesOfT<Prof>::destructible_support != - destructible::maybe>::type> - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support> { - public: - Archetype() = default; - Archetype(Archetype&&) = delete; - Archetype(const Archetype&) = default; - Archetype& operator=(Archetype&&) = delete; - Archetype& operator=(const Archetype&) = default; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> - Archetype(T&&) = delete; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteAssign<Prof, T>()>::type* = nullptr> - Archetype& operator=(T&&) = delete; - - using ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>::archetype_state; - - private: - explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), - state) {} - - friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; -}; - -template <class Prof> -class Archetype<Prof, typename std::enable_if< - PropertiesOfT<Prof>::move_constructible_support == - move_constructible::maybe && - PropertiesOfT<Prof>::move_assignable_support != - move_assignable::maybe && - PropertiesOfT<Prof>::destructible_support != - destructible::maybe>::type> - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support> { - public: - Archetype() = default; - Archetype(Archetype&&) = delete; - Archetype(const Archetype&) = default; - Archetype& operator=(Archetype&&) = default; - Archetype& operator=(const Archetype&) = default; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> - Archetype(T&&) = delete; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteAssign<Prof, T>()>::type* = nullptr> - Archetype& operator=(T&&) = delete; - - using ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>::archetype_state; - - private: - explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), - state) {} - - friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; -}; - -template <class Prof> -class Archetype<Prof, typename std::enable_if< - PropertiesOfT<Prof>::move_constructible_support != - move_constructible::maybe && - PropertiesOfT<Prof>::move_assignable_support == - move_assignable::maybe && - PropertiesOfT<Prof>::destructible_support == - destructible::maybe>::type> - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support> { - public: - Archetype() = default; - Archetype(Archetype&&) = default; - Archetype(const Archetype&) = default; - Archetype& operator=(Archetype&&) = delete; - Archetype& operator=(const Archetype&) = default; - ~Archetype() = delete; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> - Archetype(T&&) = delete; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteAssign<Prof, T>()>::type* = nullptr> - Archetype& operator=(T&&) = delete; - - using ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>::archetype_state; - - private: - explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), - state) {} - - friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; -}; - -template <class Prof> -class Archetype<Prof, typename std::enable_if< - PropertiesOfT<Prof>::move_constructible_support == - move_constructible::maybe && - PropertiesOfT<Prof>::move_assignable_support == - move_assignable::maybe && - PropertiesOfT<Prof>::destructible_support == - destructible::maybe>::type> - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support> { - public: - Archetype() = default; - Archetype(Archetype&&) = delete; - Archetype(const Archetype&) = default; - Archetype& operator=(Archetype&&) = delete; - Archetype& operator=(const Archetype&) = default; - ~Archetype() = delete; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> - Archetype(T&&) = delete; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteAssign<Prof, T>()>::type* = nullptr> - Archetype& operator=(T&&) = delete; - - using ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>::archetype_state; - - private: - explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), - state) {} - - friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; -}; - -template <class Prof> -class Archetype<Prof, typename std::enable_if< - PropertiesOfT<Prof>::move_constructible_support == - move_constructible::maybe && - PropertiesOfT<Prof>::move_assignable_support != - move_assignable::maybe && - PropertiesOfT<Prof>::destructible_support == - destructible::maybe>::type> - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support> { - public: - Archetype() = default; - Archetype(Archetype&&) = delete; - Archetype(const Archetype&) = default; - Archetype& operator=(Archetype&&) = default; - Archetype& operator=(const Archetype&) = default; - ~Archetype() = delete; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> - Archetype(T&&) = delete; - - // Disallow moves when requested, and disallow implicit conversions. - template <class T, typename std::enable_if< - ShouldDeleteAssign<Prof, T>()>::type* = nullptr> - Archetype& operator=(T&&) = delete; - - using ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>::archetype_state; - - private: - explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept - : ArchetypeSpecialMembersBase< - PropertiesOfT<Prof>::default_constructible_support, - PropertiesOfT<Prof>::move_constructible_support, - PropertiesOfT<Prof>::copy_constructible_support, - PropertiesOfT<Prof>::move_assignable_support, - PropertiesOfT<Prof>::copy_assignable_support, - PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), - state) {} - - friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; -}; - -// Explicitly deleted swap for Archetype if the profile does not require swap. -// It is important to delete it rather than simply leave it out so that the -// "using std::swap;" idiom will result in this deleted overload being picked. -template <class Prof, - absl::enable_if_t<!PropertiesOfT<Prof>::is_swappable, int> = 0> -void swap(Archetype<Prof>&, Archetype<Prof>&) = delete; // NOLINT - -// A conditionally-noexcept swap implementation for Archetype when the profile -// supports swap. -template <class Prof, - absl::enable_if_t<PropertiesOfT<Prof>::is_swappable, int> = 0> -void swap(Archetype<Prof>& lhs, Archetype<Prof>& rhs) // NOLINT - noexcept(PropertiesOfT<Prof>::swappable_support != swappable::yes) { - std::swap(lhs.archetype_state, rhs.archetype_state); -} - -// A convertible-to-bool type that is used as the return type of comparison -// operators since the standard doesn't always require exactly bool. -struct NothrowBool { - explicit NothrowBool() = delete; - ~NothrowBool() = default; - - // TODO(calabrese) Delete the copy constructor in C++17 mode since guaranteed - // elision makes it not required when returning from a function. - // NothrowBool(NothrowBool const&) = delete; - - NothrowBool& operator=(NothrowBool const&) = delete; - - explicit operator bool() const noexcept { return value; } - - static NothrowBool make(bool const value) noexcept { - return NothrowBool(value); - } - - private: - explicit NothrowBool(bool const value) noexcept : value(value) {} - - bool value; -}; - -// A convertible-to-bool type that is used as the return type of comparison -// operators since the standard doesn't always require exactly bool. -// Note: ExceptionalBool has a conversion operator that is not noexcept, so -// that even when a comparison operator is noexcept, that operation may still -// potentially throw when converted to bool. -struct ExceptionalBool { - explicit ExceptionalBool() = delete; - ~ExceptionalBool() = default; - - // TODO(calabrese) Delete the copy constructor in C++17 mode since guaranteed - // elision makes it not required when returning from a function. - // ExceptionalBool(ExceptionalBool const&) = delete; - - ExceptionalBool& operator=(ExceptionalBool const&) = delete; - - explicit operator bool() const { return value; } // NOLINT - - static ExceptionalBool make(bool const value) noexcept { - return ExceptionalBool(value); - } - - private: - explicit ExceptionalBool(bool const value) noexcept : value(value) {} - - bool value; -}; - -// The following macro is only used as a helper in this file to stamp out -// comparison operator definitions. It is undefined after usage. -// -// NOTE: Non-nothrow operators throw via their result's conversion to bool even -// though the operation itself is noexcept. -#define ABSL_TYPES_INTERNAL_OP(enum_name, op) \ - template <class Prof> \ - absl::enable_if_t<!PropertiesOfT<Prof>::is_##enum_name, bool> operator op( \ - const Archetype<Prof>&, const Archetype<Prof>&) = delete; \ - \ - template <class Prof> \ - typename absl::enable_if_t< \ - PropertiesOfT<Prof>::is_##enum_name, \ - std::conditional<PropertiesOfT<Prof>::enum_name##_support == \ - enum_name::nothrow, \ - NothrowBool, ExceptionalBool>>::type \ - operator op(const Archetype<Prof>& lhs, \ - const Archetype<Prof>& rhs) noexcept { \ - return absl::conditional_t< \ - PropertiesOfT<Prof>::enum_name##_support == enum_name::nothrow, \ - NothrowBool, ExceptionalBool>::make(lhs.archetype_state op \ - rhs.archetype_state); \ - } - -ABSL_TYPES_INTERNAL_OP(equality_comparable, ==); -ABSL_TYPES_INTERNAL_OP(inequality_comparable, !=); -ABSL_TYPES_INTERNAL_OP(less_than_comparable, <); -ABSL_TYPES_INTERNAL_OP(less_equal_comparable, <=); -ABSL_TYPES_INTERNAL_OP(greater_equal_comparable, >=); -ABSL_TYPES_INTERNAL_OP(greater_than_comparable, >); - -#undef ABSL_TYPES_INTERNAL_OP - -// Base class for std::hash specializations when an Archetype doesn't support -// hashing. -struct PoisonedHash { - PoisonedHash() = delete; - PoisonedHash(const PoisonedHash&) = delete; - PoisonedHash& operator=(const PoisonedHash&) = delete; -}; - -// Base class for std::hash specializations when an Archetype supports hashing. -template <class Prof> -struct EnabledHash { - using argument_type = Archetype<Prof>; - using result_type = std::size_t; - result_type operator()(const argument_type& arg) const { - return std::hash<ArchetypeState>()(arg.archetype_state); - } -}; - -} // namespace types_internal -ABSL_NAMESPACE_END -} // namespace absl - -namespace std { - -template <class Prof> // NOLINT -struct hash<::absl::types_internal::Archetype<Prof>> - : conditional<::absl::types_internal::PropertiesOfT<Prof>::is_hashable, - ::absl::types_internal::EnabledHash<Prof>, - ::absl::types_internal::PoisonedHash>::type {}; - -} // namespace std - -#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_ARCHETYPE_H_ +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// conformance_archetype.h +// ----------------------------------------------------------------------------- +// +// This file contains a facility for generating "archetypes" of out of +// "Conformance Profiles" (see "conformance_profiles.h" for more information +// about Conformance Profiles). An archetype is a type that aims to support the +// bare minimum requirements of a given Conformance Profile. For instance, an +// archetype that corresponds to an ImmutableProfile has exactly a nothrow +// move-constructor, a potentially-throwing copy constructor, a nothrow +// destructor, with all other special-member-functions deleted. These archetypes +// are useful for testing to make sure that templates are able to work with the +// kinds of types that they claim to support (i.e. that they do not accidentally +// under-constrain), +// +// The main type template in this file is the Archetype template, which takes +// a Conformance Profile as a template argument and its instantiations are a +// minimum-conforming model of that profile. + +#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_ARCHETYPE_H_ +#define ABSL_TYPES_INTERNAL_CONFORMANCE_ARCHETYPE_H_ + +#include <cstddef> +#include <functional> +#include <type_traits> +#include <utility> + +#include "absl/meta/type_traits.h" +#include "absl/types/internal/conformance_profile.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace types_internal { + +// A minimum-conforming implementation of a type with properties specified in +// `Prof`, where `Prof` is a valid Conformance Profile. +template <class Prof, class /*Enabler*/ = void> +class Archetype; + +// Given an Archetype, obtain the properties of the profile associated with that +// archetype. +template <class Archetype> +struct PropertiesOfArchetype; + +template <class Prof> +struct PropertiesOfArchetype<Archetype<Prof>> { + using type = PropertiesOfT<Prof>; +}; + +template <class Archetype> +using PropertiesOfArchetypeT = typename PropertiesOfArchetype<Archetype>::type; + +// A metafunction to determine if a type is an `Archetype`. +template <class T> +struct IsArchetype : std::false_type {}; + +template <class Prof> +struct IsArchetype<Archetype<Prof>> : std::true_type {}; + +// A constructor tag type used when creating an Archetype with internal state. +struct MakeArchetypeState {}; + +// Data stored within an archetype that is copied/compared/hashed when the +// corresponding operations are used. +using ArchetypeState = std::size_t; + +//////////////////////////////////////////////////////////////////////////////// +// This section of the file defines a chain of base classes for Archetype, // +// where each base defines a specific special member function with the // +// appropriate properties (deleted, noexcept(false), noexcept, or trivial). // +//////////////////////////////////////////////////////////////////////////////// + +// The bottom-most base, which contains the state and the default constructor. +template <default_constructible DefaultConstructibleValue> +struct ArchetypeStateBase { + static_assert(DefaultConstructibleValue == default_constructible::yes || + DefaultConstructibleValue == default_constructible::nothrow, + ""); + + ArchetypeStateBase() noexcept( + DefaultConstructibleValue == + default_constructible:: + nothrow) /*Vacuous archetype_state initialization*/ {} + explicit ArchetypeStateBase(MakeArchetypeState, ArchetypeState state) noexcept + : archetype_state(state) {} + + ArchetypeState archetype_state; +}; + +template <> +struct ArchetypeStateBase<default_constructible::maybe> { + explicit ArchetypeStateBase() = delete; + explicit ArchetypeStateBase(MakeArchetypeState, ArchetypeState state) noexcept + : archetype_state(state) {} + + ArchetypeState archetype_state; +}; + +template <> +struct ArchetypeStateBase<default_constructible::trivial> { + ArchetypeStateBase() = default; + explicit ArchetypeStateBase(MakeArchetypeState, ArchetypeState state) noexcept + : archetype_state(state) {} + + ArchetypeState archetype_state; +}; + +// The move-constructor base +template <default_constructible DefaultConstructibleValue, + move_constructible MoveConstructibleValue> +struct ArchetypeMoveConstructor + : ArchetypeStateBase<DefaultConstructibleValue> { + static_assert(MoveConstructibleValue == move_constructible::yes || + MoveConstructibleValue == move_constructible::nothrow, + ""); + + explicit ArchetypeMoveConstructor(MakeArchetypeState, + ArchetypeState state) noexcept + : ArchetypeStateBase<DefaultConstructibleValue>(MakeArchetypeState(), + state) {} + + ArchetypeMoveConstructor() = default; + ArchetypeMoveConstructor(ArchetypeMoveConstructor&& other) noexcept( + MoveConstructibleValue == move_constructible::nothrow) + : ArchetypeStateBase<DefaultConstructibleValue>(MakeArchetypeState(), + other.archetype_state) {} + ArchetypeMoveConstructor(const ArchetypeMoveConstructor&) = default; + ArchetypeMoveConstructor& operator=(ArchetypeMoveConstructor&&) = default; + ArchetypeMoveConstructor& operator=(const ArchetypeMoveConstructor&) = + default; +}; + +template <default_constructible DefaultConstructibleValue> +struct ArchetypeMoveConstructor<DefaultConstructibleValue, + move_constructible::trivial> + : ArchetypeStateBase<DefaultConstructibleValue> { + explicit ArchetypeMoveConstructor(MakeArchetypeState, + ArchetypeState state) noexcept + : ArchetypeStateBase<DefaultConstructibleValue>(MakeArchetypeState(), + state) {} + + ArchetypeMoveConstructor() = default; +}; + +// The copy-constructor base +template <default_constructible DefaultConstructibleValue, + move_constructible MoveConstructibleValue, + copy_constructible CopyConstructibleValue> +struct ArchetypeCopyConstructor + : ArchetypeMoveConstructor<DefaultConstructibleValue, + MoveConstructibleValue> { + static_assert(CopyConstructibleValue == copy_constructible::yes || + CopyConstructibleValue == copy_constructible::nothrow, + ""); + explicit ArchetypeCopyConstructor(MakeArchetypeState, + ArchetypeState state) noexcept + : ArchetypeMoveConstructor<DefaultConstructibleValue, + MoveConstructibleValue>(MakeArchetypeState(), + state) {} + + ArchetypeCopyConstructor() = default; + ArchetypeCopyConstructor(ArchetypeCopyConstructor&&) = default; + ArchetypeCopyConstructor(const ArchetypeCopyConstructor& other) noexcept( + CopyConstructibleValue == copy_constructible::nothrow) + : ArchetypeMoveConstructor<DefaultConstructibleValue, + MoveConstructibleValue>( + MakeArchetypeState(), other.archetype_state) {} + ArchetypeCopyConstructor& operator=(ArchetypeCopyConstructor&&) = default; + ArchetypeCopyConstructor& operator=(const ArchetypeCopyConstructor&) = + default; +}; + +template <default_constructible DefaultConstructibleValue, + move_constructible MoveConstructibleValue> +struct ArchetypeCopyConstructor<DefaultConstructibleValue, + MoveConstructibleValue, + copy_constructible::maybe> + : ArchetypeMoveConstructor<DefaultConstructibleValue, + MoveConstructibleValue> { + explicit ArchetypeCopyConstructor(MakeArchetypeState, + ArchetypeState state) noexcept + : ArchetypeMoveConstructor<DefaultConstructibleValue, + MoveConstructibleValue>(MakeArchetypeState(), + state) {} + + ArchetypeCopyConstructor() = default; + ArchetypeCopyConstructor(ArchetypeCopyConstructor&&) = default; + ArchetypeCopyConstructor(const ArchetypeCopyConstructor&) = delete; + ArchetypeCopyConstructor& operator=(ArchetypeCopyConstructor&&) = default; + ArchetypeCopyConstructor& operator=(const ArchetypeCopyConstructor&) = + default; +}; + +template <default_constructible DefaultConstructibleValue, + move_constructible MoveConstructibleValue> +struct ArchetypeCopyConstructor<DefaultConstructibleValue, + MoveConstructibleValue, + copy_constructible::trivial> + : ArchetypeMoveConstructor<DefaultConstructibleValue, + MoveConstructibleValue> { + explicit ArchetypeCopyConstructor(MakeArchetypeState, + ArchetypeState state) noexcept + : ArchetypeMoveConstructor<DefaultConstructibleValue, + MoveConstructibleValue>(MakeArchetypeState(), + state) {} + + ArchetypeCopyConstructor() = default; +}; + +// The move-assign base +template <default_constructible DefaultConstructibleValue, + move_constructible MoveConstructibleValue, + copy_constructible CopyConstructibleValue, + move_assignable MoveAssignableValue> +struct ArchetypeMoveAssign + : ArchetypeCopyConstructor<DefaultConstructibleValue, + MoveConstructibleValue, CopyConstructibleValue> { + static_assert(MoveAssignableValue == move_assignable::yes || + MoveAssignableValue == move_assignable::nothrow, + ""); + explicit ArchetypeMoveAssign(MakeArchetypeState, + ArchetypeState state) noexcept + : ArchetypeCopyConstructor<DefaultConstructibleValue, + MoveConstructibleValue, + CopyConstructibleValue>(MakeArchetypeState(), + state) {} + + ArchetypeMoveAssign() = default; + ArchetypeMoveAssign(ArchetypeMoveAssign&&) = default; + ArchetypeMoveAssign(const ArchetypeMoveAssign&) = default; + ArchetypeMoveAssign& operator=(ArchetypeMoveAssign&& other) noexcept( + MoveAssignableValue == move_assignable::nothrow) { + this->archetype_state = other.archetype_state; + return *this; + } + + ArchetypeMoveAssign& operator=(const ArchetypeMoveAssign&) = default; +}; + +template <default_constructible DefaultConstructibleValue, + move_constructible MoveConstructibleValue, + copy_constructible CopyConstructibleValue> +struct ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, move_assignable::trivial> + : ArchetypeCopyConstructor<DefaultConstructibleValue, + MoveConstructibleValue, CopyConstructibleValue> { + explicit ArchetypeMoveAssign(MakeArchetypeState, + ArchetypeState state) noexcept + : ArchetypeCopyConstructor<DefaultConstructibleValue, + MoveConstructibleValue, + CopyConstructibleValue>(MakeArchetypeState(), + state) {} + + ArchetypeMoveAssign() = default; +}; + +// The copy-assign base +template <default_constructible DefaultConstructibleValue, + move_constructible MoveConstructibleValue, + copy_constructible CopyConstructibleValue, + move_assignable MoveAssignableValue, + copy_assignable CopyAssignableValue> +struct ArchetypeCopyAssign + : ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue> { + static_assert(CopyAssignableValue == copy_assignable::yes || + CopyAssignableValue == copy_assignable::nothrow, + ""); + explicit ArchetypeCopyAssign(MakeArchetypeState, + ArchetypeState state) noexcept + : ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue>( + MakeArchetypeState(), state) {} + + ArchetypeCopyAssign() = default; + ArchetypeCopyAssign(ArchetypeCopyAssign&&) = default; + ArchetypeCopyAssign(const ArchetypeCopyAssign&) = default; + ArchetypeCopyAssign& operator=(ArchetypeCopyAssign&&) = default; + + ArchetypeCopyAssign& operator=(const ArchetypeCopyAssign& other) noexcept( + CopyAssignableValue == copy_assignable::nothrow) { + this->archetype_state = other.archetype_state; + return *this; + } +}; + +template <default_constructible DefaultConstructibleValue, + move_constructible MoveConstructibleValue, + copy_constructible CopyConstructibleValue, + move_assignable MoveAssignableValue> +struct ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue, + copy_assignable::maybe> + : ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue> { + explicit ArchetypeCopyAssign(MakeArchetypeState, + ArchetypeState state) noexcept + : ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue>( + MakeArchetypeState(), state) {} + + ArchetypeCopyAssign() = default; + ArchetypeCopyAssign(ArchetypeCopyAssign&&) = default; + ArchetypeCopyAssign(const ArchetypeCopyAssign&) = default; + ArchetypeCopyAssign& operator=(ArchetypeCopyAssign&&) = default; + ArchetypeCopyAssign& operator=(const ArchetypeCopyAssign&) = delete; +}; + +template <default_constructible DefaultConstructibleValue, + move_constructible MoveConstructibleValue, + copy_constructible CopyConstructibleValue, + move_assignable MoveAssignableValue> +struct ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue, + copy_assignable::trivial> + : ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue> { + explicit ArchetypeCopyAssign(MakeArchetypeState, + ArchetypeState state) noexcept + : ArchetypeMoveAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue>( + MakeArchetypeState(), state) {} + + ArchetypeCopyAssign() = default; +}; + +// The destructor base +template <default_constructible DefaultConstructibleValue, + move_constructible MoveConstructibleValue, + copy_constructible CopyConstructibleValue, + move_assignable MoveAssignableValue, + copy_assignable CopyAssignableValue, destructible DestructibleValue> +struct ArchetypeDestructor + : ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue, + CopyAssignableValue> { + static_assert(DestructibleValue == destructible::yes || + DestructibleValue == destructible::nothrow, + ""); + + explicit ArchetypeDestructor(MakeArchetypeState, + ArchetypeState state) noexcept + : ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue, + CopyAssignableValue>(MakeArchetypeState(), state) {} + + ArchetypeDestructor() = default; + ArchetypeDestructor(ArchetypeDestructor&&) = default; + ArchetypeDestructor(const ArchetypeDestructor&) = default; + ArchetypeDestructor& operator=(ArchetypeDestructor&&) = default; + ArchetypeDestructor& operator=(const ArchetypeDestructor&) = default; + ~ArchetypeDestructor() noexcept(DestructibleValue == destructible::nothrow) {} +}; + +template <default_constructible DefaultConstructibleValue, + move_constructible MoveConstructibleValue, + copy_constructible CopyConstructibleValue, + move_assignable MoveAssignableValue, + copy_assignable CopyAssignableValue> +struct ArchetypeDestructor<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue, + CopyAssignableValue, destructible::trivial> + : ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue, + CopyAssignableValue> { + explicit ArchetypeDestructor(MakeArchetypeState, + ArchetypeState state) noexcept + : ArchetypeCopyAssign<DefaultConstructibleValue, MoveConstructibleValue, + CopyConstructibleValue, MoveAssignableValue, + CopyAssignableValue>(MakeArchetypeState(), state) {} + + ArchetypeDestructor() = default; +}; + +// An alias to the top of the chain of bases for special-member functions. +// NOTE: move_constructible::maybe, move_assignable::maybe, and +// destructible::maybe are handled in the top-level type by way of SFINAE. +// Because of this, we never instantiate the base classes with +// move_constructible::maybe, move_assignable::maybe, or destructible::maybe so +// that we minimize the number of different possible type-template +// instantiations. +template <default_constructible DefaultConstructibleValue, + move_constructible MoveConstructibleValue, + copy_constructible CopyConstructibleValue, + move_assignable MoveAssignableValue, + copy_assignable CopyAssignableValue, destructible DestructibleValue> +using ArchetypeSpecialMembersBase = ArchetypeDestructor< + DefaultConstructibleValue, + MoveConstructibleValue != move_constructible::maybe + ? MoveConstructibleValue + : move_constructible::nothrow, + CopyConstructibleValue, + MoveAssignableValue != move_assignable::maybe ? MoveAssignableValue + : move_assignable::nothrow, + CopyAssignableValue, + DestructibleValue != destructible::maybe ? DestructibleValue + : destructible::nothrow>; + +// A function that is used to create an archetype with some associated state. +template <class Arch> +Arch MakeArchetype(ArchetypeState state) noexcept { + static_assert(IsArchetype<Arch>::value, + "The explicit template argument to MakeArchetype is required " + "to be an Archetype."); + return Arch(MakeArchetypeState(), state); +} + +// This is used to conditionally delete "copy" and "move" constructors in a way +// that is consistent with what the ConformanceProfile requires and that also +// strictly enforces the arguments to the copy/move to not come from implicit +// conversions when dealing with the Archetype. +template <class Prof, class T> +constexpr bool ShouldDeleteConstructor() { + return !((PropertiesOfT<Prof>::move_constructible_support != + move_constructible::maybe && + std::is_same<T, Archetype<Prof>>::value) || + (PropertiesOfT<Prof>::copy_constructible_support != + copy_constructible::maybe && + (std::is_same<T, const Archetype<Prof>&>::value || + std::is_same<T, Archetype<Prof>&>::value || + std::is_same<T, const Archetype<Prof>>::value))); +} + +// This is used to conditionally delete "copy" and "move" assigns in a way +// that is consistent with what the ConformanceProfile requires and that also +// strictly enforces the arguments to the copy/move to not come from implicit +// conversions when dealing with the Archetype. +template <class Prof, class T> +constexpr bool ShouldDeleteAssign() { + return !( + (PropertiesOfT<Prof>::move_assignable_support != move_assignable::maybe && + std::is_same<T, Archetype<Prof>>::value) || + (PropertiesOfT<Prof>::copy_assignable_support != copy_assignable::maybe && + (std::is_same<T, const Archetype<Prof>&>::value || + std::is_same<T, Archetype<Prof>&>::value || + std::is_same<T, const Archetype<Prof>>::value))); +} + +// TODO(calabrese) Inherit from a chain of secondary bases to pull in the +// associated functions of other concepts. +template <class Prof, class Enabler> +class Archetype : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support> { + static_assert(std::is_same<Enabler, void>::value, + "An explicit type must not be passed as the second template " + "argument to 'Archetype`."); + + // The cases mentioned in these static_asserts are expected to be handled in + // the partial template specializations of Archetype that follow this + // definition. + static_assert(PropertiesOfT<Prof>::destructible_support != + destructible::maybe, + ""); + static_assert(PropertiesOfT<Prof>::move_constructible_support != + move_constructible::maybe || + PropertiesOfT<Prof>::copy_constructible_support == + copy_constructible::maybe, + ""); + static_assert(PropertiesOfT<Prof>::move_assignable_support != + move_assignable::maybe || + PropertiesOfT<Prof>::copy_assignable_support == + copy_assignable::maybe, + ""); + + public: + Archetype() = default; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> + Archetype(T&&) = delete; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteAssign<Prof, T>()>::type* = nullptr> + Archetype& operator=(T&&) = delete; + + using ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>::archetype_state; + + private: + explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), + state) {} + + friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; +}; + +template <class Prof> +class Archetype<Prof, typename std::enable_if< + PropertiesOfT<Prof>::move_constructible_support != + move_constructible::maybe && + PropertiesOfT<Prof>::move_assignable_support == + move_assignable::maybe && + PropertiesOfT<Prof>::destructible_support != + destructible::maybe>::type> + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support> { + public: + Archetype() = default; + Archetype(Archetype&&) = default; + Archetype(const Archetype&) = default; + Archetype& operator=(Archetype&&) = delete; + Archetype& operator=(const Archetype&) = default; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> + Archetype(T&&) = delete; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteAssign<Prof, T>()>::type* = nullptr> + Archetype& operator=(T&&) = delete; + + using ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>::archetype_state; + + private: + explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), + state) {} + + friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; +}; + +template <class Prof> +class Archetype<Prof, typename std::enable_if< + PropertiesOfT<Prof>::move_constructible_support == + move_constructible::maybe && + PropertiesOfT<Prof>::move_assignable_support == + move_assignable::maybe && + PropertiesOfT<Prof>::destructible_support != + destructible::maybe>::type> + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support> { + public: + Archetype() = default; + Archetype(Archetype&&) = delete; + Archetype(const Archetype&) = default; + Archetype& operator=(Archetype&&) = delete; + Archetype& operator=(const Archetype&) = default; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> + Archetype(T&&) = delete; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteAssign<Prof, T>()>::type* = nullptr> + Archetype& operator=(T&&) = delete; + + using ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>::archetype_state; + + private: + explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), + state) {} + + friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; +}; + +template <class Prof> +class Archetype<Prof, typename std::enable_if< + PropertiesOfT<Prof>::move_constructible_support == + move_constructible::maybe && + PropertiesOfT<Prof>::move_assignable_support != + move_assignable::maybe && + PropertiesOfT<Prof>::destructible_support != + destructible::maybe>::type> + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support> { + public: + Archetype() = default; + Archetype(Archetype&&) = delete; + Archetype(const Archetype&) = default; + Archetype& operator=(Archetype&&) = default; + Archetype& operator=(const Archetype&) = default; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> + Archetype(T&&) = delete; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteAssign<Prof, T>()>::type* = nullptr> + Archetype& operator=(T&&) = delete; + + using ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>::archetype_state; + + private: + explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), + state) {} + + friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; +}; + +template <class Prof> +class Archetype<Prof, typename std::enable_if< + PropertiesOfT<Prof>::move_constructible_support != + move_constructible::maybe && + PropertiesOfT<Prof>::move_assignable_support == + move_assignable::maybe && + PropertiesOfT<Prof>::destructible_support == + destructible::maybe>::type> + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support> { + public: + Archetype() = default; + Archetype(Archetype&&) = default; + Archetype(const Archetype&) = default; + Archetype& operator=(Archetype&&) = delete; + Archetype& operator=(const Archetype&) = default; + ~Archetype() = delete; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> + Archetype(T&&) = delete; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteAssign<Prof, T>()>::type* = nullptr> + Archetype& operator=(T&&) = delete; + + using ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>::archetype_state; + + private: + explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), + state) {} + + friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; +}; + +template <class Prof> +class Archetype<Prof, typename std::enable_if< + PropertiesOfT<Prof>::move_constructible_support == + move_constructible::maybe && + PropertiesOfT<Prof>::move_assignable_support == + move_assignable::maybe && + PropertiesOfT<Prof>::destructible_support == + destructible::maybe>::type> + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support> { + public: + Archetype() = default; + Archetype(Archetype&&) = delete; + Archetype(const Archetype&) = default; + Archetype& operator=(Archetype&&) = delete; + Archetype& operator=(const Archetype&) = default; + ~Archetype() = delete; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> + Archetype(T&&) = delete; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteAssign<Prof, T>()>::type* = nullptr> + Archetype& operator=(T&&) = delete; + + using ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>::archetype_state; + + private: + explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), + state) {} + + friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; +}; + +template <class Prof> +class Archetype<Prof, typename std::enable_if< + PropertiesOfT<Prof>::move_constructible_support == + move_constructible::maybe && + PropertiesOfT<Prof>::move_assignable_support != + move_assignable::maybe && + PropertiesOfT<Prof>::destructible_support == + destructible::maybe>::type> + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support> { + public: + Archetype() = default; + Archetype(Archetype&&) = delete; + Archetype(const Archetype&) = default; + Archetype& operator=(Archetype&&) = default; + Archetype& operator=(const Archetype&) = default; + ~Archetype() = delete; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteConstructor<Prof, T>()>::type* = nullptr> + Archetype(T&&) = delete; + + // Disallow moves when requested, and disallow implicit conversions. + template <class T, typename std::enable_if< + ShouldDeleteAssign<Prof, T>()>::type* = nullptr> + Archetype& operator=(T&&) = delete; + + using ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>::archetype_state; + + private: + explicit Archetype(MakeArchetypeState, ArchetypeState state) noexcept + : ArchetypeSpecialMembersBase< + PropertiesOfT<Prof>::default_constructible_support, + PropertiesOfT<Prof>::move_constructible_support, + PropertiesOfT<Prof>::copy_constructible_support, + PropertiesOfT<Prof>::move_assignable_support, + PropertiesOfT<Prof>::copy_assignable_support, + PropertiesOfT<Prof>::destructible_support>(MakeArchetypeState(), + state) {} + + friend Archetype MakeArchetype<Archetype>(ArchetypeState) noexcept; +}; + +// Explicitly deleted swap for Archetype if the profile does not require swap. +// It is important to delete it rather than simply leave it out so that the +// "using std::swap;" idiom will result in this deleted overload being picked. +template <class Prof, + absl::enable_if_t<!PropertiesOfT<Prof>::is_swappable, int> = 0> +void swap(Archetype<Prof>&, Archetype<Prof>&) = delete; // NOLINT + +// A conditionally-noexcept swap implementation for Archetype when the profile +// supports swap. +template <class Prof, + absl::enable_if_t<PropertiesOfT<Prof>::is_swappable, int> = 0> +void swap(Archetype<Prof>& lhs, Archetype<Prof>& rhs) // NOLINT + noexcept(PropertiesOfT<Prof>::swappable_support != swappable::yes) { + std::swap(lhs.archetype_state, rhs.archetype_state); +} + +// A convertible-to-bool type that is used as the return type of comparison +// operators since the standard doesn't always require exactly bool. +struct NothrowBool { + explicit NothrowBool() = delete; + ~NothrowBool() = default; + + // TODO(calabrese) Delete the copy constructor in C++17 mode since guaranteed + // elision makes it not required when returning from a function. + // NothrowBool(NothrowBool const&) = delete; + + NothrowBool& operator=(NothrowBool const&) = delete; + + explicit operator bool() const noexcept { return value; } + + static NothrowBool make(bool const value) noexcept { + return NothrowBool(value); + } + + private: + explicit NothrowBool(bool const value) noexcept : value(value) {} + + bool value; +}; + +// A convertible-to-bool type that is used as the return type of comparison +// operators since the standard doesn't always require exactly bool. +// Note: ExceptionalBool has a conversion operator that is not noexcept, so +// that even when a comparison operator is noexcept, that operation may still +// potentially throw when converted to bool. +struct ExceptionalBool { + explicit ExceptionalBool() = delete; + ~ExceptionalBool() = default; + + // TODO(calabrese) Delete the copy constructor in C++17 mode since guaranteed + // elision makes it not required when returning from a function. + // ExceptionalBool(ExceptionalBool const&) = delete; + + ExceptionalBool& operator=(ExceptionalBool const&) = delete; + + explicit operator bool() const { return value; } // NOLINT + + static ExceptionalBool make(bool const value) noexcept { + return ExceptionalBool(value); + } + + private: + explicit ExceptionalBool(bool const value) noexcept : value(value) {} + + bool value; +}; + +// The following macro is only used as a helper in this file to stamp out +// comparison operator definitions. It is undefined after usage. +// +// NOTE: Non-nothrow operators throw via their result's conversion to bool even +// though the operation itself is noexcept. +#define ABSL_TYPES_INTERNAL_OP(enum_name, op) \ + template <class Prof> \ + absl::enable_if_t<!PropertiesOfT<Prof>::is_##enum_name, bool> operator op( \ + const Archetype<Prof>&, const Archetype<Prof>&) = delete; \ + \ + template <class Prof> \ + typename absl::enable_if_t< \ + PropertiesOfT<Prof>::is_##enum_name, \ + std::conditional<PropertiesOfT<Prof>::enum_name##_support == \ + enum_name::nothrow, \ + NothrowBool, ExceptionalBool>>::type \ + operator op(const Archetype<Prof>& lhs, \ + const Archetype<Prof>& rhs) noexcept { \ + return absl::conditional_t< \ + PropertiesOfT<Prof>::enum_name##_support == enum_name::nothrow, \ + NothrowBool, ExceptionalBool>::make(lhs.archetype_state op \ + rhs.archetype_state); \ + } + +ABSL_TYPES_INTERNAL_OP(equality_comparable, ==); +ABSL_TYPES_INTERNAL_OP(inequality_comparable, !=); +ABSL_TYPES_INTERNAL_OP(less_than_comparable, <); +ABSL_TYPES_INTERNAL_OP(less_equal_comparable, <=); +ABSL_TYPES_INTERNAL_OP(greater_equal_comparable, >=); +ABSL_TYPES_INTERNAL_OP(greater_than_comparable, >); + +#undef ABSL_TYPES_INTERNAL_OP + +// Base class for std::hash specializations when an Archetype doesn't support +// hashing. +struct PoisonedHash { + PoisonedHash() = delete; + PoisonedHash(const PoisonedHash&) = delete; + PoisonedHash& operator=(const PoisonedHash&) = delete; +}; + +// Base class for std::hash specializations when an Archetype supports hashing. +template <class Prof> +struct EnabledHash { + using argument_type = Archetype<Prof>; + using result_type = std::size_t; + result_type operator()(const argument_type& arg) const { + return std::hash<ArchetypeState>()(arg.archetype_state); + } +}; + +} // namespace types_internal +ABSL_NAMESPACE_END +} // namespace absl + +namespace std { + +template <class Prof> // NOLINT +struct hash<::absl::types_internal::Archetype<Prof>> + : conditional<::absl::types_internal::PropertiesOfT<Prof>::is_hashable, + ::absl::types_internal::EnabledHash<Prof>, + ::absl::types_internal::PoisonedHash>::type {}; + +} // namespace std + +#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_ARCHETYPE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/conformance_profile.h b/contrib/restricted/abseil-cpp/absl/types/internal/conformance_profile.h index cf64ff4fcd..f378ac8b02 100644 --- a/contrib/restricted/abseil-cpp/absl/types/internal/conformance_profile.h +++ b/contrib/restricted/abseil-cpp/absl/types/internal/conformance_profile.h @@ -1,931 +1,931 @@ -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// conformance_profiles.h -// ----------------------------------------------------------------------------- -// -// This file contains templates for representing "Regularity Profiles" and -// concisely-named versions of commonly used Regularity Profiles. -// -// A Regularity Profile is a compile-time description of the types of operations -// that a given type supports, along with properties of those operations when -// they do exist. For instance, a Regularity Profile may describe a type that -// has a move-constructor that is noexcept and a copy constructor that is not -// noexcept. This description can then be examined and passed around to other -// templates for the purposes of asserting expectations on user-defined types -// via a series trait checks, or for determining what kinds of run-time tests -// are able to be performed. -// -// Regularity Profiles are also used when creating "archetypes," which are -// minimum-conforming types that meet all of the requirements of a given -// Regularity Profile. For more information regarding archetypes, see -// "conformance_archetypes.h". - -#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_PROFILE_H_ -#define ABSL_TYPES_INTERNAL_CONFORMANCE_PROFILE_H_ - -#include <set> -#include <type_traits> -#include <utility> -#include <vector> - -#include "gtest/gtest.h" -#include "absl/algorithm/container.h" -#include "absl/meta/type_traits.h" -#include "absl/strings/ascii.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "absl/types/internal/conformance_testing_helpers.h" -#include "absl/utility/utility.h" - -// TODO(calabrese) Add support for extending profiles. - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace types_internal { - -// Converts an enum to its underlying integral value. -template <typename Enum> -constexpr absl::underlying_type_t<Enum> UnderlyingValue(Enum value) { - return static_cast<absl::underlying_type_t<Enum>>(value); -} - -// A tag type used in place of a matcher when checking that an assertion result -// does not actually contain any errors. -struct NoError {}; - -// ----------------------------------------------------------------------------- -// ConformanceErrors -// ----------------------------------------------------------------------------- -class ConformanceErrors { - public: - // Setup the error reporting mechanism by seeding it with the name of the type - // that is being tested. - explicit ConformanceErrors(std::string type_name) - : assertion_result_(false), type_name_(std::move(type_name)) { - assertion_result_ << "\n\n" - "Assuming the following type alias:\n" - "\n" - " using _T = " - << type_name_ << ";\n\n"; - outputDivider(); - } - - // Adds the test name to the list of successfully run tests iff it was not - // previously reported as failing. This behavior is useful for tests that - // have multiple parts, where failures and successes are reported individually - // with the same test name. - void addTestSuccess(absl::string_view test_name) { - auto normalized_test_name = absl::AsciiStrToLower(test_name); - - // If the test is already reported as failing, do not add it to the list of - // successes. - if (test_failures_.find(normalized_test_name) == test_failures_.end()) { - test_successes_.insert(std::move(normalized_test_name)); - } - } - - // Streams a single error description into the internal buffer (a visual - // divider is automatically inserted after the error so that multiple errors - // are visibly distinct). - // - // This function increases the error count by 1. - // - // TODO(calabrese) Determine desired behavior when if this function throws. - template <class... P> - void addTestFailure(absl::string_view test_name, const P&... args) { - // Output a message related to the test failure. - assertion_result_ << "\n\n" - "Failed test: " - << test_name << "\n\n"; - addTestFailureImpl(args...); - assertion_result_ << "\n\n"; - outputDivider(); - - auto normalized_test_name = absl::AsciiStrToLower(test_name); - - // If previous parts of this test succeeded, remove it from that set. - test_successes_.erase(normalized_test_name); - - // Add the test name to the list of failed tests. - test_failures_.insert(std::move(normalized_test_name)); - - has_error_ = true; - } - - // Convert this object into a testing::AssertionResult instance such that it - // can be used with gtest. - ::testing::AssertionResult assertionResult() const { - return has_error_ ? assertion_result_ : ::testing::AssertionSuccess(); - } - - // Convert this object into a testing::AssertionResult instance such that it - // can be used with gtest. This overload expects errors, using the specified - // matcher. - ::testing::AssertionResult expectFailedTests( - const std::set<std::string>& test_names) const { - // Since we are expecting nonconformance, output an error message when the - // type actually conformed to the specified profile. - if (!has_error_) { - return ::testing::AssertionFailure() - << "Unexpected conformance of type:\n" - " " - << type_name_ << "\n\n"; - } - - // Get a list of all expected failures that did not actually fail - // (or that were not run). - std::vector<std::string> nonfailing_tests; - absl::c_set_difference(test_names, test_failures_, - std::back_inserter(nonfailing_tests)); - - // Get a list of all "expected failures" that were never actually run. - std::vector<std::string> unrun_tests; - absl::c_set_difference(nonfailing_tests, test_successes_, - std::back_inserter(unrun_tests)); - - // Report when the user specified tests that were not run. - if (!unrun_tests.empty()) { - const bool tests_were_run = - !(test_failures_.empty() && test_successes_.empty()); - - // Prepare an assertion result used in the case that tests pass that were - // expected to fail. - ::testing::AssertionResult result = ::testing::AssertionFailure(); - result << "When testing type:\n " << type_name_ - << "\n\nThe following tests were expected to fail but were not " - "run"; - - if (tests_were_run) result << " (was the test name spelled correctly?)"; - - result << ":\n\n"; - - // List all of the tests that unexpectedly passed. - for (const auto& test_name : unrun_tests) { - result << " " << test_name << "\n"; - } - - if (!tests_were_run) result << "\nNo tests were run."; - - if (!test_failures_.empty()) { - // List test failures - result << "\nThe tests that were run and failed are:\n\n"; - for (const auto& test_name : test_failures_) { - result << " " << test_name << "\n"; - } - } - - if (!test_successes_.empty()) { - // List test successes - result << "\nThe tests that were run and succeeded are:\n\n"; - for (const auto& test_name : test_successes_) { - result << " " << test_name << "\n"; - } - } - - return result; - } - - // If some tests passed when they were expected to fail, alert the caller. - if (nonfailing_tests.empty()) return ::testing::AssertionSuccess(); - - // Prepare an assertion result used in the case that tests pass that were - // expected to fail. - ::testing::AssertionResult unexpected_successes = - ::testing::AssertionFailure(); - unexpected_successes << "When testing type:\n " << type_name_ - << "\n\nThe following tests passed when they were " - "expected to fail:\n\n"; - - // List all of the tests that unexpectedly passed. - for (const auto& test_name : nonfailing_tests) { - unexpected_successes << " " << test_name << "\n"; - } - - return unexpected_successes; - } - - private: - void outputDivider() { - assertion_result_ << "========================================"; - } - - void addTestFailureImpl() {} - - template <class H, class... T> - void addTestFailureImpl(const H& head, const T&... tail) { - assertion_result_ << head; - addTestFailureImpl(tail...); - } - - ::testing::AssertionResult assertion_result_; - std::set<std::string> test_failures_; - std::set<std::string> test_successes_; - std::string type_name_; - bool has_error_ = false; -}; - -template <class T, class /*Enabler*/ = void> -struct PropertiesOfImpl {}; - -template <class T> -struct PropertiesOfImpl<T, absl::void_t<typename T::properties>> { - using type = typename T::properties; -}; - -template <class T> -struct PropertiesOfImpl<T, absl::void_t<typename T::profile_alias_of>> { - using type = typename PropertiesOfImpl<typename T::profile_alias_of>::type; -}; - -template <class T> -struct PropertiesOf : PropertiesOfImpl<T> {}; - -template <class T> -using PropertiesOfT = typename PropertiesOf<T>::type; - -// NOTE: These enums use this naming convention to be consistent with the -// standard trait names, which is useful since it allows us to match up each -// enum name with a corresponding trait name in macro definitions. - -// An enum that describes the various expectations on an operations existence. -enum class function_support { maybe, yes, nothrow, trivial }; - -constexpr const char* PessimisticPropertyDescription(function_support v) { - return v == function_support::maybe - ? "no" - : v == function_support::yes - ? "yes, potentially throwing" - : v == function_support::nothrow ? "yes, nothrow" - : "yes, trivial"; -} - -// Return a string that describes the kind of property support that was -// expected. -inline std::string ExpectedFunctionKindList(function_support min, - function_support max) { - if (min == max) { - std::string result = - absl::StrCat("Expected:\n ", - PessimisticPropertyDescription( - static_cast<function_support>(UnderlyingValue(min))), - "\n"); - return result; - } - - std::string result = "Expected one of:\n"; - for (auto curr_support = UnderlyingValue(min); - curr_support <= UnderlyingValue(max); ++curr_support) { - absl::StrAppend(&result, " ", - PessimisticPropertyDescription( - static_cast<function_support>(curr_support)), - "\n"); - } - - return result; -} - -template <class Enum> -void ExpectModelOfImpl(ConformanceErrors* errors, Enum min_support, - Enum max_support, Enum kind) { - const auto kind_value = UnderlyingValue(kind); - const auto min_support_value = UnderlyingValue(min_support); - const auto max_support_value = UnderlyingValue(max_support); - - if (!(kind_value >= min_support_value && kind_value <= max_support_value)) { - errors->addTestFailure( - PropertyName(kind), "**Failed property expectation**\n\n", - ExpectedFunctionKindList( - static_cast<function_support>(min_support_value), - static_cast<function_support>(max_support_value)), - '\n', "Actual:\n ", - PessimisticPropertyDescription( - static_cast<function_support>(kind_value))); - } else { - errors->addTestSuccess(PropertyName(kind)); - } -} - -#define ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM(description, name) \ - enum class name { maybe, yes, nothrow, trivial }; \ - \ - constexpr const char* PropertyName(name v) { return description; } \ - static_assert(true, "") // Force a semicolon when using this macro. - -ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM("support for default construction", - default_constructible); -ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM("support for move construction", - move_constructible); -ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM("support for copy construction", - copy_constructible); -ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM("support for move assignment", - move_assignable); -ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM("support for copy assignment", - copy_assignable); -ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM("support for destruction", - destructible); - -#undef ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM - -#define ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM(description, name) \ - enum class name { maybe, yes, nothrow }; \ - \ - constexpr const char* PropertyName(name v) { return description; } \ - static_assert(true, "") // Force a semicolon when using this macro. - -ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for ==", equality_comparable); -ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for !=", inequality_comparable); -ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for <", less_than_comparable); -ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for <=", less_equal_comparable); -ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for >=", - greater_equal_comparable); -ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for >", greater_than_comparable); - -ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for swap", swappable); - -#undef ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM - -enum class hashable { maybe, yes }; - -constexpr const char* PropertyName(hashable v) { - return "support for std::hash"; -} - -template <class T> -using AlwaysFalse = std::false_type; - -#define ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(name, property) \ - template <class T> \ - constexpr property property##_support_of() { \ - return std::is_##property<T>::value \ - ? std::is_nothrow_##property<T>::value \ - ? absl::is_trivially_##property<T>::value \ - ? property::trivial \ - : property::nothrow \ - : property::yes \ - : property::maybe; \ - } \ - \ - template <class T, class MinProf, class MaxProf> \ - void ExpectModelOf##name(ConformanceErrors* errors) { \ - (ExpectModelOfImpl)(errors, PropertiesOfT<MinProf>::property##_support, \ - PropertiesOfT<MaxProf>::property##_support, \ - property##_support_of<T>()); \ - } - -ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(DefaultConstructible, - default_constructible); - -ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(MoveConstructible, - move_constructible); - -ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(CopyConstructible, - copy_constructible); - -ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(MoveAssignable, - move_assignable); - -ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(CopyAssignable, - copy_assignable); - -ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(Destructible, destructible); - -#undef ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER - -void BoolFunction(bool) noexcept; - -//////////////////////////////////////////////////////////////////////////////// -// -// A metafunction for checking if an operation exists through SFINAE. -// -// `T` is the type to test and Op is an alias containing the expression to test. -template <class T, template <class...> class Op, class = void> -struct IsOpableImpl : std::false_type {}; - -template <class T, template <class...> class Op> -struct IsOpableImpl<T, Op, absl::void_t<Op<T>>> : std::true_type {}; - -template <template <class...> class Op> -struct IsOpable { - template <class T> - using apply = typename IsOpableImpl<T, Op>::type; -}; -// -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -// -// A metafunction for checking if an operation exists and is also noexcept -// through SFINAE and the noexcept operator. -/// -// `T` is the type to test and Op is an alias containing the expression to test. -template <class T, template <class...> class Op, class = void> -struct IsNothrowOpableImpl : std::false_type {}; - -template <class T, template <class...> class Op> -struct IsNothrowOpableImpl<T, Op, absl::enable_if_t<Op<T>::value>> - : std::true_type {}; - -template <template <class...> class Op> -struct IsNothrowOpable { - template <class T> - using apply = typename IsNothrowOpableImpl<T, Op>::type; -}; -// -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -// -// A macro that produces the necessary function for reporting what kind of -// support a specific comparison operation has and a function for reporting an -// error if a given type's support for that operation does not meet the expected -// requirements. -#define ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(name, property, op) \ - template <class T, \ - class Result = std::integral_constant< \ - bool, noexcept((BoolFunction)(std::declval<const T&>() op \ - std::declval<const T&>()))>> \ - using name = Result; \ - \ - template <class T> \ - constexpr property property##_support_of() { \ - return IsOpable<name>::apply<T>::value \ - ? IsNothrowOpable<name>::apply<T>::value ? property::nothrow \ - : property::yes \ - : property::maybe; \ - } \ - \ - template <class T, class MinProf, class MaxProf> \ - void ExpectModelOf##name(ConformanceErrors* errors) { \ - (ExpectModelOfImpl)(errors, PropertiesOfT<MinProf>::property##_support, \ - PropertiesOfT<MaxProf>::property##_support, \ - property##_support_of<T>()); \ - } -// -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -// -// Generate the necessary support-checking and error reporting functions for -// each of the comparison operators. -ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(EqualityComparable, - equality_comparable, ==); - -ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(InequalityComparable, - inequality_comparable, !=); - -ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(LessThanComparable, - less_than_comparable, <); - -ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(LessEqualComparable, - less_equal_comparable, <=); - -ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(GreaterEqualComparable, - greater_equal_comparable, >=); - -ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(GreaterThanComparable, - greater_than_comparable, >); - -#undef ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON -// -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -// -// The necessary support-checking and error-reporting functions for swap. -template <class T> -constexpr swappable swappable_support_of() { - return type_traits_internal::IsSwappable<T>::value - ? type_traits_internal::IsNothrowSwappable<T>::value - ? swappable::nothrow - : swappable::yes - : swappable::maybe; -} - -template <class T, class MinProf, class MaxProf> -void ExpectModelOfSwappable(ConformanceErrors* errors) { - (ExpectModelOfImpl)(errors, PropertiesOfT<MinProf>::swappable_support, - PropertiesOfT<MaxProf>::swappable_support, - swappable_support_of<T>()); -} -// -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -// -// The necessary support-checking and error-reporting functions for std::hash. -template <class T> -constexpr hashable hashable_support_of() { - return type_traits_internal::IsHashable<T>::value ? hashable::yes - : hashable::maybe; -} - -template <class T, class MinProf, class MaxProf> -void ExpectModelOfHashable(ConformanceErrors* errors) { - (ExpectModelOfImpl)(errors, PropertiesOfT<MinProf>::hashable_support, - PropertiesOfT<MaxProf>::hashable_support, - hashable_support_of<T>()); -} -// -//////////////////////////////////////////////////////////////////////////////// - -template < - default_constructible DefaultConstructibleValue = - default_constructible::maybe, - move_constructible MoveConstructibleValue = move_constructible::maybe, - copy_constructible CopyConstructibleValue = copy_constructible::maybe, - move_assignable MoveAssignableValue = move_assignable::maybe, - copy_assignable CopyAssignableValue = copy_assignable::maybe, - destructible DestructibleValue = destructible::maybe, - equality_comparable EqualityComparableValue = equality_comparable::maybe, - inequality_comparable InequalityComparableValue = - inequality_comparable::maybe, - less_than_comparable LessThanComparableValue = less_than_comparable::maybe, - less_equal_comparable LessEqualComparableValue = - less_equal_comparable::maybe, - greater_equal_comparable GreaterEqualComparableValue = - greater_equal_comparable::maybe, - greater_than_comparable GreaterThanComparableValue = - greater_than_comparable::maybe, - swappable SwappableValue = swappable::maybe, - hashable HashableValue = hashable::maybe> -struct ConformanceProfile { - using properties = ConformanceProfile; - - static constexpr default_constructible - default_constructible_support = // NOLINT - DefaultConstructibleValue; - - static constexpr move_constructible move_constructible_support = // NOLINT - MoveConstructibleValue; - - static constexpr copy_constructible copy_constructible_support = // NOLINT - CopyConstructibleValue; - - static constexpr move_assignable move_assignable_support = // NOLINT - MoveAssignableValue; - - static constexpr copy_assignable copy_assignable_support = // NOLINT - CopyAssignableValue; - - static constexpr destructible destructible_support = // NOLINT - DestructibleValue; - - static constexpr equality_comparable equality_comparable_support = // NOLINT - EqualityComparableValue; - - static constexpr inequality_comparable - inequality_comparable_support = // NOLINT - InequalityComparableValue; - - static constexpr less_than_comparable - less_than_comparable_support = // NOLINT - LessThanComparableValue; - - static constexpr less_equal_comparable - less_equal_comparable_support = // NOLINT - LessEqualComparableValue; - - static constexpr greater_equal_comparable - greater_equal_comparable_support = // NOLINT - GreaterEqualComparableValue; - - static constexpr greater_than_comparable - greater_than_comparable_support = // NOLINT - GreaterThanComparableValue; - - static constexpr swappable swappable_support = SwappableValue; // NOLINT - - static constexpr hashable hashable_support = HashableValue; // NOLINT - - static constexpr bool is_default_constructible = // NOLINT - DefaultConstructibleValue != default_constructible::maybe; - - static constexpr bool is_move_constructible = // NOLINT - MoveConstructibleValue != move_constructible::maybe; - - static constexpr bool is_copy_constructible = // NOLINT - CopyConstructibleValue != copy_constructible::maybe; - - static constexpr bool is_move_assignable = // NOLINT - MoveAssignableValue != move_assignable::maybe; - - static constexpr bool is_copy_assignable = // NOLINT - CopyAssignableValue != copy_assignable::maybe; - - static constexpr bool is_destructible = // NOLINT - DestructibleValue != destructible::maybe; - - static constexpr bool is_equality_comparable = // NOLINT - EqualityComparableValue != equality_comparable::maybe; - - static constexpr bool is_inequality_comparable = // NOLINT - InequalityComparableValue != inequality_comparable::maybe; - - static constexpr bool is_less_than_comparable = // NOLINT - LessThanComparableValue != less_than_comparable::maybe; - - static constexpr bool is_less_equal_comparable = // NOLINT - LessEqualComparableValue != less_equal_comparable::maybe; - - static constexpr bool is_greater_equal_comparable = // NOLINT - GreaterEqualComparableValue != greater_equal_comparable::maybe; - - static constexpr bool is_greater_than_comparable = // NOLINT - GreaterThanComparableValue != greater_than_comparable::maybe; - - static constexpr bool is_swappable = // NOLINT - SwappableValue != swappable::maybe; - - static constexpr bool is_hashable = // NOLINT - HashableValue != hashable::maybe; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -// Compliant SFINAE-friendliness is not always present on the standard library -// implementations that we support. This helper-struct (and associated enum) is -// used as a means to conditionally check the hashability support of a type. -enum class CheckHashability { no, yes }; - -template <class T, CheckHashability ShouldCheckHashability> -struct conservative_hashable_support_of; - -template <class T> -struct conservative_hashable_support_of<T, CheckHashability::no> { - static constexpr hashable Invoke() { return hashable::maybe; } -}; - -template <class T> -struct conservative_hashable_support_of<T, CheckHashability::yes> { - static constexpr hashable Invoke() { return hashable_support_of<T>(); } -}; -// -//////////////////////////////////////////////////////////////////////////////// - -// The ConformanceProfile that is expected based on introspection into the type -// by way of trait checks. -template <class T, CheckHashability ShouldCheckHashability> -struct SyntacticConformanceProfileOf { - using properties = ConformanceProfile< - default_constructible_support_of<T>(), move_constructible_support_of<T>(), - copy_constructible_support_of<T>(), move_assignable_support_of<T>(), - copy_assignable_support_of<T>(), destructible_support_of<T>(), - equality_comparable_support_of<T>(), - inequality_comparable_support_of<T>(), - less_than_comparable_support_of<T>(), - less_equal_comparable_support_of<T>(), - greater_equal_comparable_support_of<T>(), - greater_than_comparable_support_of<T>(), swappable_support_of<T>(), - conservative_hashable_support_of<T, ShouldCheckHashability>::Invoke()>; -}; - -#define ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL(type, name) \ - template <default_constructible DefaultConstructibleValue, \ - move_constructible MoveConstructibleValue, \ - copy_constructible CopyConstructibleValue, \ - move_assignable MoveAssignableValue, \ - copy_assignable CopyAssignableValue, \ - destructible DestructibleValue, \ - equality_comparable EqualityComparableValue, \ - inequality_comparable InequalityComparableValue, \ - less_than_comparable LessThanComparableValue, \ - less_equal_comparable LessEqualComparableValue, \ - greater_equal_comparable GreaterEqualComparableValue, \ - greater_than_comparable GreaterThanComparableValue, \ - swappable SwappableValue, hashable HashableValue> \ - constexpr type ConformanceProfile< \ - DefaultConstructibleValue, MoveConstructibleValue, \ - CopyConstructibleValue, MoveAssignableValue, CopyAssignableValue, \ - DestructibleValue, EqualityComparableValue, InequalityComparableValue, \ - LessThanComparableValue, LessEqualComparableValue, \ - GreaterEqualComparableValue, GreaterThanComparableValue, SwappableValue, \ - HashableValue>::name - -#define ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(type) \ - ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL(type, \ - type##_support); \ - ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL(bool, is_##type) - -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(default_constructible); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(move_constructible); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(copy_constructible); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(move_assignable); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(copy_assignable); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(destructible); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(equality_comparable); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(inequality_comparable); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(less_than_comparable); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(less_equal_comparable); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(greater_equal_comparable); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(greater_than_comparable); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(swappable); -ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(hashable); - -#undef ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF -#undef ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL - -// Retrieve the enum with the minimum underlying value. -// Note: std::min is not constexpr in C++11, which is why this is necessary. -template <class H> -constexpr H MinEnum(H head) { - return head; -} - -template <class H, class N, class... T> -constexpr H MinEnum(H head, N next, T... tail) { - return (UnderlyingValue)(head) < (UnderlyingValue)(next) - ? (MinEnum)(head, tail...) - : (MinEnum)(next, tail...); -} - -template <class... Profs> -struct MinimalProfiles { - static constexpr default_constructible - default_constructible_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::default_constructible_support...); - - static constexpr move_constructible move_constructible_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::move_constructible_support...); - - static constexpr copy_constructible copy_constructible_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::copy_constructible_support...); - - static constexpr move_assignable move_assignable_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::move_assignable_support...); - - static constexpr copy_assignable copy_assignable_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::copy_assignable_support...); - - static constexpr destructible destructible_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::destructible_support...); - - static constexpr equality_comparable equality_comparable_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::equality_comparable_support...); - - static constexpr inequality_comparable - inequality_comparable_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::inequality_comparable_support...); - - static constexpr less_than_comparable - less_than_comparable_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::less_than_comparable_support...); - - static constexpr less_equal_comparable - less_equal_comparable_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::less_equal_comparable_support...); - - static constexpr greater_equal_comparable - greater_equal_comparable_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::greater_equal_comparable_support...); - - static constexpr greater_than_comparable - greater_than_comparable_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::greater_than_comparable_support...); - - static constexpr swappable swappable_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::swappable_support...); - - static constexpr hashable hashable_support = // NOLINT - (MinEnum)(PropertiesOfT<Profs>::hashable_support...); - - using properties = ConformanceProfile< - default_constructible_support, move_constructible_support, - copy_constructible_support, move_assignable_support, - copy_assignable_support, destructible_support, - equality_comparable_support, inequality_comparable_support, - less_than_comparable_support, less_equal_comparable_support, - greater_equal_comparable_support, greater_than_comparable_support, - swappable_support, hashable_support>; -}; - -// Retrieve the enum with the greatest underlying value. -// Note: std::max is not constexpr in C++11, which is why this is necessary. -template <class H> -constexpr H MaxEnum(H head) { - return head; -} - -template <class H, class N, class... T> -constexpr H MaxEnum(H head, N next, T... tail) { - return (UnderlyingValue)(next) < (UnderlyingValue)(head) - ? (MaxEnum)(head, tail...) - : (MaxEnum)(next, tail...); -} - -template <class... Profs> -struct CombineProfilesImpl { - static constexpr default_constructible - default_constructible_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::default_constructible_support...); - - static constexpr move_constructible move_constructible_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::move_constructible_support...); - - static constexpr copy_constructible copy_constructible_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::copy_constructible_support...); - - static constexpr move_assignable move_assignable_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::move_assignable_support...); - - static constexpr copy_assignable copy_assignable_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::copy_assignable_support...); - - static constexpr destructible destructible_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::destructible_support...); - - static constexpr equality_comparable equality_comparable_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::equality_comparable_support...); - - static constexpr inequality_comparable - inequality_comparable_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::inequality_comparable_support...); - - static constexpr less_than_comparable - less_than_comparable_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::less_than_comparable_support...); - - static constexpr less_equal_comparable - less_equal_comparable_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::less_equal_comparable_support...); - - static constexpr greater_equal_comparable - greater_equal_comparable_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::greater_equal_comparable_support...); - - static constexpr greater_than_comparable - greater_than_comparable_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::greater_than_comparable_support...); - - static constexpr swappable swappable_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::swappable_support...); - - static constexpr hashable hashable_support = // NOLINT - (MaxEnum)(PropertiesOfT<Profs>::hashable_support...); - - using properties = ConformanceProfile< - default_constructible_support, move_constructible_support, - copy_constructible_support, move_assignable_support, - copy_assignable_support, destructible_support, - equality_comparable_support, inequality_comparable_support, - less_than_comparable_support, less_equal_comparable_support, - greater_equal_comparable_support, greater_than_comparable_support, - swappable_support, hashable_support>; -}; - -// NOTE: We use this as opposed to a direct alias of CombineProfilesImpl so that -// when named aliases of CombineProfiles are created (such as in -// conformance_aliases.h), we only pay for the combination algorithm on the -// profiles that are actually used. -template <class... Profs> -struct CombineProfiles { - using profile_alias_of = CombineProfilesImpl<Profs...>; -}; - -template <> -struct CombineProfiles<> { - using properties = ConformanceProfile<>; -}; - -template <class Profile, class Tag> -struct StrongProfileTypedef { - using properties = PropertiesOfT<Profile>; -}; - -template <class T, class /*Enabler*/ = void> -struct IsProfileImpl : std::false_type {}; - -template <class T> -struct IsProfileImpl<T, absl::void_t<PropertiesOfT<T>>> : std::true_type {}; - -template <class T> -struct IsProfile : IsProfileImpl<T>::type {}; - -// A tag that describes which set of properties we will check when the user -// requires a strict match in conformance (as opposed to a loose match which -// allows more-refined support of any given operation). -// -// Currently only the RegularityDomain exists and it includes all operations -// that the conformance testing suite knows about. The intent is that if the -// suite is expanded to support extension, such as for checking conformance of -// concepts like Iterators or Containers, additional corresponding domains can -// be created. -struct RegularityDomain {}; - -} // namespace types_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_PROFILE_H_ +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// conformance_profiles.h +// ----------------------------------------------------------------------------- +// +// This file contains templates for representing "Regularity Profiles" and +// concisely-named versions of commonly used Regularity Profiles. +// +// A Regularity Profile is a compile-time description of the types of operations +// that a given type supports, along with properties of those operations when +// they do exist. For instance, a Regularity Profile may describe a type that +// has a move-constructor that is noexcept and a copy constructor that is not +// noexcept. This description can then be examined and passed around to other +// templates for the purposes of asserting expectations on user-defined types +// via a series trait checks, or for determining what kinds of run-time tests +// are able to be performed. +// +// Regularity Profiles are also used when creating "archetypes," which are +// minimum-conforming types that meet all of the requirements of a given +// Regularity Profile. For more information regarding archetypes, see +// "conformance_archetypes.h". + +#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_PROFILE_H_ +#define ABSL_TYPES_INTERNAL_CONFORMANCE_PROFILE_H_ + +#include <set> +#include <type_traits> +#include <utility> +#include <vector> + +#include "gtest/gtest.h" +#include "absl/algorithm/container.h" +#include "absl/meta/type_traits.h" +#include "absl/strings/ascii.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "absl/types/internal/conformance_testing_helpers.h" +#include "absl/utility/utility.h" + +// TODO(calabrese) Add support for extending profiles. + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace types_internal { + +// Converts an enum to its underlying integral value. +template <typename Enum> +constexpr absl::underlying_type_t<Enum> UnderlyingValue(Enum value) { + return static_cast<absl::underlying_type_t<Enum>>(value); +} + +// A tag type used in place of a matcher when checking that an assertion result +// does not actually contain any errors. +struct NoError {}; + +// ----------------------------------------------------------------------------- +// ConformanceErrors +// ----------------------------------------------------------------------------- +class ConformanceErrors { + public: + // Setup the error reporting mechanism by seeding it with the name of the type + // that is being tested. + explicit ConformanceErrors(std::string type_name) + : assertion_result_(false), type_name_(std::move(type_name)) { + assertion_result_ << "\n\n" + "Assuming the following type alias:\n" + "\n" + " using _T = " + << type_name_ << ";\n\n"; + outputDivider(); + } + + // Adds the test name to the list of successfully run tests iff it was not + // previously reported as failing. This behavior is useful for tests that + // have multiple parts, where failures and successes are reported individually + // with the same test name. + void addTestSuccess(absl::string_view test_name) { + auto normalized_test_name = absl::AsciiStrToLower(test_name); + + // If the test is already reported as failing, do not add it to the list of + // successes. + if (test_failures_.find(normalized_test_name) == test_failures_.end()) { + test_successes_.insert(std::move(normalized_test_name)); + } + } + + // Streams a single error description into the internal buffer (a visual + // divider is automatically inserted after the error so that multiple errors + // are visibly distinct). + // + // This function increases the error count by 1. + // + // TODO(calabrese) Determine desired behavior when if this function throws. + template <class... P> + void addTestFailure(absl::string_view test_name, const P&... args) { + // Output a message related to the test failure. + assertion_result_ << "\n\n" + "Failed test: " + << test_name << "\n\n"; + addTestFailureImpl(args...); + assertion_result_ << "\n\n"; + outputDivider(); + + auto normalized_test_name = absl::AsciiStrToLower(test_name); + + // If previous parts of this test succeeded, remove it from that set. + test_successes_.erase(normalized_test_name); + + // Add the test name to the list of failed tests. + test_failures_.insert(std::move(normalized_test_name)); + + has_error_ = true; + } + + // Convert this object into a testing::AssertionResult instance such that it + // can be used with gtest. + ::testing::AssertionResult assertionResult() const { + return has_error_ ? assertion_result_ : ::testing::AssertionSuccess(); + } + + // Convert this object into a testing::AssertionResult instance such that it + // can be used with gtest. This overload expects errors, using the specified + // matcher. + ::testing::AssertionResult expectFailedTests( + const std::set<std::string>& test_names) const { + // Since we are expecting nonconformance, output an error message when the + // type actually conformed to the specified profile. + if (!has_error_) { + return ::testing::AssertionFailure() + << "Unexpected conformance of type:\n" + " " + << type_name_ << "\n\n"; + } + + // Get a list of all expected failures that did not actually fail + // (or that were not run). + std::vector<std::string> nonfailing_tests; + absl::c_set_difference(test_names, test_failures_, + std::back_inserter(nonfailing_tests)); + + // Get a list of all "expected failures" that were never actually run. + std::vector<std::string> unrun_tests; + absl::c_set_difference(nonfailing_tests, test_successes_, + std::back_inserter(unrun_tests)); + + // Report when the user specified tests that were not run. + if (!unrun_tests.empty()) { + const bool tests_were_run = + !(test_failures_.empty() && test_successes_.empty()); + + // Prepare an assertion result used in the case that tests pass that were + // expected to fail. + ::testing::AssertionResult result = ::testing::AssertionFailure(); + result << "When testing type:\n " << type_name_ + << "\n\nThe following tests were expected to fail but were not " + "run"; + + if (tests_were_run) result << " (was the test name spelled correctly?)"; + + result << ":\n\n"; + + // List all of the tests that unexpectedly passed. + for (const auto& test_name : unrun_tests) { + result << " " << test_name << "\n"; + } + + if (!tests_were_run) result << "\nNo tests were run."; + + if (!test_failures_.empty()) { + // List test failures + result << "\nThe tests that were run and failed are:\n\n"; + for (const auto& test_name : test_failures_) { + result << " " << test_name << "\n"; + } + } + + if (!test_successes_.empty()) { + // List test successes + result << "\nThe tests that were run and succeeded are:\n\n"; + for (const auto& test_name : test_successes_) { + result << " " << test_name << "\n"; + } + } + + return result; + } + + // If some tests passed when they were expected to fail, alert the caller. + if (nonfailing_tests.empty()) return ::testing::AssertionSuccess(); + + // Prepare an assertion result used in the case that tests pass that were + // expected to fail. + ::testing::AssertionResult unexpected_successes = + ::testing::AssertionFailure(); + unexpected_successes << "When testing type:\n " << type_name_ + << "\n\nThe following tests passed when they were " + "expected to fail:\n\n"; + + // List all of the tests that unexpectedly passed. + for (const auto& test_name : nonfailing_tests) { + unexpected_successes << " " << test_name << "\n"; + } + + return unexpected_successes; + } + + private: + void outputDivider() { + assertion_result_ << "========================================"; + } + + void addTestFailureImpl() {} + + template <class H, class... T> + void addTestFailureImpl(const H& head, const T&... tail) { + assertion_result_ << head; + addTestFailureImpl(tail...); + } + + ::testing::AssertionResult assertion_result_; + std::set<std::string> test_failures_; + std::set<std::string> test_successes_; + std::string type_name_; + bool has_error_ = false; +}; + +template <class T, class /*Enabler*/ = void> +struct PropertiesOfImpl {}; + +template <class T> +struct PropertiesOfImpl<T, absl::void_t<typename T::properties>> { + using type = typename T::properties; +}; + +template <class T> +struct PropertiesOfImpl<T, absl::void_t<typename T::profile_alias_of>> { + using type = typename PropertiesOfImpl<typename T::profile_alias_of>::type; +}; + +template <class T> +struct PropertiesOf : PropertiesOfImpl<T> {}; + +template <class T> +using PropertiesOfT = typename PropertiesOf<T>::type; + +// NOTE: These enums use this naming convention to be consistent with the +// standard trait names, which is useful since it allows us to match up each +// enum name with a corresponding trait name in macro definitions. + +// An enum that describes the various expectations on an operations existence. +enum class function_support { maybe, yes, nothrow, trivial }; + +constexpr const char* PessimisticPropertyDescription(function_support v) { + return v == function_support::maybe + ? "no" + : v == function_support::yes + ? "yes, potentially throwing" + : v == function_support::nothrow ? "yes, nothrow" + : "yes, trivial"; +} + +// Return a string that describes the kind of property support that was +// expected. +inline std::string ExpectedFunctionKindList(function_support min, + function_support max) { + if (min == max) { + std::string result = + absl::StrCat("Expected:\n ", + PessimisticPropertyDescription( + static_cast<function_support>(UnderlyingValue(min))), + "\n"); + return result; + } + + std::string result = "Expected one of:\n"; + for (auto curr_support = UnderlyingValue(min); + curr_support <= UnderlyingValue(max); ++curr_support) { + absl::StrAppend(&result, " ", + PessimisticPropertyDescription( + static_cast<function_support>(curr_support)), + "\n"); + } + + return result; +} + +template <class Enum> +void ExpectModelOfImpl(ConformanceErrors* errors, Enum min_support, + Enum max_support, Enum kind) { + const auto kind_value = UnderlyingValue(kind); + const auto min_support_value = UnderlyingValue(min_support); + const auto max_support_value = UnderlyingValue(max_support); + + if (!(kind_value >= min_support_value && kind_value <= max_support_value)) { + errors->addTestFailure( + PropertyName(kind), "**Failed property expectation**\n\n", + ExpectedFunctionKindList( + static_cast<function_support>(min_support_value), + static_cast<function_support>(max_support_value)), + '\n', "Actual:\n ", + PessimisticPropertyDescription( + static_cast<function_support>(kind_value))); + } else { + errors->addTestSuccess(PropertyName(kind)); + } +} + +#define ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM(description, name) \ + enum class name { maybe, yes, nothrow, trivial }; \ + \ + constexpr const char* PropertyName(name v) { return description; } \ + static_assert(true, "") // Force a semicolon when using this macro. + +ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM("support for default construction", + default_constructible); +ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM("support for move construction", + move_constructible); +ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM("support for copy construction", + copy_constructible); +ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM("support for move assignment", + move_assignable); +ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM("support for copy assignment", + copy_assignable); +ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM("support for destruction", + destructible); + +#undef ABSL_INTERNAL_SPECIAL_MEMBER_FUNCTION_ENUM + +#define ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM(description, name) \ + enum class name { maybe, yes, nothrow }; \ + \ + constexpr const char* PropertyName(name v) { return description; } \ + static_assert(true, "") // Force a semicolon when using this macro. + +ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for ==", equality_comparable); +ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for !=", inequality_comparable); +ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for <", less_than_comparable); +ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for <=", less_equal_comparable); +ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for >=", + greater_equal_comparable); +ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for >", greater_than_comparable); + +ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM("support for swap", swappable); + +#undef ABSL_INTERNAL_INTRINSIC_FUNCTION_ENUM + +enum class hashable { maybe, yes }; + +constexpr const char* PropertyName(hashable v) { + return "support for std::hash"; +} + +template <class T> +using AlwaysFalse = std::false_type; + +#define ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(name, property) \ + template <class T> \ + constexpr property property##_support_of() { \ + return std::is_##property<T>::value \ + ? std::is_nothrow_##property<T>::value \ + ? absl::is_trivially_##property<T>::value \ + ? property::trivial \ + : property::nothrow \ + : property::yes \ + : property::maybe; \ + } \ + \ + template <class T, class MinProf, class MaxProf> \ + void ExpectModelOf##name(ConformanceErrors* errors) { \ + (ExpectModelOfImpl)(errors, PropertiesOfT<MinProf>::property##_support, \ + PropertiesOfT<MaxProf>::property##_support, \ + property##_support_of<T>()); \ + } + +ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(DefaultConstructible, + default_constructible); + +ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(MoveConstructible, + move_constructible); + +ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(CopyConstructible, + copy_constructible); + +ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(MoveAssignable, + move_assignable); + +ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(CopyAssignable, + copy_assignable); + +ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER(Destructible, destructible); + +#undef ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_SPECIAL_MEMBER + +void BoolFunction(bool) noexcept; + +//////////////////////////////////////////////////////////////////////////////// +// +// A metafunction for checking if an operation exists through SFINAE. +// +// `T` is the type to test and Op is an alias containing the expression to test. +template <class T, template <class...> class Op, class = void> +struct IsOpableImpl : std::false_type {}; + +template <class T, template <class...> class Op> +struct IsOpableImpl<T, Op, absl::void_t<Op<T>>> : std::true_type {}; + +template <template <class...> class Op> +struct IsOpable { + template <class T> + using apply = typename IsOpableImpl<T, Op>::type; +}; +// +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// A metafunction for checking if an operation exists and is also noexcept +// through SFINAE and the noexcept operator. +/// +// `T` is the type to test and Op is an alias containing the expression to test. +template <class T, template <class...> class Op, class = void> +struct IsNothrowOpableImpl : std::false_type {}; + +template <class T, template <class...> class Op> +struct IsNothrowOpableImpl<T, Op, absl::enable_if_t<Op<T>::value>> + : std::true_type {}; + +template <template <class...> class Op> +struct IsNothrowOpable { + template <class T> + using apply = typename IsNothrowOpableImpl<T, Op>::type; +}; +// +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// A macro that produces the necessary function for reporting what kind of +// support a specific comparison operation has and a function for reporting an +// error if a given type's support for that operation does not meet the expected +// requirements. +#define ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(name, property, op) \ + template <class T, \ + class Result = std::integral_constant< \ + bool, noexcept((BoolFunction)(std::declval<const T&>() op \ + std::declval<const T&>()))>> \ + using name = Result; \ + \ + template <class T> \ + constexpr property property##_support_of() { \ + return IsOpable<name>::apply<T>::value \ + ? IsNothrowOpable<name>::apply<T>::value ? property::nothrow \ + : property::yes \ + : property::maybe; \ + } \ + \ + template <class T, class MinProf, class MaxProf> \ + void ExpectModelOf##name(ConformanceErrors* errors) { \ + (ExpectModelOfImpl)(errors, PropertiesOfT<MinProf>::property##_support, \ + PropertiesOfT<MaxProf>::property##_support, \ + property##_support_of<T>()); \ + } +// +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// Generate the necessary support-checking and error reporting functions for +// each of the comparison operators. +ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(EqualityComparable, + equality_comparable, ==); + +ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(InequalityComparable, + inequality_comparable, !=); + +ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(LessThanComparable, + less_than_comparable, <); + +ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(LessEqualComparable, + less_equal_comparable, <=); + +ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(GreaterEqualComparable, + greater_equal_comparable, >=); + +ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON(GreaterThanComparable, + greater_than_comparable, >); + +#undef ABSL_INTERNAL_PESSIMISTIC_MODEL_OF_COMPARISON +// +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// The necessary support-checking and error-reporting functions for swap. +template <class T> +constexpr swappable swappable_support_of() { + return type_traits_internal::IsSwappable<T>::value + ? type_traits_internal::IsNothrowSwappable<T>::value + ? swappable::nothrow + : swappable::yes + : swappable::maybe; +} + +template <class T, class MinProf, class MaxProf> +void ExpectModelOfSwappable(ConformanceErrors* errors) { + (ExpectModelOfImpl)(errors, PropertiesOfT<MinProf>::swappable_support, + PropertiesOfT<MaxProf>::swappable_support, + swappable_support_of<T>()); +} +// +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// The necessary support-checking and error-reporting functions for std::hash. +template <class T> +constexpr hashable hashable_support_of() { + return type_traits_internal::IsHashable<T>::value ? hashable::yes + : hashable::maybe; +} + +template <class T, class MinProf, class MaxProf> +void ExpectModelOfHashable(ConformanceErrors* errors) { + (ExpectModelOfImpl)(errors, PropertiesOfT<MinProf>::hashable_support, + PropertiesOfT<MaxProf>::hashable_support, + hashable_support_of<T>()); +} +// +//////////////////////////////////////////////////////////////////////////////// + +template < + default_constructible DefaultConstructibleValue = + default_constructible::maybe, + move_constructible MoveConstructibleValue = move_constructible::maybe, + copy_constructible CopyConstructibleValue = copy_constructible::maybe, + move_assignable MoveAssignableValue = move_assignable::maybe, + copy_assignable CopyAssignableValue = copy_assignable::maybe, + destructible DestructibleValue = destructible::maybe, + equality_comparable EqualityComparableValue = equality_comparable::maybe, + inequality_comparable InequalityComparableValue = + inequality_comparable::maybe, + less_than_comparable LessThanComparableValue = less_than_comparable::maybe, + less_equal_comparable LessEqualComparableValue = + less_equal_comparable::maybe, + greater_equal_comparable GreaterEqualComparableValue = + greater_equal_comparable::maybe, + greater_than_comparable GreaterThanComparableValue = + greater_than_comparable::maybe, + swappable SwappableValue = swappable::maybe, + hashable HashableValue = hashable::maybe> +struct ConformanceProfile { + using properties = ConformanceProfile; + + static constexpr default_constructible + default_constructible_support = // NOLINT + DefaultConstructibleValue; + + static constexpr move_constructible move_constructible_support = // NOLINT + MoveConstructibleValue; + + static constexpr copy_constructible copy_constructible_support = // NOLINT + CopyConstructibleValue; + + static constexpr move_assignable move_assignable_support = // NOLINT + MoveAssignableValue; + + static constexpr copy_assignable copy_assignable_support = // NOLINT + CopyAssignableValue; + + static constexpr destructible destructible_support = // NOLINT + DestructibleValue; + + static constexpr equality_comparable equality_comparable_support = // NOLINT + EqualityComparableValue; + + static constexpr inequality_comparable + inequality_comparable_support = // NOLINT + InequalityComparableValue; + + static constexpr less_than_comparable + less_than_comparable_support = // NOLINT + LessThanComparableValue; + + static constexpr less_equal_comparable + less_equal_comparable_support = // NOLINT + LessEqualComparableValue; + + static constexpr greater_equal_comparable + greater_equal_comparable_support = // NOLINT + GreaterEqualComparableValue; + + static constexpr greater_than_comparable + greater_than_comparable_support = // NOLINT + GreaterThanComparableValue; + + static constexpr swappable swappable_support = SwappableValue; // NOLINT + + static constexpr hashable hashable_support = HashableValue; // NOLINT + + static constexpr bool is_default_constructible = // NOLINT + DefaultConstructibleValue != default_constructible::maybe; + + static constexpr bool is_move_constructible = // NOLINT + MoveConstructibleValue != move_constructible::maybe; + + static constexpr bool is_copy_constructible = // NOLINT + CopyConstructibleValue != copy_constructible::maybe; + + static constexpr bool is_move_assignable = // NOLINT + MoveAssignableValue != move_assignable::maybe; + + static constexpr bool is_copy_assignable = // NOLINT + CopyAssignableValue != copy_assignable::maybe; + + static constexpr bool is_destructible = // NOLINT + DestructibleValue != destructible::maybe; + + static constexpr bool is_equality_comparable = // NOLINT + EqualityComparableValue != equality_comparable::maybe; + + static constexpr bool is_inequality_comparable = // NOLINT + InequalityComparableValue != inequality_comparable::maybe; + + static constexpr bool is_less_than_comparable = // NOLINT + LessThanComparableValue != less_than_comparable::maybe; + + static constexpr bool is_less_equal_comparable = // NOLINT + LessEqualComparableValue != less_equal_comparable::maybe; + + static constexpr bool is_greater_equal_comparable = // NOLINT + GreaterEqualComparableValue != greater_equal_comparable::maybe; + + static constexpr bool is_greater_than_comparable = // NOLINT + GreaterThanComparableValue != greater_than_comparable::maybe; + + static constexpr bool is_swappable = // NOLINT + SwappableValue != swappable::maybe; + + static constexpr bool is_hashable = // NOLINT + HashableValue != hashable::maybe; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +// Compliant SFINAE-friendliness is not always present on the standard library +// implementations that we support. This helper-struct (and associated enum) is +// used as a means to conditionally check the hashability support of a type. +enum class CheckHashability { no, yes }; + +template <class T, CheckHashability ShouldCheckHashability> +struct conservative_hashable_support_of; + +template <class T> +struct conservative_hashable_support_of<T, CheckHashability::no> { + static constexpr hashable Invoke() { return hashable::maybe; } +}; + +template <class T> +struct conservative_hashable_support_of<T, CheckHashability::yes> { + static constexpr hashable Invoke() { return hashable_support_of<T>(); } +}; +// +//////////////////////////////////////////////////////////////////////////////// + +// The ConformanceProfile that is expected based on introspection into the type +// by way of trait checks. +template <class T, CheckHashability ShouldCheckHashability> +struct SyntacticConformanceProfileOf { + using properties = ConformanceProfile< + default_constructible_support_of<T>(), move_constructible_support_of<T>(), + copy_constructible_support_of<T>(), move_assignable_support_of<T>(), + copy_assignable_support_of<T>(), destructible_support_of<T>(), + equality_comparable_support_of<T>(), + inequality_comparable_support_of<T>(), + less_than_comparable_support_of<T>(), + less_equal_comparable_support_of<T>(), + greater_equal_comparable_support_of<T>(), + greater_than_comparable_support_of<T>(), swappable_support_of<T>(), + conservative_hashable_support_of<T, ShouldCheckHashability>::Invoke()>; +}; + +#define ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL(type, name) \ + template <default_constructible DefaultConstructibleValue, \ + move_constructible MoveConstructibleValue, \ + copy_constructible CopyConstructibleValue, \ + move_assignable MoveAssignableValue, \ + copy_assignable CopyAssignableValue, \ + destructible DestructibleValue, \ + equality_comparable EqualityComparableValue, \ + inequality_comparable InequalityComparableValue, \ + less_than_comparable LessThanComparableValue, \ + less_equal_comparable LessEqualComparableValue, \ + greater_equal_comparable GreaterEqualComparableValue, \ + greater_than_comparable GreaterThanComparableValue, \ + swappable SwappableValue, hashable HashableValue> \ + constexpr type ConformanceProfile< \ + DefaultConstructibleValue, MoveConstructibleValue, \ + CopyConstructibleValue, MoveAssignableValue, CopyAssignableValue, \ + DestructibleValue, EqualityComparableValue, InequalityComparableValue, \ + LessThanComparableValue, LessEqualComparableValue, \ + GreaterEqualComparableValue, GreaterThanComparableValue, SwappableValue, \ + HashableValue>::name + +#define ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(type) \ + ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL(type, \ + type##_support); \ + ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL(bool, is_##type) + +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(default_constructible); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(move_constructible); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(copy_constructible); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(move_assignable); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(copy_assignable); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(destructible); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(equality_comparable); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(inequality_comparable); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(less_than_comparable); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(less_equal_comparable); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(greater_equal_comparable); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(greater_than_comparable); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(swappable); +ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF(hashable); + +#undef ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF +#undef ABSL_INTERNAL_CONFORMANCE_TESTING_DATA_MEMBER_DEF_IMPL + +// Retrieve the enum with the minimum underlying value. +// Note: std::min is not constexpr in C++11, which is why this is necessary. +template <class H> +constexpr H MinEnum(H head) { + return head; +} + +template <class H, class N, class... T> +constexpr H MinEnum(H head, N next, T... tail) { + return (UnderlyingValue)(head) < (UnderlyingValue)(next) + ? (MinEnum)(head, tail...) + : (MinEnum)(next, tail...); +} + +template <class... Profs> +struct MinimalProfiles { + static constexpr default_constructible + default_constructible_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::default_constructible_support...); + + static constexpr move_constructible move_constructible_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::move_constructible_support...); + + static constexpr copy_constructible copy_constructible_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::copy_constructible_support...); + + static constexpr move_assignable move_assignable_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::move_assignable_support...); + + static constexpr copy_assignable copy_assignable_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::copy_assignable_support...); + + static constexpr destructible destructible_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::destructible_support...); + + static constexpr equality_comparable equality_comparable_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::equality_comparable_support...); + + static constexpr inequality_comparable + inequality_comparable_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::inequality_comparable_support...); + + static constexpr less_than_comparable + less_than_comparable_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::less_than_comparable_support...); + + static constexpr less_equal_comparable + less_equal_comparable_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::less_equal_comparable_support...); + + static constexpr greater_equal_comparable + greater_equal_comparable_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::greater_equal_comparable_support...); + + static constexpr greater_than_comparable + greater_than_comparable_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::greater_than_comparable_support...); + + static constexpr swappable swappable_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::swappable_support...); + + static constexpr hashable hashable_support = // NOLINT + (MinEnum)(PropertiesOfT<Profs>::hashable_support...); + + using properties = ConformanceProfile< + default_constructible_support, move_constructible_support, + copy_constructible_support, move_assignable_support, + copy_assignable_support, destructible_support, + equality_comparable_support, inequality_comparable_support, + less_than_comparable_support, less_equal_comparable_support, + greater_equal_comparable_support, greater_than_comparable_support, + swappable_support, hashable_support>; +}; + +// Retrieve the enum with the greatest underlying value. +// Note: std::max is not constexpr in C++11, which is why this is necessary. +template <class H> +constexpr H MaxEnum(H head) { + return head; +} + +template <class H, class N, class... T> +constexpr H MaxEnum(H head, N next, T... tail) { + return (UnderlyingValue)(next) < (UnderlyingValue)(head) + ? (MaxEnum)(head, tail...) + : (MaxEnum)(next, tail...); +} + +template <class... Profs> +struct CombineProfilesImpl { + static constexpr default_constructible + default_constructible_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::default_constructible_support...); + + static constexpr move_constructible move_constructible_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::move_constructible_support...); + + static constexpr copy_constructible copy_constructible_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::copy_constructible_support...); + + static constexpr move_assignable move_assignable_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::move_assignable_support...); + + static constexpr copy_assignable copy_assignable_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::copy_assignable_support...); + + static constexpr destructible destructible_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::destructible_support...); + + static constexpr equality_comparable equality_comparable_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::equality_comparable_support...); + + static constexpr inequality_comparable + inequality_comparable_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::inequality_comparable_support...); + + static constexpr less_than_comparable + less_than_comparable_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::less_than_comparable_support...); + + static constexpr less_equal_comparable + less_equal_comparable_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::less_equal_comparable_support...); + + static constexpr greater_equal_comparable + greater_equal_comparable_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::greater_equal_comparable_support...); + + static constexpr greater_than_comparable + greater_than_comparable_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::greater_than_comparable_support...); + + static constexpr swappable swappable_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::swappable_support...); + + static constexpr hashable hashable_support = // NOLINT + (MaxEnum)(PropertiesOfT<Profs>::hashable_support...); + + using properties = ConformanceProfile< + default_constructible_support, move_constructible_support, + copy_constructible_support, move_assignable_support, + copy_assignable_support, destructible_support, + equality_comparable_support, inequality_comparable_support, + less_than_comparable_support, less_equal_comparable_support, + greater_equal_comparable_support, greater_than_comparable_support, + swappable_support, hashable_support>; +}; + +// NOTE: We use this as opposed to a direct alias of CombineProfilesImpl so that +// when named aliases of CombineProfiles are created (such as in +// conformance_aliases.h), we only pay for the combination algorithm on the +// profiles that are actually used. +template <class... Profs> +struct CombineProfiles { + using profile_alias_of = CombineProfilesImpl<Profs...>; +}; + +template <> +struct CombineProfiles<> { + using properties = ConformanceProfile<>; +}; + +template <class Profile, class Tag> +struct StrongProfileTypedef { + using properties = PropertiesOfT<Profile>; +}; + +template <class T, class /*Enabler*/ = void> +struct IsProfileImpl : std::false_type {}; + +template <class T> +struct IsProfileImpl<T, absl::void_t<PropertiesOfT<T>>> : std::true_type {}; + +template <class T> +struct IsProfile : IsProfileImpl<T>::type {}; + +// A tag that describes which set of properties we will check when the user +// requires a strict match in conformance (as opposed to a loose match which +// allows more-refined support of any given operation). +// +// Currently only the RegularityDomain exists and it includes all operations +// that the conformance testing suite knows about. The intent is that if the +// suite is expanded to support extension, such as for checking conformance of +// concepts like Iterators or Containers, additional corresponding domains can +// be created. +struct RegularityDomain {}; + +} // namespace types_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_PROFILE_H_ diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/conformance_testing.h b/contrib/restricted/abseil-cpp/absl/types/internal/conformance_testing.h index 487b0f786b..7765f9f4e4 100644 --- a/contrib/restricted/abseil-cpp/absl/types/internal/conformance_testing.h +++ b/contrib/restricted/abseil-cpp/absl/types/internal/conformance_testing.h @@ -1,1386 +1,1386 @@ -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// conformance_testing.h -// ----------------------------------------------------------------------------- -// - -#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_TESTING_H_ -#define ABSL_TYPES_INTERNAL_CONFORMANCE_TESTING_H_ - -//////////////////////////////////////////////////////////////////////////////// -// // -// Many templates in this file take a `T` and a `Prof` type as explicit // -// template arguments. These are a type to be checked and a // -// "Regularity Profile" that describes what operations that type `T` is // -// expected to support. See "regularity_profiles.h" for more details // -// regarding Regularity Profiles. // -// // -//////////////////////////////////////////////////////////////////////////////// - -#include <cstddef> -#include <set> -#include <tuple> -#include <type_traits> -#include <utility> - -#include "gtest/gtest.h" -#include "absl/meta/type_traits.h" -#include "absl/strings/ascii.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "absl/types/internal/conformance_aliases.h" -#include "absl/types/internal/conformance_archetype.h" -#include "absl/types/internal/conformance_profile.h" -#include "absl/types/internal/conformance_testing_helpers.h" -#include "absl/types/internal/parentheses.h" -#include "absl/types/internal/transform_args.h" -#include "absl/utility/utility.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace types_internal { - -// Returns true if the compiler incorrectly greedily instantiates constexpr -// templates in any unevaluated context. -constexpr bool constexpr_instantiation_when_unevaluated() { -#if defined(__apple_build_version__) // TODO(calabrese) Make more specific - return true; -#elif defined(__clang__) - return __clang_major__ < 4; -#elif defined(__GNUC__) - // TODO(calabrese) Figure out why gcc 7 fails (seems like a different bug) - return __GNUC__ < 5 || (__GNUC__ == 5 && __GNUC_MINOR__ < 2) || __GNUC__ >= 7; -#else - return false; -#endif -} - -// Returns true if the standard library being used incorrectly produces an error -// when instantiating the definition of a poisoned std::hash specialization. -constexpr bool poisoned_hash_fails_instantiation() { -#if defined(_MSC_VER) && !defined(_LIBCPP_VERSION) - return _MSC_VER < 1914; -#else - return false; -#endif -} - -template <class Fun> -struct GeneratorType { - decltype(std::declval<const Fun&>()()) operator()() const - noexcept(noexcept(std::declval<const Fun&>()())) { - return fun(); - } - - Fun fun; - const char* description; -}; - -// A "make" function for the GeneratorType template that deduces the function -// object type. -template <class Fun, - absl::enable_if_t<IsNullaryCallable<Fun>::value>** = nullptr> -GeneratorType<Fun> Generator(Fun fun, const char* description) { - return GeneratorType<Fun>{absl::move(fun), description}; -} - -// A type that contains a set of nullary function objects that each return an -// instance of the same type and value (though possibly different -// representations, such as +0 and -0 or two vectors with the same elements but -// with different capacities). -template <class... Funs> -struct EquivalenceClassType { - std::tuple<GeneratorType<Funs>...> generators; -}; - -// A "make" function for the EquivalenceClassType template that deduces the -// function object types and is constrained such that a user can only pass in -// function objects that all have the same return type. -template <class... Funs, absl::enable_if_t<AreGeneratorsWithTheSameReturnType< - Funs...>::value>** = nullptr> -EquivalenceClassType<Funs...> EquivalenceClass(GeneratorType<Funs>... funs) { - return {std::make_tuple(absl::move(funs)...)}; -} - -// A type that contains an ordered series of EquivalenceClassTypes, from -// smallest value to largest value. -template <class... EqClasses> -struct OrderedEquivalenceClasses { - std::tuple<EqClasses...> eq_classes; -}; - -// An object containing the parts of a given (name, initialization expression), -// and is capable of generating a string that describes the given. -struct GivenDeclaration { - std::string outputDeclaration(std::size_t width) const { - const std::size_t indent_size = 2; - std::string result = absl::StrCat(" ", name); - - if (!expression.empty()) { - // Indent - result.resize(indent_size + width, ' '); - absl::StrAppend(&result, " = ", expression, ";\n"); - } else { - absl::StrAppend(&result, ";\n"); - } - - return result; - } - - std::string name; - std::string expression; -}; - -// Produce a string that contains all of the givens of an error report. -template <class... Decls> -std::string PrepareGivenContext(const Decls&... decls) { - const std::size_t width = (std::max)({decls.name.size()...}); - return absl::StrCat("Given:\n", decls.outputDeclaration(width)..., "\n"); -} - -//////////////////////////////////////////////////////////////////////////////// -// Function objects that perform a check for each comparison operator // -//////////////////////////////////////////////////////////////////////////////// - -#define ABSL_INTERNAL_EXPECT_OP(name, op) \ - struct Expect##name { \ - template <class T> \ - void operator()(absl::string_view test_name, absl::string_view context, \ - const T& lhs, const T& rhs, absl::string_view lhs_name, \ - absl::string_view rhs_name) const { \ - if (!static_cast<bool>(lhs op rhs)) { \ - errors->addTestFailure( \ - test_name, absl::StrCat(context, \ - "**Unexpected comparison result**\n" \ - "\n" \ - "Expression:\n" \ - " ", \ - lhs_name, " " #op " ", rhs_name, \ - "\n" \ - "\n" \ - "Expected: true\n" \ - " Actual: false")); \ - } else { \ - errors->addTestSuccess(test_name); \ - } \ - } \ - \ - ConformanceErrors* errors; \ - }; \ - \ - struct ExpectNot##name { \ - template <class T> \ - void operator()(absl::string_view test_name, absl::string_view context, \ - const T& lhs, const T& rhs, absl::string_view lhs_name, \ - absl::string_view rhs_name) const { \ - if (lhs op rhs) { \ - errors->addTestFailure( \ - test_name, absl::StrCat(context, \ - "**Unexpected comparison result**\n" \ - "\n" \ - "Expression:\n" \ - " ", \ - lhs_name, " " #op " ", rhs_name, \ - "\n" \ - "\n" \ - "Expected: false\n" \ - " Actual: true")); \ - } else { \ - errors->addTestSuccess(test_name); \ - } \ - } \ - \ - ConformanceErrors* errors; \ - } - -ABSL_INTERNAL_EXPECT_OP(Eq, ==); -ABSL_INTERNAL_EXPECT_OP(Ne, !=); -ABSL_INTERNAL_EXPECT_OP(Lt, <); -ABSL_INTERNAL_EXPECT_OP(Le, <=); -ABSL_INTERNAL_EXPECT_OP(Ge, >=); -ABSL_INTERNAL_EXPECT_OP(Gt, >); - -#undef ABSL_INTERNAL_EXPECT_OP - -// A function object that verifies that two objects hash to the same value by -// way of the std::hash specialization. -struct ExpectSameHash { - template <class T> - void operator()(absl::string_view test_name, absl::string_view context, - const T& lhs, const T& rhs, absl::string_view lhs_name, - absl::string_view rhs_name) const { - if (std::hash<T>()(lhs) != std::hash<T>()(rhs)) { - errors->addTestFailure( - test_name, absl::StrCat(context, - "**Unexpected hash result**\n" - "\n" - "Expression:\n" - " std::hash<T>()(", - lhs_name, ") == std::hash<T>()(", rhs_name, - ")\n" - "\n" - "Expected: true\n" - " Actual: false")); - } else { - errors->addTestSuccess(test_name); - } - } - - ConformanceErrors* errors; -}; - -// A function template that takes two objects and verifies that each comparison -// operator behaves in a way that is consistent with equality. It has "OneWay" -// in the name because the first argument will always be the left-hand operand -// of the corresponding comparison operator and the second argument will -// always be the right-hand operand. It will never switch that order. -// At a higher level in the test suite, the one-way form is called once for each -// of the two possible orders whenever lhs and rhs are not the same initializer. -template <class T, class Prof> -void ExpectOneWayEquality(ConformanceErrors* errors, - absl::string_view test_name, - absl::string_view context, const T& lhs, const T& rhs, - absl::string_view lhs_name, - absl::string_view rhs_name) { - If<PropertiesOfT<Prof>::is_equality_comparable>::Invoke( - ExpectEq{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); - - If<PropertiesOfT<Prof>::is_inequality_comparable>::Invoke( - ExpectNotNe{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); - - If<PropertiesOfT<Prof>::is_less_than_comparable>::Invoke( - ExpectNotLt{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); - - If<PropertiesOfT<Prof>::is_less_equal_comparable>::Invoke( - ExpectLe{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); - - If<PropertiesOfT<Prof>::is_greater_equal_comparable>::Invoke( - ExpectGe{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); - - If<PropertiesOfT<Prof>::is_greater_than_comparable>::Invoke( - ExpectNotGt{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); - - If<PropertiesOfT<Prof>::is_hashable>::Invoke( - ExpectSameHash{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); -} - -// A function template that takes two objects and verifies that each comparison -// operator behaves in a way that is consistent with equality. This function -// differs from ExpectOneWayEquality in that this will do checks with argument -// order reversed in addition to in-order. -template <class T, class Prof> -void ExpectEquality(ConformanceErrors* errors, absl::string_view test_name, - absl::string_view context, const T& lhs, const T& rhs, - absl::string_view lhs_name, absl::string_view rhs_name) { - (ExpectOneWayEquality<T, Prof>)(errors, test_name, context, lhs, rhs, - lhs_name, rhs_name); - (ExpectOneWayEquality<T, Prof>)(errors, test_name, context, rhs, lhs, - rhs_name, lhs_name); -} - -// Given a generator, makes sure that a generated value and a moved-from -// generated value are equal. -template <class T, class Prof> -struct ExpectMoveConstructOneGenerator { - template <class Fun> - void operator()(const Fun& generator) const { - const T object = generator(); - const T moved_object = absl::move(generator()); // Force no elision. - - (ExpectEquality<T, Prof>)(errors, "Move construction", - PrepareGivenContext( - GivenDeclaration{"const _T object", - generator.description}, - GivenDeclaration{"const _T moved_object", - std::string("std::move(") + - generator.description + - ")"}), - object, moved_object, "object", "moved_object"); - } - - ConformanceErrors* errors; -}; - -// Given a generator, makes sure that a generated value and a copied-from -// generated value are equal. -template <class T, class Prof> -struct ExpectCopyConstructOneGenerator { - template <class Fun> - void operator()(const Fun& generator) const { - const T object = generator(); - const T copied_object = static_cast<const T&>(generator()); - - (ExpectEquality<T, Prof>)(errors, "Copy construction", - PrepareGivenContext( - GivenDeclaration{"const _T object", - generator.description}, - GivenDeclaration{ - "const _T copied_object", - std::string("static_cast<const _T&>(") + - generator.description + ")"}), - object, copied_object, "object", "copied_object"); - } - - ConformanceErrors* errors; -}; - -// Default-construct and do nothing before destruction. -// -// This is useful in exercising the codepath of default construction followed by -// destruction, but does not explicitly test anything. An example of where this -// might fail is a default destructor that default-initializes a scalar and a -// destructor reads the value of that member. Sanitizers can catch this as long -// as our test attempts to execute such a case. -template <class T> -struct ExpectDefaultConstructWithDestruct { - void operator()() const { - // Scoped so that destructor gets called before reporting success. - { - T object; - static_cast<void>(object); - } - - errors->addTestSuccess("Default construction"); - } - - ConformanceErrors* errors; -}; - -// Check move-assign into a default-constructed object. -template <class T, class Prof> -struct ExpectDefaultConstructWithMoveAssign { - template <class Fun> - void operator()(const Fun& generator) const { - const T source_of_truth = generator(); - T object; - object = generator(); - - (ExpectEquality<T, Prof>)(errors, "Move assignment", - PrepareGivenContext( - GivenDeclaration{"const _T object", - generator.description}, - GivenDeclaration{"_T object", ""}, - GivenDeclaration{"object", - generator.description}), - object, source_of_truth, "std::as_const(object)", - "source_of_truth"); - } - - ConformanceErrors* errors; -}; - -// Check copy-assign into a default-constructed object. -template <class T, class Prof> -struct ExpectDefaultConstructWithCopyAssign { - template <class Fun> - void operator()(const Fun& generator) const { - const T source_of_truth = generator(); - T object; - object = static_cast<const T&>(generator()); - - (ExpectEquality<T, Prof>)(errors, "Copy assignment", - PrepareGivenContext( - GivenDeclaration{"const _T source_of_truth", - generator.description}, - GivenDeclaration{"_T object", ""}, - GivenDeclaration{ - "object", - std::string("static_cast<const _T&>(") + - generator.description + ")"}), - object, source_of_truth, "std::as_const(object)", - "source_of_truth"); - } - - ConformanceErrors* errors; -}; - -// Perform a self move-assign. -template <class T, class Prof> -struct ExpectSelfMoveAssign { - template <class Fun> - void operator()(const Fun& generator) const { - T object = generator(); - object = absl::move(object); - - // NOTE: Self move-assign results in a valid-but-unspecified state. - - (ExpectEquality<T, Prof>)(errors, "Move assignment", - PrepareGivenContext( - GivenDeclaration{"_T object", - generator.description}, - GivenDeclaration{"object", - "std::move(object)"}), - object, object, "object", "object"); - } - - ConformanceErrors* errors; -}; - -// Perform a self copy-assign. -template <class T, class Prof> -struct ExpectSelfCopyAssign { - template <class Fun> - void operator()(const Fun& generator) const { - const T source_of_truth = generator(); - T object = generator(); - const T& const_object = object; - object = const_object; - - (ExpectEquality<T, Prof>)(errors, "Copy assignment", - PrepareGivenContext( - GivenDeclaration{"const _T source_of_truth", - generator.description}, - GivenDeclaration{"_T object", - generator.description}, - GivenDeclaration{"object", - "std::as_const(object)"}), - const_object, source_of_truth, - "std::as_const(object)", "source_of_truth"); - } - - ConformanceErrors* errors; -}; - -// Perform a self-swap. -template <class T, class Prof> -struct ExpectSelfSwap { - template <class Fun> - void operator()(const Fun& generator) const { - const T source_of_truth = generator(); - T object = generator(); - - type_traits_internal::Swap(object, object); - - std::string preliminary_info = absl::StrCat( - PrepareGivenContext( - GivenDeclaration{"const _T source_of_truth", generator.description}, - GivenDeclaration{"_T object", generator.description}), - "After performing a self-swap:\n" - " using std::swap;\n" - " swap(object, object);\n" - "\n"); - - (ExpectEquality<T, Prof>)(errors, "Swap", std::move(preliminary_info), - object, source_of_truth, "std::as_const(object)", - "source_of_truth"); - } - - ConformanceErrors* errors; -}; - -// Perform each of the single-generator checks when necessary operations are -// supported. -template <class T, class Prof> -struct ExpectSelfComparison { - template <class Fun> - void operator()(const Fun& generator) const { - const T object = generator(); - (ExpectOneWayEquality<T, Prof>)(errors, "Comparison", - PrepareGivenContext(GivenDeclaration{ - "const _T object", - generator.description}), - object, object, "object", "object"); - } - - ConformanceErrors* errors; -}; - -// Perform each of the single-generator checks when necessary operations are -// supported. -template <class T, class Prof> -struct ExpectConsistency { - template <class Fun> - void operator()(const Fun& generator) const { - If<PropertiesOfT<Prof>::is_move_constructible>::Invoke( - ExpectMoveConstructOneGenerator<T, Prof>{errors}, generator); - - If<PropertiesOfT<Prof>::is_copy_constructible>::Invoke( - ExpectCopyConstructOneGenerator<T, Prof>{errors}, generator); - - If<PropertiesOfT<Prof>::is_default_constructible && - PropertiesOfT<Prof>::is_move_assignable>:: - Invoke(ExpectDefaultConstructWithMoveAssign<T, Prof>{errors}, - generator); - - If<PropertiesOfT<Prof>::is_default_constructible && - PropertiesOfT<Prof>::is_copy_assignable>:: - Invoke(ExpectDefaultConstructWithCopyAssign<T, Prof>{errors}, - generator); - - If<PropertiesOfT<Prof>::is_move_assignable>::Invoke( - ExpectSelfMoveAssign<T, Prof>{errors}, generator); - - If<PropertiesOfT<Prof>::is_copy_assignable>::Invoke( - ExpectSelfCopyAssign<T, Prof>{errors}, generator); - - If<PropertiesOfT<Prof>::is_swappable>::Invoke( - ExpectSelfSwap<T, Prof>{errors}, generator); - } - - ConformanceErrors* errors; -}; - -// Check move-assign with two different values. -template <class T, class Prof> -struct ExpectMoveAssign { - template <class Fun0, class Fun1> - void operator()(const Fun0& generator0, const Fun1& generator1) const { - const T source_of_truth1 = generator1(); - T object = generator0(); - object = generator1(); - - (ExpectEquality<T, Prof>)(errors, "Move assignment", - PrepareGivenContext( - GivenDeclaration{"const _T source_of_truth1", - generator1.description}, - GivenDeclaration{"_T object", - generator0.description}, - GivenDeclaration{"object", - generator1.description}), - object, source_of_truth1, "std::as_const(object)", - "source_of_truth1"); - } - - ConformanceErrors* errors; -}; - -// Check copy-assign with two different values. -template <class T, class Prof> -struct ExpectCopyAssign { - template <class Fun0, class Fun1> - void operator()(const Fun0& generator0, const Fun1& generator1) const { - const T source_of_truth1 = generator1(); - T object = generator0(); - object = static_cast<const T&>(generator1()); - - (ExpectEquality<T, Prof>)(errors, "Copy assignment", - PrepareGivenContext( - GivenDeclaration{"const _T source_of_truth1", - generator1.description}, - GivenDeclaration{"_T object", - generator0.description}, - GivenDeclaration{ - "object", - std::string("static_cast<const _T&>(") + - generator1.description + ")"}), - object, source_of_truth1, "std::as_const(object)", - "source_of_truth1"); - } - - ConformanceErrors* errors; -}; - -// Check swap with two different values. -template <class T, class Prof> -struct ExpectSwap { - template <class Fun0, class Fun1> - void operator()(const Fun0& generator0, const Fun1& generator1) const { - const T source_of_truth0 = generator0(); - const T source_of_truth1 = generator1(); - T object0 = generator0(); - T object1 = generator1(); - - type_traits_internal::Swap(object0, object1); - - const std::string context = - PrepareGivenContext( - GivenDeclaration{"const _T source_of_truth0", - generator0.description}, - GivenDeclaration{"const _T source_of_truth1", - generator1.description}, - GivenDeclaration{"_T object0", generator0.description}, - GivenDeclaration{"_T object1", generator1.description}) + - "After performing a swap:\n" - " using std::swap;\n" - " swap(object0, object1);\n" - "\n"; - - (ExpectEquality<T, Prof>)(errors, "Swap", context, object0, - source_of_truth1, "std::as_const(object0)", - "source_of_truth1"); - (ExpectEquality<T, Prof>)(errors, "Swap", context, object1, - source_of_truth0, "std::as_const(object1)", - "source_of_truth0"); - } - - ConformanceErrors* errors; -}; - -// Validate that `generator0` and `generator1` produce values that are equal. -template <class T, class Prof> -struct ExpectEquivalenceClassComparison { - template <class Fun0, class Fun1> - void operator()(const Fun0& generator0, const Fun1& generator1) const { - const T object0 = generator0(); - const T object1 = generator1(); - - (ExpectEquality<T, Prof>)(errors, "Comparison", - PrepareGivenContext( - GivenDeclaration{"const _T object0", - generator0.description}, - GivenDeclaration{"const _T object1", - generator1.description}), - object0, object1, "object0", "object1"); - } - - ConformanceErrors* errors; -}; - -// Validate that all objects in the same equivalence-class have the same value. -template <class T, class Prof> -struct ExpectEquivalenceClassConsistency { - template <class Fun0, class Fun1> - void operator()(const Fun0& generator0, const Fun1& generator1) const { - If<PropertiesOfT<Prof>::is_move_assignable>::Invoke( - ExpectMoveAssign<T, Prof>{errors}, generator0, generator1); - - If<PropertiesOfT<Prof>::is_copy_assignable>::Invoke( - ExpectCopyAssign<T, Prof>{errors}, generator0, generator1); - - If<PropertiesOfT<Prof>::is_swappable>::Invoke(ExpectSwap<T, Prof>{errors}, - generator0, generator1); - } - - ConformanceErrors* errors; -}; - -// Given a "lesser" object and a "greater" object, perform every combination of -// comparison operators supported for the type, expecting consistent results. -template <class T, class Prof> -void ExpectOrdered(ConformanceErrors* errors, absl::string_view context, - const T& small, const T& big, absl::string_view small_name, - absl::string_view big_name) { - const absl::string_view test_name = "Comparison"; - - If<PropertiesOfT<Prof>::is_equality_comparable>::Invoke( - ExpectNotEq{errors}, test_name, context, small, big, small_name, - big_name); - If<PropertiesOfT<Prof>::is_equality_comparable>::Invoke( - ExpectNotEq{errors}, test_name, context, big, small, big_name, - small_name); - - If<PropertiesOfT<Prof>::is_inequality_comparable>::Invoke( - ExpectNe{errors}, test_name, context, small, big, small_name, big_name); - If<PropertiesOfT<Prof>::is_inequality_comparable>::Invoke( - ExpectNe{errors}, test_name, context, big, small, big_name, small_name); - - If<PropertiesOfT<Prof>::is_less_than_comparable>::Invoke( - ExpectLt{errors}, test_name, context, small, big, small_name, big_name); - If<PropertiesOfT<Prof>::is_less_than_comparable>::Invoke( - ExpectNotLt{errors}, test_name, context, big, small, big_name, - small_name); - - If<PropertiesOfT<Prof>::is_less_equal_comparable>::Invoke( - ExpectLe{errors}, test_name, context, small, big, small_name, big_name); - If<PropertiesOfT<Prof>::is_less_equal_comparable>::Invoke( - ExpectNotLe{errors}, test_name, context, big, small, big_name, - small_name); - - If<PropertiesOfT<Prof>::is_greater_equal_comparable>::Invoke( - ExpectNotGe{errors}, test_name, context, small, big, small_name, - big_name); - If<PropertiesOfT<Prof>::is_greater_equal_comparable>::Invoke( - ExpectGe{errors}, test_name, context, big, small, big_name, small_name); - - If<PropertiesOfT<Prof>::is_greater_than_comparable>::Invoke( - ExpectNotGt{errors}, test_name, context, small, big, small_name, - big_name); - If<PropertiesOfT<Prof>::is_greater_than_comparable>::Invoke( - ExpectGt{errors}, test_name, context, big, small, big_name, small_name); -} - -// For every two elements of an equivalence class, makes sure that those two -// elements compare equal, including checks with the same argument passed as -// both operands. -template <class T, class Prof> -struct ExpectEquivalenceClassComparisons { - template <class... Funs> - void operator()(EquivalenceClassType<Funs...> eq_class) const { - (ForEachTupleElement)(ExpectSelfComparison<T, Prof>{errors}, - eq_class.generators); - - (ForEveryTwo)(ExpectEquivalenceClassComparison<T, Prof>{errors}, - eq_class.generators); - } - - ConformanceErrors* errors; -}; - -// For every element of an equivalence class, makes sure that the element is -// self-consistent (in other words, if any of move/copy/swap are defined, -// perform those operations and make such that results and operands still -// compare equal to known values whenever it is required for that operation. -template <class T, class Prof> -struct ExpectEquivalenceClass { - template <class... Funs> - void operator()(EquivalenceClassType<Funs...> eq_class) const { - (ForEachTupleElement)(ExpectConsistency<T, Prof>{errors}, - eq_class.generators); - - (ForEveryTwo)(ExpectEquivalenceClassConsistency<T, Prof>{errors}, - eq_class.generators); - } - - ConformanceErrors* errors; -}; - -// Validate that the passed-in argument is a generator of a greater value than -// the one produced by the "small_gen" datamember with respect to all of the -// comparison operators that Prof requires, with both argument orders to test. -template <class T, class Prof, class SmallGenerator> -struct ExpectBiggerGeneratorThanComparisons { - template <class BigGenerator> - void operator()(BigGenerator big_gen) const { - const T small = small_gen(); - const T big = big_gen(); - - (ExpectOrdered<T, Prof>)(errors, - PrepareGivenContext( - GivenDeclaration{"const _T small", - small_gen.description}, - GivenDeclaration{"const _T big", - big_gen.description}), - small, big, "small", "big"); - } - - SmallGenerator small_gen; - ConformanceErrors* errors; -}; - -// Perform all of the move, copy, and swap checks on the value generated by -// `small_gen` and the value generated by `big_gen`. -template <class T, class Prof, class SmallGenerator> -struct ExpectBiggerGeneratorThan { - template <class BigGenerator> - void operator()(BigGenerator big_gen) const { - If<PropertiesOfT<Prof>::is_move_assignable>::Invoke( - ExpectMoveAssign<T, Prof>{errors}, small_gen, big_gen); - If<PropertiesOfT<Prof>::is_move_assignable>::Invoke( - ExpectMoveAssign<T, Prof>{errors}, big_gen, small_gen); - - If<PropertiesOfT<Prof>::is_copy_assignable>::Invoke( - ExpectCopyAssign<T, Prof>{errors}, small_gen, big_gen); - If<PropertiesOfT<Prof>::is_copy_assignable>::Invoke( - ExpectCopyAssign<T, Prof>{errors}, big_gen, small_gen); - - If<PropertiesOfT<Prof>::is_swappable>::Invoke(ExpectSwap<T, Prof>{errors}, - small_gen, big_gen); - } - - SmallGenerator small_gen; - ConformanceErrors* errors; -}; - -// Validate that the result of a generator is greater than the results of all -// generators in an equivalence class with respect to comparisons. -template <class T, class Prof, class SmallGenerator> -struct ExpectBiggerGeneratorThanEqClassesComparisons { - template <class BigEqClass> - void operator()(BigEqClass big_eq_class) const { - (ForEachTupleElement)( - ExpectBiggerGeneratorThanComparisons<T, Prof, SmallGenerator>{small_gen, - errors}, - big_eq_class.generators); - } - - SmallGenerator small_gen; - ConformanceErrors* errors; -}; - -// Validate that the non-comparison binary operations required by Prof are -// correct for the result of each generator of big_eq_class and a generator of -// the logically smaller value returned by small_gen. -template <class T, class Prof, class SmallGenerator> -struct ExpectBiggerGeneratorThanEqClasses { - template <class BigEqClass> - void operator()(BigEqClass big_eq_class) const { - (ForEachTupleElement)( - ExpectBiggerGeneratorThan<T, Prof, SmallGenerator>{small_gen, errors}, - big_eq_class.generators); - } - - SmallGenerator small_gen; - ConformanceErrors* errors; -}; - -// Validate that each equivalence class that is passed is logically less than -// the equivalence classes that comes later on in the argument list. -template <class T, class Prof> -struct ExpectOrderedEquivalenceClassesComparisons { - template <class... BigEqClasses> - struct Impl { - // Validate that the value produced by `small_gen` is less than all of the - // values generated by those of the logically larger equivalence classes. - template <class SmallGenerator> - void operator()(SmallGenerator small_gen) const { - (ForEachTupleElement)(ExpectBiggerGeneratorThanEqClassesComparisons< - T, Prof, SmallGenerator>{small_gen, errors}, - big_eq_classes); - } - - std::tuple<BigEqClasses...> big_eq_classes; - ConformanceErrors* errors; - }; - - // When given no equivalence classes, no validation is necessary. - void operator()() const {} - - template <class SmallEqClass, class... BigEqClasses> - void operator()(SmallEqClass small_eq_class, - BigEqClasses... big_eq_classes) const { - // For each generator in the first equivalence class, make sure that it is - // less than each of those in the logically greater equivalence classes. - (ForEachTupleElement)( - Impl<BigEqClasses...>{std::make_tuple(absl::move(big_eq_classes)...), - errors}, - small_eq_class.generators); - - // Recurse so that all equivalence class combinations are checked. - (*this)(absl::move(big_eq_classes)...); - } - - ConformanceErrors* errors; -}; - -// Validate that the non-comparison binary operations required by Prof are -// correct for the result of each generator of big_eq_classes and a generator of -// the logically smaller value returned by small_gen. -template <class T, class Prof> -struct ExpectOrderedEquivalenceClasses { - template <class... BigEqClasses> - struct Impl { - template <class SmallGenerator> - void operator()(SmallGenerator small_gen) const { - (ForEachTupleElement)( - ExpectBiggerGeneratorThanEqClasses<T, Prof, SmallGenerator>{small_gen, - errors}, - big_eq_classes); - } - - std::tuple<BigEqClasses...> big_eq_classes; - ConformanceErrors* errors; - }; - - // Check that small_eq_class is logically consistent and also is logically - // less than all values in big_eq_classes. - template <class SmallEqClass, class... BigEqClasses> - void operator()(SmallEqClass small_eq_class, - BigEqClasses... big_eq_classes) const { - (ForEachTupleElement)( - Impl<BigEqClasses...>{std::make_tuple(absl::move(big_eq_classes)...), - errors}, - small_eq_class.generators); - - (*this)(absl::move(big_eq_classes)...); - } - - // Terminating case of operator(). - void operator()() const {} - - ConformanceErrors* errors; -}; - -// Validate that a type meets the syntactic requirements of std::hash if the -// range of profiles requires it. -template <class T, class MinProf, class MaxProf> -struct ExpectHashable { - void operator()() const { - ExpectModelOfHashable<T, MinProf, MaxProf>(errors); - } - - ConformanceErrors* errors; -}; - -// Validate that the type `T` meets all of the requirements associated with -// `MinProf` and without going beyond the syntactic properties of `MaxProf`. -template <class T, class MinProf, class MaxProf> -struct ExpectModels { - void operator()(ConformanceErrors* errors) const { - ExpectModelOfDefaultConstructible<T, MinProf, MaxProf>(errors); - ExpectModelOfMoveConstructible<T, MinProf, MaxProf>(errors); - ExpectModelOfCopyConstructible<T, MinProf, MaxProf>(errors); - ExpectModelOfMoveAssignable<T, MinProf, MaxProf>(errors); - ExpectModelOfCopyAssignable<T, MinProf, MaxProf>(errors); - ExpectModelOfDestructible<T, MinProf, MaxProf>(errors); - ExpectModelOfEqualityComparable<T, MinProf, MaxProf>(errors); - ExpectModelOfInequalityComparable<T, MinProf, MaxProf>(errors); - ExpectModelOfLessThanComparable<T, MinProf, MaxProf>(errors); - ExpectModelOfLessEqualComparable<T, MinProf, MaxProf>(errors); - ExpectModelOfGreaterEqualComparable<T, MinProf, MaxProf>(errors); - ExpectModelOfGreaterThanComparable<T, MinProf, MaxProf>(errors); - ExpectModelOfSwappable<T, MinProf, MaxProf>(errors); - - // Only check hashability on compilers that have a compliant default-hash. - If<!poisoned_hash_fails_instantiation()>::Invoke( - ExpectHashable<T, MinProf, MaxProf>{errors}); - } -}; - -// A metafunction that yields a Profile matching the set of properties that are -// safe to be checked (lack-of-hashability is only checked on standard library -// implementations that are standards compliant in that they provide a std::hash -// primary template that is SFINAE-friendly) -template <class LogicalProf, class T> -struct MinimalCheckableProfile { - using type = - MinimalProfiles<PropertiesOfT<LogicalProf>, - PropertiesOfT<SyntacticConformanceProfileOf< - T, !PropertiesOfT<LogicalProf>::is_hashable && - poisoned_hash_fails_instantiation() - ? CheckHashability::no - : CheckHashability::yes>>>; -}; - -// An identity metafunction -template <class T> -struct Always { - using type = T; -}; - -// Validate the T meets all of the necessary requirements of LogicalProf, with -// syntactic requirements defined by the profile range [MinProf, MaxProf]. -template <class T, class LogicalProf, class MinProf, class MaxProf, - class... EqClasses> -ConformanceErrors ExpectRegularityImpl( - OrderedEquivalenceClasses<EqClasses...> vals) { - ConformanceErrors errors((NameOf<T>())); - - If<!constexpr_instantiation_when_unevaluated()>::Invoke( - ExpectModels<T, MinProf, MaxProf>(), &errors); - - using minimal_profile = typename absl::conditional_t< - constexpr_instantiation_when_unevaluated(), Always<LogicalProf>, - MinimalCheckableProfile<LogicalProf, T>>::type; - - If<PropertiesOfT<minimal_profile>::is_default_constructible>::Invoke( - ExpectDefaultConstructWithDestruct<T>{&errors}); - - ////////////////////////////////////////////////////////////////////////////// - // Perform all comparison checks first, since later checks depend on their - // correctness. - // - // Check all of the comparisons for all values in the same equivalence - // class (equal with respect to comparison operators and hash the same). - (ForEachTupleElement)( - ExpectEquivalenceClassComparisons<T, minimal_profile>{&errors}, - vals.eq_classes); - - // Check all of the comparisons for each combination of values that are in - // different equivalence classes (not equal with respect to comparison - // operators). - absl::apply( - ExpectOrderedEquivalenceClassesComparisons<T, minimal_profile>{&errors}, - vals.eq_classes); - // - ////////////////////////////////////////////////////////////////////////////// - - // Perform remaining checks, relying on comparisons. - // TODO(calabrese) short circuit if any comparisons above failed. - (ForEachTupleElement)(ExpectEquivalenceClass<T, minimal_profile>{&errors}, - vals.eq_classes); - - absl::apply(ExpectOrderedEquivalenceClasses<T, minimal_profile>{&errors}, - vals.eq_classes); - - return errors; -} - -// A type that represents a range of profiles that are acceptable to be matched. -// -// `MinProf` is the minimum set of syntactic requirements that must be met. -// -// `MaxProf` is the maximum set of syntactic requirements that must be met. -// This maximum is particularly useful for certain "strictness" checking. Some -// examples for when this is useful: -// -// * Making sure that a type is move-only (rather than simply movable) -// -// * Making sure that a member function is *not* noexcept in cases where it -// cannot be noexcept, such as if a dependent datamember has certain -// operations that are not noexcept. -// -// * Making sure that a type tightly matches a spec, such as the standard. -// -// `LogicalProf` is the Profile for which run-time testing is to take place. -// -// Note: The reason for `LogicalProf` is because it is often the case, when -// dealing with templates, that a declaration of a given operation is specified, -// but whose body would fail to instantiate. Examples include the -// copy-constructor of a standard container when the element-type is move-only, -// or the comparison operators of a standard container when the element-type -// does not have the necessary comparison operations defined. The `LogicalProf` -// parameter allows us to capture the intent of what should be tested at -// run-time, even in the cases where syntactically it might otherwise appear as -// though the type undergoing testing supports more than it actually does. -template <class LogicalProf, class MinProf = LogicalProf, - class MaxProf = MinProf> -struct ProfileRange { - using logical_profile = LogicalProf; - using min_profile = MinProf; - using max_profile = MaxProf; -}; - -// Similar to ProfileRange except that it creates a profile range that is -// coupled with a Domain and is used when testing that a type matches exactly -// the "minimum" requirements of LogicalProf. -template <class StrictnessDomain, class LogicalProf, - class MinProf = LogicalProf, class MaxProf = MinProf> -struct StrictProfileRange { - // We do not yet support extension. - static_assert( - std::is_same<StrictnessDomain, RegularityDomain>::value, - "Currently, the only valid StrictnessDomain is RegularityDomain."); - using strictness_domain = StrictnessDomain; - using logical_profile = LogicalProf; - using min_profile = MinProf; - using max_profile = MaxProf; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -// A metafunction that creates a StrictProfileRange from a Domain and either a -// Profile or ProfileRange. -template <class StrictnessDomain, class ProfOrRange> -struct MakeStrictProfileRange; - -template <class StrictnessDomain, class LogicalProf> -struct MakeStrictProfileRange { - using type = StrictProfileRange<StrictnessDomain, LogicalProf>; -}; - -template <class StrictnessDomain, class LogicalProf, class MinProf, - class MaxProf> -struct MakeStrictProfileRange<StrictnessDomain, - ProfileRange<LogicalProf, MinProf, MaxProf>> { - using type = - StrictProfileRange<StrictnessDomain, LogicalProf, MinProf, MaxProf>; -}; - -template <class StrictnessDomain, class ProfOrRange> -using MakeStrictProfileRangeT = - typename MakeStrictProfileRange<StrictnessDomain, ProfOrRange>::type; -// -//////////////////////////////////////////////////////////////////////////////// - -// A profile in the RegularityDomain with the strongest possible requirements. -using MostStrictProfile = - CombineProfiles<TriviallyCompleteProfile, NothrowComparableProfile>; - -// Forms a ProfileRange that treats the Profile as the bare minimum requirements -// of a type. -template <class LogicalProf, class MinProf = LogicalProf> -using LooseProfileRange = StrictProfileRange<RegularityDomain, LogicalProf, - MinProf, MostStrictProfile>; - -template <class Prof> -using MakeLooseProfileRangeT = Prof; - -//////////////////////////////////////////////////////////////////////////////// -// -// The following classes implement the metafunction ProfileRangeOfT<T> that -// takes either a Profile or ProfileRange and yields the ProfileRange to be -// used during testing. -// -template <class T, class /*Enabler*/ = void> -struct ProfileRangeOfImpl; - -template <class T> -struct ProfileRangeOfImpl<T, absl::void_t<PropertiesOfT<T>>> { - using type = LooseProfileRange<T>; -}; - -template <class T> -struct ProfileRangeOf : ProfileRangeOfImpl<T> {}; - -template <class StrictnessDomain, class LogicalProf, class MinProf, - class MaxProf> -struct ProfileRangeOf< - StrictProfileRange<StrictnessDomain, LogicalProf, MinProf, MaxProf>> { - using type = - StrictProfileRange<StrictnessDomain, LogicalProf, MinProf, MaxProf>; -}; - -template <class T> -using ProfileRangeOfT = typename ProfileRangeOf<T>::type; -// -//////////////////////////////////////////////////////////////////////////////// - -// Extract the logical profile of a range (what will be runtime tested). -template <class T> -using LogicalProfileOfT = typename ProfileRangeOfT<T>::logical_profile; - -// Extract the minimal syntactic profile of a range (error if not at least). -template <class T> -using MinProfileOfT = typename ProfileRangeOfT<T>::min_profile; - -// Extract the maximum syntactic profile of a range (error if more than). -template <class T> -using MaxProfileOfT = typename ProfileRangeOfT<T>::max_profile; - -//////////////////////////////////////////////////////////////////////////////// -// -template <class T> -struct IsProfileOrProfileRange : IsProfile<T>::type {}; - -template <class StrictnessDomain, class LogicalProf, class MinProf, - class MaxProf> -struct IsProfileOrProfileRange< - StrictProfileRange<StrictnessDomain, LogicalProf, MinProf, MaxProf>> - : std::true_type {}; -// -//////////////////////////////////////////////////////////////////////////////// - -// TODO(calabrese): Consider naming the functions in this class the same as -// the macros (defined later on) so that auto-complete leads to the correct name -// and so that a user cannot accidentally call a function rather than the macro -// form. -template <bool ExpectSuccess, class T, class... EqClasses> -struct ExpectConformanceOf { - // Add a value to be tested. Subsequent calls to this function on the same - // object must specify logically "larger" values with respect to the - // comparison operators of the type, if any. - // - // NOTE: This function should not be called directly. A stateless lambda is - // implicitly formed and passed when using the INITIALIZER macro at the bottom - // of this file. - template <class Fun, - absl::enable_if_t<std::is_same< - ResultOfGeneratorT<GeneratorType<Fun>>, T>::value>** = nullptr> - ABSL_MUST_USE_RESULT ExpectConformanceOf<ExpectSuccess, T, EqClasses..., - EquivalenceClassType<Fun>> - initializer(GeneratorType<Fun> fun) && { - return { - {std::tuple_cat(absl::move(ordered_vals.eq_classes), - std::make_tuple((EquivalenceClass)(absl::move(fun))))}, - std::move(expected_failed_tests)}; - } - - template <class... TestNames, - absl::enable_if_t<!ExpectSuccess && sizeof...(EqClasses) == 0 && - absl::conjunction<std::is_convertible< - TestNames, absl::string_view>...>::value>** = - nullptr> - ABSL_MUST_USE_RESULT ExpectConformanceOf<ExpectSuccess, T, EqClasses...> - due_to(TestNames&&... test_names) && { - (InsertEach)(&expected_failed_tests, - absl::AsciiStrToLower(absl::string_view(test_names))...); - - return {absl::move(ordered_vals), std::move(expected_failed_tests)}; - } - - template <class... TestNames, int = 0, // MSVC disambiguator - absl::enable_if_t<ExpectSuccess && sizeof...(EqClasses) == 0 && - absl::conjunction<std::is_convertible< - TestNames, absl::string_view>...>::value>** = - nullptr> - ABSL_MUST_USE_RESULT ExpectConformanceOf<ExpectSuccess, T, EqClasses...> - due_to(TestNames&&... test_names) && { - // TODO(calabrese) Instead have DUE_TO only exist via a CRTP base. - // This would produce better errors messages than the static_assert. - static_assert(!ExpectSuccess, - "DUE_TO cannot be called when conformance is expected -- did " - "you mean to use ASSERT_NONCONFORMANCE_OF?"); - } - - // Add a value to be tested. Subsequent calls to this function on the same - // object must specify logically "larger" values with respect to the - // comparison operators of the type, if any. - // - // NOTE: This function should not be called directly. A stateful lambda is - // implicitly formed and passed when using the INITIALIZER macro at the bottom - // of this file. - template <class Fun, - absl::enable_if_t<std::is_same< - ResultOfGeneratorT<GeneratorType<Fun>>, T>::value>** = nullptr> - ABSL_MUST_USE_RESULT ExpectConformanceOf<ExpectSuccess, T, EqClasses..., - EquivalenceClassType<Fun>> - dont_class_directly_stateful_initializer(GeneratorType<Fun> fun) && { - return { - {std::tuple_cat(absl::move(ordered_vals.eq_classes), - std::make_tuple((EquivalenceClass)(absl::move(fun))))}, - std::move(expected_failed_tests)}; - } - - // Add a set of value to be tested, where each value is equal with respect to - // the comparison operators and std::hash specialization, if defined. - template < - class... Funs, - absl::void_t<absl::enable_if_t<std::is_same< - ResultOfGeneratorT<GeneratorType<Funs>>, T>::value>...>** = nullptr> - ABSL_MUST_USE_RESULT ExpectConformanceOf<ExpectSuccess, T, EqClasses..., - EquivalenceClassType<Funs...>> - equivalence_class(GeneratorType<Funs>... funs) && { - return {{std::tuple_cat( - absl::move(ordered_vals.eq_classes), - std::make_tuple((EquivalenceClass)(absl::move(funs)...)))}, - std::move(expected_failed_tests)}; - } - - // Execute the tests for the captured set of values, strictly matching a range - // of expected profiles in a given domain. - template < - class ProfRange, - absl::enable_if_t<IsProfileOrProfileRange<ProfRange>::value>** = nullptr> - ABSL_MUST_USE_RESULT ::testing::AssertionResult with_strict_profile( - ProfRange /*profile*/) { - ConformanceErrors test_result = - (ExpectRegularityImpl< - T, LogicalProfileOfT<ProfRange>, MinProfileOfT<ProfRange>, - MaxProfileOfT<ProfRange>>)(absl::move(ordered_vals)); - - return ExpectSuccess ? test_result.assertionResult() - : test_result.expectFailedTests(expected_failed_tests); - } - - // Execute the tests for the captured set of values, loosely matching a range - // of expected profiles (loose in that an interface is allowed to be more - // refined that a profile suggests, such as a type having a noexcept copy - // constructor when all that is required is that the copy constructor exists). - template <class Prof, absl::enable_if_t<IsProfile<Prof>::value>** = nullptr> - ABSL_MUST_USE_RESULT ::testing::AssertionResult with_loose_profile( - Prof /*profile*/) { - ConformanceErrors test_result = - (ExpectRegularityImpl< - T, Prof, Prof, - CombineProfiles<TriviallyCompleteProfile, - NothrowComparableProfile>>)(absl:: - move(ordered_vals)); - - return ExpectSuccess ? test_result.assertionResult() - : test_result.expectFailedTests(expected_failed_tests); - } - - OrderedEquivalenceClasses<EqClasses...> ordered_vals; - std::set<std::string> expected_failed_tests; -}; - -template <class T> -using ExpectConformanceOfType = ExpectConformanceOf</*ExpectSuccess=*/true, T>; - -template <class T> -using ExpectNonconformanceOfType = - ExpectConformanceOf</*ExpectSuccess=*/false, T>; - -struct EquivalenceClassMaker { - // TODO(calabrese) Constrain to callable - template <class Fun> - static GeneratorType<Fun> initializer(GeneratorType<Fun> fun) { - return fun; - } -}; - -// A top-level macro that begins the builder pattern. -// -// The argument here takes the datatype to be tested. -#define ABSL_INTERNAL_ASSERT_CONFORMANCE_OF(...) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if ABSL_INTERNAL_LPAREN \ - const ::testing::AssertionResult gtest_ar = \ - ABSL_INTERNAL_LPAREN ::absl::types_internal::ExpectConformanceOfType< \ - __VA_ARGS__>() - -// Akin to ASSERT_CONFORMANCE_OF except that it expects failure and tries to -// match text. -#define ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(...) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if ABSL_INTERNAL_LPAREN \ - const ::testing::AssertionResult gtest_ar = \ - ABSL_INTERNAL_LPAREN ::absl::types_internal::ExpectNonconformanceOfType< \ - __VA_ARGS__>() - -//////////////////////////////////////////////////////////////////////////////// -// NOTE: The following macros look like they are recursive, but are not (macros -// cannot recurse). These actually refer to member functions of the same name. -// This is done intentionally so that a user cannot accidentally invoke a -// member function of the conformance-testing suite without going through the -// macro. -//////////////////////////////////////////////////////////////////////////////// - -// Specify expected test failures as comma-separated strings. -#define DUE_TO(...) due_to(__VA_ARGS__) - -// Specify a value to be tested. -// -// Note: Internally, this takes an expression and turns it into the return value -// of lambda that captures no data. The expression is stringized during -// preprocessing so that it can be used in error reports. -#define INITIALIZER(...) \ - initializer(::absl::types_internal::Generator( \ - [] { return __VA_ARGS__; }, ABSL_INTERNAL_STRINGIZE(__VA_ARGS__))) - -// Specify a value to be tested. -// -// Note: Internally, this takes an expression and turns it into the return value -// of lambda that captures data by reference. The expression is stringized -// during preprocessing so that it can be used in error reports. -#define STATEFUL_INITIALIZER(...) \ - stateful_initializer(::absl::types_internal::Generator( \ - [&] { return __VA_ARGS__; }, ABSL_INTERNAL_STRINGIZE(__VA_ARGS__))) - -// Used in the builder-pattern. -// -// Takes a series of INITIALIZER and/or STATEFUL_INITIALIZER invocations and -// forwards them along to be tested, grouping them such that the testing suite -// knows that they are supposed to represent the same logical value (the values -// compare the same, hash the same, etc.). -#define EQUIVALENCE_CLASS(...) \ - equivalence_class(ABSL_INTERNAL_TRANSFORM_ARGS( \ - ABSL_INTERNAL_PREPEND_EQ_MAKER, __VA_ARGS__)) - -// An invocation of this or WITH_STRICT_PROFILE must end the builder-pattern. -// It takes a Profile as its argument. -// -// This executes the tests and allows types that are "more referined" than the -// profile specifies, but not less. For instance, if the Profile specifies -// noexcept copy-constructiblity, the test will fail if the copy-constructor is -// not noexcept, however, it will succeed if the copy constructor is trivial. -// -// This is useful for testing that a type meets some minimum set of -// requirements. -#define WITH_LOOSE_PROFILE(...) \ - with_loose_profile( \ - ::absl::types_internal::MakeLooseProfileRangeT<__VA_ARGS__>()) \ - ABSL_INTERNAL_RPAREN ABSL_INTERNAL_RPAREN; \ - else GTEST_FATAL_FAILURE_(gtest_ar.failure_message()) // NOLINT - -// An invocation of this or WITH_STRICT_PROFILE must end the builder-pattern. -// It takes a Domain and a Profile as its arguments. -// -// This executes the tests and disallows types that differ at all from the -// properties of the Profile. For instance, if the Profile specifies noexcept -// copy-constructiblity, the test will fail if the copy constructor is trivial. -// -// This is useful for testing that a type does not do anything more than a -// specification requires, such as to minimize things like Hyrum's Law, or more -// commonly, to prevent a type from being "accidentally" copy-constructible in -// a way that may produce incorrect results, simply because the user forget to -// delete that operation. -#define WITH_STRICT_PROFILE(...) \ - with_strict_profile( \ - ::absl::types_internal::MakeStrictProfileRangeT<__VA_ARGS__>()) \ - ABSL_INTERNAL_RPAREN ABSL_INTERNAL_RPAREN; \ - else GTEST_FATAL_FAILURE_(gtest_ar.failure_message()) // NOLINT - -// Internal macro that is used in the internals of the EDSL when forming -// equivalence classes. -#define ABSL_INTERNAL_PREPEND_EQ_MAKER(arg) \ - ::absl::types_internal::EquivalenceClassMaker().arg - -} // namespace types_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_TESTING_H_ +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// conformance_testing.h +// ----------------------------------------------------------------------------- +// + +#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_TESTING_H_ +#define ABSL_TYPES_INTERNAL_CONFORMANCE_TESTING_H_ + +//////////////////////////////////////////////////////////////////////////////// +// // +// Many templates in this file take a `T` and a `Prof` type as explicit // +// template arguments. These are a type to be checked and a // +// "Regularity Profile" that describes what operations that type `T` is // +// expected to support. See "regularity_profiles.h" for more details // +// regarding Regularity Profiles. // +// // +//////////////////////////////////////////////////////////////////////////////// + +#include <cstddef> +#include <set> +#include <tuple> +#include <type_traits> +#include <utility> + +#include "gtest/gtest.h" +#include "absl/meta/type_traits.h" +#include "absl/strings/ascii.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "absl/types/internal/conformance_aliases.h" +#include "absl/types/internal/conformance_archetype.h" +#include "absl/types/internal/conformance_profile.h" +#include "absl/types/internal/conformance_testing_helpers.h" +#include "absl/types/internal/parentheses.h" +#include "absl/types/internal/transform_args.h" +#include "absl/utility/utility.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace types_internal { + +// Returns true if the compiler incorrectly greedily instantiates constexpr +// templates in any unevaluated context. +constexpr bool constexpr_instantiation_when_unevaluated() { +#if defined(__apple_build_version__) // TODO(calabrese) Make more specific + return true; +#elif defined(__clang__) + return __clang_major__ < 4; +#elif defined(__GNUC__) + // TODO(calabrese) Figure out why gcc 7 fails (seems like a different bug) + return __GNUC__ < 5 || (__GNUC__ == 5 && __GNUC_MINOR__ < 2) || __GNUC__ >= 7; +#else + return false; +#endif +} + +// Returns true if the standard library being used incorrectly produces an error +// when instantiating the definition of a poisoned std::hash specialization. +constexpr bool poisoned_hash_fails_instantiation() { +#if defined(_MSC_VER) && !defined(_LIBCPP_VERSION) + return _MSC_VER < 1914; +#else + return false; +#endif +} + +template <class Fun> +struct GeneratorType { + decltype(std::declval<const Fun&>()()) operator()() const + noexcept(noexcept(std::declval<const Fun&>()())) { + return fun(); + } + + Fun fun; + const char* description; +}; + +// A "make" function for the GeneratorType template that deduces the function +// object type. +template <class Fun, + absl::enable_if_t<IsNullaryCallable<Fun>::value>** = nullptr> +GeneratorType<Fun> Generator(Fun fun, const char* description) { + return GeneratorType<Fun>{absl::move(fun), description}; +} + +// A type that contains a set of nullary function objects that each return an +// instance of the same type and value (though possibly different +// representations, such as +0 and -0 or two vectors with the same elements but +// with different capacities). +template <class... Funs> +struct EquivalenceClassType { + std::tuple<GeneratorType<Funs>...> generators; +}; + +// A "make" function for the EquivalenceClassType template that deduces the +// function object types and is constrained such that a user can only pass in +// function objects that all have the same return type. +template <class... Funs, absl::enable_if_t<AreGeneratorsWithTheSameReturnType< + Funs...>::value>** = nullptr> +EquivalenceClassType<Funs...> EquivalenceClass(GeneratorType<Funs>... funs) { + return {std::make_tuple(absl::move(funs)...)}; +} + +// A type that contains an ordered series of EquivalenceClassTypes, from +// smallest value to largest value. +template <class... EqClasses> +struct OrderedEquivalenceClasses { + std::tuple<EqClasses...> eq_classes; +}; + +// An object containing the parts of a given (name, initialization expression), +// and is capable of generating a string that describes the given. +struct GivenDeclaration { + std::string outputDeclaration(std::size_t width) const { + const std::size_t indent_size = 2; + std::string result = absl::StrCat(" ", name); + + if (!expression.empty()) { + // Indent + result.resize(indent_size + width, ' '); + absl::StrAppend(&result, " = ", expression, ";\n"); + } else { + absl::StrAppend(&result, ";\n"); + } + + return result; + } + + std::string name; + std::string expression; +}; + +// Produce a string that contains all of the givens of an error report. +template <class... Decls> +std::string PrepareGivenContext(const Decls&... decls) { + const std::size_t width = (std::max)({decls.name.size()...}); + return absl::StrCat("Given:\n", decls.outputDeclaration(width)..., "\n"); +} + +//////////////////////////////////////////////////////////////////////////////// +// Function objects that perform a check for each comparison operator // +//////////////////////////////////////////////////////////////////////////////// + +#define ABSL_INTERNAL_EXPECT_OP(name, op) \ + struct Expect##name { \ + template <class T> \ + void operator()(absl::string_view test_name, absl::string_view context, \ + const T& lhs, const T& rhs, absl::string_view lhs_name, \ + absl::string_view rhs_name) const { \ + if (!static_cast<bool>(lhs op rhs)) { \ + errors->addTestFailure( \ + test_name, absl::StrCat(context, \ + "**Unexpected comparison result**\n" \ + "\n" \ + "Expression:\n" \ + " ", \ + lhs_name, " " #op " ", rhs_name, \ + "\n" \ + "\n" \ + "Expected: true\n" \ + " Actual: false")); \ + } else { \ + errors->addTestSuccess(test_name); \ + } \ + } \ + \ + ConformanceErrors* errors; \ + }; \ + \ + struct ExpectNot##name { \ + template <class T> \ + void operator()(absl::string_view test_name, absl::string_view context, \ + const T& lhs, const T& rhs, absl::string_view lhs_name, \ + absl::string_view rhs_name) const { \ + if (lhs op rhs) { \ + errors->addTestFailure( \ + test_name, absl::StrCat(context, \ + "**Unexpected comparison result**\n" \ + "\n" \ + "Expression:\n" \ + " ", \ + lhs_name, " " #op " ", rhs_name, \ + "\n" \ + "\n" \ + "Expected: false\n" \ + " Actual: true")); \ + } else { \ + errors->addTestSuccess(test_name); \ + } \ + } \ + \ + ConformanceErrors* errors; \ + } + +ABSL_INTERNAL_EXPECT_OP(Eq, ==); +ABSL_INTERNAL_EXPECT_OP(Ne, !=); +ABSL_INTERNAL_EXPECT_OP(Lt, <); +ABSL_INTERNAL_EXPECT_OP(Le, <=); +ABSL_INTERNAL_EXPECT_OP(Ge, >=); +ABSL_INTERNAL_EXPECT_OP(Gt, >); + +#undef ABSL_INTERNAL_EXPECT_OP + +// A function object that verifies that two objects hash to the same value by +// way of the std::hash specialization. +struct ExpectSameHash { + template <class T> + void operator()(absl::string_view test_name, absl::string_view context, + const T& lhs, const T& rhs, absl::string_view lhs_name, + absl::string_view rhs_name) const { + if (std::hash<T>()(lhs) != std::hash<T>()(rhs)) { + errors->addTestFailure( + test_name, absl::StrCat(context, + "**Unexpected hash result**\n" + "\n" + "Expression:\n" + " std::hash<T>()(", + lhs_name, ") == std::hash<T>()(", rhs_name, + ")\n" + "\n" + "Expected: true\n" + " Actual: false")); + } else { + errors->addTestSuccess(test_name); + } + } + + ConformanceErrors* errors; +}; + +// A function template that takes two objects and verifies that each comparison +// operator behaves in a way that is consistent with equality. It has "OneWay" +// in the name because the first argument will always be the left-hand operand +// of the corresponding comparison operator and the second argument will +// always be the right-hand operand. It will never switch that order. +// At a higher level in the test suite, the one-way form is called once for each +// of the two possible orders whenever lhs and rhs are not the same initializer. +template <class T, class Prof> +void ExpectOneWayEquality(ConformanceErrors* errors, + absl::string_view test_name, + absl::string_view context, const T& lhs, const T& rhs, + absl::string_view lhs_name, + absl::string_view rhs_name) { + If<PropertiesOfT<Prof>::is_equality_comparable>::Invoke( + ExpectEq{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); + + If<PropertiesOfT<Prof>::is_inequality_comparable>::Invoke( + ExpectNotNe{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); + + If<PropertiesOfT<Prof>::is_less_than_comparable>::Invoke( + ExpectNotLt{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); + + If<PropertiesOfT<Prof>::is_less_equal_comparable>::Invoke( + ExpectLe{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); + + If<PropertiesOfT<Prof>::is_greater_equal_comparable>::Invoke( + ExpectGe{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); + + If<PropertiesOfT<Prof>::is_greater_than_comparable>::Invoke( + ExpectNotGt{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); + + If<PropertiesOfT<Prof>::is_hashable>::Invoke( + ExpectSameHash{errors}, test_name, context, lhs, rhs, lhs_name, rhs_name); +} + +// A function template that takes two objects and verifies that each comparison +// operator behaves in a way that is consistent with equality. This function +// differs from ExpectOneWayEquality in that this will do checks with argument +// order reversed in addition to in-order. +template <class T, class Prof> +void ExpectEquality(ConformanceErrors* errors, absl::string_view test_name, + absl::string_view context, const T& lhs, const T& rhs, + absl::string_view lhs_name, absl::string_view rhs_name) { + (ExpectOneWayEquality<T, Prof>)(errors, test_name, context, lhs, rhs, + lhs_name, rhs_name); + (ExpectOneWayEquality<T, Prof>)(errors, test_name, context, rhs, lhs, + rhs_name, lhs_name); +} + +// Given a generator, makes sure that a generated value and a moved-from +// generated value are equal. +template <class T, class Prof> +struct ExpectMoveConstructOneGenerator { + template <class Fun> + void operator()(const Fun& generator) const { + const T object = generator(); + const T moved_object = absl::move(generator()); // Force no elision. + + (ExpectEquality<T, Prof>)(errors, "Move construction", + PrepareGivenContext( + GivenDeclaration{"const _T object", + generator.description}, + GivenDeclaration{"const _T moved_object", + std::string("std::move(") + + generator.description + + ")"}), + object, moved_object, "object", "moved_object"); + } + + ConformanceErrors* errors; +}; + +// Given a generator, makes sure that a generated value and a copied-from +// generated value are equal. +template <class T, class Prof> +struct ExpectCopyConstructOneGenerator { + template <class Fun> + void operator()(const Fun& generator) const { + const T object = generator(); + const T copied_object = static_cast<const T&>(generator()); + + (ExpectEquality<T, Prof>)(errors, "Copy construction", + PrepareGivenContext( + GivenDeclaration{"const _T object", + generator.description}, + GivenDeclaration{ + "const _T copied_object", + std::string("static_cast<const _T&>(") + + generator.description + ")"}), + object, copied_object, "object", "copied_object"); + } + + ConformanceErrors* errors; +}; + +// Default-construct and do nothing before destruction. +// +// This is useful in exercising the codepath of default construction followed by +// destruction, but does not explicitly test anything. An example of where this +// might fail is a default destructor that default-initializes a scalar and a +// destructor reads the value of that member. Sanitizers can catch this as long +// as our test attempts to execute such a case. +template <class T> +struct ExpectDefaultConstructWithDestruct { + void operator()() const { + // Scoped so that destructor gets called before reporting success. + { + T object; + static_cast<void>(object); + } + + errors->addTestSuccess("Default construction"); + } + + ConformanceErrors* errors; +}; + +// Check move-assign into a default-constructed object. +template <class T, class Prof> +struct ExpectDefaultConstructWithMoveAssign { + template <class Fun> + void operator()(const Fun& generator) const { + const T source_of_truth = generator(); + T object; + object = generator(); + + (ExpectEquality<T, Prof>)(errors, "Move assignment", + PrepareGivenContext( + GivenDeclaration{"const _T object", + generator.description}, + GivenDeclaration{"_T object", ""}, + GivenDeclaration{"object", + generator.description}), + object, source_of_truth, "std::as_const(object)", + "source_of_truth"); + } + + ConformanceErrors* errors; +}; + +// Check copy-assign into a default-constructed object. +template <class T, class Prof> +struct ExpectDefaultConstructWithCopyAssign { + template <class Fun> + void operator()(const Fun& generator) const { + const T source_of_truth = generator(); + T object; + object = static_cast<const T&>(generator()); + + (ExpectEquality<T, Prof>)(errors, "Copy assignment", + PrepareGivenContext( + GivenDeclaration{"const _T source_of_truth", + generator.description}, + GivenDeclaration{"_T object", ""}, + GivenDeclaration{ + "object", + std::string("static_cast<const _T&>(") + + generator.description + ")"}), + object, source_of_truth, "std::as_const(object)", + "source_of_truth"); + } + + ConformanceErrors* errors; +}; + +// Perform a self move-assign. +template <class T, class Prof> +struct ExpectSelfMoveAssign { + template <class Fun> + void operator()(const Fun& generator) const { + T object = generator(); + object = absl::move(object); + + // NOTE: Self move-assign results in a valid-but-unspecified state. + + (ExpectEquality<T, Prof>)(errors, "Move assignment", + PrepareGivenContext( + GivenDeclaration{"_T object", + generator.description}, + GivenDeclaration{"object", + "std::move(object)"}), + object, object, "object", "object"); + } + + ConformanceErrors* errors; +}; + +// Perform a self copy-assign. +template <class T, class Prof> +struct ExpectSelfCopyAssign { + template <class Fun> + void operator()(const Fun& generator) const { + const T source_of_truth = generator(); + T object = generator(); + const T& const_object = object; + object = const_object; + + (ExpectEquality<T, Prof>)(errors, "Copy assignment", + PrepareGivenContext( + GivenDeclaration{"const _T source_of_truth", + generator.description}, + GivenDeclaration{"_T object", + generator.description}, + GivenDeclaration{"object", + "std::as_const(object)"}), + const_object, source_of_truth, + "std::as_const(object)", "source_of_truth"); + } + + ConformanceErrors* errors; +}; + +// Perform a self-swap. +template <class T, class Prof> +struct ExpectSelfSwap { + template <class Fun> + void operator()(const Fun& generator) const { + const T source_of_truth = generator(); + T object = generator(); + + type_traits_internal::Swap(object, object); + + std::string preliminary_info = absl::StrCat( + PrepareGivenContext( + GivenDeclaration{"const _T source_of_truth", generator.description}, + GivenDeclaration{"_T object", generator.description}), + "After performing a self-swap:\n" + " using std::swap;\n" + " swap(object, object);\n" + "\n"); + + (ExpectEquality<T, Prof>)(errors, "Swap", std::move(preliminary_info), + object, source_of_truth, "std::as_const(object)", + "source_of_truth"); + } + + ConformanceErrors* errors; +}; + +// Perform each of the single-generator checks when necessary operations are +// supported. +template <class T, class Prof> +struct ExpectSelfComparison { + template <class Fun> + void operator()(const Fun& generator) const { + const T object = generator(); + (ExpectOneWayEquality<T, Prof>)(errors, "Comparison", + PrepareGivenContext(GivenDeclaration{ + "const _T object", + generator.description}), + object, object, "object", "object"); + } + + ConformanceErrors* errors; +}; + +// Perform each of the single-generator checks when necessary operations are +// supported. +template <class T, class Prof> +struct ExpectConsistency { + template <class Fun> + void operator()(const Fun& generator) const { + If<PropertiesOfT<Prof>::is_move_constructible>::Invoke( + ExpectMoveConstructOneGenerator<T, Prof>{errors}, generator); + + If<PropertiesOfT<Prof>::is_copy_constructible>::Invoke( + ExpectCopyConstructOneGenerator<T, Prof>{errors}, generator); + + If<PropertiesOfT<Prof>::is_default_constructible && + PropertiesOfT<Prof>::is_move_assignable>:: + Invoke(ExpectDefaultConstructWithMoveAssign<T, Prof>{errors}, + generator); + + If<PropertiesOfT<Prof>::is_default_constructible && + PropertiesOfT<Prof>::is_copy_assignable>:: + Invoke(ExpectDefaultConstructWithCopyAssign<T, Prof>{errors}, + generator); + + If<PropertiesOfT<Prof>::is_move_assignable>::Invoke( + ExpectSelfMoveAssign<T, Prof>{errors}, generator); + + If<PropertiesOfT<Prof>::is_copy_assignable>::Invoke( + ExpectSelfCopyAssign<T, Prof>{errors}, generator); + + If<PropertiesOfT<Prof>::is_swappable>::Invoke( + ExpectSelfSwap<T, Prof>{errors}, generator); + } + + ConformanceErrors* errors; +}; + +// Check move-assign with two different values. +template <class T, class Prof> +struct ExpectMoveAssign { + template <class Fun0, class Fun1> + void operator()(const Fun0& generator0, const Fun1& generator1) const { + const T source_of_truth1 = generator1(); + T object = generator0(); + object = generator1(); + + (ExpectEquality<T, Prof>)(errors, "Move assignment", + PrepareGivenContext( + GivenDeclaration{"const _T source_of_truth1", + generator1.description}, + GivenDeclaration{"_T object", + generator0.description}, + GivenDeclaration{"object", + generator1.description}), + object, source_of_truth1, "std::as_const(object)", + "source_of_truth1"); + } + + ConformanceErrors* errors; +}; + +// Check copy-assign with two different values. +template <class T, class Prof> +struct ExpectCopyAssign { + template <class Fun0, class Fun1> + void operator()(const Fun0& generator0, const Fun1& generator1) const { + const T source_of_truth1 = generator1(); + T object = generator0(); + object = static_cast<const T&>(generator1()); + + (ExpectEquality<T, Prof>)(errors, "Copy assignment", + PrepareGivenContext( + GivenDeclaration{"const _T source_of_truth1", + generator1.description}, + GivenDeclaration{"_T object", + generator0.description}, + GivenDeclaration{ + "object", + std::string("static_cast<const _T&>(") + + generator1.description + ")"}), + object, source_of_truth1, "std::as_const(object)", + "source_of_truth1"); + } + + ConformanceErrors* errors; +}; + +// Check swap with two different values. +template <class T, class Prof> +struct ExpectSwap { + template <class Fun0, class Fun1> + void operator()(const Fun0& generator0, const Fun1& generator1) const { + const T source_of_truth0 = generator0(); + const T source_of_truth1 = generator1(); + T object0 = generator0(); + T object1 = generator1(); + + type_traits_internal::Swap(object0, object1); + + const std::string context = + PrepareGivenContext( + GivenDeclaration{"const _T source_of_truth0", + generator0.description}, + GivenDeclaration{"const _T source_of_truth1", + generator1.description}, + GivenDeclaration{"_T object0", generator0.description}, + GivenDeclaration{"_T object1", generator1.description}) + + "After performing a swap:\n" + " using std::swap;\n" + " swap(object0, object1);\n" + "\n"; + + (ExpectEquality<T, Prof>)(errors, "Swap", context, object0, + source_of_truth1, "std::as_const(object0)", + "source_of_truth1"); + (ExpectEquality<T, Prof>)(errors, "Swap", context, object1, + source_of_truth0, "std::as_const(object1)", + "source_of_truth0"); + } + + ConformanceErrors* errors; +}; + +// Validate that `generator0` and `generator1` produce values that are equal. +template <class T, class Prof> +struct ExpectEquivalenceClassComparison { + template <class Fun0, class Fun1> + void operator()(const Fun0& generator0, const Fun1& generator1) const { + const T object0 = generator0(); + const T object1 = generator1(); + + (ExpectEquality<T, Prof>)(errors, "Comparison", + PrepareGivenContext( + GivenDeclaration{"const _T object0", + generator0.description}, + GivenDeclaration{"const _T object1", + generator1.description}), + object0, object1, "object0", "object1"); + } + + ConformanceErrors* errors; +}; + +// Validate that all objects in the same equivalence-class have the same value. +template <class T, class Prof> +struct ExpectEquivalenceClassConsistency { + template <class Fun0, class Fun1> + void operator()(const Fun0& generator0, const Fun1& generator1) const { + If<PropertiesOfT<Prof>::is_move_assignable>::Invoke( + ExpectMoveAssign<T, Prof>{errors}, generator0, generator1); + + If<PropertiesOfT<Prof>::is_copy_assignable>::Invoke( + ExpectCopyAssign<T, Prof>{errors}, generator0, generator1); + + If<PropertiesOfT<Prof>::is_swappable>::Invoke(ExpectSwap<T, Prof>{errors}, + generator0, generator1); + } + + ConformanceErrors* errors; +}; + +// Given a "lesser" object and a "greater" object, perform every combination of +// comparison operators supported for the type, expecting consistent results. +template <class T, class Prof> +void ExpectOrdered(ConformanceErrors* errors, absl::string_view context, + const T& small, const T& big, absl::string_view small_name, + absl::string_view big_name) { + const absl::string_view test_name = "Comparison"; + + If<PropertiesOfT<Prof>::is_equality_comparable>::Invoke( + ExpectNotEq{errors}, test_name, context, small, big, small_name, + big_name); + If<PropertiesOfT<Prof>::is_equality_comparable>::Invoke( + ExpectNotEq{errors}, test_name, context, big, small, big_name, + small_name); + + If<PropertiesOfT<Prof>::is_inequality_comparable>::Invoke( + ExpectNe{errors}, test_name, context, small, big, small_name, big_name); + If<PropertiesOfT<Prof>::is_inequality_comparable>::Invoke( + ExpectNe{errors}, test_name, context, big, small, big_name, small_name); + + If<PropertiesOfT<Prof>::is_less_than_comparable>::Invoke( + ExpectLt{errors}, test_name, context, small, big, small_name, big_name); + If<PropertiesOfT<Prof>::is_less_than_comparable>::Invoke( + ExpectNotLt{errors}, test_name, context, big, small, big_name, + small_name); + + If<PropertiesOfT<Prof>::is_less_equal_comparable>::Invoke( + ExpectLe{errors}, test_name, context, small, big, small_name, big_name); + If<PropertiesOfT<Prof>::is_less_equal_comparable>::Invoke( + ExpectNotLe{errors}, test_name, context, big, small, big_name, + small_name); + + If<PropertiesOfT<Prof>::is_greater_equal_comparable>::Invoke( + ExpectNotGe{errors}, test_name, context, small, big, small_name, + big_name); + If<PropertiesOfT<Prof>::is_greater_equal_comparable>::Invoke( + ExpectGe{errors}, test_name, context, big, small, big_name, small_name); + + If<PropertiesOfT<Prof>::is_greater_than_comparable>::Invoke( + ExpectNotGt{errors}, test_name, context, small, big, small_name, + big_name); + If<PropertiesOfT<Prof>::is_greater_than_comparable>::Invoke( + ExpectGt{errors}, test_name, context, big, small, big_name, small_name); +} + +// For every two elements of an equivalence class, makes sure that those two +// elements compare equal, including checks with the same argument passed as +// both operands. +template <class T, class Prof> +struct ExpectEquivalenceClassComparisons { + template <class... Funs> + void operator()(EquivalenceClassType<Funs...> eq_class) const { + (ForEachTupleElement)(ExpectSelfComparison<T, Prof>{errors}, + eq_class.generators); + + (ForEveryTwo)(ExpectEquivalenceClassComparison<T, Prof>{errors}, + eq_class.generators); + } + + ConformanceErrors* errors; +}; + +// For every element of an equivalence class, makes sure that the element is +// self-consistent (in other words, if any of move/copy/swap are defined, +// perform those operations and make such that results and operands still +// compare equal to known values whenever it is required for that operation. +template <class T, class Prof> +struct ExpectEquivalenceClass { + template <class... Funs> + void operator()(EquivalenceClassType<Funs...> eq_class) const { + (ForEachTupleElement)(ExpectConsistency<T, Prof>{errors}, + eq_class.generators); + + (ForEveryTwo)(ExpectEquivalenceClassConsistency<T, Prof>{errors}, + eq_class.generators); + } + + ConformanceErrors* errors; +}; + +// Validate that the passed-in argument is a generator of a greater value than +// the one produced by the "small_gen" datamember with respect to all of the +// comparison operators that Prof requires, with both argument orders to test. +template <class T, class Prof, class SmallGenerator> +struct ExpectBiggerGeneratorThanComparisons { + template <class BigGenerator> + void operator()(BigGenerator big_gen) const { + const T small = small_gen(); + const T big = big_gen(); + + (ExpectOrdered<T, Prof>)(errors, + PrepareGivenContext( + GivenDeclaration{"const _T small", + small_gen.description}, + GivenDeclaration{"const _T big", + big_gen.description}), + small, big, "small", "big"); + } + + SmallGenerator small_gen; + ConformanceErrors* errors; +}; + +// Perform all of the move, copy, and swap checks on the value generated by +// `small_gen` and the value generated by `big_gen`. +template <class T, class Prof, class SmallGenerator> +struct ExpectBiggerGeneratorThan { + template <class BigGenerator> + void operator()(BigGenerator big_gen) const { + If<PropertiesOfT<Prof>::is_move_assignable>::Invoke( + ExpectMoveAssign<T, Prof>{errors}, small_gen, big_gen); + If<PropertiesOfT<Prof>::is_move_assignable>::Invoke( + ExpectMoveAssign<T, Prof>{errors}, big_gen, small_gen); + + If<PropertiesOfT<Prof>::is_copy_assignable>::Invoke( + ExpectCopyAssign<T, Prof>{errors}, small_gen, big_gen); + If<PropertiesOfT<Prof>::is_copy_assignable>::Invoke( + ExpectCopyAssign<T, Prof>{errors}, big_gen, small_gen); + + If<PropertiesOfT<Prof>::is_swappable>::Invoke(ExpectSwap<T, Prof>{errors}, + small_gen, big_gen); + } + + SmallGenerator small_gen; + ConformanceErrors* errors; +}; + +// Validate that the result of a generator is greater than the results of all +// generators in an equivalence class with respect to comparisons. +template <class T, class Prof, class SmallGenerator> +struct ExpectBiggerGeneratorThanEqClassesComparisons { + template <class BigEqClass> + void operator()(BigEqClass big_eq_class) const { + (ForEachTupleElement)( + ExpectBiggerGeneratorThanComparisons<T, Prof, SmallGenerator>{small_gen, + errors}, + big_eq_class.generators); + } + + SmallGenerator small_gen; + ConformanceErrors* errors; +}; + +// Validate that the non-comparison binary operations required by Prof are +// correct for the result of each generator of big_eq_class and a generator of +// the logically smaller value returned by small_gen. +template <class T, class Prof, class SmallGenerator> +struct ExpectBiggerGeneratorThanEqClasses { + template <class BigEqClass> + void operator()(BigEqClass big_eq_class) const { + (ForEachTupleElement)( + ExpectBiggerGeneratorThan<T, Prof, SmallGenerator>{small_gen, errors}, + big_eq_class.generators); + } + + SmallGenerator small_gen; + ConformanceErrors* errors; +}; + +// Validate that each equivalence class that is passed is logically less than +// the equivalence classes that comes later on in the argument list. +template <class T, class Prof> +struct ExpectOrderedEquivalenceClassesComparisons { + template <class... BigEqClasses> + struct Impl { + // Validate that the value produced by `small_gen` is less than all of the + // values generated by those of the logically larger equivalence classes. + template <class SmallGenerator> + void operator()(SmallGenerator small_gen) const { + (ForEachTupleElement)(ExpectBiggerGeneratorThanEqClassesComparisons< + T, Prof, SmallGenerator>{small_gen, errors}, + big_eq_classes); + } + + std::tuple<BigEqClasses...> big_eq_classes; + ConformanceErrors* errors; + }; + + // When given no equivalence classes, no validation is necessary. + void operator()() const {} + + template <class SmallEqClass, class... BigEqClasses> + void operator()(SmallEqClass small_eq_class, + BigEqClasses... big_eq_classes) const { + // For each generator in the first equivalence class, make sure that it is + // less than each of those in the logically greater equivalence classes. + (ForEachTupleElement)( + Impl<BigEqClasses...>{std::make_tuple(absl::move(big_eq_classes)...), + errors}, + small_eq_class.generators); + + // Recurse so that all equivalence class combinations are checked. + (*this)(absl::move(big_eq_classes)...); + } + + ConformanceErrors* errors; +}; + +// Validate that the non-comparison binary operations required by Prof are +// correct for the result of each generator of big_eq_classes and a generator of +// the logically smaller value returned by small_gen. +template <class T, class Prof> +struct ExpectOrderedEquivalenceClasses { + template <class... BigEqClasses> + struct Impl { + template <class SmallGenerator> + void operator()(SmallGenerator small_gen) const { + (ForEachTupleElement)( + ExpectBiggerGeneratorThanEqClasses<T, Prof, SmallGenerator>{small_gen, + errors}, + big_eq_classes); + } + + std::tuple<BigEqClasses...> big_eq_classes; + ConformanceErrors* errors; + }; + + // Check that small_eq_class is logically consistent and also is logically + // less than all values in big_eq_classes. + template <class SmallEqClass, class... BigEqClasses> + void operator()(SmallEqClass small_eq_class, + BigEqClasses... big_eq_classes) const { + (ForEachTupleElement)( + Impl<BigEqClasses...>{std::make_tuple(absl::move(big_eq_classes)...), + errors}, + small_eq_class.generators); + + (*this)(absl::move(big_eq_classes)...); + } + + // Terminating case of operator(). + void operator()() const {} + + ConformanceErrors* errors; +}; + +// Validate that a type meets the syntactic requirements of std::hash if the +// range of profiles requires it. +template <class T, class MinProf, class MaxProf> +struct ExpectHashable { + void operator()() const { + ExpectModelOfHashable<T, MinProf, MaxProf>(errors); + } + + ConformanceErrors* errors; +}; + +// Validate that the type `T` meets all of the requirements associated with +// `MinProf` and without going beyond the syntactic properties of `MaxProf`. +template <class T, class MinProf, class MaxProf> +struct ExpectModels { + void operator()(ConformanceErrors* errors) const { + ExpectModelOfDefaultConstructible<T, MinProf, MaxProf>(errors); + ExpectModelOfMoveConstructible<T, MinProf, MaxProf>(errors); + ExpectModelOfCopyConstructible<T, MinProf, MaxProf>(errors); + ExpectModelOfMoveAssignable<T, MinProf, MaxProf>(errors); + ExpectModelOfCopyAssignable<T, MinProf, MaxProf>(errors); + ExpectModelOfDestructible<T, MinProf, MaxProf>(errors); + ExpectModelOfEqualityComparable<T, MinProf, MaxProf>(errors); + ExpectModelOfInequalityComparable<T, MinProf, MaxProf>(errors); + ExpectModelOfLessThanComparable<T, MinProf, MaxProf>(errors); + ExpectModelOfLessEqualComparable<T, MinProf, MaxProf>(errors); + ExpectModelOfGreaterEqualComparable<T, MinProf, MaxProf>(errors); + ExpectModelOfGreaterThanComparable<T, MinProf, MaxProf>(errors); + ExpectModelOfSwappable<T, MinProf, MaxProf>(errors); + + // Only check hashability on compilers that have a compliant default-hash. + If<!poisoned_hash_fails_instantiation()>::Invoke( + ExpectHashable<T, MinProf, MaxProf>{errors}); + } +}; + +// A metafunction that yields a Profile matching the set of properties that are +// safe to be checked (lack-of-hashability is only checked on standard library +// implementations that are standards compliant in that they provide a std::hash +// primary template that is SFINAE-friendly) +template <class LogicalProf, class T> +struct MinimalCheckableProfile { + using type = + MinimalProfiles<PropertiesOfT<LogicalProf>, + PropertiesOfT<SyntacticConformanceProfileOf< + T, !PropertiesOfT<LogicalProf>::is_hashable && + poisoned_hash_fails_instantiation() + ? CheckHashability::no + : CheckHashability::yes>>>; +}; + +// An identity metafunction +template <class T> +struct Always { + using type = T; +}; + +// Validate the T meets all of the necessary requirements of LogicalProf, with +// syntactic requirements defined by the profile range [MinProf, MaxProf]. +template <class T, class LogicalProf, class MinProf, class MaxProf, + class... EqClasses> +ConformanceErrors ExpectRegularityImpl( + OrderedEquivalenceClasses<EqClasses...> vals) { + ConformanceErrors errors((NameOf<T>())); + + If<!constexpr_instantiation_when_unevaluated()>::Invoke( + ExpectModels<T, MinProf, MaxProf>(), &errors); + + using minimal_profile = typename absl::conditional_t< + constexpr_instantiation_when_unevaluated(), Always<LogicalProf>, + MinimalCheckableProfile<LogicalProf, T>>::type; + + If<PropertiesOfT<minimal_profile>::is_default_constructible>::Invoke( + ExpectDefaultConstructWithDestruct<T>{&errors}); + + ////////////////////////////////////////////////////////////////////////////// + // Perform all comparison checks first, since later checks depend on their + // correctness. + // + // Check all of the comparisons for all values in the same equivalence + // class (equal with respect to comparison operators and hash the same). + (ForEachTupleElement)( + ExpectEquivalenceClassComparisons<T, minimal_profile>{&errors}, + vals.eq_classes); + + // Check all of the comparisons for each combination of values that are in + // different equivalence classes (not equal with respect to comparison + // operators). + absl::apply( + ExpectOrderedEquivalenceClassesComparisons<T, minimal_profile>{&errors}, + vals.eq_classes); + // + ////////////////////////////////////////////////////////////////////////////// + + // Perform remaining checks, relying on comparisons. + // TODO(calabrese) short circuit if any comparisons above failed. + (ForEachTupleElement)(ExpectEquivalenceClass<T, minimal_profile>{&errors}, + vals.eq_classes); + + absl::apply(ExpectOrderedEquivalenceClasses<T, minimal_profile>{&errors}, + vals.eq_classes); + + return errors; +} + +// A type that represents a range of profiles that are acceptable to be matched. +// +// `MinProf` is the minimum set of syntactic requirements that must be met. +// +// `MaxProf` is the maximum set of syntactic requirements that must be met. +// This maximum is particularly useful for certain "strictness" checking. Some +// examples for when this is useful: +// +// * Making sure that a type is move-only (rather than simply movable) +// +// * Making sure that a member function is *not* noexcept in cases where it +// cannot be noexcept, such as if a dependent datamember has certain +// operations that are not noexcept. +// +// * Making sure that a type tightly matches a spec, such as the standard. +// +// `LogicalProf` is the Profile for which run-time testing is to take place. +// +// Note: The reason for `LogicalProf` is because it is often the case, when +// dealing with templates, that a declaration of a given operation is specified, +// but whose body would fail to instantiate. Examples include the +// copy-constructor of a standard container when the element-type is move-only, +// or the comparison operators of a standard container when the element-type +// does not have the necessary comparison operations defined. The `LogicalProf` +// parameter allows us to capture the intent of what should be tested at +// run-time, even in the cases where syntactically it might otherwise appear as +// though the type undergoing testing supports more than it actually does. +template <class LogicalProf, class MinProf = LogicalProf, + class MaxProf = MinProf> +struct ProfileRange { + using logical_profile = LogicalProf; + using min_profile = MinProf; + using max_profile = MaxProf; +}; + +// Similar to ProfileRange except that it creates a profile range that is +// coupled with a Domain and is used when testing that a type matches exactly +// the "minimum" requirements of LogicalProf. +template <class StrictnessDomain, class LogicalProf, + class MinProf = LogicalProf, class MaxProf = MinProf> +struct StrictProfileRange { + // We do not yet support extension. + static_assert( + std::is_same<StrictnessDomain, RegularityDomain>::value, + "Currently, the only valid StrictnessDomain is RegularityDomain."); + using strictness_domain = StrictnessDomain; + using logical_profile = LogicalProf; + using min_profile = MinProf; + using max_profile = MaxProf; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +// A metafunction that creates a StrictProfileRange from a Domain and either a +// Profile or ProfileRange. +template <class StrictnessDomain, class ProfOrRange> +struct MakeStrictProfileRange; + +template <class StrictnessDomain, class LogicalProf> +struct MakeStrictProfileRange { + using type = StrictProfileRange<StrictnessDomain, LogicalProf>; +}; + +template <class StrictnessDomain, class LogicalProf, class MinProf, + class MaxProf> +struct MakeStrictProfileRange<StrictnessDomain, + ProfileRange<LogicalProf, MinProf, MaxProf>> { + using type = + StrictProfileRange<StrictnessDomain, LogicalProf, MinProf, MaxProf>; +}; + +template <class StrictnessDomain, class ProfOrRange> +using MakeStrictProfileRangeT = + typename MakeStrictProfileRange<StrictnessDomain, ProfOrRange>::type; +// +//////////////////////////////////////////////////////////////////////////////// + +// A profile in the RegularityDomain with the strongest possible requirements. +using MostStrictProfile = + CombineProfiles<TriviallyCompleteProfile, NothrowComparableProfile>; + +// Forms a ProfileRange that treats the Profile as the bare minimum requirements +// of a type. +template <class LogicalProf, class MinProf = LogicalProf> +using LooseProfileRange = StrictProfileRange<RegularityDomain, LogicalProf, + MinProf, MostStrictProfile>; + +template <class Prof> +using MakeLooseProfileRangeT = Prof; + +//////////////////////////////////////////////////////////////////////////////// +// +// The following classes implement the metafunction ProfileRangeOfT<T> that +// takes either a Profile or ProfileRange and yields the ProfileRange to be +// used during testing. +// +template <class T, class /*Enabler*/ = void> +struct ProfileRangeOfImpl; + +template <class T> +struct ProfileRangeOfImpl<T, absl::void_t<PropertiesOfT<T>>> { + using type = LooseProfileRange<T>; +}; + +template <class T> +struct ProfileRangeOf : ProfileRangeOfImpl<T> {}; + +template <class StrictnessDomain, class LogicalProf, class MinProf, + class MaxProf> +struct ProfileRangeOf< + StrictProfileRange<StrictnessDomain, LogicalProf, MinProf, MaxProf>> { + using type = + StrictProfileRange<StrictnessDomain, LogicalProf, MinProf, MaxProf>; +}; + +template <class T> +using ProfileRangeOfT = typename ProfileRangeOf<T>::type; +// +//////////////////////////////////////////////////////////////////////////////// + +// Extract the logical profile of a range (what will be runtime tested). +template <class T> +using LogicalProfileOfT = typename ProfileRangeOfT<T>::logical_profile; + +// Extract the minimal syntactic profile of a range (error if not at least). +template <class T> +using MinProfileOfT = typename ProfileRangeOfT<T>::min_profile; + +// Extract the maximum syntactic profile of a range (error if more than). +template <class T> +using MaxProfileOfT = typename ProfileRangeOfT<T>::max_profile; + +//////////////////////////////////////////////////////////////////////////////// +// +template <class T> +struct IsProfileOrProfileRange : IsProfile<T>::type {}; + +template <class StrictnessDomain, class LogicalProf, class MinProf, + class MaxProf> +struct IsProfileOrProfileRange< + StrictProfileRange<StrictnessDomain, LogicalProf, MinProf, MaxProf>> + : std::true_type {}; +// +//////////////////////////////////////////////////////////////////////////////// + +// TODO(calabrese): Consider naming the functions in this class the same as +// the macros (defined later on) so that auto-complete leads to the correct name +// and so that a user cannot accidentally call a function rather than the macro +// form. +template <bool ExpectSuccess, class T, class... EqClasses> +struct ExpectConformanceOf { + // Add a value to be tested. Subsequent calls to this function on the same + // object must specify logically "larger" values with respect to the + // comparison operators of the type, if any. + // + // NOTE: This function should not be called directly. A stateless lambda is + // implicitly formed and passed when using the INITIALIZER macro at the bottom + // of this file. + template <class Fun, + absl::enable_if_t<std::is_same< + ResultOfGeneratorT<GeneratorType<Fun>>, T>::value>** = nullptr> + ABSL_MUST_USE_RESULT ExpectConformanceOf<ExpectSuccess, T, EqClasses..., + EquivalenceClassType<Fun>> + initializer(GeneratorType<Fun> fun) && { + return { + {std::tuple_cat(absl::move(ordered_vals.eq_classes), + std::make_tuple((EquivalenceClass)(absl::move(fun))))}, + std::move(expected_failed_tests)}; + } + + template <class... TestNames, + absl::enable_if_t<!ExpectSuccess && sizeof...(EqClasses) == 0 && + absl::conjunction<std::is_convertible< + TestNames, absl::string_view>...>::value>** = + nullptr> + ABSL_MUST_USE_RESULT ExpectConformanceOf<ExpectSuccess, T, EqClasses...> + due_to(TestNames&&... test_names) && { + (InsertEach)(&expected_failed_tests, + absl::AsciiStrToLower(absl::string_view(test_names))...); + + return {absl::move(ordered_vals), std::move(expected_failed_tests)}; + } + + template <class... TestNames, int = 0, // MSVC disambiguator + absl::enable_if_t<ExpectSuccess && sizeof...(EqClasses) == 0 && + absl::conjunction<std::is_convertible< + TestNames, absl::string_view>...>::value>** = + nullptr> + ABSL_MUST_USE_RESULT ExpectConformanceOf<ExpectSuccess, T, EqClasses...> + due_to(TestNames&&... test_names) && { + // TODO(calabrese) Instead have DUE_TO only exist via a CRTP base. + // This would produce better errors messages than the static_assert. + static_assert(!ExpectSuccess, + "DUE_TO cannot be called when conformance is expected -- did " + "you mean to use ASSERT_NONCONFORMANCE_OF?"); + } + + // Add a value to be tested. Subsequent calls to this function on the same + // object must specify logically "larger" values with respect to the + // comparison operators of the type, if any. + // + // NOTE: This function should not be called directly. A stateful lambda is + // implicitly formed and passed when using the INITIALIZER macro at the bottom + // of this file. + template <class Fun, + absl::enable_if_t<std::is_same< + ResultOfGeneratorT<GeneratorType<Fun>>, T>::value>** = nullptr> + ABSL_MUST_USE_RESULT ExpectConformanceOf<ExpectSuccess, T, EqClasses..., + EquivalenceClassType<Fun>> + dont_class_directly_stateful_initializer(GeneratorType<Fun> fun) && { + return { + {std::tuple_cat(absl::move(ordered_vals.eq_classes), + std::make_tuple((EquivalenceClass)(absl::move(fun))))}, + std::move(expected_failed_tests)}; + } + + // Add a set of value to be tested, where each value is equal with respect to + // the comparison operators and std::hash specialization, if defined. + template < + class... Funs, + absl::void_t<absl::enable_if_t<std::is_same< + ResultOfGeneratorT<GeneratorType<Funs>>, T>::value>...>** = nullptr> + ABSL_MUST_USE_RESULT ExpectConformanceOf<ExpectSuccess, T, EqClasses..., + EquivalenceClassType<Funs...>> + equivalence_class(GeneratorType<Funs>... funs) && { + return {{std::tuple_cat( + absl::move(ordered_vals.eq_classes), + std::make_tuple((EquivalenceClass)(absl::move(funs)...)))}, + std::move(expected_failed_tests)}; + } + + // Execute the tests for the captured set of values, strictly matching a range + // of expected profiles in a given domain. + template < + class ProfRange, + absl::enable_if_t<IsProfileOrProfileRange<ProfRange>::value>** = nullptr> + ABSL_MUST_USE_RESULT ::testing::AssertionResult with_strict_profile( + ProfRange /*profile*/) { + ConformanceErrors test_result = + (ExpectRegularityImpl< + T, LogicalProfileOfT<ProfRange>, MinProfileOfT<ProfRange>, + MaxProfileOfT<ProfRange>>)(absl::move(ordered_vals)); + + return ExpectSuccess ? test_result.assertionResult() + : test_result.expectFailedTests(expected_failed_tests); + } + + // Execute the tests for the captured set of values, loosely matching a range + // of expected profiles (loose in that an interface is allowed to be more + // refined that a profile suggests, such as a type having a noexcept copy + // constructor when all that is required is that the copy constructor exists). + template <class Prof, absl::enable_if_t<IsProfile<Prof>::value>** = nullptr> + ABSL_MUST_USE_RESULT ::testing::AssertionResult with_loose_profile( + Prof /*profile*/) { + ConformanceErrors test_result = + (ExpectRegularityImpl< + T, Prof, Prof, + CombineProfiles<TriviallyCompleteProfile, + NothrowComparableProfile>>)(absl:: + move(ordered_vals)); + + return ExpectSuccess ? test_result.assertionResult() + : test_result.expectFailedTests(expected_failed_tests); + } + + OrderedEquivalenceClasses<EqClasses...> ordered_vals; + std::set<std::string> expected_failed_tests; +}; + +template <class T> +using ExpectConformanceOfType = ExpectConformanceOf</*ExpectSuccess=*/true, T>; + +template <class T> +using ExpectNonconformanceOfType = + ExpectConformanceOf</*ExpectSuccess=*/false, T>; + +struct EquivalenceClassMaker { + // TODO(calabrese) Constrain to callable + template <class Fun> + static GeneratorType<Fun> initializer(GeneratorType<Fun> fun) { + return fun; + } +}; + +// A top-level macro that begins the builder pattern. +// +// The argument here takes the datatype to be tested. +#define ABSL_INTERNAL_ASSERT_CONFORMANCE_OF(...) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if ABSL_INTERNAL_LPAREN \ + const ::testing::AssertionResult gtest_ar = \ + ABSL_INTERNAL_LPAREN ::absl::types_internal::ExpectConformanceOfType< \ + __VA_ARGS__>() + +// Akin to ASSERT_CONFORMANCE_OF except that it expects failure and tries to +// match text. +#define ABSL_INTERNAL_ASSERT_NONCONFORMANCE_OF(...) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if ABSL_INTERNAL_LPAREN \ + const ::testing::AssertionResult gtest_ar = \ + ABSL_INTERNAL_LPAREN ::absl::types_internal::ExpectNonconformanceOfType< \ + __VA_ARGS__>() + +//////////////////////////////////////////////////////////////////////////////// +// NOTE: The following macros look like they are recursive, but are not (macros +// cannot recurse). These actually refer to member functions of the same name. +// This is done intentionally so that a user cannot accidentally invoke a +// member function of the conformance-testing suite without going through the +// macro. +//////////////////////////////////////////////////////////////////////////////// + +// Specify expected test failures as comma-separated strings. +#define DUE_TO(...) due_to(__VA_ARGS__) + +// Specify a value to be tested. +// +// Note: Internally, this takes an expression and turns it into the return value +// of lambda that captures no data. The expression is stringized during +// preprocessing so that it can be used in error reports. +#define INITIALIZER(...) \ + initializer(::absl::types_internal::Generator( \ + [] { return __VA_ARGS__; }, ABSL_INTERNAL_STRINGIZE(__VA_ARGS__))) + +// Specify a value to be tested. +// +// Note: Internally, this takes an expression and turns it into the return value +// of lambda that captures data by reference. The expression is stringized +// during preprocessing so that it can be used in error reports. +#define STATEFUL_INITIALIZER(...) \ + stateful_initializer(::absl::types_internal::Generator( \ + [&] { return __VA_ARGS__; }, ABSL_INTERNAL_STRINGIZE(__VA_ARGS__))) + +// Used in the builder-pattern. +// +// Takes a series of INITIALIZER and/or STATEFUL_INITIALIZER invocations and +// forwards them along to be tested, grouping them such that the testing suite +// knows that they are supposed to represent the same logical value (the values +// compare the same, hash the same, etc.). +#define EQUIVALENCE_CLASS(...) \ + equivalence_class(ABSL_INTERNAL_TRANSFORM_ARGS( \ + ABSL_INTERNAL_PREPEND_EQ_MAKER, __VA_ARGS__)) + +// An invocation of this or WITH_STRICT_PROFILE must end the builder-pattern. +// It takes a Profile as its argument. +// +// This executes the tests and allows types that are "more referined" than the +// profile specifies, but not less. For instance, if the Profile specifies +// noexcept copy-constructiblity, the test will fail if the copy-constructor is +// not noexcept, however, it will succeed if the copy constructor is trivial. +// +// This is useful for testing that a type meets some minimum set of +// requirements. +#define WITH_LOOSE_PROFILE(...) \ + with_loose_profile( \ + ::absl::types_internal::MakeLooseProfileRangeT<__VA_ARGS__>()) \ + ABSL_INTERNAL_RPAREN ABSL_INTERNAL_RPAREN; \ + else GTEST_FATAL_FAILURE_(gtest_ar.failure_message()) // NOLINT + +// An invocation of this or WITH_STRICT_PROFILE must end the builder-pattern. +// It takes a Domain and a Profile as its arguments. +// +// This executes the tests and disallows types that differ at all from the +// properties of the Profile. For instance, if the Profile specifies noexcept +// copy-constructiblity, the test will fail if the copy constructor is trivial. +// +// This is useful for testing that a type does not do anything more than a +// specification requires, such as to minimize things like Hyrum's Law, or more +// commonly, to prevent a type from being "accidentally" copy-constructible in +// a way that may produce incorrect results, simply because the user forget to +// delete that operation. +#define WITH_STRICT_PROFILE(...) \ + with_strict_profile( \ + ::absl::types_internal::MakeStrictProfileRangeT<__VA_ARGS__>()) \ + ABSL_INTERNAL_RPAREN ABSL_INTERNAL_RPAREN; \ + else GTEST_FATAL_FAILURE_(gtest_ar.failure_message()) // NOLINT + +// Internal macro that is used in the internals of the EDSL when forming +// equivalence classes. +#define ABSL_INTERNAL_PREPEND_EQ_MAKER(arg) \ + ::absl::types_internal::EquivalenceClassMaker().arg + +} // namespace types_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_TESTING_H_ diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/conformance_testing_helpers.h b/contrib/restricted/abseil-cpp/absl/types/internal/conformance_testing_helpers.h index 00775f960c..7028d0ed80 100644 --- a/contrib/restricted/abseil-cpp/absl/types/internal/conformance_testing_helpers.h +++ b/contrib/restricted/abseil-cpp/absl/types/internal/conformance_testing_helpers.h @@ -1,391 +1,391 @@ -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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. - -#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_TESTING_HELPERS_H_ -#define ABSL_TYPES_INTERNAL_CONFORMANCE_TESTING_HELPERS_H_ - -// Checks to determine whether or not we can use abi::__cxa_demangle -#if (defined(__ANDROID__) || defined(ANDROID)) && !defined(OS_ANDROID) -#define ABSL_INTERNAL_OS_ANDROID -#endif - -// We support certain compilers only. See demangle.h for details. -#if defined(OS_ANDROID) && (defined(__i386__) || defined(__x86_64__)) -#define ABSL_TYPES_INTERNAL_HAS_CXA_DEMANGLE 0 -#elif (__GNUC__ >= 4 || (__GNUC__ >= 3 && __GNUC_MINOR__ >= 4)) && \ - !defined(__mips__) -#define ABSL_TYPES_INTERNAL_HAS_CXA_DEMANGLE 1 -#elif defined(__clang__) && !defined(_MSC_VER) -#define ABSL_TYPES_INTERNAL_HAS_CXA_DEMANGLE 1 -#else -#define ABSL_TYPES_INTERNAL_HAS_CXA_DEMANGLE 0 -#endif - -#include <tuple> -#include <type_traits> -#include <utility> - -#include "absl/meta/type_traits.h" -#include "absl/strings/string_view.h" -#include "absl/utility/utility.h" - -#if ABSL_TYPES_INTERNAL_HAS_CXA_DEMANGLE -#include <cxxabi.h> - -#include <cstdlib> -#endif - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace types_internal { - -// Return a readable name for type T. -template <class T> -absl::string_view NameOfImpl() { -// TODO(calabrese) Investigate using debugging:internal_demangle as a fallback. -#if ABSL_TYPES_INTERNAL_HAS_CXA_DEMANGLE - int status = 0; - char* demangled_name = nullptr; - - demangled_name = - abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status); - - if (status == 0 && demangled_name != nullptr) { - return demangled_name; - } else { - return typeid(T).name(); - } -#else - return typeid(T).name(); -#endif - // NOTE: We intentionally leak demangled_name so that it remains valid - // throughout the remainder of the program. -} - -// Given a type, returns as nice of a type name as we can produce (demangled). -// -// Note: This currently strips cv-qualifiers and references, but that is okay -// because we only use this internally with unqualified object types. -template <class T> -std::string NameOf() { - static const absl::string_view result = NameOfImpl<T>(); - return std::string(result); -} - -//////////////////////////////////////////////////////////////////////////////// -// -// Metafunction to check if a type is callable with no explicit arguments -template <class Fun, class /*Enabler*/ = void> -struct IsNullaryCallableImpl : std::false_type {}; - -template <class Fun> -struct IsNullaryCallableImpl< - Fun, absl::void_t<decltype(std::declval<const Fun&>()())>> - : std::true_type { - using result_type = decltype(std::declval<const Fun&>()()); - - template <class ValueType> - using for_type = std::is_same<ValueType, result_type>; - - using void_if_true = void; -}; - -template <class Fun> -struct IsNullaryCallable : IsNullaryCallableImpl<Fun> {}; -// -//////////////////////////////////////////////////////////////////////////////// - -// A type that contains a function object that returns an instance of a type -// that is undergoing conformance testing. This function is required to always -// return the same value upon invocation. -template <class Fun> -struct GeneratorType; - -// A type that contains a tuple of GeneratorType<Fun> where each Fun has the -// same return type. The result of each of the different generators should all -// be equal values, though the underlying object representation may differ (such -// as if one returns 0.0 and another return -0.0, or if one returns an empty -// vector and another returns an empty vector with a different capacity. -template <class... Funs> -struct EquivalenceClassType; - -//////////////////////////////////////////////////////////////////////////////// -// -// A metafunction to check if a type is a specialization of EquivalenceClassType -template <class T> -struct IsEquivalenceClass : std::false_type {}; - -template <> -struct IsEquivalenceClass<EquivalenceClassType<>> : std::true_type { - using self = IsEquivalenceClass; - - // A metafunction to check if this EquivalenceClassType is a valid - // EquivalenceClassType for a type `ValueType` that is undergoing testing - template <class ValueType> - using for_type = std::true_type; -}; - -template <class Head, class... Tail> -struct IsEquivalenceClass<EquivalenceClassType<Head, Tail...>> - : std::true_type { - using self = IsEquivalenceClass; - - // The type undergoing conformance testing that this EquivalenceClass - // corresponds to - using result_type = typename IsNullaryCallable<Head>::result_type; - - // A metafunction to check if this EquivalenceClassType is a valid - // EquivalenceClassType for a type `ValueType` that is undergoing testing - template <class ValueType> - using for_type = std::is_same<ValueType, result_type>; -}; -// -//////////////////////////////////////////////////////////////////////////////// - -// A type that contains an ordered series of EquivalenceClassTypes, where the -// the function object of each underlying GeneratorType has the same return type -// -// These equivalence classes are required to be in a logical ascending order -// that is consistent with comparison operators that are defined for the return -// type of each GeneratorType, if any. -template <class... EqClasses> -struct OrderedEquivalenceClasses; - -//////////////////////////////////////////////////////////////////////////////// -// -// A metafunction to determine the return type of the function object contained -// in a GeneratorType specialization. -template <class T> -struct ResultOfGenerator {}; - -template <class Fun> -struct ResultOfGenerator<GeneratorType<Fun>> { - using type = decltype(std::declval<const Fun&>()()); -}; - -template <class Fun> -using ResultOfGeneratorT = typename ResultOfGenerator<GeneratorType<Fun>>::type; -// -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -// -// A metafunction that yields true iff each of Funs is a GeneratorType -// specialization and they all contain functions with the same return type -template <class /*Enabler*/, class... Funs> -struct AreGeneratorsWithTheSameReturnTypeImpl : std::false_type {}; - -template <> -struct AreGeneratorsWithTheSameReturnTypeImpl<void> : std::true_type {}; - -template <class Head, class... Tail> -struct AreGeneratorsWithTheSameReturnTypeImpl< - typename std::enable_if<absl::conjunction<std::is_same< - ResultOfGeneratorT<Head>, ResultOfGeneratorT<Tail>>...>::value>::type, - Head, Tail...> : std::true_type {}; - -template <class... Funs> -struct AreGeneratorsWithTheSameReturnType - : AreGeneratorsWithTheSameReturnTypeImpl<void, Funs...>::type {}; -// -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -// -// A metafunction that yields true iff each of Funs is an EquivalenceClassType -// specialization and they all contain GeneratorType specializations that have -// the same return type -template <class... EqClasses> -struct AreEquivalenceClassesOfTheSameType { - static_assert(sizeof...(EqClasses) != sizeof...(EqClasses), ""); -}; - -template <> -struct AreEquivalenceClassesOfTheSameType<> : std::true_type { - using self = AreEquivalenceClassesOfTheSameType; - - // Metafunction to check that a type is the same as all of the equivalence - // classes, if any. - // Note: In this specialization there are no equivalence classes, so the - // value type is always compatible. - template <class /*ValueType*/> - using for_type = std::true_type; -}; - -template <class... Funs> -struct AreEquivalenceClassesOfTheSameType<EquivalenceClassType<Funs...>> - : std::true_type { - using self = AreEquivalenceClassesOfTheSameType; - - // Metafunction to check that a type is the same as all of the equivalence - // classes, if any. - template <class ValueType> - using for_type = typename IsEquivalenceClass< - EquivalenceClassType<Funs...>>::template for_type<ValueType>; -}; - -template <class... TailEqClasses> -struct AreEquivalenceClassesOfTheSameType< - EquivalenceClassType<>, EquivalenceClassType<>, TailEqClasses...> - : AreEquivalenceClassesOfTheSameType<TailEqClasses...>::self {}; - -template <class HeadNextFun, class... TailNextFuns, class... TailEqClasses> -struct AreEquivalenceClassesOfTheSameType< - EquivalenceClassType<>, EquivalenceClassType<HeadNextFun, TailNextFuns...>, - TailEqClasses...> - : AreEquivalenceClassesOfTheSameType< - EquivalenceClassType<HeadNextFun, TailNextFuns...>, - TailEqClasses...>::self {}; - -template <class HeadHeadFun, class... TailHeadFuns, class... TailEqClasses> -struct AreEquivalenceClassesOfTheSameType< - EquivalenceClassType<HeadHeadFun, TailHeadFuns...>, EquivalenceClassType<>, - TailEqClasses...> - : AreEquivalenceClassesOfTheSameType< - EquivalenceClassType<HeadHeadFun, TailHeadFuns...>, - TailEqClasses...>::self {}; - -template <class HeadHeadFun, class... TailHeadFuns, class HeadNextFun, - class... TailNextFuns, class... TailEqClasses> -struct AreEquivalenceClassesOfTheSameType< - EquivalenceClassType<HeadHeadFun, TailHeadFuns...>, - EquivalenceClassType<HeadNextFun, TailNextFuns...>, TailEqClasses...> - : absl::conditional_t< - IsNullaryCallable<HeadNextFun>::template for_type< - typename IsNullaryCallable<HeadHeadFun>::result_type>::value, - AreEquivalenceClassesOfTheSameType< - EquivalenceClassType<HeadHeadFun, TailHeadFuns...>, - TailEqClasses...>, - std::false_type> {}; -// -//////////////////////////////////////////////////////////////////////////////// - -// Execute a function for each passed-in parameter. -template <class Fun, class... Cases> -void ForEachParameter(const Fun& fun, const Cases&... cases) { - const std::initializer_list<bool> results = { - (static_cast<void>(fun(cases)), true)...}; - - (void)results; -} - -// Execute a function on each passed-in parameter (using a bound function). -template <class Fun> -struct ForEachParameterFun { - template <class... T> - void operator()(const T&... cases) const { - (ForEachParameter)(fun, cases...); - } - - Fun fun; -}; - -// Execute a function on each element of a tuple. -template <class Fun, class Tup> -void ForEachTupleElement(const Fun& fun, const Tup& tup) { - absl::apply(ForEachParameterFun<Fun>{fun}, tup); -} - -//////////////////////////////////////////////////////////////////////////////// -// -// Execute a function for each combination of two elements of a tuple, including -// combinations of an element with itself. -template <class Fun, class... T> -struct ForEveryTwoImpl { - template <class Lhs> - struct WithBoundLhs { - template <class Rhs> - void operator()(const Rhs& rhs) const { - fun(lhs, rhs); - } - - Fun fun; - Lhs lhs; - }; - - template <class Lhs> - void operator()(const Lhs& lhs) const { - (ForEachTupleElement)(WithBoundLhs<Lhs>{fun, lhs}, args); - } - - Fun fun; - std::tuple<T...> args; -}; - -template <class Fun, class... T> -void ForEveryTwo(const Fun& fun, std::tuple<T...> args) { - (ForEachTupleElement)(ForEveryTwoImpl<Fun, T...>{fun, args}, args); -} -// -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -// -// Insert all values into an associative container -template<class Container> -void InsertEach(Container* cont) { -} - -template<class Container, class H, class... T> -void InsertEach(Container* cont, H&& head, T&&... tail) { - cont->insert(head); - (InsertEach)(cont, tail...); -} -// -//////////////////////////////////////////////////////////////////////////////// -// A template with a nested "Invoke" static-member-function that executes a -// passed-in Callable when `Condition` is true, otherwise it ignores the -// Callable. This is useful for executing a function object with a condition -// that corresponds to whether or not the Callable can be safely instantiated. -// It has some overlapping uses with C++17 `if constexpr`. -template <bool Condition> -struct If; - -template <> -struct If</*Condition =*/false> { - template <class Fun, class... P> - static void Invoke(const Fun& /*fun*/, P&&... /*args*/) {} -}; - -template <> -struct If</*Condition =*/true> { - template <class Fun, class... P> - static void Invoke(const Fun& fun, P&&... args) { - // TODO(calabrese) Use std::invoke equivalent instead of function-call. - fun(absl::forward<P>(args)...); - } -}; - -// -// ABSL_INTERNAL_STRINGIZE(...) -// -// This variadic macro transforms its arguments into a c-string literal after -// expansion. -// -// Example: -// -// ABSL_INTERNAL_STRINGIZE(std::array<int, 10>) -// -// Results in: -// -// "std::array<int, 10>" -#define ABSL_INTERNAL_STRINGIZE(...) ABSL_INTERNAL_STRINGIZE_IMPL((__VA_ARGS__)) -#define ABSL_INTERNAL_STRINGIZE_IMPL(arg) ABSL_INTERNAL_STRINGIZE_IMPL2 arg -#define ABSL_INTERNAL_STRINGIZE_IMPL2(...) #__VA_ARGS__ - -} // namespace types_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_TESTING_HELPERS_H_ +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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. + +#ifndef ABSL_TYPES_INTERNAL_CONFORMANCE_TESTING_HELPERS_H_ +#define ABSL_TYPES_INTERNAL_CONFORMANCE_TESTING_HELPERS_H_ + +// Checks to determine whether or not we can use abi::__cxa_demangle +#if (defined(__ANDROID__) || defined(ANDROID)) && !defined(OS_ANDROID) +#define ABSL_INTERNAL_OS_ANDROID +#endif + +// We support certain compilers only. See demangle.h for details. +#if defined(OS_ANDROID) && (defined(__i386__) || defined(__x86_64__)) +#define ABSL_TYPES_INTERNAL_HAS_CXA_DEMANGLE 0 +#elif (__GNUC__ >= 4 || (__GNUC__ >= 3 && __GNUC_MINOR__ >= 4)) && \ + !defined(__mips__) +#define ABSL_TYPES_INTERNAL_HAS_CXA_DEMANGLE 1 +#elif defined(__clang__) && !defined(_MSC_VER) +#define ABSL_TYPES_INTERNAL_HAS_CXA_DEMANGLE 1 +#else +#define ABSL_TYPES_INTERNAL_HAS_CXA_DEMANGLE 0 +#endif + +#include <tuple> +#include <type_traits> +#include <utility> + +#include "absl/meta/type_traits.h" +#include "absl/strings/string_view.h" +#include "absl/utility/utility.h" + +#if ABSL_TYPES_INTERNAL_HAS_CXA_DEMANGLE +#include <cxxabi.h> + +#include <cstdlib> +#endif + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace types_internal { + +// Return a readable name for type T. +template <class T> +absl::string_view NameOfImpl() { +// TODO(calabrese) Investigate using debugging:internal_demangle as a fallback. +#if ABSL_TYPES_INTERNAL_HAS_CXA_DEMANGLE + int status = 0; + char* demangled_name = nullptr; + + demangled_name = + abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status); + + if (status == 0 && demangled_name != nullptr) { + return demangled_name; + } else { + return typeid(T).name(); + } +#else + return typeid(T).name(); +#endif + // NOTE: We intentionally leak demangled_name so that it remains valid + // throughout the remainder of the program. +} + +// Given a type, returns as nice of a type name as we can produce (demangled). +// +// Note: This currently strips cv-qualifiers and references, but that is okay +// because we only use this internally with unqualified object types. +template <class T> +std::string NameOf() { + static const absl::string_view result = NameOfImpl<T>(); + return std::string(result); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Metafunction to check if a type is callable with no explicit arguments +template <class Fun, class /*Enabler*/ = void> +struct IsNullaryCallableImpl : std::false_type {}; + +template <class Fun> +struct IsNullaryCallableImpl< + Fun, absl::void_t<decltype(std::declval<const Fun&>()())>> + : std::true_type { + using result_type = decltype(std::declval<const Fun&>()()); + + template <class ValueType> + using for_type = std::is_same<ValueType, result_type>; + + using void_if_true = void; +}; + +template <class Fun> +struct IsNullaryCallable : IsNullaryCallableImpl<Fun> {}; +// +//////////////////////////////////////////////////////////////////////////////// + +// A type that contains a function object that returns an instance of a type +// that is undergoing conformance testing. This function is required to always +// return the same value upon invocation. +template <class Fun> +struct GeneratorType; + +// A type that contains a tuple of GeneratorType<Fun> where each Fun has the +// same return type. The result of each of the different generators should all +// be equal values, though the underlying object representation may differ (such +// as if one returns 0.0 and another return -0.0, or if one returns an empty +// vector and another returns an empty vector with a different capacity. +template <class... Funs> +struct EquivalenceClassType; + +//////////////////////////////////////////////////////////////////////////////// +// +// A metafunction to check if a type is a specialization of EquivalenceClassType +template <class T> +struct IsEquivalenceClass : std::false_type {}; + +template <> +struct IsEquivalenceClass<EquivalenceClassType<>> : std::true_type { + using self = IsEquivalenceClass; + + // A metafunction to check if this EquivalenceClassType is a valid + // EquivalenceClassType for a type `ValueType` that is undergoing testing + template <class ValueType> + using for_type = std::true_type; +}; + +template <class Head, class... Tail> +struct IsEquivalenceClass<EquivalenceClassType<Head, Tail...>> + : std::true_type { + using self = IsEquivalenceClass; + + // The type undergoing conformance testing that this EquivalenceClass + // corresponds to + using result_type = typename IsNullaryCallable<Head>::result_type; + + // A metafunction to check if this EquivalenceClassType is a valid + // EquivalenceClassType for a type `ValueType` that is undergoing testing + template <class ValueType> + using for_type = std::is_same<ValueType, result_type>; +}; +// +//////////////////////////////////////////////////////////////////////////////// + +// A type that contains an ordered series of EquivalenceClassTypes, where the +// the function object of each underlying GeneratorType has the same return type +// +// These equivalence classes are required to be in a logical ascending order +// that is consistent with comparison operators that are defined for the return +// type of each GeneratorType, if any. +template <class... EqClasses> +struct OrderedEquivalenceClasses; + +//////////////////////////////////////////////////////////////////////////////// +// +// A metafunction to determine the return type of the function object contained +// in a GeneratorType specialization. +template <class T> +struct ResultOfGenerator {}; + +template <class Fun> +struct ResultOfGenerator<GeneratorType<Fun>> { + using type = decltype(std::declval<const Fun&>()()); +}; + +template <class Fun> +using ResultOfGeneratorT = typename ResultOfGenerator<GeneratorType<Fun>>::type; +// +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// A metafunction that yields true iff each of Funs is a GeneratorType +// specialization and they all contain functions with the same return type +template <class /*Enabler*/, class... Funs> +struct AreGeneratorsWithTheSameReturnTypeImpl : std::false_type {}; + +template <> +struct AreGeneratorsWithTheSameReturnTypeImpl<void> : std::true_type {}; + +template <class Head, class... Tail> +struct AreGeneratorsWithTheSameReturnTypeImpl< + typename std::enable_if<absl::conjunction<std::is_same< + ResultOfGeneratorT<Head>, ResultOfGeneratorT<Tail>>...>::value>::type, + Head, Tail...> : std::true_type {}; + +template <class... Funs> +struct AreGeneratorsWithTheSameReturnType + : AreGeneratorsWithTheSameReturnTypeImpl<void, Funs...>::type {}; +// +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// A metafunction that yields true iff each of Funs is an EquivalenceClassType +// specialization and they all contain GeneratorType specializations that have +// the same return type +template <class... EqClasses> +struct AreEquivalenceClassesOfTheSameType { + static_assert(sizeof...(EqClasses) != sizeof...(EqClasses), ""); +}; + +template <> +struct AreEquivalenceClassesOfTheSameType<> : std::true_type { + using self = AreEquivalenceClassesOfTheSameType; + + // Metafunction to check that a type is the same as all of the equivalence + // classes, if any. + // Note: In this specialization there are no equivalence classes, so the + // value type is always compatible. + template <class /*ValueType*/> + using for_type = std::true_type; +}; + +template <class... Funs> +struct AreEquivalenceClassesOfTheSameType<EquivalenceClassType<Funs...>> + : std::true_type { + using self = AreEquivalenceClassesOfTheSameType; + + // Metafunction to check that a type is the same as all of the equivalence + // classes, if any. + template <class ValueType> + using for_type = typename IsEquivalenceClass< + EquivalenceClassType<Funs...>>::template for_type<ValueType>; +}; + +template <class... TailEqClasses> +struct AreEquivalenceClassesOfTheSameType< + EquivalenceClassType<>, EquivalenceClassType<>, TailEqClasses...> + : AreEquivalenceClassesOfTheSameType<TailEqClasses...>::self {}; + +template <class HeadNextFun, class... TailNextFuns, class... TailEqClasses> +struct AreEquivalenceClassesOfTheSameType< + EquivalenceClassType<>, EquivalenceClassType<HeadNextFun, TailNextFuns...>, + TailEqClasses...> + : AreEquivalenceClassesOfTheSameType< + EquivalenceClassType<HeadNextFun, TailNextFuns...>, + TailEqClasses...>::self {}; + +template <class HeadHeadFun, class... TailHeadFuns, class... TailEqClasses> +struct AreEquivalenceClassesOfTheSameType< + EquivalenceClassType<HeadHeadFun, TailHeadFuns...>, EquivalenceClassType<>, + TailEqClasses...> + : AreEquivalenceClassesOfTheSameType< + EquivalenceClassType<HeadHeadFun, TailHeadFuns...>, + TailEqClasses...>::self {}; + +template <class HeadHeadFun, class... TailHeadFuns, class HeadNextFun, + class... TailNextFuns, class... TailEqClasses> +struct AreEquivalenceClassesOfTheSameType< + EquivalenceClassType<HeadHeadFun, TailHeadFuns...>, + EquivalenceClassType<HeadNextFun, TailNextFuns...>, TailEqClasses...> + : absl::conditional_t< + IsNullaryCallable<HeadNextFun>::template for_type< + typename IsNullaryCallable<HeadHeadFun>::result_type>::value, + AreEquivalenceClassesOfTheSameType< + EquivalenceClassType<HeadHeadFun, TailHeadFuns...>, + TailEqClasses...>, + std::false_type> {}; +// +//////////////////////////////////////////////////////////////////////////////// + +// Execute a function for each passed-in parameter. +template <class Fun, class... Cases> +void ForEachParameter(const Fun& fun, const Cases&... cases) { + const std::initializer_list<bool> results = { + (static_cast<void>(fun(cases)), true)...}; + + (void)results; +} + +// Execute a function on each passed-in parameter (using a bound function). +template <class Fun> +struct ForEachParameterFun { + template <class... T> + void operator()(const T&... cases) const { + (ForEachParameter)(fun, cases...); + } + + Fun fun; +}; + +// Execute a function on each element of a tuple. +template <class Fun, class Tup> +void ForEachTupleElement(const Fun& fun, const Tup& tup) { + absl::apply(ForEachParameterFun<Fun>{fun}, tup); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Execute a function for each combination of two elements of a tuple, including +// combinations of an element with itself. +template <class Fun, class... T> +struct ForEveryTwoImpl { + template <class Lhs> + struct WithBoundLhs { + template <class Rhs> + void operator()(const Rhs& rhs) const { + fun(lhs, rhs); + } + + Fun fun; + Lhs lhs; + }; + + template <class Lhs> + void operator()(const Lhs& lhs) const { + (ForEachTupleElement)(WithBoundLhs<Lhs>{fun, lhs}, args); + } + + Fun fun; + std::tuple<T...> args; +}; + +template <class Fun, class... T> +void ForEveryTwo(const Fun& fun, std::tuple<T...> args) { + (ForEachTupleElement)(ForEveryTwoImpl<Fun, T...>{fun, args}, args); +} +// +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// Insert all values into an associative container +template<class Container> +void InsertEach(Container* cont) { +} + +template<class Container, class H, class... T> +void InsertEach(Container* cont, H&& head, T&&... tail) { + cont->insert(head); + (InsertEach)(cont, tail...); +} +// +//////////////////////////////////////////////////////////////////////////////// +// A template with a nested "Invoke" static-member-function that executes a +// passed-in Callable when `Condition` is true, otherwise it ignores the +// Callable. This is useful for executing a function object with a condition +// that corresponds to whether or not the Callable can be safely instantiated. +// It has some overlapping uses with C++17 `if constexpr`. +template <bool Condition> +struct If; + +template <> +struct If</*Condition =*/false> { + template <class Fun, class... P> + static void Invoke(const Fun& /*fun*/, P&&... /*args*/) {} +}; + +template <> +struct If</*Condition =*/true> { + template <class Fun, class... P> + static void Invoke(const Fun& fun, P&&... args) { + // TODO(calabrese) Use std::invoke equivalent instead of function-call. + fun(absl::forward<P>(args)...); + } +}; + +// +// ABSL_INTERNAL_STRINGIZE(...) +// +// This variadic macro transforms its arguments into a c-string literal after +// expansion. +// +// Example: +// +// ABSL_INTERNAL_STRINGIZE(std::array<int, 10>) +// +// Results in: +// +// "std::array<int, 10>" +#define ABSL_INTERNAL_STRINGIZE(...) ABSL_INTERNAL_STRINGIZE_IMPL((__VA_ARGS__)) +#define ABSL_INTERNAL_STRINGIZE_IMPL(arg) ABSL_INTERNAL_STRINGIZE_IMPL2 arg +#define ABSL_INTERNAL_STRINGIZE_IMPL2(...) #__VA_ARGS__ + +} // namespace types_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_TYPES_INTERNAL_CONFORMANCE_TESTING_HELPERS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/optional.h b/contrib/restricted/abseil-cpp/absl/types/internal/optional.h index 92932b6001..d6819992a8 100644 --- a/contrib/restricted/abseil-cpp/absl/types/internal/optional.h +++ b/contrib/restricted/abseil-cpp/absl/types/internal/optional.h @@ -54,7 +54,7 @@ #endif namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // Forward declaration template <typename T> @@ -388,7 +388,7 @@ struct optional_hash_base<T, decltype(std::hash<absl::remove_const_t<T> >()( }; } // namespace optional_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #undef ABSL_OPTIONAL_USE_INHERITING_CONSTRUCTORS diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/parentheses.h b/contrib/restricted/abseil-cpp/absl/types/internal/parentheses.h index 5aebee8fde..1a5e108a21 100644 --- a/contrib/restricted/abseil-cpp/absl/types/internal/parentheses.h +++ b/contrib/restricted/abseil-cpp/absl/types/internal/parentheses.h @@ -1,34 +1,34 @@ -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// parentheses.h -// ----------------------------------------------------------------------------- -// -// This file contains macros that expand to a left parenthesis and a right -// parenthesis. These are in their own file and are generated from macros -// because otherwise clang-format gets confused and clang-format off directives -// do not help. -// -// The parentheses macros are used when wanting to require a rescan before -// expansion of parenthesized text appearing after a function-style macro name. - -#ifndef ABSL_TYPES_INTERNAL_PARENTHESES_H_ -#define ABSL_TYPES_INTERNAL_PARENTHESES_H_ - -#define ABSL_INTERNAL_LPAREN ( - -#define ABSL_INTERNAL_RPAREN ) - -#endif // ABSL_TYPES_INTERNAL_PARENTHESES_H_ +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// parentheses.h +// ----------------------------------------------------------------------------- +// +// This file contains macros that expand to a left parenthesis and a right +// parenthesis. These are in their own file and are generated from macros +// because otherwise clang-format gets confused and clang-format off directives +// do not help. +// +// The parentheses macros are used when wanting to require a rescan before +// expansion of parenthesized text appearing after a function-style macro name. + +#ifndef ABSL_TYPES_INTERNAL_PARENTHESES_H_ +#define ABSL_TYPES_INTERNAL_PARENTHESES_H_ + +#define ABSL_INTERNAL_LPAREN ( + +#define ABSL_INTERNAL_RPAREN ) + +#endif // ABSL_TYPES_INTERNAL_PARENTHESES_H_ diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/span.h b/contrib/restricted/abseil-cpp/absl/types/internal/span.h index 112612f4bd..4144fb5293 100644 --- a/contrib/restricted/abseil-cpp/absl/types/internal/span.h +++ b/contrib/restricted/abseil-cpp/absl/types/internal/span.h @@ -26,7 +26,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace span_internal { // A constexpr min function @@ -122,7 +122,7 @@ template <typename From, typename To> using EnableIfConvertibleTo = typename std::enable_if<IsConvertible<From, To>::value>::type; } // namespace span_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TYPES_INTERNAL_SPAN_H_ diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/transform_args.h b/contrib/restricted/abseil-cpp/absl/types/internal/transform_args.h index 4a0ab42ac4..c89f4992fd 100644 --- a/contrib/restricted/abseil-cpp/absl/types/internal/transform_args.h +++ b/contrib/restricted/abseil-cpp/absl/types/internal/transform_args.h @@ -1,246 +1,246 @@ -// Copyright 2019 The Abseil Authors. -// -// 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 -// -// https://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. -// -// ----------------------------------------------------------------------------- -// transform_args.h -// ----------------------------------------------------------------------------- -// -// This file contains a higher-order macro that "transforms" each element of a -// a variadic argument by a provided secondary macro. - -#ifndef ABSL_TYPES_INTERNAL_TRANSFORM_ARGS_H_ -#define ABSL_TYPES_INTERNAL_TRANSFORM_ARGS_H_ - -// -// ABSL_INTERNAL_CAT(a, b) -// -// This macro takes two arguments and concatenates them together via ## after -// expansion. -// -// Example: -// -// ABSL_INTERNAL_CAT(foo_, bar) -// -// Results in: -// -// foo_bar -#define ABSL_INTERNAL_CAT(a, b) ABSL_INTERNAL_CAT_IMPL(a, b) -#define ABSL_INTERNAL_CAT_IMPL(a, b) a##b - -// -// ABSL_INTERNAL_TRANSFORM_ARGS(m, ...) -// -// This macro takes another macro as an argument followed by a trailing series -// of additional parameters (up to 32 additional arguments). It invokes the -// passed-in macro once for each of the additional arguments, with the -// expansions separated by commas. -// -// Example: -// -// ABSL_INTERNAL_TRANSFORM_ARGS(MY_MACRO, a, b, c) -// -// Results in: -// -// MY_MACRO(a), MY_MACRO(b), MY_MACRO(c) -// -// TODO(calabrese) Handle no arguments as a special case. -#define ABSL_INTERNAL_TRANSFORM_ARGS(m, ...) \ - ABSL_INTERNAL_CAT(ABSL_INTERNAL_TRANSFORM_ARGS, \ - ABSL_INTERNAL_NUM_ARGS(__VA_ARGS__)) \ - (m, __VA_ARGS__) - -#define ABSL_INTERNAL_TRANSFORM_ARGS1(m, a0) m(a0) - -#define ABSL_INTERNAL_TRANSFORM_ARGS2(m, a0, a1) m(a0), m(a1) - -#define ABSL_INTERNAL_TRANSFORM_ARGS3(m, a0, a1, a2) m(a0), m(a1), m(a2) - -#define ABSL_INTERNAL_TRANSFORM_ARGS4(m, a0, a1, a2, a3) \ - m(a0), m(a1), m(a2), m(a3) - -#define ABSL_INTERNAL_TRANSFORM_ARGS5(m, a0, a1, a2, a3, a4) \ - m(a0), m(a1), m(a2), m(a3), m(a4) - -#define ABSL_INTERNAL_TRANSFORM_ARGS6(m, a0, a1, a2, a3, a4, a5) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5) - -#define ABSL_INTERNAL_TRANSFORM_ARGS7(m, a0, a1, a2, a3, a4, a5, a6) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6) - -#define ABSL_INTERNAL_TRANSFORM_ARGS8(m, a0, a1, a2, a3, a4, a5, a6, a7) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7) - -#define ABSL_INTERNAL_TRANSFORM_ARGS9(m, a0, a1, a2, a3, a4, a5, a6, a7, a8) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8) - -#define ABSL_INTERNAL_TRANSFORM_ARGS10(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9) - -#define ABSL_INTERNAL_TRANSFORM_ARGS11(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), m(a10) - -#define ABSL_INTERNAL_TRANSFORM_ARGS12(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11) - -#define ABSL_INTERNAL_TRANSFORM_ARGS13(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12) - -#define ABSL_INTERNAL_TRANSFORM_ARGS14(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13) - -#define ABSL_INTERNAL_TRANSFORM_ARGS15(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13, a14) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14) - -#define ABSL_INTERNAL_TRANSFORM_ARGS16(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13, a14, a15) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15) - -#define ABSL_INTERNAL_TRANSFORM_ARGS17(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13, a14, a15, a16) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16) - -#define ABSL_INTERNAL_TRANSFORM_ARGS18(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13, a14, a15, a16, \ - a17) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17) - -#define ABSL_INTERNAL_TRANSFORM_ARGS19(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13, a14, a15, a16, \ - a17, a18) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18) - -#define ABSL_INTERNAL_TRANSFORM_ARGS20(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13, a14, a15, a16, \ - a17, a18, a19) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19) - -#define ABSL_INTERNAL_TRANSFORM_ARGS21(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13, a14, a15, a16, \ - a17, a18, a19, a20) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19), m(a20) - -#define ABSL_INTERNAL_TRANSFORM_ARGS22(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13, a14, a15, a16, \ - a17, a18, a19, a20, a21) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19), m(a20), m(a21) - -#define ABSL_INTERNAL_TRANSFORM_ARGS23(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13, a14, a15, a16, \ - a17, a18, a19, a20, a21, a22) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19), m(a20), m(a21), m(a22) - -#define ABSL_INTERNAL_TRANSFORM_ARGS24(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13, a14, a15, a16, \ - a17, a18, a19, a20, a21, a22, a23) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19), m(a20), m(a21), m(a22), m(a23) - -#define ABSL_INTERNAL_TRANSFORM_ARGS25(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13, a14, a15, a16, \ - a17, a18, a19, a20, a21, a22, a23, a24) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19), m(a20), m(a21), m(a22), m(a23), m(a24) - -#define ABSL_INTERNAL_TRANSFORM_ARGS26( \ - m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, \ - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25) - -#define ABSL_INTERNAL_TRANSFORM_ARGS27( \ - m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, \ - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25), m(a26) - -#define ABSL_INTERNAL_TRANSFORM_ARGS28( \ - m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, \ - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25), m(a26), m(a27) - -#define ABSL_INTERNAL_TRANSFORM_ARGS29( \ - m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, \ - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25), m(a26), m(a27), \ - m(a28) - -#define ABSL_INTERNAL_TRANSFORM_ARGS30( \ - m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, \ - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25), m(a26), m(a27), \ - m(a28), m(a29) - -#define ABSL_INTERNAL_TRANSFORM_ARGS31( \ - m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, \ - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25), m(a26), m(a27), \ - m(a28), m(a29), m(a30) - -#define ABSL_INTERNAL_TRANSFORM_ARGS32(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ - a9, a10, a11, a12, a13, a14, a15, a16, \ - a17, a18, a19, a20, a21, a22, a23, a24, \ - a25, a26, a27, a28, a29, a30, a31) \ - m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ - m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ - m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25), m(a26), m(a27), \ - m(a28), m(a29), m(a30), m(a31) - -#define ABSL_INTERNAL_NUM_ARGS_IMPL(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, \ - a10, a11, a12, a13, a14, a15, a16, a17, \ - a18, a19, a20, a21, a22, a23, a24, a25, \ - a26, a27, a28, a29, a30, a31, result, ...) \ - result - -#define ABSL_INTERNAL_FORCE_EXPANSION(...) __VA_ARGS__ - -#define ABSL_INTERNAL_NUM_ARGS(...) \ - ABSL_INTERNAL_FORCE_EXPANSION(ABSL_INTERNAL_NUM_ARGS_IMPL( \ - __VA_ARGS__, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, \ - 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, )) - -#endif // ABSL_TYPES_INTERNAL_TRANSFORM_ARGS_H_ +// Copyright 2019 The Abseil Authors. +// +// 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 +// +// https://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. +// +// ----------------------------------------------------------------------------- +// transform_args.h +// ----------------------------------------------------------------------------- +// +// This file contains a higher-order macro that "transforms" each element of a +// a variadic argument by a provided secondary macro. + +#ifndef ABSL_TYPES_INTERNAL_TRANSFORM_ARGS_H_ +#define ABSL_TYPES_INTERNAL_TRANSFORM_ARGS_H_ + +// +// ABSL_INTERNAL_CAT(a, b) +// +// This macro takes two arguments and concatenates them together via ## after +// expansion. +// +// Example: +// +// ABSL_INTERNAL_CAT(foo_, bar) +// +// Results in: +// +// foo_bar +#define ABSL_INTERNAL_CAT(a, b) ABSL_INTERNAL_CAT_IMPL(a, b) +#define ABSL_INTERNAL_CAT_IMPL(a, b) a##b + +// +// ABSL_INTERNAL_TRANSFORM_ARGS(m, ...) +// +// This macro takes another macro as an argument followed by a trailing series +// of additional parameters (up to 32 additional arguments). It invokes the +// passed-in macro once for each of the additional arguments, with the +// expansions separated by commas. +// +// Example: +// +// ABSL_INTERNAL_TRANSFORM_ARGS(MY_MACRO, a, b, c) +// +// Results in: +// +// MY_MACRO(a), MY_MACRO(b), MY_MACRO(c) +// +// TODO(calabrese) Handle no arguments as a special case. +#define ABSL_INTERNAL_TRANSFORM_ARGS(m, ...) \ + ABSL_INTERNAL_CAT(ABSL_INTERNAL_TRANSFORM_ARGS, \ + ABSL_INTERNAL_NUM_ARGS(__VA_ARGS__)) \ + (m, __VA_ARGS__) + +#define ABSL_INTERNAL_TRANSFORM_ARGS1(m, a0) m(a0) + +#define ABSL_INTERNAL_TRANSFORM_ARGS2(m, a0, a1) m(a0), m(a1) + +#define ABSL_INTERNAL_TRANSFORM_ARGS3(m, a0, a1, a2) m(a0), m(a1), m(a2) + +#define ABSL_INTERNAL_TRANSFORM_ARGS4(m, a0, a1, a2, a3) \ + m(a0), m(a1), m(a2), m(a3) + +#define ABSL_INTERNAL_TRANSFORM_ARGS5(m, a0, a1, a2, a3, a4) \ + m(a0), m(a1), m(a2), m(a3), m(a4) + +#define ABSL_INTERNAL_TRANSFORM_ARGS6(m, a0, a1, a2, a3, a4, a5) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5) + +#define ABSL_INTERNAL_TRANSFORM_ARGS7(m, a0, a1, a2, a3, a4, a5, a6) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6) + +#define ABSL_INTERNAL_TRANSFORM_ARGS8(m, a0, a1, a2, a3, a4, a5, a6, a7) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7) + +#define ABSL_INTERNAL_TRANSFORM_ARGS9(m, a0, a1, a2, a3, a4, a5, a6, a7, a8) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8) + +#define ABSL_INTERNAL_TRANSFORM_ARGS10(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9) + +#define ABSL_INTERNAL_TRANSFORM_ARGS11(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), m(a10) + +#define ABSL_INTERNAL_TRANSFORM_ARGS12(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11) + +#define ABSL_INTERNAL_TRANSFORM_ARGS13(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12) + +#define ABSL_INTERNAL_TRANSFORM_ARGS14(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13) + +#define ABSL_INTERNAL_TRANSFORM_ARGS15(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13, a14) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14) + +#define ABSL_INTERNAL_TRANSFORM_ARGS16(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13, a14, a15) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15) + +#define ABSL_INTERNAL_TRANSFORM_ARGS17(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13, a14, a15, a16) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16) + +#define ABSL_INTERNAL_TRANSFORM_ARGS18(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13, a14, a15, a16, \ + a17) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17) + +#define ABSL_INTERNAL_TRANSFORM_ARGS19(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13, a14, a15, a16, \ + a17, a18) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18) + +#define ABSL_INTERNAL_TRANSFORM_ARGS20(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13, a14, a15, a16, \ + a17, a18, a19) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19) + +#define ABSL_INTERNAL_TRANSFORM_ARGS21(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13, a14, a15, a16, \ + a17, a18, a19, a20) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19), m(a20) + +#define ABSL_INTERNAL_TRANSFORM_ARGS22(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13, a14, a15, a16, \ + a17, a18, a19, a20, a21) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19), m(a20), m(a21) + +#define ABSL_INTERNAL_TRANSFORM_ARGS23(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13, a14, a15, a16, \ + a17, a18, a19, a20, a21, a22) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19), m(a20), m(a21), m(a22) + +#define ABSL_INTERNAL_TRANSFORM_ARGS24(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13, a14, a15, a16, \ + a17, a18, a19, a20, a21, a22, a23) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19), m(a20), m(a21), m(a22), m(a23) + +#define ABSL_INTERNAL_TRANSFORM_ARGS25(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13, a14, a15, a16, \ + a17, a18, a19, a20, a21, a22, a23, a24) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19), m(a20), m(a21), m(a22), m(a23), m(a24) + +#define ABSL_INTERNAL_TRANSFORM_ARGS26( \ + m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, \ + a16, a17, a18, a19, a20, a21, a22, a23, a24, a25) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25) + +#define ABSL_INTERNAL_TRANSFORM_ARGS27( \ + m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, \ + a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25), m(a26) + +#define ABSL_INTERNAL_TRANSFORM_ARGS28( \ + m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, \ + a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25), m(a26), m(a27) + +#define ABSL_INTERNAL_TRANSFORM_ARGS29( \ + m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, \ + a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25), m(a26), m(a27), \ + m(a28) + +#define ABSL_INTERNAL_TRANSFORM_ARGS30( \ + m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, \ + a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25), m(a26), m(a27), \ + m(a28), m(a29) + +#define ABSL_INTERNAL_TRANSFORM_ARGS31( \ + m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, \ + a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25), m(a26), m(a27), \ + m(a28), m(a29), m(a30) + +#define ABSL_INTERNAL_TRANSFORM_ARGS32(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, \ + a9, a10, a11, a12, a13, a14, a15, a16, \ + a17, a18, a19, a20, a21, a22, a23, a24, \ + a25, a26, a27, a28, a29, a30, a31) \ + m(a0), m(a1), m(a2), m(a3), m(a4), m(a5), m(a6), m(a7), m(a8), m(a9), \ + m(a10), m(a11), m(a12), m(a13), m(a14), m(a15), m(a16), m(a17), m(a18), \ + m(a19), m(a20), m(a21), m(a22), m(a23), m(a24), m(a25), m(a26), m(a27), \ + m(a28), m(a29), m(a30), m(a31) + +#define ABSL_INTERNAL_NUM_ARGS_IMPL(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, \ + a10, a11, a12, a13, a14, a15, a16, a17, \ + a18, a19, a20, a21, a22, a23, a24, a25, \ + a26, a27, a28, a29, a30, a31, result, ...) \ + result + +#define ABSL_INTERNAL_FORCE_EXPANSION(...) __VA_ARGS__ + +#define ABSL_INTERNAL_NUM_ARGS(...) \ + ABSL_INTERNAL_FORCE_EXPANSION(ABSL_INTERNAL_NUM_ARGS_IMPL( \ + __VA_ARGS__, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, \ + 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, )) + +#endif // ABSL_TYPES_INTERNAL_TRANSFORM_ARGS_H_ diff --git a/contrib/restricted/abseil-cpp/absl/types/internal/variant.h b/contrib/restricted/abseil-cpp/absl/types/internal/variant.h index 772008c74e..53aeb3c95c 100644 --- a/contrib/restricted/abseil-cpp/absl/types/internal/variant.h +++ b/contrib/restricted/abseil-cpp/absl/types/internal/variant.h @@ -40,12 +40,12 @@ #if !defined(ABSL_USES_STD_VARIANT) namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN template <class... Types> class variant; -ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, static_cast<size_t>(-1)); +ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, static_cast<size_t>(-1)); template <class T> struct variant_size; @@ -292,7 +292,7 @@ struct UnreachableSwitchCase { template <class Op, std::size_t I> struct ReachableSwitchCase { static VisitIndicesResultT<Op, std::size_t> Run(Op&& op) { - return absl::base_internal::invoke(absl::forward<Op>(op), SizeT<I>()); + return absl::base_internal::invoke(absl::forward<Op>(op), SizeT<I>()); } }; @@ -424,7 +424,7 @@ struct VisitIndicesSwitch { return PickCase<Op, 32, EndIndex>::Run(absl::forward<Op>(op)); default: ABSL_ASSERT(i == variant_npos); - return absl::base_internal::invoke(absl::forward<Op>(op), NPos()); + return absl::base_internal::invoke(absl::forward<Op>(op), NPos()); } } }; @@ -488,7 +488,7 @@ struct VisitIndicesVariadicImpl<absl::index_sequence<N...>, EndIndices...> { template <std::size_t I> VisitIndicesResultT<Op, decltype(EndIndices)...> operator()( SizeT<I> /*index*/) && { - return base_internal::invoke( + return base_internal::invoke( absl::forward<Op>(op), SizeT<UnflattenIndex<I, N, (EndIndices + 1)...>::value - std::size_t{1}>()...); @@ -930,7 +930,7 @@ struct PerformVisitation { absl::result_of_t<Op(VariantAccessResult< Is, QualifiedVariants>...)>>::value, "All visitation overloads must have the same return type."); - return absl::base_internal::invoke( + return absl::base_internal::invoke( absl::forward<Op>(op), VariantCoreAccess::Access<Is>( absl::forward<QualifiedVariants>(std::get<TupIs>(variant_tup)))...); @@ -1639,7 +1639,7 @@ struct VariantHashBase<Variant, }; } // namespace variant_internal -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // !defined(ABSL_USES_STD_VARIANT) diff --git a/contrib/restricted/abseil-cpp/absl/types/optional.h b/contrib/restricted/abseil-cpp/absl/types/optional.h index 61540cfdb2..f9c085bc74 100644 --- a/contrib/restricted/abseil-cpp/absl/types/optional.h +++ b/contrib/restricted/abseil-cpp/absl/types/optional.h @@ -43,13 +43,13 @@ #include <optional> // IWYU pragma: export namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN using std::bad_optional_access; using std::optional; using std::make_optional; using std::nullopt_t; using std::nullopt; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_OPTIONAL @@ -67,7 +67,7 @@ ABSL_NAMESPACE_END #include "absl/types/internal/optional.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // nullopt_t // @@ -136,10 +136,10 @@ class optional : private optional_internal::optional_data<T>, constexpr optional(nullopt_t) noexcept {} // NOLINT(runtime/explicit) // Copy constructor, standard semantics - optional(const optional&) = default; + optional(const optional&) = default; // Move constructor, standard semantics - optional(optional&&) = default; + optional(optional&&) = default; // Constructs a non-empty `optional` direct-initialized value of type `T` from // the arguments `std::forward<Args>(args)...` within the `optional`. @@ -412,11 +412,11 @@ class optional : private optional_internal::optional_data<T>, // // If you need myOpt->foo in constexpr, use (*myOpt).foo instead. const T* operator->() const { - ABSL_HARDENING_ASSERT(this->engaged_); + ABSL_HARDENING_ASSERT(this->engaged_); return std::addressof(this->data_); } T* operator->() { - ABSL_HARDENING_ASSERT(this->engaged_); + ABSL_HARDENING_ASSERT(this->engaged_); return std::addressof(this->data_); } @@ -425,17 +425,17 @@ class optional : private optional_internal::optional_data<T>, // Accesses the underlying `T` value of an `optional`. If the `optional` is // empty, behavior is undefined. constexpr const T& operator*() const& { - return ABSL_HARDENING_ASSERT(this->engaged_), reference(); + return ABSL_HARDENING_ASSERT(this->engaged_), reference(); } T& operator*() & { - ABSL_HARDENING_ASSERT(this->engaged_); + ABSL_HARDENING_ASSERT(this->engaged_); return reference(); } constexpr const T&& operator*() const && { - return ABSL_HARDENING_ASSERT(this->engaged_), absl::move(reference()); + return ABSL_HARDENING_ASSERT(this->engaged_), absl::move(reference()); } T&& operator*() && { - ABSL_HARDENING_ASSERT(this->engaged_); + ABSL_HARDENING_ASSERT(this->engaged_); return std::move(reference()); } @@ -444,7 +444,7 @@ class optional : private optional_internal::optional_data<T>, // Returns false if and only if the `optional` is empty. // // if (opt) { - // // do something with *opt or opt->; + // // do something with *opt or opt->; // } else { // // opt is empty. // } @@ -757,7 +757,7 @@ constexpr auto operator>=(const U& v, const optional<T>& x) return static_cast<bool>(x) ? static_cast<bool>(v >= *x) : true; } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl namespace std { diff --git a/contrib/restricted/abseil-cpp/absl/types/span.h b/contrib/restricted/abseil-cpp/absl/types/span.h index 6272bb7ad1..ed350d055c 100644 --- a/contrib/restricted/abseil-cpp/absl/types/span.h +++ b/contrib/restricted/abseil-cpp/absl/types/span.h @@ -17,23 +17,23 @@ // span.h // ----------------------------------------------------------------------------- // -// This header file defines a `Span<T>` type for holding a reference to existing -// array data. The `Span` object, much like the `absl::string_view` object, -// does not own such data itself, and the data being referenced by the span must -// outlive the span itself. Unlike `view` type references, a span can hold a -// reference to mutable data (and can mutate it for underlying types of -// non-const T.) A span provides a lightweight way to pass a reference to such -// data. +// This header file defines a `Span<T>` type for holding a reference to existing +// array data. The `Span` object, much like the `absl::string_view` object, +// does not own such data itself, and the data being referenced by the span must +// outlive the span itself. Unlike `view` type references, a span can hold a +// reference to mutable data (and can mutate it for underlying types of +// non-const T.) A span provides a lightweight way to pass a reference to such +// data. // // Additionally, this header file defines `MakeSpan()` and `MakeConstSpan()` // factory functions, for clearly creating spans of type `Span<T>` or read-only // `Span<const T>` when such types may be difficult to identify due to issues // with implicit conversion. // -// The C++20 draft standard includes a `std::span` type. As of June 2020, the -// differences between `absl::Span` and `std::span` are: -// * `absl::Span` has `operator==` (which is likely a design bug, -// per https://abseil.io/blog/20180531-regular-types) +// The C++20 draft standard includes a `std::span` type. As of June 2020, the +// differences between `absl::Span` and `std::span` are: +// * `absl::Span` has `operator==` (which is likely a design bug, +// per https://abseil.io/blog/20180531-regular-types) // * `absl::Span` has the factory functions `MakeSpan()` and // `MakeConstSpan()` // * bounds-checked access to `absl::Span` is accomplished with `at()` @@ -68,15 +68,15 @@ #include "absl/types/internal/span.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN //------------------------------------------------------------------------------ // Span //------------------------------------------------------------------------------ // -// A `Span` is an "array reference" type for holding a reference of contiguous -// array data; the `Span` object does not and cannot own such data itself. A -// span provides an easy way to provide overloads for anything operating on +// A `Span` is an "array reference" type for holding a reference of contiguous +// array data; the `Span` object does not and cannot own such data itself. A +// span provides an easy way to provide overloads for anything operating on // contiguous sequences without needing to manage pointers and array lengths // manually. @@ -94,8 +94,8 @@ ABSL_NAMESPACE_BEGIN // constructors. // // A `Span<T>` is somewhat analogous to an `absl::string_view`, but for an array -// of elements of type `T`, and unlike an `absl::string_view`, a span can hold a -// reference to mutable data. A user of `Span` must ensure that the data being +// of elements of type `T`, and unlike an `absl::string_view`, a span can hold a +// reference to mutable data. A user of `Span` must ensure that the data being // pointed to outlives the `Span` itself. // // You can construct a `Span<T>` in several ways: @@ -125,7 +125,7 @@ ABSL_NAMESPACE_BEGIN // Note that `Span` objects, in addition to requiring that the memory they // point to remains alive, must also ensure that such memory does not get // reallocated. Therefore, to avoid undefined behavior, containers with -// associated spans should not invoke operations that may reallocate memory +// associated spans should not invoke operations that may reallocate memory // (such as resizing) or invalidate iterators into the container. // // One common use for a `Span` is when passing arguments to a routine that can @@ -275,7 +275,7 @@ class Span { // Returns a reference to the i'th element of this span. constexpr reference operator[](size_type i) const noexcept { // MSVC 2015 accepts this as constexpr, but not ptr_[i] - return ABSL_HARDENING_ASSERT(i < size()), *(data() + i); + return ABSL_HARDENING_ASSERT(i < size()), *(data() + i); } // Span::at() @@ -291,74 +291,74 @@ class Span { // Span::front() // - // Returns a reference to the first element of this span. The span must not - // be empty. + // Returns a reference to the first element of this span. The span must not + // be empty. constexpr reference front() const noexcept { - return ABSL_HARDENING_ASSERT(size() > 0), *data(); + return ABSL_HARDENING_ASSERT(size() > 0), *data(); } // Span::back() // - // Returns a reference to the last element of this span. The span must not - // be empty. + // Returns a reference to the last element of this span. The span must not + // be empty. constexpr reference back() const noexcept { - return ABSL_HARDENING_ASSERT(size() > 0), *(data() + size() - 1); + return ABSL_HARDENING_ASSERT(size() > 0), *(data() + size() - 1); } // Span::begin() // - // Returns an iterator pointing to the first element of this span, or `end()` - // if the span is empty. + // Returns an iterator pointing to the first element of this span, or `end()` + // if the span is empty. constexpr iterator begin() const noexcept { return data(); } // Span::cbegin() // - // Returns a const iterator pointing to the first element of this span, or - // `end()` if the span is empty. + // Returns a const iterator pointing to the first element of this span, or + // `end()` if the span is empty. constexpr const_iterator cbegin() const noexcept { return begin(); } // Span::end() // - // Returns an iterator pointing just beyond the last element at the - // end of this span. This iterator acts as a placeholder; attempting to - // access it results in undefined behavior. + // Returns an iterator pointing just beyond the last element at the + // end of this span. This iterator acts as a placeholder; attempting to + // access it results in undefined behavior. constexpr iterator end() const noexcept { return data() + size(); } // Span::cend() // - // Returns a const iterator pointing just beyond the last element at the - // end of this span. This iterator acts as a placeholder; attempting to - // access it results in undefined behavior. + // Returns a const iterator pointing just beyond the last element at the + // end of this span. This iterator acts as a placeholder; attempting to + // access it results in undefined behavior. constexpr const_iterator cend() const noexcept { return end(); } // Span::rbegin() // - // Returns a reverse iterator pointing to the last element at the end of this - // span, or `rend()` if the span is empty. + // Returns a reverse iterator pointing to the last element at the end of this + // span, or `rend()` if the span is empty. constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } // Span::crbegin() // - // Returns a const reverse iterator pointing to the last element at the end of - // this span, or `crend()` if the span is empty. + // Returns a const reverse iterator pointing to the last element at the end of + // this span, or `crend()` if the span is empty. constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); } // Span::rend() // - // Returns a reverse iterator pointing just before the first element - // at the beginning of this span. This pointer acts as a placeholder; - // attempting to access its element results in undefined behavior. + // Returns a reverse iterator pointing just before the first element + // at the beginning of this span. This pointer acts as a placeholder; + // attempting to access its element results in undefined behavior. constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } // Span::crend() // - // Returns a reverse const iterator pointing just before the first element - // at the beginning of this span. This pointer acts as a placeholder; - // attempting to access its element results in undefined behavior. + // Returns a reverse const iterator pointing just before the first element + // at the beginning of this span. This pointer acts as a placeholder; + // attempting to access its element results in undefined behavior. constexpr const_reverse_iterator crend() const noexcept { return rend(); } // Span mutations @@ -367,7 +367,7 @@ class Span { // // Removes the first `n` elements from the span. void remove_prefix(size_type n) noexcept { - ABSL_HARDENING_ASSERT(size() >= n); + ABSL_HARDENING_ASSERT(size() >= n); ptr_ += n; len_ -= n; } @@ -376,7 +376,7 @@ class Span { // // Removes the last `n` elements from the span. void remove_suffix(size_type n) noexcept { - ABSL_HARDENING_ASSERT(size() >= n); + ABSL_HARDENING_ASSERT(size() >= n); len_ -= n; } @@ -664,7 +664,7 @@ constexpr Span<T> MakeSpan(T* ptr, size_t size) noexcept { template <int&... ExplicitArgumentBarrier, typename T> Span<T> MakeSpan(T* begin, T* end) noexcept { - return ABSL_HARDENING_ASSERT(begin <= end), Span<T>(begin, end - begin); + return ABSL_HARDENING_ASSERT(begin <= end), Span<T>(begin, end - begin); } template <int&... ExplicitArgumentBarrier, typename C> @@ -709,7 +709,7 @@ constexpr Span<const T> MakeConstSpan(T* ptr, size_t size) noexcept { template <int&... ExplicitArgumentBarrier, typename T> Span<const T> MakeConstSpan(T* begin, T* end) noexcept { - return ABSL_HARDENING_ASSERT(begin <= end), Span<const T>(begin, end - begin); + return ABSL_HARDENING_ASSERT(begin <= end), Span<const T>(begin, end - begin); } template <int&... ExplicitArgumentBarrier, typename C> @@ -721,6 +721,6 @@ template <int&... ExplicitArgumentBarrier, typename T, size_t N> constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept { return Span<const T>(array, N); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TYPES_SPAN_H_ diff --git a/contrib/restricted/abseil-cpp/absl/types/variant.h b/contrib/restricted/abseil-cpp/absl/types/variant.h index ac93464bf8..b2056827b8 100644 --- a/contrib/restricted/abseil-cpp/absl/types/variant.h +++ b/contrib/restricted/abseil-cpp/absl/types/variant.h @@ -50,7 +50,7 @@ #include <variant> // IWYU pragma: export namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN using std::bad_variant_access; using std::get; using std::get_if; @@ -63,7 +63,7 @@ using std::variant_npos; using std::variant_size; using std::variant_size_v; using std::visit; -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #else // ABSL_USES_STD_VARIANT @@ -79,7 +79,7 @@ ABSL_NAMESPACE_END #include "absl/types/internal/variant.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // ----------------------------------------------------------------------------- // absl::variant @@ -803,7 +803,7 @@ operator>=(const variant<Types...>& a, const variant<Types...>& b) { a.index()); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl namespace std { @@ -824,7 +824,7 @@ struct hash<absl::variant<T...>> #endif // ABSL_USES_STD_VARIANT namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN namespace variant_internal { // Helper visitor for converting a variant<Ts...>` into another type (mostly @@ -860,7 +860,7 @@ To ConvertVariantTo(Variant&& variant) { std::forward<Variant>(variant)); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_TYPES_VARIANT_H_ diff --git a/contrib/restricted/abseil-cpp/absl/utility/utility.h b/contrib/restricted/abseil-cpp/absl/utility/utility.h index bf9232209a..45b54e6da6 100644 --- a/contrib/restricted/abseil-cpp/absl/utility/utility.h +++ b/contrib/restricted/abseil-cpp/absl/utility/utility.h @@ -51,7 +51,7 @@ #include "absl/meta/type_traits.h" namespace absl { -ABSL_NAMESPACE_BEGIN +ABSL_NAMESPACE_BEGIN // integer_sequence // @@ -236,10 +236,10 @@ namespace utility_internal { // Helper method for expanding tuple into a called method. template <typename Functor, typename Tuple, std::size_t... Indexes> auto apply_helper(Functor&& functor, Tuple&& t, index_sequence<Indexes...>) - -> decltype(absl::base_internal::invoke( + -> decltype(absl::base_internal::invoke( absl::forward<Functor>(functor), std::get<Indexes>(absl::forward<Tuple>(t))...)) { - return absl::base_internal::invoke( + return absl::base_internal::invoke( absl::forward<Functor>(functor), std::get<Indexes>(absl::forward<Tuple>(t))...); } @@ -344,7 +344,7 @@ constexpr T make_from_tuple(Tuple&& tup) { std::tuple_size<absl::decay_t<Tuple>>::value>{}); } -ABSL_NAMESPACE_END +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_UTILITY_UTILITY_H_ diff --git a/contrib/restricted/abseil-cpp/ya.make b/contrib/restricted/abseil-cpp/ya.make index f69125bf2d..b1cd6096a7 100644 --- a/contrib/restricted/abseil-cpp/ya.make +++ b/contrib/restricted/abseil-cpp/ya.make @@ -17,7 +17,7 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/base/internal/raw_logging contrib/restricted/abseil-cpp/absl/base/internal/scoped_set_env contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait - contrib/restricted/abseil-cpp/absl/base/internal/strerror + contrib/restricted/abseil-cpp/absl/base/internal/strerror contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate contrib/restricted/abseil-cpp/absl/base/log_severity contrib/restricted/abseil-cpp/absl/city @@ -33,15 +33,15 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/debugging/symbolize contrib/restricted/abseil-cpp/absl/demangle contrib/restricted/abseil-cpp/absl/flags - contrib/restricted/abseil-cpp/absl/flags/commandlineflag + contrib/restricted/abseil-cpp/absl/flags/commandlineflag contrib/restricted/abseil-cpp/absl/flags/internal/commandlineflag contrib/restricted/abseil-cpp/absl/flags/internal/flag - contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor + contrib/restricted/abseil-cpp/absl/flags/internal/private_handle_accessor contrib/restricted/abseil-cpp/absl/flags/internal/program_name contrib/restricted/abseil-cpp/absl/flags/internal/usage contrib/restricted/abseil-cpp/absl/flags/marshalling contrib/restricted/abseil-cpp/absl/flags/parse - contrib/restricted/abseil-cpp/absl/flags/reflection + contrib/restricted/abseil-cpp/absl/flags/reflection contrib/restricted/abseil-cpp/absl/flags/usage contrib/restricted/abseil-cpp/absl/flags/usage_config contrib/restricted/abseil-cpp/absl/functional @@ -58,13 +58,13 @@ PEERDIR( contrib/restricted/abseil-cpp/absl/random/internal/randen contrib/restricted/abseil-cpp/absl/random/internal/randen_detect contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes - contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys + contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys contrib/restricted/abseil-cpp/absl/random/internal/randen_slow contrib/restricted/abseil-cpp/absl/random/internal/seed_material contrib/restricted/abseil-cpp/absl/random/seed_gen_exception contrib/restricted/abseil-cpp/absl/random/seed_sequences - contrib/restricted/abseil-cpp/absl/status - contrib/restricted/abseil-cpp/absl/status/statusor + contrib/restricted/abseil-cpp/absl/status + contrib/restricted/abseil-cpp/absl/status/statusor contrib/restricted/abseil-cpp/absl/strings contrib/restricted/abseil-cpp/absl/strings/cord contrib/restricted/abseil-cpp/absl/strings/internal/absl_cord_internal @@ -88,7 +88,7 @@ PEERDIR( ) NO_RUNTIME() - + END() RECURSE( @@ -98,7 +98,7 @@ RECURSE( absl/base/internal/raw_logging absl/base/internal/scoped_set_env absl/base/internal/spinlock_wait - absl/base/internal/strerror + absl/base/internal/strerror absl/base/internal/throw_delegate absl/base/log_severity absl/city @@ -114,15 +114,15 @@ RECURSE( absl/debugging/symbolize absl/demangle absl/flags - absl/flags/commandlineflag + absl/flags/commandlineflag absl/flags/internal/commandlineflag absl/flags/internal/flag - absl/flags/internal/private_handle_accessor + absl/flags/internal/private_handle_accessor absl/flags/internal/program_name absl/flags/internal/usage absl/flags/marshalling absl/flags/parse - absl/flags/reflection + absl/flags/reflection absl/flags/usage absl/flags/usage_config absl/functional @@ -139,13 +139,13 @@ RECURSE( absl/random/internal/randen absl/random/internal/randen_detect absl/random/internal/randen_hwaes - absl/random/internal/randen_round_keys + absl/random/internal/randen_round_keys absl/random/internal/randen_slow absl/random/internal/seed_material absl/random/seed_gen_exception absl/random/seed_sequences - absl/status - absl/status/statusor + absl/status + absl/status/statusor absl/strings absl/strings/cord absl/strings/internal/absl_cord_internal |