Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marked _Doraise() functions as override (improves #207) #302

Merged
merged 1 commit into from Nov 16, 2019

Conversation

@jpjjulie
Copy link
Contributor

jpjjulie commented Nov 15, 2019

I have fixed _doraise() to become override functions. Unfortunately, I couldn't fix all the functions as I am not very familiar with the code. Sorry about that!

@jpjjulie jpjjulie requested a review from microsoft/vclibs as a code owner Nov 15, 2019
Copy link
Member

StephanTLavavej left a comment

Looks good to me, but clang-format validation is failing because there should be a space before the brace in override{ . If you fix those occurrences, the validation should pass. You can either run clang-format 9.0.0 on these files, or you can click on the Details for the "microsoft.STL (x64)" check, which will display the edits that clang-format wants to make. Thanks!

@jpjjulie jpjjulie force-pushed the jpjjulie:issue-207 branch from 044b03b to c0a123d Nov 15, 2019
@jpjjulie

This comment has been minimized.

Copy link
Contributor Author

jpjjulie commented Nov 15, 2019

Thank you for the feedback! I have made the necessary corrections.

@jpjjulie jpjjulie requested a review from StephanTLavavej Nov 15, 2019
Copy link
Member

CaseyCarter left a comment

Looks good! I counted, and they're all here.

@StephanTLavavej StephanTLavavej changed the title Fix #102: Marked _Doraise() functions as override Marked _Doraise() functions as override (improves #207) Nov 15, 2019
@StephanTLavavej

This comment has been minimized.

Copy link
Member

StephanTLavavej commented Nov 15, 2019

I'm porting this to our Microsoft-internal MSVC repo now, for a full build and test run.

@StephanTLavavej StephanTLavavej merged commit 580e61a into microsoft:master Nov 16, 2019
6 checks passed
6 checks passed
license/cla All CLA requirements met.
Details
microsoft.STL Build #20191115.3 succeeded
Details
microsoft.STL (arm) arm succeeded
Details
microsoft.STL (arm64) arm64 succeeded
Details
microsoft.STL (x64) x64 succeeded
Details
microsoft.STL (x86) x86 succeeded
Details
@StephanTLavavej

This comment has been minimized.

Copy link
Member

StephanTLavavej commented Nov 16, 2019

This passed our tests, so I've merged your improvement for the VS 2019 16.5 Preview 2 release. Thanks again!

fengjixuchui added a commit to fengjixuchui/STL that referenced this pull request Nov 16, 2019
Marked _Doraise() functions as override (microsoft#302)
SachieKang added a commit to SachieKang/STL that referenced this pull request Jan 21, 2020
* Update the PR template to fix microsoft#117. (microsoft#152)

Update the PR template to fix microsoft#117.

This adds a checkbox to the PR template mentioning
license discipline.

It clarifies the instructions regarding unchecked
and inapplicable boxes.

It fuses the "acceptance will be delayed" disclaimer
into the README checkbox.

This also rewraps the issue template (we usually wrap to 120,
but 80 is friendlier to the issue textbox) and improves the
wording by changing "Alternately" to "Alternatively".

* Corrected URI to URL (microsoft#149)

On line 157,corrected URI to URL

* Implement LWG 3268's PR to fix microsoft#150. (microsoft#151)

This is a back-compat fix for users who were saying things like
`std::memory_order::memory_order_relaxed`. As there is nothing
especially problematic about such usage, and LWG's ultimate resolution
is unknown, I'm not deprecating these enumerators at this time. If and
when this is voted into the WP in the deprecated clause, then we can
add deprecated attributes.

This mirrors a Microsoft-internal PR:
https://devdiv.visualstudio.com/DevDiv/_git/msvc/pullrequest/205250

* Activate FrameHandler4 to fix microsoft#118. (microsoft#154)

This affects the x64 build. Before this change, msvcp140.dll
was 601,600 bytes. After this change, it's 540,672 bytes.

This ports a Microsoft-internal PR:
https://devdiv.visualstudio.com/DevDiv/_git/msvc/pullrequest/204636

* * Replaced Microsoft/STL with microsoft/STL (microsoft#157)

* Capitalised first letter of every word in header

* Parallelize enforcement of clang-format (microsoft#163)

Add jobify.exe and parallelize.exe
Add a "tools" directory for test/build support tools.
Add jobify.exe from the msvc repo.
Extract parts of jobify into stljobs.h, and author wrappers for other test support.
Add parallelize.exe which runs a command in parallel over all inputs in a directory.
Teach Azure DevOps to enforce clang-format in parallel.

* Workaround clang __is_base_of bug in <type_traits> (microsoft#167)

Clang's `__is_base_of` intrinsic incorrectly handles some corner cases involving incomplete union types before LLVM 9. Workaround by guarding with `__is_class`.

* Update comments to follow custom autolink syntax (microsoft#168)

* Use custom autolinks.

* Also update .clang-format.

* Use ArchivedOS.

* Add back the missing unique_ptr swap (microsoft#170)

Resolves DevCom-754487 / VSO-1000729

* Cleanup <any> and allow overaligned types (microsoft#173)

`<any>` cleanup:

* Prefer variable templates to class templates
* Prefer `if constexpr` to tag dispatch
* Function pointers may be `noexcept` in C++17
* Remove the layer of "symbolic member name" functions to improve debug codegen
* Conventionally use `enable_if_t<conjunction_v<meow, woof>` instead of `enable_if_t<meow::value && woof::value>`
* Apply `_NODISCARD` and `noexcept` to internal functions as appropriate
* Allow overaligned types, which are properly handled by the `_Big` representation

Resolves [DevCom-724444](https://developercommunity.visualstudio.com/content/problem/724444/meow.html).

* Fix microsoft#94 and remove compiler bug workarounds. (microsoft#175)

* Properly comment "Tukey's ninther".

* Remove workarounds for VSO-946746.

VSO-946746 "conditional explicit(bool) doesn't work with /clr:pure"
was fixed on 2019-07-23, and should be available in
VS 2019 16.4 Preview 1.

* Remove workarounds for VSO-433486.

VSO-433486 "_Count / 2 inside while (0 < _Count) loop is not
transformed into a simple shift" was fixed on 2019-08-27
and should be available in VS 2019 16.4 Preview 2.

Some shifts are still necessary, and are now commented.

* This mirrors a Microsoft-internal PR:
https://devdiv.visualstudio.com/DevDiv/_git/msvc/pullrequest/207988

* P0966R1 string::reserve() should not shrink (microsoft#176)

Fixes microsoft#42.

* Update README and PR template (microsoft#194)

* README.md: New Working Draft N4835.

* Simplify pull_request_template.md.

We can remove the N/A guidance by updating
the two checkboxes that are commonly N/A.

Remove the "feature has been voted into the WP" checkbox.
We haven't had issues with people submitting non-Standard PRs,
and the README's Non-Goals section clearly explains
our acceptance criteria.

For the `_Ugly` checkbox, allow people to check it
if there aren't any product code changes at all.

* P0356R5 bind_front() (microsoft#158)

Resolves microsoft#13.

* P0767R1 Deprecating is_pod (microsoft#179)

Resolves microsoft#36.

* LWG-3158 tuple(allocator_arg_t, const Alloc&) should be conditionally explicit (microsoft#195)

Resolves microsoft#69.

* LWG-2899 is_(nothrow_)move_constructible and tuple, optional, and unique_ptr (microsoft#193)

Resolves microsoft#68.

* Changes made from update to clang-format to 9.0.0. (microsoft#205)

* Fix microsoft#218 - remove public redundancy (microsoft#219)

* P0655R1 visit<R>() (microsoft#201)

Implements P0655R1 `visit<R>()` 

Resolves microsoft#31.

* Move nlsdownlevel.h into winapinls.cpp (microsoft#220)

Fixes microsoft#188.

* Changed TODO comments to TRANSITION comments (microsoft#221)

Fixes microsoft#200.

* Use casts for most common atomic cases (microsoft#227)

Resolves microsoft#85 / DevCom-706195

Casey applying the new atomic implementation fixed us breaking the
strict aliasing rules, but the memcpy is causing a code size regression
for non-`/Oi` customers. This change should restore code size for the
most common uses of atomic, which are `atomic<integral>` and
`atomic<pointer>`.

* Avoid self-move-assign of all elements in vector when erasing an empty range. (microsoft#228)

Resolves DevCom-776568.

* Update required compiler versions (microsoft#231)

* Update required compiler versions

Update required version of MSVC to VS 2019 16.4p2, and Clang/LLVM to 9.0.0.

* Tell `<yvals_core.h>` that Clang 9 implements `consteval` (WG21 hasn't yet defined a feature-test macro for `consteval`)
* Tell `<atomic>` that Clang 9 implements the `__iso_volatile_load64` intrinsic on x86

* Update mentions of VS version in `README.md`

* Enforce ASCII and whitespace conventions (microsoft#229)

Fixes microsoft#141.

* Change LF to CRLF.
* Remove UTF-8 BOMs.
* Add validate.cpp.
* Add validate to CMakeLists.txt.
* Add validate to azure-devops.
* Wrap enforce-clang-format.cmd.
* Code review feedback: abort().
* Code review feedback: Assign previous3.
* Code review feedback: Don't catch everything.
* Code review feedback: MaxErrorsForDisallowedCharacters.
* Cleanup: Remove `enabled: true`.
* Code review feedback: Character code comments.
* Code review feedback: Allow certain files to be tabby.
* Code review feedback: Use native wchar_t paths.

* Update cgmanifest.json and README.md. (microsoft#238)

* Replay MSVC internal PR 209928.

* README.md: Capitalize Preview.

* <compare> implement == for comparison categories (microsoft#242)

WG21-P1614 "The Mothership has Landed" added `==` operators to the comparison category types (`weak_equality`, `strong_equality`, `partial_ordering`, `weak_ordering`, and `strong_ordering`) defined in `<compare>`. This PR implements those operators to bring the comparison category types up to spec once again. It also implements P1614R2's removal of operators that rewrite into calls to `operator==(X, nullptr_t)` for each comparison category type `X`.

Drive-by changes:
* Move the TODO list of tasks for WG21-P0768 "Library Support for the Spaceship (Comparison) Operator" completion out of `<compare>` and into microsoft#64
* Remove the `#if 0 // Not yet implemented` block from `<compare>`

* Remove delay comment in PR template because we've been merging PRs (microsoft#243)

* Remove delay comment in PR template because we've been merging PRs.

* Add readme.md note, and change "CI" to "automated testing" in checklist.

* Also remove statement from readme.md.

* P1209R0 erase_if(), erase() (microsoft#236)

Resolves microsoft#55.

* Deprecate experimental::erase

* Implement P1209R0

* Update yvals_core.h

* Update deprecations and remove <experimental/xutility>

* move and reorder erase/erase_if

* moved _Erase and remove and friends to <xmemory>

* Consistently place erase_if() definitions.

* Consistently use "int = 0" SFINAE (microsoft#226)

Fixes microsoft#187.

Add TRANSITION comments for microsoft#248 and microsoft#249, blocked by compiler bugs.

Add `_Enabled` names. When we don't have `enable_if_t`, this makes the
template parameter's purpose clearer. When we do have `enable_if_t`
but without `= 0`, this makes it somewhat clearer that we haven't
forgotten the default argument (it's simply elsewhere).

* Update _MSVC_STL_UPDATE to 201911L (microsoft#253)

Fixes microsoft#247.

* Use consistent phrasing of required standard mode (microsoft#252)

Fixes microsoft#250.

* Make enforce-clang-format.cmd also run `git diff`. (microsoft#255)

* Make `enforce-clang-format.cmd` also run `git diff`. This will produce more informative output for clang-format failures.
* Also add timeouts to every task in `run_build.yml`.
* Also remove default `targetPlatform` from `run_build.yml`. This is provided by `azure-pipelines.yml`.

* Move vcpkg_windows.txt to azure-devops. (microsoft#262)

`azure-devops/run_build.yml` is the only thing that uses
`vcpkg_windows.txt`, so I don't believe that it belongs
in the root of the repo.

* Add .vscode/settings.json. (microsoft#263)

This file is gitignored, so it will provide default settings that can
be further customized without showing up as pending changes.

It enables `editor.formatOnSave` to help with clang-format enforcement.

It sets `files.eol` to CRLF and enables `files.insertFinalNewline`,
`files.trimFinalNewlines`, and `files.trimTrailingWhitespace` to help
with whitespace enforcement.

It uses `files.associations` to mark our extensionless headers as C++.

It excludes the `stl/msbuild` subdirectory (which isn't used by the
GitHub repo, and is doomed soon). It also excludes the `vcpkg`
submodule, to prevent its files from showing up in Quick Open (Ctrl+P).

* Enable clang-format AlignConsecutiveMacros. (microsoft#269)

* Update `.clang-format` defaults.

* Enable `AlignConsecutiveMacros`, newly supported by clang-format 9.
We often followed this style before using clang-format, and I believe
that it produces generally positive changes.

* Apply clang-format changes.

* Replace `_FITS` and `_NEXT_ALIGN` macros. clang-format didn't damage
them, it just brought them to my attention. These macros weren't
improving clarity, and the code is more systematic without them.
(For the time being, I have refrained from further overhauling the
metaprogramming here.)

* P0738R2 istream_iterator Cleanup (microsoft#246)

This change is unconditional.

Resolves microsoft#35.

* P0631R8 <numbers> Math Constants (microsoft#261)

Resolves microsoft#29.

* P0340R3 SFINAE-Friendly underlying_type (microsoft#284)

Resolves microsoft#11. Implemented unconditionally.

* Use unqualified function calls for valarray (microsoft#286)

* Use unqualified function calls for valarray

The transcend functions require that the function is applied unqualified to each element

* Add comments to unqualified calls.

Fixes microsoft#285.

* Update __cpp_lib_concepts (see WG21-P1902). (microsoft#287)

This feature-test macro is being extensively queried, so we're updating it with high priority ahead of the other feature-test macro changes in this paper.

* Improve the PR and issue templates (microsoft#288)

* Simplify paths in ISSUE_TEMPLATE.md.

* Mention WG21 papers and LWG issues in PR template.

* Exclude reference implementations.

* Increase clang-format timeout to 60 minutes.

* <algorithm>: Use iter[idx] for clarity (microsoft#289)

Fixes microsoft#278.

* STL: Remove !_HAS_EXACT_COMPOUND_REQUIREMENT fallback (microsoft#301)

Fixes microsoft#299.

* Marked _Doraise() functions as override (microsoft#302)

Improves microsoft#207.

* P1612R1 Relocating endian To <bit> (microsoft#305)

Resolves  microsoft#61.

* Add P0553R4 and P0556R3 to <bit> (with D1956 rename) (microsoft#310)

Resolves microsoft#25 and resolves microsoft#26. Currently active for Clang and EDG, but not C1XX.

* Simplify thread0.cpp and xthrow.cpp. (microsoft#320)

* Simplify thread0.cpp and xthrow.cpp.

I verified with `#error` that these files are always compiled with
`_HAS_EXCEPTIONS=1`.

thread0.cpp
Include only necessary headers.

Move the lookup tables within `_STD_BEGIN` to avoid repeated `_STD`
qualification. They're `static`, so this doesn't affect bincompat.

Add trailing commas for readability.

Make `codes` a table of `errc` so we don't need to cast each value.

Mark `_Throw_Cpp_error` as `[[noreturn]]`, matching its declaration
in the header. (No bincompat effect.)

Use `_THROW` for consistency. (Even though exceptions are enabled,
we conventionally use this in `src`.)

`system_error` is a type, so we don't need to `_STD` qualify it.

`static_cast<int>` the `errc`, once.

xthrow.cpp
Coalesce headers. Coalesce `std` regions.

Remove unnecessary comments.

Mark value parameters as const.

* Add constexpr.

* Use on/off SFINAE in std::function when not blocked by compiler bugs. (microsoft#244)

Xiang Fan of the C1XX frontend team reported that this improved throughput in a customer submitted benchmark.

* [range.iter.ops], default_sentinel, and unreachable_sentinel (microsoft#329)

Implements iterator primitive operations `std::ranges::advance`, `std::ranges::next`, `std::ranges::prev`, and `std::ranges::distance`; as well as `std::default_sentinel` and `std::unreachable_sentinel`.

This change reworks the STL's iterator unwrapping machinery to enable unwrapping of C++20 move-only single-pass iterators (and `if constepxr`s all the things). Consequently, `_Iter_ref_t`, `_Iter_value_t`, and `_Iter_diff_t` resolve to `iter_reference_t`, `iter_value_t`, and `iter_difference_t` (respectively) in `__cpp_lib_concepts` (soon to be C++20) mode. This change necessitates some fixes to `unique_copy` and `_Fill_memset_is_safe` which both assume that `_Iter_value_t<T>` is well-formed for any iterator `T`. (`iter_value_t<T>` does not have that property: it is only well-formed when `readable<T>`.)

I notably haven't unified `default_sentinel_t` with `_Default_sentinel` out of an abundance of paranoia. Our `move_iterator` is comparable with `_Default_sentinel`, which is not the case for `std::default_sentinel`.

Drive-by:
* This change `if constexpr`-izes `unique_copy`.

* The latest C++ Working Draft is now WG21-N4842. (microsoft#346)

* Implement P1690R1 Refining Heterogeneous Lookup For Unordered Containers (microsoft#341)

* Implement P1690R1 Refining Heterogeneous Lookup For Unordered Containers

* Mark P1690R1 as implemented in yvals_core.h.

* Change return type from non-const to const (microsoft#324)

Addresses microsoft#268 by changing the implementation to match the current Standardese.

* Improve diagnostic for std::function<void() noexcept> (microsoft#350)

Programs that include such specializations are ill-formed, since the Standard only specifies a partial specialization of `std::function<T>` for non-`noexcept` function types `T`. The current diagnostic:
```
error C2027: use of undefined type 'std::_Get_function_impl<_Fty>'
```
is not great.

Fixes DevCom-825902.

[This is a replay of Microsoft-internal MSVC-PR-215822.]

* Hide std::unreachable_sentinel_t's friends harder (microsoft#352)

Hidden friends aren't hidden in C1XX's permissive mode, so let's use an alternate mechanism to make these operators truly ADL-only. (We want to avoid checking `weakly_incrementable` for every type that is compared via `==` or `!=` with a type associated with namespace `std`.)

* Fix microsoft#332: LWG-3266 to_chars(bool) should be deleted

* Fix microsoft#70: LWG-3199 istream >> bitset<0> fails

* Fix microsoft#335: LWG-3257 Missing feature testing macro update from WG21-P0858

* Fix microsoft#339: WG21-P1902 Missing Feature-Test Macros 2017-2019

* Fix microsoft#156: WG21-P0595 is_constant_evaluated()

* Reorder and rewrap yvals_core.h comments.

* Fix microsoft#322: <filesystem>: GetVolumePathNameW linker errors for UWP developers

* Improve clang-format with StatementMacros.

* Rewrap comments in <execution>.

* Use _STD addressof(_Val), update _MSVC_STL_UPDATE (microsoft#358)

* Fix microsoft#272: `<future>: promise<_Ty&>::set_value(_Ty& _Val)` should use `_STD addressof(_Val)`
* Fix microsoft#344: `<yvals_core.h>`: Update `_MSVC_STL_UPDATE` to December 2019

* Fix microsoft#249: Change <hash_map> to consistently use int = 0 SFINAE (microsoft#328)

Permanently work around DevCom-848104 by simplifying hash_meow::value_type. This is what unordered_meow::value_type already does, which is why that can already use int = 0 SFINAE.

* Strengthen noexcept on std::exchange, which improves codegen for many move constructors and move assignments that use std::exchange. (microsoft#364)

Works toward microsoftGH-363

* Reduce stack space consumption of list<T>::insert (microsoft#366)

* Avoid burning unused stack space for a T in _List_node_insert_op. Resolves #973579 and microsoftGH-365.

* Change forward_list to follow a similar pattern for consistency.

* First round of code review feedback.

* yvals_core.h: Remove "toolset update" workaround. (microsoft#372)

Currently, we're building the STL in both our Microsoft-internal MSVC
repo and in GitHub, as we work on the migration. The MSVC repo uses a
checked-in compiler (the "toolset") to build the STL and the compiler
itself. Earlier, the checked-in toolset identified itself as
19.25.28318.97 but lacked support for `is_constant_evaluated`, so we
needed to detect that exact version number. Now, the toolset has been
updated, so this workaround is no longer necessary.

When VS 2019 16.5 Preview 2 is available in the future, we'll begin
requiring it to build the GitHub sources, at which point we'll be able
to unconditionally define `__cpp_lib_is_constant_evaluated`.

* Fix microsoft#347: <shared_mutex>: Do we still need the _USING_V110_SDK71_ guard? (microsoft#373)

While we must continue to support `msvcp140.dll` running on Windows XP,
we don't need to support compiling our headers with the (removed)
`v140_xp` toolset and its corresponding old Windows SDK. Accordingly,
we can unconditionally define `shared_mutex`. (This is a C++17 feature,
but it was implemented before Standard modes, so it's not guarded by
`_HAS_CXX17`.)

* Fix microsoft#192: <cmath>: Fuse <xtgmath.h> (microsoft#374)

* Fix microsoft#340: <functional>: _HAS_STATIC_RTTI=0 shouldn't say typeid(void) (microsoft#375)

This calls `abort()` as there's no need to invoke the terminate handler.

(This is a virtual function, so eliminating it entirely would risk ODR
violations leading to crashes. It's much safer to provide a definition
that can't be called.)

Additionally, fix `<xlocale>` to qualify `_CSTD abort()`.

* Update README.md. (microsoft#376)

* We're accepting pull requests.
* Mention compiler switches in code font.
* Explain the current status of CI.
* Mention that bugs and enhancement issues are being ported.
* VS 2019 16.4 has been released.
* Link to clang-format.

* Explain why invoke is implemented with a macro (microsoft#368)

* Remove weak_equality and strong_equality (microsoft#381)

Implement WG21-P1959 Removing `weak_equality` And `strong_equality`, working towards microsoft#64.

* update stl cgmanifest (microsoft#384)

* update stl cgmanifest

* <iterator>: reduced parsing time (microsoft#355)

* Replaced `<istream>` include with `<iosfwd>` because `[io]stream_iterator`
  needs only `basic_[io]stream` forward declaration.
* Moved `[io]streambuf_iterator` iterator definition to `<iterator>` because
  their definition has to come when `<iterator>` is included.
* Include `<iterator>` in `<xlocmon>`, `<xlocnum>`, and `<xloctime>` as
  the `[io]streambuf_iterator` definition are required there, and `<xutility>`
  already included via other includes.

Parsing times:

| header     |          clang          |           msvc          |
|------------|-------------------------|-------------------------|
| <iterator> | 0.371 -> 0.163 (-56.1%) | 0.216 -> 0.094 (-56.5%) |
| <istream>  | 0.366 -> 0.372 ( +1.6%) | 0.215 -> 0.216 ( +0.5%) |
| <xlocmon>  | 0.358 -> 0.364 ( +1.7%) | 0.211 -> 0.211 (    0%) |
| <xlocnum>  | 0.357 -> 0.360 ( +0.8%) | 0.207 -> 0.208 ( +0.5%) |
| <xloctime> | 0.364 -> 0.370 ( +1.6%) | 0.211 -> 0.214 ( +1.4%) |

* Define _CONSTEXPR20 (microsoft#387)

* [ranges] Implement some range concepts (microsoft#389)

P1456R1 Move-Only Views
P1870R1 safe_range

* Add libcxx (not yet running) working towards microsoft#145. (microsoft#394)

* Port Microsoft-internal MSVC-PR-218746 and MSVC-PR-219383.
* And MSVC-PR-219451:
  * Skip llvm-project in validate.cpp.
  * Change .vscode/settings.json to CRLF.

* Don't enumerate libcxx/test/std/pstl (microsoft#400)

In the test runer. `pstl` is a symlink to `../../../pstl/test/std` (when it exists - which only happens when git is honoring symlinks). The test runner is not prepared for this.

* Implement LWG-3356 (microsoft#404)

...which renames the feature-test macro `__cpp_lib_nothrow_convertible` to `__cpp_lib_is_nothrow_convertible`. We *just* added this feature-test macro which hasn't yet shipped, and therefore want to rename it quickly - ideally before customers notice it exists. LWG has tentatively approved this issue resolution.

* Fix std::filesystem::remove on ReFS targets (microsoft#407)

* Fix std::filesystem::remove on ReFS targets by falling back to standard delete on ERROR_NOT_SUPPORTED.

Resolves DevCom-857535.

* <utility> Deprecate std::rel_ops & resolve microsoft#403 (microsoft#402)

Co-authored-by: Casey Carter <cartec69@gmail.com>
Co-authored-by: Billy O'Neal <billy.oneal@gmail.com>

* <numeric> Implement P1645R1 "constexpr for <numeric> algorithms" (microsoft#399)


Co-authored-by: Billy O'Neal <billy.oneal@gmail.com>

* P1006R1 constexpr For pointer_traits<T*>::pointer_to() (microsoft#397)


Co-authored-by: Billy O'Neal <billy.oneal@gmail.com>

* system_error: Map `errc::broken_pipe` to `ERROR_BROKEN_PIPE`. (microsoft#406)

Co-authored-by: Billy O'Neal <billy.oneal@gmail.com>

* Support For Incomplete Types In reference_wrapper (microsoft#393)

* Implement P0357R3
* Update LLVM to get skip of libcxx\test\std\utilities\function.objects\refwrap\weak_result.pass.cpp, and exclude "// REQUIRES: c++98 || c++03 || c++11 || c++14 || c++17" as a 'magic comment'.

Co-authored-by: Billy O'Neal <billy.oneal@gmail.com>
Co-authored-by: Casey Carter <cartec69@gmail.com>

* Don't assume _HAS_CONDITIONAL_EXPLICIT for __INTEL_COMPILER (microsoft#424)

This change is not a statement of support for the Intel C++ compiler by the STL, so much as an attempt to not break it gratuitously.

Fixes DevCom-744112.

* P0122R7 <span> (microsoft#142)

Fixes microsoft#4.

* Optimize the is_permutation family and _Hash::operator== for multicontainers (microsoft#423)

* Optimize the is_permutation family and _Hash::operator== for multicontaniers slightly.

<xutility>
4660: _Find_pr is a helper for is_permutation, so move it down to that area.
4684: The SHOUTY banners were attached to functions which were implmentation details of is_permutation, so I fixed them up to say is_permutation and removed the banners for helper functions.
4711: Use if constexpr to avoid a tag dispatch call for _Trim_matching_suffixes. Optimizers will like this because they generally hate reference-to-pointer, and it also serves to workaround DevCom-883631 when this algorithm is constexprized.
4766: Indicate that we are trimming matching prefixes in this loop body, and break apart comment block that was incorrectly merged by clang-format.
4817: In the dual range forward version of the algorithm, calculate the distances concurrently to avoid wasting lots of time when the distances vary by a lot. For example, is_permutation( a forward range of length 1, a forward range of length 1'000'000 ) used to do the million increments, now it stops at 1 increment.
4862: In the dual range random-access version, avoid recalculating _Last2 when it has already been supplied to us.

<xhash>
1404: Move down construction of _Bucket_hi in _Equal_range to before the first loop body using it.
1918: Added a new function to calculate equality for unordered multicontainers. We loop over the elements in the left container, find corresponding ranges in the right container, trim prefixes, then dispatch to is_permutation's helper _Check_match_counts.
Improvements over the old implementation:
* For standard containers, we no longer need to hash any elements from the left container; we know that we've found the "run" of equivalent elements because we *started* with an element in that container. We also never go "backwards" or multiply enumerate _Left (even for !_Standard), which improves cache use when the container becomes large.
* Just like the dual range is_permutation improvement above, when the equal_ranges of the containers are of wildly varying lengths, this will stop on the shorter of the lengths.
* We avoid the 3-arg is_permutation doing a linear time operation to discover _Last2 that we already had calculated in determining _Right's equal_range.
The function _Multi_equal_check_equal_range tests one equal_range from the left container against the corresponding equal_range from the right container, while _Multi_equal invokes _Multi_equal_check_equal_range for each equal_range.

Performance results:

```
Benchmark	Before (ns)	After (ns)	Percent Better
HashRandomUnequal<unordered_multimap>/1	18.7	11.7	59.83%
HashRandomUnequal<unordered_multimap>/10	137	97	41.24%
HashRandomUnequal<unordered_multimap>/100	1677	1141	46.98%
HashRandomUnequal<unordered_multimap>/512	10386	7036	47.61%
HashRandomUnequal<unordered_multimap>/4096	173807	119391	45.58%
HashRandomUnequal<unordered_multimap>/32768	2898405	1529710	89.47%
HashRandomUnequal<unordered_multimap>/100000	27441112	18602792	47.51%
HashRandomUnequal<hash_multimap>/1	18.9	11.8	60.17%
HashRandomUnequal<hash_multimap>/10	138	101	36.63%
HashRandomUnequal<hash_multimap>/100	1613	1154	39.77%
HashRandomUnequal<hash_multimap>/512	10385	7178	44.68%
HashRandomUnequal<hash_multimap>/4096	171718	120115	42.96%
HashRandomUnequal<hash_multimap>/32768	3352231	1510245	121.97%
HashRandomUnequal<hash_multimap>/100000	26532471	19209741	38.12%
HashRandomEqual<unordered_multimap>/1	16	9.4	70.21%
HashRandomEqual<unordered_multimap>/10	126	89.2	41.26%
HashRandomEqual<unordered_multimap>/100	1644	1133	45.10%
HashRandomEqual<unordered_multimap>/512	10532	7183	46.62%
HashRandomEqual<unordered_multimap>/4096	174580	120029	45.45%
HashRandomEqual<unordered_multimap>/32768	3031653	1455416	108.30%
HashRandomEqual<unordered_multimap>/100000	26100504	19240571	35.65%
HashRandomEqual<hash_multimap>/1	15.9	9.38	69.51%
HashRandomEqual<hash_multimap>/10	123	94.1	30.71%
HashRandomEqual<hash_multimap>/100	1645	1151	42.92%
HashRandomEqual<hash_multimap>/512	10177	7144	42.46%
HashRandomEqual<hash_multimap>/4096	172994	121381	42.52%
HashRandomEqual<hash_multimap>/32768	3045242	1966513	54.85%
HashRandomEqual<hash_multimap>/100000	26013781	22025482	18.11%
HashUnequalDifferingBuckets<unordered_multimap>/2	5.87	3.41	72.14%
HashUnequalDifferingBuckets<unordered_multimap>/10	12	3.39	253.98%
HashUnequalDifferingBuckets<unordered_multimap>/100	106	3.41	3008.50%
HashUnequalDifferingBuckets<unordered_multimap>/512	691	3.46	19871.10%
HashUnequalDifferingBuckets<unordered_multimap>/4096	6965	3.47	200620.46%
HashUnequalDifferingBuckets<unordered_multimap>/32768	91451	3.46	2642992.49%
HashUnequalDifferingBuckets<unordered_multimap>/100000	290430	3.52	8250752.27%
HashUnequalDifferingBuckets<hash_multimap>/2	5.97	3.4	75.59%
HashUnequalDifferingBuckets<hash_multimap>/10	11.8	3.54	233.33%
HashUnequalDifferingBuckets<hash_multimap>/100	105	3.54	2866.10%
HashUnequalDifferingBuckets<hash_multimap>/512	763	3.46	21952.02%
HashUnequalDifferingBuckets<hash_multimap>/4096	6862	3.4	201723.53%
HashUnequalDifferingBuckets<hash_multimap>/32768	94583	3.4	2781752.94%
HashUnequalDifferingBuckets<hash_multimap>/100000	287996	3.43	8396284.84%
```

Benchmark code:
```
#undef NDEBUG
#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
#include <assert.h>
#include <benchmark/benchmark.h>
#include <hash_map>
#include <random>
#include <stddef.h>
#include <unordered_map>
#include <utility>
#include <vector>

using namespace std;

template <template <class...> class MapType> void HashRandomUnequal(benchmark::State &state) {
    std::minstd_rand rng(std::random_device{}());
    const auto range0 = static_cast<ptrdiff_t>(state.range(0));
    vector<pair<unsigned, unsigned>> testData;
    testData.resize(range0 * 5);
    const auto dataEnd = testData.begin() + range0;
    std::generate(testData.begin(), dataEnd, [&]() { return pair<unsigned, unsigned>{rng(), 0u}; });
    std::copy(testData.begin(), dataEnd,
              std::copy(testData.begin(), dataEnd,
                        std::copy(testData.begin(), dataEnd, std::copy(testData.begin(), dataEnd, dataEnd))));
    std::unordered_multimap<unsigned, unsigned> a(testData.begin(), testData.end());
    testData.clear();
    std::unordered_multimap<unsigned, unsigned> b = a;
    next(b.begin(), b.size() - 1)->second = 1u;
    for (auto &&_ : state) {
        (void)_;
        assert(a != b);
    }
}

BENCHMARK_TEMPLATE1(HashRandomUnequal, unordered_multimap)->Arg(1)->Arg(10)->Range(100, 100'000);
BENCHMARK_TEMPLATE1(HashRandomUnequal, hash_multimap)->Arg(1)->Arg(10)->Range(100, 100'000);

template <template <class...> class MapType> void HashRandomEqual(benchmark::State &state) {
    std::minstd_rand rng(std::random_device{}());
    const auto range0 = static_cast<ptrdiff_t>(state.range(0));
    vector<pair<unsigned, unsigned>> testData;
    testData.resize(range0 * 5);
    const auto dataEnd = testData.begin() + range0;
    std::generate(testData.begin(), dataEnd, [&]() { return pair<unsigned, unsigned>{rng(), 0}; });
    std::copy(testData.begin(), dataEnd,
              std::copy(testData.begin(), dataEnd,
                        std::copy(testData.begin(), dataEnd, std::copy(testData.begin(), dataEnd, dataEnd))));
    std::unordered_multimap<unsigned, unsigned> a(testData.begin(), testData.end());
    testData.clear();
    std::unordered_multimap<unsigned, unsigned> b = a;
    for (auto &&_ : state) {
        (void)_;
        assert(a == b);
    }
}

BENCHMARK_TEMPLATE1(HashRandomEqual, unordered_multimap)->Arg(1)->Arg(10)->Range(100, 100'000);
BENCHMARK_TEMPLATE1(HashRandomEqual, hash_multimap)->Arg(1)->Arg(10)->Range(100, 100'000);

template <template <class...> class MapType> void HashUnequalDifferingBuckets(benchmark::State &state) {
    std::unordered_multimap<unsigned, unsigned> a;
    std::unordered_multimap<unsigned, unsigned> b;
    const auto range0 = static_cast<ptrdiff_t>(state.range(0));
    for (ptrdiff_t idx = 0; idx < range0; ++idx) {
        a.emplace(0, 1);
        b.emplace(1, 0);
    }

    a.emplace(1, 0);
    b.emplace(0, 1);
    for (auto &&_ : state) {
        (void)_;
        assert(a != b);
    }
}

BENCHMARK_TEMPLATE1(HashUnequalDifferingBuckets, unordered_multimap)->Arg(2)->Arg(10)->Range(100, 100'000);
BENCHMARK_TEMPLATE1(HashUnequalDifferingBuckets, hash_multimap)->Arg(2)->Arg(10)->Range(100, 100'000);

BENCHMARK_MAIN();

* Apply a bunch of code review comments from Casey.

* clang-format

* Apply @miscco's code deduplication idea for <xhash>.

* Fix code review comments from Stephan: comments and add DMIs.

* Optimize the is_permutation family and _Hash::operator== for multicontainers (microsoft#423)

* Optimize the is_permutation family and _Hash::operator== for multicontaniers slightly.

<xutility>
4660: _Find_pr is a helper for is_permutation, so move it down to that area.
4684: The SHOUTY banners were attached to functions which were implmentation details of is_permutation, so I fixed them up to say is_permutation and removed the banners for helper functions.
4711: Use if constexpr to avoid a tag dispatch call for _Trim_matching_suffixes. Optimizers will like this because they generally hate reference-to-pointer, and it also serves to workaround DevCom-883631 when this algorithm is constexprized.
4766: Indicate that we are trimming matching prefixes in this loop body, and break apart comment block that was incorrectly merged by clang-format.
4817: In the dual range forward version of the algorithm, calculate the distances concurrently to avoid wasting lots of time when the distances vary by a lot. For example, is_permutation( a forward range of length 1, a forward range of length 1'000'000 ) used to do the million increments, now it stops at 1 increment.
4862: In the dual range random-access version, avoid recalculating _Last2 when it has already been supplied to us.

<xhash>
1404: Move down construction of _Bucket_hi in _Equal_range to before the first loop body using it.
1918: Added a new function to calculate equality for unordered multicontainers. We loop over the elements in the left container, find corresponding ranges in the right container, trim prefixes, then dispatch to is_permutation's helper _Check_match_counts.
Improvements over the old implementation:
* For standard containers, we no longer need to hash any elements from the left container; we know that we've found the "run" of equivalent elements because we *started* with an element in that container. We also never go "backwards" or multiply enumerate _Left (even for !_Standard), which improves cache use when the container becomes large.
* Just like the dual range is_permutation improvement above, when the equal_ranges of the containers are of wildly varying lengths, this will stop on the shorter of the lengths.
* We avoid the 3-arg is_permutation doing a linear time operation to discover _Last2 that we already had calculated in determining _Right's equal_range.
The function _Multi_equal_check_equal_range tests one equal_range from the left container against the corresponding equal_range from the right container, while _Multi_equal invokes _Multi_equal_check_equal_range for each equal_range.

Performance results:

```
Benchmark	Before (ns)	After (ns)	Percent Better
HashRandomUnequal<unordered_multimap>/1	18.7	11.7	59.83%
HashRandomUnequal<unordered_multimap>/10	137	97	41.24%
HashRandomUnequal<unordered_multimap>/100	1677	1141	46.98%
HashRandomUnequal<unordered_multimap>/512	10386	7036	47.61%
HashRandomUnequal<unordered_multimap>/4096	173807	119391	45.58%
HashRandomUnequal<unordered_multimap>/32768	2898405	1529710	89.47%
HashRandomUnequal<unordered_multimap>/100000	27441112	18602792	47.51%
HashRandomUnequal<hash_multimap>/1	18.9	11.8	60.17%
HashRandomUnequal<hash_multimap>/10	138	101	36.63%
HashRandomUnequal<hash_multimap>/100	1613	1154	39.77%
HashRandomUnequal<hash_multimap>/512	10385	7178	44.68%
HashRandomUnequal<hash_multimap>/4096	171718	120115	42.96%
HashRandomUnequal<hash_multimap>/32768	3352231	1510245	121.97%
HashRandomUnequal<hash_multimap>/100000	26532471	19209741	38.12%
HashRandomEqual<unordered_multimap>/1	16	9.4	70.21%
HashRandomEqual<unordered_multimap>/10	126	89.2	41.26%
HashRandomEqual<unordered_multimap>/100	1644	1133	45.10%
HashRandomEqual<unordered_multimap>/512	10532	7183	46.62%
HashRandomEqual<unordered_multimap>/4096	174580	120029	45.45%
HashRandomEqual<unordered_multimap>/32768	3031653	1455416	108.30%
HashRandomEqual<unordered_multimap>/100000	26100504	19240571	35.65%
HashRandomEqual<hash_multimap>/1	15.9	9.38	69.51%
HashRandomEqual<hash_multimap>/10	123	94.1	30.71%
HashRandomEqual<hash_multimap>/100	1645	1151	42.92%
HashRandomEqual<hash_multimap>/512	10177	7144	42.46%
HashRandomEqual<hash_multimap>/4096	172994	121381	42.52%
HashRandomEqual<hash_multimap>/32768	3045242	1966513	54.85%
HashRandomEqual<hash_multimap>/100000	26013781	22025482	18.11%
HashUnequalDifferingBuckets<unordered_multimap>/2	5.87	3.41	72.14%
HashUnequalDifferingBuckets<unordered_multimap>/10	12	3.39	253.98%
HashUnequalDifferingBuckets<unordered_multimap>/100	106	3.41	3008.50%
HashUnequalDifferingBuckets<unordered_multimap>/512	691	3.46	19871.10%
HashUnequalDifferingBuckets<unordered_multimap>/4096	6965	3.47	200620.46%
HashUnequalDifferingBuckets<unordered_multimap>/32768	91451	3.46	2642992.49%
HashUnequalDifferingBuckets<unordered_multimap>/100000	290430	3.52	8250752.27%
HashUnequalDifferingBuckets<hash_multimap>/2	5.97	3.4	75.59%
HashUnequalDifferingBuckets<hash_multimap>/10	11.8	3.54	233.33%
HashUnequalDifferingBuckets<hash_multimap>/100	105	3.54	2866.10%
HashUnequalDifferingBuckets<hash_multimap>/512	763	3.46	21952.02%
HashUnequalDifferingBuckets<hash_multimap>/4096	6862	3.4	201723.53%
HashUnequalDifferingBuckets<hash_multimap>/32768	94583	3.4	2781752.94%
HashUnequalDifferingBuckets<hash_multimap>/100000	287996	3.43	8396284.84%
```

Benchmark code:
```
#undef NDEBUG
#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
#include <assert.h>
#include <benchmark/benchmark.h>
#include <hash_map>
#include <random>
#include <stddef.h>
#include <unordered_map>
#include <utility>
#include <vector>

using namespace std;

template <template <class...> class MapType> void HashRandomUnequal(benchmark::State &state) {
    std::minstd_rand rng(std::random_device{}());
    const auto range0 = static_cast<ptrdiff_t>(state.range(0));
    vector<pair<unsigned, unsigned>> testData;
    testData.resize(range0 * 5);
    const auto dataEnd = testData.begin() + range0;
    std::generate(testData.begin(), dataEnd, [&]() { return pair<unsigned, unsigned>{rng(), 0u}; });
    std::copy(testData.begin(), dataEnd,
              std::copy(testData.begin(), dataEnd,
                        std::copy(testData.begin(), dataEnd, std::copy(testData.begin(), dataEnd, dataEnd))));
    std::unordered_multimap<unsigned, unsigned> a(testData.begin(), testData.end());
    testData.clear();
    std::unordered_multimap<unsigned, unsigned> b = a;
    next(b.begin(), b.size() - 1)->second = 1u;
    for (auto &&_ : state) {
        (void)_;
        assert(a != b);
    }
}

BENCHMARK_TEMPLATE1(HashRandomUnequal, unordered_multimap)->Arg(1)->Arg(10)->Range(100, 100'000);
BENCHMARK_TEMPLATE1(HashRandomUnequal, hash_multimap)->Arg(1)->Arg(10)->Range(100, 100'000);

template <template <class...> class MapType> void HashRandomEqual(benchmark::State &state) {
    std::minstd_rand rng(std::random_device{}());
    const auto range0 = static_cast<ptrdiff_t>(state.range(0));
    vector<pair<unsigned, unsigned>> testData;
    testData.resize(range0 * 5);
    const auto dataEnd = testData.begin() + range0;
    std::generate(testData.begin(), dataEnd, [&]() { return pair<unsigned, unsigned>{rng(), 0}; });
    std::copy(testData.begin(), dataEnd,
              std::copy(testData.begin(), dataEnd,
                        std::copy(testData.begin(), dataEnd, std::copy(testData.begin(), dataEnd, dataEnd))));
    std::unordered_multimap<unsigned, unsigned> a(testData.begin(), testData.end());
    testData.clear();
    std::unordered_multimap<unsigned, unsigned> b = a;
    for (auto &&_ : state) {
        (void)_;
        assert(a == b);
    }
}

BENCHMARK_TEMPLATE1(HashRandomEqual, unordered_multimap)->Arg(1)->Arg(10)->Range(100, 100'000);
BENCHMARK_TEMPLATE1(HashRandomEqual, hash_multimap)->Arg(1)->Arg(10)->Range(100, 100'000);

template <template <class...> class MapType> void HashUnequalDifferingBuckets(benchmark::State &state) {
    std::unordered_multimap<unsigned, unsigned> a;
    std::unordered_multimap<unsigned, unsigned> b;
    const auto range0 = static_cast<ptrdiff_t>(state.range(0));
    for (ptrdiff_t idx = 0; idx < range0; ++idx) {
        a.emplace(0, 1);
        b.emplace(1, 0);
    }

    a.emplace(1, 0);
    b.emplace(0, 1);
    for (auto &&_ : state) {
        (void)_;
        assert(a != b);
    }
}

BENCHMARK_TEMPLATE1(HashUnequalDifferingBuckets, unordered_multimap)->Arg(2)->Arg(10)->Range(100, 100'000);
BENCHMARK_TEMPLATE1(HashUnequalDifferingBuckets, hash_multimap)->Arg(2)->Arg(10)->Range(100, 100'000);

BENCHMARK_MAIN();

* Apply a bunch of code review comments from Casey.

* clang-format

* Apply @miscco's code deduplication idea for <xhash>.

* Fix code review comments from Stephan: comments and add DMIs.

* Optimize the is_permutation family and _Hash::operator== for multicontainers (microsoft#423)

* Optimize the is_permutation family and _Hash::operator== for multicontaniers slightly.

<xutility>
4660: _Find_pr is a helper for is_permutation, so move it down to that area.
4684: The SHOUTY banners were attached to functions which were implmentation details of is_permutation, so I fixed them up to say is_permutation and removed the banners for helper functions.
4711: Use if constexpr to avoid a tag dispatch call for _Trim_matching_suffixes. Optimizers will like this because they generally hate reference-to-pointer, and it also serves to workaround DevCom-883631 when this algorithm is constexprized.
4766: Indicate that we are trimming matching prefixes in this loop body, and break apart comment block that was incorrectly merged by clang-format.
4817: In the dual range forward version of the algorithm, calculate the distances concurrently to avoid wasting lots of time when the distances vary by a lot. For example, is_permutation( a forward range of length 1, a forward range of length 1'000'000 ) used to do the million increments, now it stops at 1 increment.
4862: In the dual range random-access version, avoid recalculating _Last2 when it has already been supplied to us.

<xhash>
1404: Move down construction of _Bucket_hi in _Equal_range to before the first loop body using it.
1918: Added a new function to calculate equality for unordered multicontainers. We loop over the elements in the left container, find corresponding ranges in the right container, trim prefixes, then dispatch to is_permutation's helper _Check_match_counts.
Improvements over the old implementation:
* For standard containers, we no longer need to hash any elements from the left container; we know that we've found the "run" of equivalent elements because we *started* with an element in that container. We also never go "backwards" or multiply enumerate _Left (even for !_Standard), which improves cache use when the container becomes large.
* Just like the dual range is_permutation improvement above, when the equal_ranges of the containers are of wildly varying lengths, this will stop on the shorter of the lengths.
* We avoid the 3-arg is_permutation doing a linear time operation to discover _Last2 that we already had calculated in determining _Right's equal_range.
The function _Multi_equal_check_equal_range tests one equal_range from the left container against the corresponding equal_range from the right container, while _Multi_equal invokes _Multi_equal_check_equal_range for each equal_range.

Performance results:

```
Benchmark	Before (ns)	After (ns)	Percent Better
HashRandomUnequal<unordered_multimap>/1	18.7	11.7	59.83%
HashRandomUnequal<unordered_multimap>/10	137	97	41.24%
HashRandomUnequal<unordered_multimap>/100	1677	1141	46.98%
HashRandomUnequal<unordered_multimap>/512	10386	7036	47.61%
HashRandomUnequal<unordered_multimap>/4096	173807	119391	45.58%
HashRandomUnequal<unordered_multimap>/32768	2898405	1529710	89.47%
HashRandomUnequal<unordered_multimap>/100000	27441112	18602792	47.51%
HashRandomUnequal<hash_multimap>/1	18.9	11.8	60.17%
HashRandomUnequal<hash_multimap>/10	138	101	36.63%
HashRandomUnequal<hash_multimap>/100	1613	1154	39.77%
HashRandomUnequal<hash_multimap>/512	10385	7178	44.68%
HashRandomUnequal<hash_multimap>/4096	171718	120115	42.96%
HashRandomUnequal<hash_multimap>/32768	3352231	1510245	121.97%
HashRandomUnequal<hash_multimap>/100000	26532471	19209741	38.12%
HashRandomEqual<unordered_multimap>/1	16	9.4	70.21%
HashRandomEqual<unordered_multimap>/10	126	89.2	41.26%
HashRandomEqual<unordered_multimap>/100	1644	1133	45.10%
HashRandomEqual<unordered_multimap>/512	10532	7183	46.62%
HashRandomEqual<unordered_multimap>/4096	174580	120029	45.45%
HashRandomEqual<unordered_multimap>/32768	3031653	1455416	108.30%
HashRandomEqual<unordered_multimap>/100000	26100504	19240571	35.65%
HashRandomEqual<hash_multimap>/1	15.9	9.38	69.51%
HashRandomEqual<hash_multimap>/10	123	94.1	30.71%
HashRandomEqual<hash_multimap>/100	1645	1151	42.92%
HashRandomEqual<hash_multimap>/512	10177	7144	42.46%
HashRandomEqual<hash_multimap>/4096	172994	121381	42.52%
HashRandomEqual<hash_multimap>/32768	3045242	1966513	54.85%
HashRandomEqual<hash_multimap>/100000	26013781	22025482	18.11%
HashUnequalDifferingBuckets<unordered_multimap>/2	5.87	3.41	72.14%
HashUnequalDifferingBuckets<unordered_multimap>/10	12	3.39	253.98%
HashUnequalDifferingBuckets<unordered_multimap>/100	106	3.41	3008.50%
HashUnequalDifferingBuckets<unordered_multimap>/512	691	3.46	19871.10%
HashUnequalDifferingBuckets<unordered_multimap>/4096	6965	3.47	200620.46%
HashUnequalDifferingBuckets<unordered_multimap>/32768	91451	3.46	2642992.49%
HashUnequalDifferingBuckets<unordered_multimap>/100000	290430	3.52	8250752.27%
HashUnequalDifferingBuckets<hash_multimap>/2	5.97	3.4	75.59%
HashUnequalDifferingBuckets<hash_multimap>/10	11.8	3.54	233.33%
HashUnequalDifferingBuckets<hash_multimap>/100	105	3.54	2866.10%
HashUnequalDifferingBuckets<hash_multimap>/512	763	3.46	21952.02%
HashUnequalDifferingBuckets<hash_multimap>/4096	6862	3.4	201723.53%
HashUnequalDifferingBuckets<hash_multimap>/32768	94583	3.4	2781752.94%
HashUnequalDifferingBuckets<hash_multimap>/100000	287996	3.43	8396284.84%
```

Benchmark code:
```
#undef NDEBUG
#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
#include <assert.h>
#include <benchmark/benchmark.h>
#include <hash_map>
#include <random>
#include <stddef.h>
#include <unordered_map>
#include <utility>
#include <vector>

using namespace std;

template <template <class...> class MapType> void HashRandomUnequal(benchmark::State &state) {
    std::minstd_rand rng(std::random_device{}());
    const auto range0 = static_cast<ptrdiff_t>(state.range(0));
    vector<pair<unsigned, unsigned>> testData;
    testData.resize(range0 * 5);
    const auto dataEnd = testData.begin() + range0;
    std::generate(testData.begin(), dataEnd, [&]() { return pair<unsigned, unsigned>{rng(), 0u}; });
    std::copy(testData.begin(), dataEnd,
              std::copy(testData.begin(), dataEnd,
                        std::copy(testData.begin(), dataEnd, std::copy(testData.begin(), dataEnd, dataEnd))));
    std::unordered_multimap<unsigned, unsigned> a(testData.begin(), testData.end());
    testData.clear();
    std::unordered_multimap<unsigned, unsigned> b = a;
    next(b.begin(), b.size() - 1)->second = 1u;
    for (auto &&_ : state) {
        (void)_;
        assert(a != b);
    }
}

BENCHMARK_TEMPLATE1(HashRandomUnequal, unordered_multimap)->Arg(1)->Arg(10)->Range(100, 100'000);
BENCHMARK_TEMPLATE1(HashRandomUnequal, hash_multimap)->Arg(1)->Arg(10)->Range(100, 100'000);

template <template <class...> class MapType> void HashRandomEqual(benchmark::State &state) {
    std::minstd_rand rng(std::random_device{}());
    const auto range0 = static_cast<ptrdiff_t>(state.range(0));
    vector<pair<unsigned, unsigned>> testData;
    testData.resize(range0 * 5);
    const auto dataEnd = testData.begin() + range0;
    std::generate(testData.begin(), dataEnd, [&]() { return pair<unsigned, unsigned>{rng(), 0}; });
    std::copy(testData.begin(), dataEnd,
              std::copy(testData.begin(), dataEnd,
                        std::copy(testData.begin(), dataEnd, std::copy(testData.begin(), dataEnd, dataEnd))));
    std::unordered_multimap<unsigned, unsigned> a(testData.begin(), testData.end());
    testData.clear();
    std::unordered_multimap<unsigned, unsigned> b = a;
    for (auto &&_ : state) {
        (void)_;
        assert(a == b);
    }
}

BENCHMARK_TEMPLATE1(HashRandomEqual, unordered_multimap)->Arg(1)->Arg(10)->Range(100, 100'000);
BENCHMARK_TEMPLATE1(HashRandomEqual, hash_multimap)->Arg(1)->Arg(10)->Range(100, 100'000);

template <template <class...> class MapType> void HashUnequalDifferingBuckets(benchmark::State &state) {
    std::unordered_multimap<unsigned, unsigned> a;
    std::unordered_multimap<unsigned, unsigned> b;
    const auto range0 = static_cast<ptrdiff_t>(state.range(0));
    for (ptrdiff_t idx = 0; idx < range0; ++idx) {
        a.emplace(0, 1);
        b.emplace(1, 0);
    }

    a.emplace(1, 0);
    b.emplace(0, 1);
    for (auto &&_ : state) {
        (void)_;
        assert(a != b);
    }
}

BENCHMARK_TEMPLATE1(HashUnequalDifferingBuckets, unordered_multimap)->Arg(2)->Arg(10)->Range(100, 100'000);
BENCHMARK_TEMPLATE1(HashUnequalDifferingBuckets, hash_multimap)->Arg(2)->Arg(10)->Range(100, 100'000);

BENCHMARK_MAIN();

* Apply a bunch of code review comments from Casey.

* clang-format

* Apply @miscco's code deduplication idea for <xhash>.

* Fix code review comments from Stephan: comments and add DMIs.

Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
Co-authored-by: rithikmali <51767737+rithikmali@users.noreply.github.com>
Co-authored-by: Bhumij Gupta <bhumijgupta@gmail.com>
Co-authored-by: Billy O'Neal <billy.oneal@gmail.com>
Co-authored-by: Casey Carter <cartec69@gmail.com>
Co-authored-by: Nathan Ward <43621845+NathanSWard@users.noreply.github.com>
Co-authored-by: Stanislav Ershov <digital.stream.of.mind@gmail.com>
Co-authored-by: Krystyna Lopez <49209351+lozinska@users.noreply.github.com>
Co-authored-by: Christian Deneke <43907599+chris0x44@users.noreply.github.com>
Co-authored-by: Julie Philip James <41449664+jpjjulie@users.noreply.github.com>
Co-authored-by: Daniel Marshall <xandan@gmail.com>
Co-authored-by: Michael Schellenberger Costa <mschellenbergercosta@gmail.com>
Co-authored-by: SumanjaliDamarla <48714608+SumanjaliDamarla@users.noreply.github.com>
Co-authored-by: S. B. Tam <cpplearner@outlook.com>
Co-authored-by: Adam Bucior <35536269+AdamBucior@users.noreply.github.com>
Co-authored-by: Charlie Barto <chbarto@microsoft.com>
Co-authored-by: SasLuca <sas.luca.alex@gmail.com>
Co-authored-by: Nikita Kniazev <nok.raven@gmail.com>
Co-authored-by: Daniil Goncharov <neargye@gmail.com>
Co-authored-by: Daan De Meyer <daan.j.demeyer@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.