diff --git a/chromium-86-use-range-based-algorithms.patch b/chromium-86-use-range-based-algorithms.patch index afbcb6ef..e9ea3f30 100644 --- a/chromium-86-use-range-based-algorithms.patch +++ b/chromium-86-use-range-based-algorithms.patch @@ -1,6 +1,6 @@ -diff -up chromium-86.0.4240.75/base/callback_list.h.a61fb57e chromium-86.0.4240.75/base/callback_list.h ---- chromium-86.0.4240.75/base/callback_list.h.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/callback_list.h 2020-10-21 16:38:29.003091331 -0400 +diff -up chromium-86.0.4240.111/base/callback_list.h.a61fb57e chromium-86.0.4240.111/base/callback_list.h +--- chromium-86.0.4240.111/base/callback_list.h.a61fb57e 2020-10-20 20:14:17.000000000 -0400 ++++ chromium-86.0.4240.111/base/callback_list.h 2020-10-21 17:11:20.000228716 -0400 @@ -5,7 +5,6 @@ #ifndef BASE_CALLBACK_LIST_H_ #define BASE_CALLBACK_LIST_H_ @@ -28,9 +28,9 @@ diff -up chromium-86.0.4240.75/base/callback_list.h.a61fb57e chromium-86.0.4240. } // Calls all registered callbacks that are not canceled beforehand. If any -diff -up chromium-86.0.4240.75/base/command_line.cc.a61fb57e chromium-86.0.4240.75/base/command_line.cc ---- chromium-86.0.4240.75/base/command_line.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/command_line.cc 2020-10-21 16:38:29.003091331 -0400 +diff -up chromium-86.0.4240.111/base/command_line.cc.a61fb57e chromium-86.0.4240.111/base/command_line.cc +--- chromium-86.0.4240.111/base/command_line.cc.a61fb57e 2020-10-20 20:14:17.000000000 -0400 ++++ chromium-86.0.4240.111/base/command_line.cc 2020-10-21 17:11:20.000228716 -0400 @@ -4,13 +4,13 @@ #include "base/command_line.h" @@ -56,9 +56,9 @@ diff -up chromium-86.0.4240.75/base/command_line.cc.a61fb57e chromium-86.0.4240. if (switch_terminator != args.end()) args.erase(switch_terminator); return args; -diff -up chromium-86.0.4240.75/base/containers/checked_range_unittest.cc.a61fb57e chromium-86.0.4240.75/base/containers/checked_range_unittest.cc ---- chromium-86.0.4240.75/base/containers/checked_range_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/containers/checked_range_unittest.cc 2020-10-21 16:38:29.003091331 -0400 +diff -up chromium-86.0.4240.111/base/containers/checked_range_unittest.cc.a61fb57e chromium-86.0.4240.111/base/containers/checked_range_unittest.cc +--- chromium-86.0.4240.111/base/containers/checked_range_unittest.cc.a61fb57e 2020-10-20 20:14:17.000000000 -0400 ++++ chromium-86.0.4240.111/base/containers/checked_range_unittest.cc 2020-10-21 17:11:20.001228724 -0400 @@ -8,6 +8,7 @@ #include #include @@ -79,9 +79,9 @@ diff -up chromium-86.0.4240.75/base/containers/checked_range_unittest.cc.a61fb57 } TEST(CheckedContiguousRange, DataSizeEmpty_Constexpr) { -diff -up chromium-86.0.4240.75/base/containers/circular_deque.h.a61fb57e chromium-86.0.4240.75/base/containers/circular_deque.h ---- chromium-86.0.4240.75/base/containers/circular_deque.h.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/containers/circular_deque.h 2020-10-21 16:38:29.003091331 -0400 +diff -up chromium-86.0.4240.111/base/containers/circular_deque.h.a61fb57e chromium-86.0.4240.111/base/containers/circular_deque.h +--- chromium-86.0.4240.111/base/containers/circular_deque.h.a61fb57e 2020-10-20 20:14:17.000000000 -0400 ++++ chromium-86.0.4240.111/base/containers/circular_deque.h 2020-10-21 17:11:20.001228724 -0400 @@ -14,6 +14,7 @@ #include "base/check_op.h" #include "base/containers/vector_buffer.h" @@ -108,9 +108,9 @@ diff -up chromium-86.0.4240.75/base/containers/circular_deque.h.a61fb57e chromiu size_t removed = std::distance(it, container.end()); container.erase(it, container.end()); return removed; -diff -up chromium-86.0.4240.75/base/containers/flat_map_unittest.cc.a61fb57e chromium-86.0.4240.75/base/containers/flat_map_unittest.cc ---- chromium-86.0.4240.75/base/containers/flat_map_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/containers/flat_map_unittest.cc 2020-10-21 16:38:29.003091331 -0400 +diff -up chromium-86.0.4240.111/base/containers/flat_map_unittest.cc.a61fb57e chromium-86.0.4240.111/base/containers/flat_map_unittest.cc +--- chromium-86.0.4240.111/base/containers/flat_map_unittest.cc.a61fb57e 2020-10-20 20:14:17.000000000 -0400 ++++ chromium-86.0.4240.111/base/containers/flat_map_unittest.cc 2020-10-21 17:11:20.001228724 -0400 @@ -8,6 +8,7 @@ #include @@ -155,9 +155,9 @@ diff -up chromium-86.0.4240.75/base/containers/flat_map_unittest.cc.a61fb57e chr } } -diff -up chromium-86.0.4240.75/base/containers/flat_tree.h.a61fb57e chromium-86.0.4240.75/base/containers/flat_tree.h ---- chromium-86.0.4240.75/base/containers/flat_tree.h.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/containers/flat_tree.h 2020-10-21 16:38:29.004091339 -0400 +diff -up chromium-86.0.4240.111/base/containers/flat_tree.h.a61fb57e chromium-86.0.4240.111/base/containers/flat_tree.h +--- chromium-86.0.4240.111/base/containers/flat_tree.h.a61fb57e 2020-10-20 20:14:17.000000000 -0400 ++++ chromium-86.0.4240.111/base/containers/flat_tree.h 2020-10-21 17:11:20.002228733 -0400 @@ -11,6 +11,7 @@ #include #include @@ -209,9 +209,9 @@ diff -up chromium-86.0.4240.75/base/containers/flat_tree.h.a61fb57e chromium-86. size_t removed = std::distance(it, container.end()); container.erase(it, container.end()); return removed; -diff -up chromium-86.0.4240.75/base/containers/flat_tree_unittest.cc.a61fb57e chromium-86.0.4240.75/base/containers/flat_tree_unittest.cc ---- chromium-86.0.4240.75/base/containers/flat_tree_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/containers/flat_tree_unittest.cc 2020-10-21 16:38:29.004091339 -0400 +diff -up chromium-86.0.4240.111/base/containers/flat_tree_unittest.cc.a61fb57e chromium-86.0.4240.111/base/containers/flat_tree_unittest.cc +--- chromium-86.0.4240.111/base/containers/flat_tree_unittest.cc.a61fb57e 2020-10-20 20:14:17.000000000 -0400 ++++ chromium-86.0.4240.111/base/containers/flat_tree_unittest.cc 2020-10-21 17:11:20.003228742 -0400 @@ -35,6 +35,7 @@ #include #include @@ -259,9 +259,9 @@ diff -up chromium-86.0.4240.75/base/containers/flat_tree_unittest.cc.a61fb57e ch } // ---------------------------------------------------------------------------- -diff -up chromium-86.0.4240.75/base/containers/span_unittest.cc.a61fb57e chromium-86.0.4240.75/base/containers/span_unittest.cc ---- chromium-86.0.4240.75/base/containers/span_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/containers/span_unittest.cc 2020-10-21 16:38:29.004091339 -0400 +diff -up chromium-86.0.4240.111/base/containers/span_unittest.cc.a61fb57e chromium-86.0.4240.111/base/containers/span_unittest.cc +--- chromium-86.0.4240.111/base/containers/span_unittest.cc.a61fb57e 2020-10-20 20:14:17.000000000 -0400 ++++ chromium-86.0.4240.111/base/containers/span_unittest.cc 2020-10-21 17:11:20.003228742 -0400 @@ -6,7 +6,6 @@ #include @@ -296,9 +296,9 @@ diff -up chromium-86.0.4240.75/base/containers/span_unittest.cc.a61fb57e chromiu EXPECT_THAT(array, ElementsAre(5, 4, 3, 2, 1)); } -diff -up chromium-86.0.4240.75/base/containers/unique_ptr_adapters_unittest.cc.a61fb57e chromium-86.0.4240.75/base/containers/unique_ptr_adapters_unittest.cc ---- chromium-86.0.4240.75/base/containers/unique_ptr_adapters_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/containers/unique_ptr_adapters_unittest.cc 2020-10-21 16:38:29.004091339 -0400 +diff -up chromium-86.0.4240.111/base/containers/unique_ptr_adapters_unittest.cc.a61fb57e chromium-86.0.4240.111/base/containers/unique_ptr_adapters_unittest.cc +--- chromium-86.0.4240.111/base/containers/unique_ptr_adapters_unittest.cc.a61fb57e 2020-10-20 20:14:17.000000000 -0400 ++++ chromium-86.0.4240.111/base/containers/unique_ptr_adapters_unittest.cc 2020-10-21 17:11:20.004228750 -0400 @@ -4,10 +4,10 @@ #include "base/containers/unique_ptr_adapters.h" @@ -360,9 +360,9 @@ diff -up chromium-86.0.4240.75/base/containers/unique_ptr_adapters_unittest.cc.a ASSERT_TRUE(iter != v.end()); EXPECT_EQ(foo2, iter->get()); } -diff -up chromium-86.0.4240.75/base/debug/activity_analyzer.cc.a61fb57e chromium-86.0.4240.75/base/debug/activity_analyzer.cc ---- chromium-86.0.4240.75/base/debug/activity_analyzer.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/debug/activity_analyzer.cc 2020-10-21 16:38:29.004091339 -0400 +diff -up chromium-86.0.4240.111/base/debug/activity_analyzer.cc.a61fb57e chromium-86.0.4240.111/base/debug/activity_analyzer.cc +--- chromium-86.0.4240.111/base/debug/activity_analyzer.cc.a61fb57e 2020-10-20 20:14:17.000000000 -0400 ++++ chromium-86.0.4240.111/base/debug/activity_analyzer.cc 2020-10-21 17:11:20.004228750 -0400 @@ -4,7 +4,6 @@ #include "base/debug/activity_analyzer.h" @@ -388,9 +388,9 @@ diff -up chromium-86.0.4240.75/base/debug/activity_analyzer.cc.a61fb57e chromium } } // namespace debug -diff -up chromium-86.0.4240.75/base/debug/task_trace.cc.a61fb57e chromium-86.0.4240.75/base/debug/task_trace.cc ---- chromium-86.0.4240.75/base/debug/task_trace.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/debug/task_trace.cc 2020-10-21 16:38:29.004091339 -0400 +diff -up chromium-86.0.4240.111/base/debug/task_trace.cc.a61fb57e chromium-86.0.4240.111/base/debug/task_trace.cc +--- chromium-86.0.4240.111/base/debug/task_trace.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/debug/task_trace.cc 2020-10-21 17:11:20.004228750 -0400 @@ -4,13 +4,13 @@ #include "base/debug/task_trace.h" @@ -416,9 +416,9 @@ diff -up chromium-86.0.4240.75/base/debug/task_trace.cc.a61fb57e chromium-86.0.4 size_t length = 0; while (length < task_trace.size() && task_trace[length]) ++length; -diff -up chromium-86.0.4240.75/base/feature_list_unittest.cc.a61fb57e chromium-86.0.4240.75/base/feature_list_unittest.cc ---- chromium-86.0.4240.75/base/feature_list_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/feature_list_unittest.cc 2020-10-21 16:38:29.005091348 -0400 +diff -up chromium-86.0.4240.111/base/feature_list_unittest.cc.a61fb57e chromium-86.0.4240.111/base/feature_list_unittest.cc +--- chromium-86.0.4240.111/base/feature_list_unittest.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/feature_list_unittest.cc 2020-10-21 17:11:20.005228759 -0400 @@ -6,7 +6,6 @@ #include @@ -444,9 +444,9 @@ diff -up chromium-86.0.4240.75/base/feature_list_unittest.cc.a61fb57e chromium-8 return JoinString(features, ","); } -diff -up chromium-86.0.4240.75/base/hash/sha1_perftest.cc.a61fb57e chromium-86.0.4240.75/base/hash/sha1_perftest.cc ---- chromium-86.0.4240.75/base/hash/sha1_perftest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/hash/sha1_perftest.cc 2020-10-21 16:38:29.005091348 -0400 +diff -up chromium-86.0.4240.111/base/hash/sha1_perftest.cc.a61fb57e chromium-86.0.4240.111/base/hash/sha1_perftest.cc +--- chromium-86.0.4240.111/base/hash/sha1_perftest.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/hash/sha1_perftest.cc 2020-10-21 17:11:20.005228759 -0400 @@ -6,11 +6,11 @@ #include @@ -480,9 +480,9 @@ diff -up chromium-86.0.4240.75/base/hash/sha1_perftest.cc.a61fb57e chromium-86.0 reporter.AddResultList(kMetricThroughput, JoinString(rate_strings, ",")); } -diff -up chromium-86.0.4240.75/base/i18n/break_iterator_unittest.cc.a61fb57e chromium-86.0.4240.75/base/i18n/break_iterator_unittest.cc ---- chromium-86.0.4240.75/base/i18n/break_iterator_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/i18n/break_iterator_unittest.cc 2020-10-21 16:38:29.005091348 -0400 +diff -up chromium-86.0.4240.111/base/i18n/break_iterator_unittest.cc.a61fb57e chromium-86.0.4240.111/base/i18n/break_iterator_unittest.cc +--- chromium-86.0.4240.111/base/i18n/break_iterator_unittest.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/i18n/break_iterator_unittest.cc 2020-10-21 17:11:20.006228768 -0400 @@ -7,6 +7,7 @@ #include #include @@ -501,10 +501,9 @@ diff -up chromium-86.0.4240.75/base/i18n/break_iterator_unittest.cc.a61fb57e chr EXPECT_TRUE(iter.IsSentenceBoundary(i)) << " at index=" << i; } else { EXPECT_FALSE(iter.IsSentenceBoundary(i)) << " at index=" << i; -diff -up chromium-86.0.4240.75/base/immediate_crash_unittest.cc.a61fb57e chromium-86.0.4240.75/base/immediate_crash_unittest.cc -diff -up chromium-86.0.4240.75/base/json/json_parser.cc.a61fb57e chromium-86.0.4240.75/base/json/json_parser.cc ---- chromium-86.0.4240.75/base/json/json_parser.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/json/json_parser.cc 2020-10-21 16:38:29.005091348 -0400 +diff -up chromium-86.0.4240.111/base/json/json_parser.cc.a61fb57e chromium-86.0.4240.111/base/json/json_parser.cc +--- chromium-86.0.4240.111/base/json/json_parser.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/json/json_parser.cc 2020-10-21 17:11:20.006228768 -0400 @@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/notreached.h" @@ -522,9 +521,9 @@ diff -up chromium-86.0.4240.75/base/json/json_parser.cc.a61fb57e chromium-86.0.4 return Value(Value::DictStorage(std::move(dict_storage))); } -diff -up chromium-86.0.4240.75/base/memory/platform_shared_memory_region_unittest.cc.a61fb57e chromium-86.0.4240.75/base/memory/platform_shared_memory_region_unittest.cc ---- chromium-86.0.4240.75/base/memory/platform_shared_memory_region_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/memory/platform_shared_memory_region_unittest.cc 2020-10-21 16:38:29.005091348 -0400 +diff -up chromium-86.0.4240.111/base/memory/platform_shared_memory_region_unittest.cc.a61fb57e chromium-86.0.4240.111/base/memory/platform_shared_memory_region_unittest.cc +--- chromium-86.0.4240.111/base/memory/platform_shared_memory_region_unittest.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/memory/platform_shared_memory_region_unittest.cc 2020-10-21 17:11:20.006228768 -0400 @@ -7,6 +7,7 @@ #include "base/check.h" #include "base/memory/shared_memory_mapping.h" @@ -549,9 +548,9 @@ diff -up chromium-86.0.4240.75/base/memory/platform_shared_memory_region_unittes ASSERT_TRUE(it != regions.end()); // PROT_READ may imply PROT_EXEC on some architectures, so just check that // permissions don't contain PROT_WRITE bit. -diff -up chromium-86.0.4240.75/base/memory/shared_memory_mapping_unittest.cc.a61fb57e chromium-86.0.4240.75/base/memory/shared_memory_mapping_unittest.cc ---- chromium-86.0.4240.75/base/memory/shared_memory_mapping_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/memory/shared_memory_mapping_unittest.cc 2020-10-21 16:38:29.005091348 -0400 +diff -up chromium-86.0.4240.111/base/memory/shared_memory_mapping_unittest.cc.a61fb57e chromium-86.0.4240.111/base/memory/shared_memory_mapping_unittest.cc +--- chromium-86.0.4240.111/base/memory/shared_memory_mapping_unittest.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/memory/shared_memory_mapping_unittest.cc 2020-10-21 17:11:20.007228776 -0400 @@ -6,12 +6,12 @@ #include @@ -593,9 +592,9 @@ diff -up chromium-86.0.4240.75/base/memory/shared_memory_mapping_unittest.cc.a61 EXPECT_EQ(0u, read_span[0]); EXPECT_EQ(0x08070605u, read_span[1]); EXPECT_EQ(0u, read_span_2[0]); -diff -up chromium-86.0.4240.75/base/metrics/histogram.cc.a61fb57e chromium-86.0.4240.75/base/metrics/histogram.cc ---- chromium-86.0.4240.75/base/metrics/histogram.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/metrics/histogram.cc 2020-10-21 16:38:29.006091357 -0400 +diff -up chromium-86.0.4240.111/base/metrics/histogram.cc.a61fb57e chromium-86.0.4240.111/base/metrics/histogram.cc +--- chromium-86.0.4240.111/base/metrics/histogram.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/metrics/histogram.cc 2020-10-21 17:11:20.008228785 -0400 @@ -13,7 +13,6 @@ #include #include @@ -623,9 +622,9 @@ diff -up chromium-86.0.4240.75/base/metrics/histogram.cc.a61fb57e chromium-86.0. BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); for (uint32_t i = 0; i < ranges.size(); i++) { -diff -up chromium-86.0.4240.75/base/metrics/statistics_recorder.cc.a61fb57e chromium-86.0.4240.75/base/metrics/statistics_recorder.cc ---- chromium-86.0.4240.75/base/metrics/statistics_recorder.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/metrics/statistics_recorder.cc 2020-10-21 16:38:29.006091357 -0400 +diff -up chromium-86.0.4240.111/base/metrics/statistics_recorder.cc.a61fb57e chromium-86.0.4240.111/base/metrics/statistics_recorder.cc +--- chromium-86.0.4240.111/base/metrics/statistics_recorder.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/metrics/statistics_recorder.cc 2020-10-21 17:11:20.008228785 -0400 @@ -16,6 +16,7 @@ #include "base/metrics/metrics_hashes.h" #include "base/metrics/persistent_histogram_allocator.h" @@ -678,9 +677,9 @@ diff -up chromium-86.0.4240.75/base/metrics/statistics_recorder.cc.a61fb57e chro histograms.end()); return histograms; } -diff -up chromium-86.0.4240.75/base/observer_list.h.a61fb57e chromium-86.0.4240.75/base/observer_list.h ---- chromium-86.0.4240.75/base/observer_list.h.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/observer_list.h 2020-10-21 16:44:23.777189648 -0400 +diff -up chromium-86.0.4240.111/base/observer_list.h.a61fb57e chromium-86.0.4240.111/base/observer_list.h +--- chromium-86.0.4240.111/base/observer_list.h.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/observer_list.h 2020-10-21 17:11:20.009228794 -0400 @@ -18,6 +18,7 @@ #include "base/macros.h" #include "base/notreached.h" @@ -714,9 +713,9 @@ diff -up chromium-86.0.4240.75/base/observer_list.h.a61fb57e chromium-86.0.4240. } // Removes all the observers from this list. -diff -up chromium-86.0.4240.75/base/process/process_metrics_unittest.cc.a61fb57e chromium-86.0.4240.75/base/process/process_metrics_unittest.cc ---- chromium-86.0.4240.75/base/process/process_metrics_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/process/process_metrics_unittest.cc 2020-10-21 16:38:29.006091357 -0400 +diff -up chromium-86.0.4240.111/base/process/process_metrics_unittest.cc.a61fb57e chromium-86.0.4240.111/base/process/process_metrics_unittest.cc +--- chromium-86.0.4240.111/base/process/process_metrics_unittest.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/process/process_metrics_unittest.cc 2020-10-21 17:11:20.009228794 -0400 @@ -19,6 +19,7 @@ #include "base/macros.h" #include "base/memory/shared_memory_mapping.h" @@ -775,9 +774,9 @@ diff -up chromium-86.0.4240.75/base/process/process_metrics_unittest.cc.a61fb57e [&entry](const ProcessMetrics::ThreadTimeInState& prev_entry) { return entry.thread_id == prev_entry.thread_id && entry.core_type == prev_entry.core_type && -diff -up chromium-86.0.4240.75/base/profiler/arm_cfi_table.cc.a61fb57e chromium-86.0.4240.75/base/profiler/arm_cfi_table.cc ---- chromium-86.0.4240.75/base/profiler/arm_cfi_table.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/profiler/arm_cfi_table.cc 2020-10-21 16:38:29.006091357 -0400 +diff -up chromium-86.0.4240.111/base/profiler/arm_cfi_table.cc.a61fb57e chromium-86.0.4240.111/base/profiler/arm_cfi_table.cc +--- chromium-86.0.4240.111/base/profiler/arm_cfi_table.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/profiler/arm_cfi_table.cc 2020-10-21 17:11:20.009228794 -0400 @@ -4,7 +4,7 @@ #include "base/profiler/arm_cfi_table.h" @@ -804,9 +803,9 @@ diff -up chromium-86.0.4240.75/base/profiler/arm_cfi_table.cc.a61fb57e chromium- -} // namespace base \ No newline at end of file +} // namespace base -diff -up chromium-86.0.4240.75/base/profiler/metadata_recorder_unittest.cc.a61fb57e chromium-86.0.4240.75/base/profiler/metadata_recorder_unittest.cc ---- chromium-86.0.4240.75/base/profiler/metadata_recorder_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/profiler/metadata_recorder_unittest.cc 2020-10-21 16:38:29.006091357 -0400 +diff -up chromium-86.0.4240.111/base/profiler/metadata_recorder_unittest.cc.a61fb57e chromium-86.0.4240.111/base/profiler/metadata_recorder_unittest.cc +--- chromium-86.0.4240.111/base/profiler/metadata_recorder_unittest.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/profiler/metadata_recorder_unittest.cc 2020-10-21 17:11:20.010228802 -0400 @@ -4,6 +4,7 @@ #include "base/profiler/metadata_recorder.h" @@ -824,9 +823,9 @@ diff -up chromium-86.0.4240.75/base/profiler/metadata_recorder_unittest.cc.a61fb MetadataRecorder::ItemArray recorder_items; size_t recorder_item_count = -diff -up chromium-86.0.4240.75/base/profiler/module_cache.cc.a61fb57e chromium-86.0.4240.75/base/profiler/module_cache.cc ---- chromium-86.0.4240.75/base/profiler/module_cache.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/profiler/module_cache.cc 2020-10-21 16:38:29.007091366 -0400 +diff -up chromium-86.0.4240.111/base/profiler/module_cache.cc.a61fb57e chromium-86.0.4240.111/base/profiler/module_cache.cc +--- chromium-86.0.4240.111/base/profiler/module_cache.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/profiler/module_cache.cc 2020-10-21 17:11:20.010228802 -0400 @@ -4,10 +4,11 @@ #include "base/profiler/module_cache.h" @@ -840,9 +839,9 @@ diff -up chromium-86.0.4240.75/base/profiler/module_cache.cc.a61fb57e chromium-8 namespace base { namespace { -diff -up chromium-86.0.4240.75/base/profiler/stack_sampler_impl.cc.a61fb57e chromium-86.0.4240.75/base/profiler/stack_sampler_impl.cc ---- chromium-86.0.4240.75/base/profiler/stack_sampler_impl.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/profiler/stack_sampler_impl.cc 2020-10-21 16:38:29.007091366 -0400 +diff -up chromium-86.0.4240.111/base/profiler/stack_sampler_impl.cc.a61fb57e chromium-86.0.4240.111/base/profiler/stack_sampler_impl.cc +--- chromium-86.0.4240.111/base/profiler/stack_sampler_impl.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/profiler/stack_sampler_impl.cc 2020-10-21 17:11:20.010228802 -0400 @@ -16,6 +16,7 @@ #include "base/profiler/stack_copier.h" #include "base/profiler/suspendable_thread_delegate.h" @@ -867,9 +866,9 @@ diff -up chromium-86.0.4240.75/base/profiler/stack_sampler_impl.cc.a61fb57e chro if (unwinder == unwinders.end()) return stack; -diff -up chromium-86.0.4240.75/base/profiler/stack_sampling_profiler_unittest.cc.a61fb57e chromium-86.0.4240.75/base/profiler/stack_sampling_profiler_unittest.cc ---- chromium-86.0.4240.75/base/profiler/stack_sampling_profiler_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/profiler/stack_sampling_profiler_unittest.cc 2020-10-21 16:38:29.007091366 -0400 +diff -up chromium-86.0.4240.111/base/profiler/stack_sampling_profiler_unittest.cc.a61fb57e chromium-86.0.4240.111/base/profiler/stack_sampling_profiler_unittest.cc +--- chromium-86.0.4240.111/base/profiler/stack_sampling_profiler_unittest.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/profiler/stack_sampling_profiler_unittest.cc 2020-10-21 17:11:20.011228811 -0400 @@ -5,7 +5,6 @@ #include #include @@ -901,9 +900,5158 @@ diff -up chromium-86.0.4240.75/base/profiler/stack_sampling_profiler_unittest.cc // Wait for one profiler to finish. return WaitableEvent::WaitMany(sampling_completed_rawptrs.data(), sampling_completed_rawptrs.size()); -diff -up chromium-86.0.4240.75/base/sampling_heap_profiler/poisson_allocation_sampler.cc.a61fb57e chromium-86.0.4240.75/base/sampling_heap_profiler/poisson_allocation_sampler.cc ---- chromium-86.0.4240.75/base/sampling_heap_profiler/poisson_allocation_sampler.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/sampling_heap_profiler/poisson_allocation_sampler.cc 2020-10-21 16:38:29.007091366 -0400 +diff -up chromium-86.0.4240.111/base/ranges/algorithm.h.a61fb57e chromium-86.0.4240.111/base/ranges/algorithm.h +--- chromium-86.0.4240.111/base/ranges/algorithm.h.a61fb57e 2020-10-21 17:44:59.179014291 -0400 ++++ chromium-86.0.4240.111/base/ranges/algorithm.h 2020-10-21 17:43:40.094374195 -0400 +@@ -0,0 +1,4965 @@ ++// Copyright 2020 The Chromium Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++#ifndef BASE_RANGES_ALGORITHM_H_ ++#define BASE_RANGES_ALGORITHM_H_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "base/ranges/functional.h" ++#include "base/ranges/ranges.h" ++#include "base/stl_util.h" ++#include "base/template_util.h" ++ ++namespace base { ++ ++namespace internal { ++ ++// Returns a transformed version of the unary predicate `pred` applying `proj` ++// to its argument before invoking `pred` on it. ++// Ensures that the return type of `invoke(pred, ...)` is convertible to bool. ++template ++constexpr auto ProjectedUnaryPredicate(Pred& pred, Proj& proj) noexcept { ++ return [&pred, &proj](auto&& arg) -> bool { ++ return base::invoke(pred, ++ base::invoke(proj, std::forward(arg))); ++ }; ++} ++ ++// Returns a transformed version of the binary predicate `pred` applying `proj1` ++// and `proj2` to its arguments before invoking `pred` on them. ++// ++// Provides an opt-in to considers all four permutations of projections and ++// argument types. This is sometimes necessary to allow usage with legacy ++// non-ranges std:: algorithms that don't support projections. ++// ++// These permutations are assigned different priorities to break ambiguities in ++// case several permutations are possible, e.g. when Proj1 and Proj2 are the ++// same type. ++// ++// Note that even when opting in to using all permutations of projections, ++// calling code should still ensure that the canonical mapping of {Proj1, Proj2} ++// to {LHS, RHS} compiles for all members of the range. This can be done by ++// adding the following constraint: ++// ++// typename = indirect_result_t, Proj1>, ++// projected, Proj2>> ++// ++// Ensures that the return type of `invoke(pred, ...)` is convertible to bool. ++template ++class BinaryPredicateProjector { ++ public: ++ constexpr BinaryPredicateProjector(Pred& pred, Proj1& proj1, Proj2& proj2) ++ : pred_(pred), proj1_(proj1), proj2_(proj2) {} ++ ++ private: ++ template ++ using InvokeResult = invoke_result_t, ++ invoke_result_t>; ++ ++ template > ++ constexpr std::pair GetProjs(priority_tag<3>) const { ++ return {proj1_, proj2_}; ++ } ++ ++ template , ++ typename = InvokeResult> ++ constexpr std::pair GetProjs(priority_tag<2>) const { ++ return {proj2_, proj1_}; ++ } ++ ++ template , ++ typename = InvokeResult> ++ constexpr std::pair GetProjs(priority_tag<1>) const { ++ return {proj1_, proj1_}; ++ } ++ ++ template , ++ typename = InvokeResult> ++ constexpr std::pair GetProjs(priority_tag<0>) const { ++ return {proj2_, proj2_}; ++ } ++ ++ public: ++ template ++ constexpr bool operator()(T&& lhs, U&& rhs) const { ++ auto projs = GetProjs(priority_tag<3>()); ++ return base::invoke(pred_, base::invoke(projs.first, std::forward(lhs)), ++ base::invoke(projs.second, std::forward(rhs))); ++ } ++ ++ private: ++ Pred& pred_; ++ Proj1& proj1_; ++ Proj2& proj2_; ++}; ++ ++// Small wrappers around BinaryPredicateProjector to make the calling side more ++// readable. ++template ++constexpr auto ProjectedBinaryPredicate(Pred& pred, ++ Proj1& proj1, ++ Proj2& proj2) noexcept { ++ return BinaryPredicateProjector(pred, proj1, proj2); ++} ++ ++template ++constexpr auto PermutedProjectedBinaryPredicate(Pred& pred, ++ Proj1& proj1, ++ Proj2& proj2) noexcept { ++ return BinaryPredicateProjector(pred, proj1, proj2); ++} ++ ++// This alias is used below to restrict iterator based APIs to types for which ++// `iterator_category` and the pre-increment and post-increment operators are ++// defined. This is required in situations where otherwise an undesired overload ++// would be chosen, e.g. copy_if. In spirit this is similar to C++20's ++// std::input_or_output_iterator, a concept that each iterator should satisfy. ++template ()), ++ typename = decltype(std::declval()++)> ++using iterator_category_t = ++ typename std::iterator_traits::iterator_category; ++ ++// This alias is used below to restrict range based APIs to types for which ++// `iterator_category_t` is defined for the underlying iterator. This is ++// required in situations where otherwise an undesired overload would be chosen, ++// e.g. transform. In spirit this is similar to C++20's std::ranges::range, a ++// concept that each range should satisfy. ++template ++using range_category_t = iterator_category_t>; ++ ++} // namespace internal ++ ++namespace ranges { ++ ++// C++14 implementation of std::ranges::in_fun_result. Note the because C++14 ++// lacks the `no_unique_address` attribute it is commented out. ++// ++// Reference: https://wg21.link/algorithms.results#:~:text=in_fun_result ++template ++struct in_fun_result { ++ /* [[no_unique_address]] */ I in; ++ /* [[no_unique_address]] */ F fun; ++ ++ template {} && ++ std::is_convertible{}>> ++ constexpr operator in_fun_result() const& { ++ return {in, fun}; ++ } ++ ++ template {} && ++ std::is_convertible{}>> ++ constexpr operator in_fun_result() && { ++ return {std::move(in), std::move(fun)}; ++ } ++}; ++ ++// TODO(crbug.com/1071094): Implement the other result types. ++ ++// [alg.nonmodifying] Non-modifying sequence operations ++// Reference: https://wg21.link/alg.nonmodifying ++ ++// [alg.all.of] All of ++// Reference: https://wg21.link/alg.all.of ++ ++// Let `E(i)` be `invoke(pred, invoke(proj, *i))`. ++// ++// Returns: `false` if `E(i)` is `false` for some iterator `i` in the range ++// `[first, last)`, and `true` otherwise. ++// ++// Complexity: At most `last - first` applications of the predicate and any ++// projection. ++// ++// Reference: https://wg21.link/alg.all.of#:~:text=ranges::all_of(I ++template > ++constexpr bool all_of(InputIterator first, ++ InputIterator last, ++ Pred pred, ++ Proj proj = {}) { ++ for (; first != last; ++first) { ++ if (!base::invoke(pred, base::invoke(proj, *first))) ++ return false; ++ } ++ ++ return true; ++} ++ ++// Let `E(i)` be `invoke(pred, invoke(proj, *i))`. ++// ++// Returns: `false` if `E(i)` is `false` for some iterator `i` in `range`, and ++// `true` otherwise. ++// ++// Complexity: At most `size(range)` applications of the predicate and any ++// projection. ++// ++// Reference: https://wg21.link/alg.all.of#:~:text=ranges::all_of(R ++template > ++constexpr bool all_of(Range&& range, Pred pred, Proj proj = {}) { ++ return ranges::all_of(ranges::begin(range), ranges::end(range), ++ std::move(pred), std::move(proj)); ++} ++ ++// [alg.any.of] Any of ++// Reference: https://wg21.link/alg.any.of ++ ++// Let `E(i)` be `invoke(pred, invoke(proj, *i))`. ++// ++// Returns: `true` if `E(i)` is `true` for some iterator `i` in the range ++// `[first, last)`, and `false` otherwise. ++// ++// Complexity: At most `last - first` applications of the predicate and any ++// projection. ++// ++// Reference: https://wg21.link/alg.any.of#:~:text=ranges::any_of(I ++template > ++constexpr bool any_of(InputIterator first, ++ InputIterator last, ++ Pred pred, ++ Proj proj = {}) { ++ for (; first != last; ++first) { ++ if (base::invoke(pred, base::invoke(proj, *first))) ++ return true; ++ } ++ ++ return false; ++} ++ ++// Let `E(i)` be `invoke(pred, invoke(proj, *i))`. ++// ++// Returns: `true` if `E(i)` is `true` for some iterator `i` in `range`, and ++// `false` otherwise. ++// ++// Complexity: At most `size(range)` applications of the predicate and any ++// projection. ++// ++// Reference: https://wg21.link/alg.any.of#:~:text=ranges::any_of(R ++template > ++constexpr bool any_of(Range&& range, Pred pred, Proj proj = {}) { ++ return ranges::any_of(ranges::begin(range), ranges::end(range), ++ std::move(pred), std::move(proj)); ++} ++ ++// [alg.none.of] None of ++// Reference: https://wg21.link/alg.none.of ++ ++// Let `E(i)` be `invoke(pred, invoke(proj, *i))`. ++// ++// Returns: `false` if `E(i)` is `true` for some iterator `i` in the range ++// `[first, last)`, and `true` otherwise. ++// ++// Complexity: At most `last - first` applications of the predicate and any ++// projection. ++// ++// Reference: https://wg21.link/alg.none.of#:~:text=ranges::none_of(I ++template > ++constexpr bool none_of(InputIterator first, ++ InputIterator last, ++ Pred pred, ++ Proj proj = {}) { ++ for (; first != last; ++first) { ++ if (base::invoke(pred, base::invoke(proj, *first))) ++ return false; ++ } ++ ++ return true; ++} ++ ++// Let `E(i)` be `invoke(pred, invoke(proj, *i))`. ++// ++// Returns: `false` if `E(i)` is `true` for some iterator `i` in `range`, and ++// `true` otherwise. ++// ++// Complexity: At most `size(range)` applications of the predicate and any ++// projection. ++// ++// Reference: https://wg21.link/alg.none.of#:~:text=ranges::none_of(R ++template > ++constexpr bool none_of(Range&& range, Pred pred, Proj proj = {}) { ++ return ranges::none_of(ranges::begin(range), ranges::end(range), ++ std::move(pred), std::move(proj)); ++} ++ ++// [alg.foreach] For each ++// Reference: https://wg21.link/alg.foreach ++ ++// Reference: https://wg21.link/algorithm.syn#:~:text=for_each_result ++template ++using for_each_result = in_fun_result; ++ ++// Effects: Calls `invoke(f, invoke(proj, *i))` for every iterator `i` in the ++// range `[first, last)`, starting from `first` and proceeding to `last - 1`. ++// ++// Returns: `{last, std::move(f)}`. ++// ++// Complexity: Applies `f` and `proj` exactly `last - first` times. ++// ++// Remarks: If `f` returns a result, the result is ignored. ++// ++// Reference: https://wg21.link/alg.foreach#:~:text=ranges::for_each(I ++template > ++constexpr auto for_each(InputIterator first, ++ InputIterator last, ++ Fun f, ++ Proj proj = {}) { ++ for (; first != last; ++first) ++ base::invoke(f, base::invoke(proj, *first)); ++ return for_each_result{first, std::move(f)}; ++} ++ ++// Effects: Calls `invoke(f, invoke(proj, *i))` for every iterator `i` in the ++// range `range`, starting from `begin(range)` and proceeding to `end(range) - ++// 1`. ++// ++// Returns: `{last, std::move(f)}`. ++// ++// Complexity: Applies `f` and `proj` exactly `size(range)` times. ++// ++// Remarks: If `f` returns a result, the result is ignored. ++// ++// Reference: https://wg21.link/alg.foreach#:~:text=ranges::for_each(R ++template > ++constexpr auto for_each(Range&& range, Fun f, Proj proj = {}) { ++ return ranges::for_each(ranges::begin(range), ranges::end(range), ++ std::move(f), std::move(proj)); ++} ++ ++// Reference: https://wg21.link/algorithm.syn#:~:text=for_each_n_result ++template ++using for_each_n_result = in_fun_result; ++ ++// Preconditions: `n >= 0` is `true`. ++// ++// Effects: Calls `invoke(f, invoke(proj, *i))` for every iterator `i` in the ++// range `[first, first + n)` in order. ++// ++// Returns: `{first + n, std::move(f)}`. ++// ++// Remarks: If `f` returns a result, the result is ignored. ++// ++// Reference: https://wg21.link/alg.foreach#:~:text=ranges::for_each_n ++template > ++constexpr auto for_each_n(InputIterator first, Size n, Fun f, Proj proj = {}) { ++ while (n > 0) { ++ base::invoke(f, base::invoke(proj, *first)); ++ ++first; ++ --n; ++ } ++ ++ return for_each_n_result{first, std::move(f)}; ++} ++ ++// [alg.find] Find ++// Reference: https://wg21.link/alg.find ++ ++// Let `E(i)` be `bool(invoke(proj, *i) == value)`. ++// ++// Returns: The first iterator `i` in the range `[first, last)` for which `E(i)` ++// is `true`. Returns `last` if no such iterator is found. ++// ++// Complexity: At most `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.find#:~:text=ranges::find(I ++template > ++constexpr auto find(InputIterator first, ++ InputIterator last, ++ const T& value, ++ Proj proj = {}) { ++ // Note: In order to be able to apply `proj` to each element in [first, last) ++ // we are dispatching to std::find_if instead of std::find. ++ return std::find_if(first, last, [&proj, &value](auto&& lhs) { ++ return base::invoke(proj, std::forward(lhs)) == value; ++ }); ++} ++ ++// Let `E(i)` be `bool(invoke(proj, *i) == value)`. ++// ++// Returns: The first iterator `i` in `range` for which `E(i)` is `true`. ++// Returns `end(range)` if no such iterator is found. ++// ++// Complexity: At most `size(range)` applications of the corresponding predicate ++// and any projection. ++// ++// Reference: https://wg21.link/alg.find#:~:text=ranges::find(R ++template > ++constexpr auto find(Range&& range, const T& value, Proj proj = {}) { ++ return ranges::find(ranges::begin(range), ranges::end(range), value, ++ std::move(proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`. ++// ++// Returns: The first iterator `i` in the range `[first, last)` for which `E(i)` ++// is `true`. Returns `last` if no such iterator is found. ++// ++// Complexity: At most `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.find#:~:text=ranges::find_if(I ++template > ++constexpr auto find_if(InputIterator first, ++ InputIterator last, ++ Pred pred, ++ Proj proj = {}) { ++ return std::find_if(first, last, ++ internal::ProjectedUnaryPredicate(pred, proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`. ++// ++// Returns: The first iterator `i` in `range` for which `E(i)` is `true`. ++// Returns `end(range)` if no such iterator is found. ++// ++// Complexity: At most `size(range)` applications of the corresponding predicate ++// and any projection. ++// ++// Reference: https://wg21.link/alg.find#:~:text=ranges::find_if(R ++template > ++constexpr auto find_if(Range&& range, Pred pred, Proj proj = {}) { ++ return ranges::find_if(ranges::begin(range), ranges::end(range), ++ std::move(pred), std::move(proj)); ++} ++ ++// Let `E(i)` be `bool(!invoke(pred, invoke(proj, *i)))`. ++// ++// Returns: The first iterator `i` in the range `[first, last)` for which `E(i)` ++// is `true`. Returns `last` if no such iterator is found. ++// ++// Complexity: At most `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.find#:~:text=ranges::find_if_not(I ++template > ++constexpr auto find_if_not(InputIterator first, ++ InputIterator last, ++ Pred pred, ++ Proj proj = {}) { ++ return std::find_if_not(first, last, ++ internal::ProjectedUnaryPredicate(pred, proj)); ++} ++ ++// Let `E(i)` be `bool(!invoke(pred, invoke(proj, *i)))`. ++// ++// Returns: The first iterator `i` in `range` for which `E(i)` is `true`. ++// Returns `end(range)` if no such iterator is found. ++// ++// Complexity: At most `size(range)` applications of the corresponding predicate ++// and any projection. ++// ++// Reference: https://wg21.link/alg.find#:~:text=ranges::find_if_not(R ++template > ++constexpr auto find_if_not(Range&& range, Pred pred, Proj proj = {}) { ++ return ranges::find_if_not(ranges::begin(range), ranges::end(range), ++ std::move(pred), std::move(proj)); ++} ++ ++// [alg.find.end] Find end ++// Reference: https://wg21.link/alg.find.end ++ ++// Let: ++// - `E(i,n)` be `invoke(pred, invoke(proj1, *(i + n)), ++// invoke(proj2, *(first2 + n)))` ++// ++// - `i` be `last1` if `[first2, last2)` is empty, or if ++// `(last2 - first2) > (last1 - first1)` is `true`, or if there is no iterator ++// in the range `[first1, last1 - (last2 - first2))` such that for every ++// non-negative integer `n < (last2 - first2)`, `E(i,n)` is `true`. Otherwise ++// `i` is the last such iterator in `[first1, last1 - (last2 - first2))`. ++// ++// Returns: `i` ++// Note: std::ranges::find_end(I1 first1,...) returns a range, rather than an ++// iterator. For simplicitly we match std::find_end's return type instead. ++// ++// Complexity: ++// At most `(last2 - first2) * (last1 - first1 - (last2 - first2) + 1)` ++// applications of the corresponding predicate and any projections. ++// ++// Reference: https://wg21.link/alg.find.end#:~:text=ranges::find_end(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>> ++constexpr auto find_end(ForwardIterator1 first1, ++ ForwardIterator1 last1, ++ ForwardIterator2 first2, ++ ForwardIterator2 last2, ++ Pred pred = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return std::find_end(first1, last1, first2, last2, ++ internal::ProjectedBinaryPredicate(pred, proj1, proj2)); ++} ++ ++// Let: ++// - `E(i,n)` be `invoke(pred, invoke(proj1, *(i + n)), ++// invoke(proj2, *(first2 + n)))` ++// ++// - `i` be `end(range1)` if `range2` is empty, or if ++// `size(range2) > size(range1)` is `true`, or if there is no iterator in the ++// range `[begin(range1), end(range1) - size(range2))` such that for every ++// non-negative integer `n < size(range2)`, `E(i,n)` is `true`. Otherwise `i` ++// is the last such iterator in `[begin(range1), end(range1) - size(range2))`. ++// ++// Returns: `i` ++// Note: std::ranges::find_end(R1&& r1,...) returns a range, rather than an ++// iterator. For simplicitly we match std::find_end's return type instead. ++// ++// Complexity: At most `size(range2) * (size(range1) - size(range2) + 1)` ++// applications of the corresponding predicate and any projections. ++// ++// Reference: https://wg21.link/alg.find.end#:~:text=ranges::find_end(R1 ++template , ++ typename = internal::range_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>> ++constexpr auto find_end(Range1&& range1, ++ Range2&& range2, ++ Pred pred = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::find_end(ranges::begin(range1), ranges::end(range1), ++ ranges::begin(range2), ranges::end(range2), ++ std::move(pred), std::move(proj1), std::move(proj2)); ++} ++ ++// [alg.find.first.of] Find first ++// Reference: https://wg21.link/alg.find.first.of ++ ++// Let `E(i,j)` be `bool(invoke(pred, invoke(proj1, *i), invoke(proj2, *j)))`. ++// ++// Effects: Finds an element that matches one of a set of values. ++// ++// Returns: The first iterator `i` in the range `[first1, last1)` such that for ++// some iterator `j` in the range `[first2, last2)` `E(i,j)` holds. Returns ++// `last1` if `[first2, last2)` is empty or if no such iterator is found. ++// ++// Complexity: At most `(last1 - first1) * (last2 - first2)` applications of the ++// corresponding predicate and any projections. ++// ++// Reference: ++// https://wg21.link/alg.find.first.of#:~:text=ranges::find_first_of(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>> ++constexpr auto find_first_of(ForwardIterator1 first1, ++ ForwardIterator1 last1, ++ ForwardIterator2 first2, ++ ForwardIterator2 last2, ++ Pred pred = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return std::find_first_of( ++ first1, last1, first2, last2, ++ internal::ProjectedBinaryPredicate(pred, proj1, proj2)); ++} ++ ++// Let `E(i,j)` be `bool(invoke(pred, invoke(proj1, *i), invoke(proj2, *j)))`. ++// ++// Effects: Finds an element that matches one of a set of values. ++// ++// Returns: The first iterator `i` in `range1` such that for some iterator `j` ++// in `range2` `E(i,j)` holds. Returns `end(range1)` if `range2` is empty or if ++// no such iterator is found. ++// ++// Complexity: At most `size(range1) * size(range2)` applications of the ++// corresponding predicate and any projections. ++// ++// Reference: ++// https://wg21.link/alg.find.first.of#:~:text=ranges::find_first_of(R1 ++template , ++ typename = internal::range_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>> ++constexpr auto find_first_of(Range1&& range1, ++ Range2&& range2, ++ Pred pred = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::find_first_of( ++ ranges::begin(range1), ranges::end(range1), ranges::begin(range2), ++ ranges::end(range2), std::move(pred), std::move(proj1), std::move(proj2)); ++} ++ ++// [alg.adjacent.find] Adjacent find ++// Reference: https://wg21.link/alg.adjacent.find ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i), invoke(proj, *(i + 1))))`. ++// ++// Returns: The first iterator `i` such that both `i` and `i + 1` are in the ++// range `[first, last)` for which `E(i)` holds. Returns `last` if no such ++// iterator is found. ++// ++// Complexity: Exactly `min((i - first) + 1, (last - first) - 1)` applications ++// of the corresponding predicate, where `i` is `adjacent_find`'s return value. ++// ++// Reference: ++// https://wg21.link/alg.adjacent.find#:~:text=ranges::adjacent_find(I ++template > ++constexpr auto adjacent_find(ForwardIterator first, ++ ForwardIterator last, ++ Pred pred = {}, ++ Proj proj = {}) { ++ return std::adjacent_find( ++ first, last, internal::ProjectedBinaryPredicate(pred, proj, proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i), invoke(proj, *(i + 1))))`. ++// ++// Returns: The first iterator `i` such that both `i` and `i + 1` are in the ++// range `range` for which `E(i)` holds. Returns `end(range)` if no such ++// iterator is found. ++// ++// Complexity: Exactly `min((i - begin(range)) + 1, size(range) - 1)` ++// applications of the corresponding predicate, where `i` is `adjacent_find`'s ++// return value. ++// ++// Reference: ++// https://wg21.link/alg.adjacent.find#:~:text=ranges::adjacent_find(R ++template > ++constexpr auto adjacent_find(Range&& range, Pred pred = {}, Proj proj = {}) { ++ return ranges::adjacent_find(ranges::begin(range), ranges::end(range), ++ std::move(pred), std::move(proj)); ++} ++ ++// [alg.count] Count ++// Reference: https://wg21.link/alg.count ++ ++// Let `E(i)` be `invoke(proj, *i) == value`. ++// ++// Effects: Returns the number of iterators `i` in the range `[first, last)` for ++// which `E(i)` holds. ++// ++// Complexity: Exactly `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.count#:~:text=ranges::count(I ++template > ++constexpr auto count(InputIterator first, ++ InputIterator last, ++ const T& value, ++ Proj proj = {}) { ++ // Note: In order to be able to apply `proj` to each element in [first, last) ++ // we are dispatching to std::count_if instead of std::count. ++ return std::count_if(first, last, [&proj, &value](auto&& lhs) { ++ return base::invoke(proj, std::forward(lhs)) == value; ++ }); ++} ++ ++// Let `E(i)` be `invoke(proj, *i) == value`. ++// ++// Effects: Returns the number of iterators `i` in `range` for which `E(i)` ++// holds. ++// ++// Complexity: Exactly `size(range)` applications of the corresponding predicate ++// and any projection. ++// ++// Reference: https://wg21.link/alg.count#:~:text=ranges::count(R ++template > ++constexpr auto count(Range&& range, const T& value, Proj proj = {}) { ++ return ranges::count(ranges::begin(range), ranges::end(range), value, ++ std::move(proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`. ++// ++// Effects: Returns the number of iterators `i` in the range `[first, last)` for ++// which `E(i)` holds. ++// ++// Complexity: Exactly `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.count#:~:text=ranges::count_if(I ++template > ++constexpr auto count_if(InputIterator first, ++ InputIterator last, ++ Pred pred, ++ Proj proj = {}) { ++ return std::count_if(first, last, ++ internal::ProjectedUnaryPredicate(pred, proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`. ++// ++// Effects: Returns the number of iterators `i` in `range` for which `E(i)` ++// holds. ++// ++// Complexity: Exactly `size(range)` applications of the corresponding predicate ++// and any projection. ++// ++// Reference: https://wg21.link/alg.count#:~:text=ranges::count_if(R ++template > ++constexpr auto count_if(Range&& range, Pred pred, Proj proj = {}) { ++ return ranges::count_if(ranges::begin(range), ranges::end(range), ++ std::move(pred), std::move(proj)); ++} ++ ++// [mismatch] Mismatch ++// Reference: https://wg21.link/mismatch ++ ++// Let `E(n)` be `!invoke(pred, invoke(proj1, *(first1 + n)), ++// invoke(proj2, *(first2 + n)))`. ++// ++// Let `N` be `min(last1 - first1, last2 - first2)`. ++// ++// Returns: `{ first1 + n, first2 + n }`, where `n` is the smallest integer in ++// `[0, N)` such that `E(n)` holds, or `N` if no such integer exists. ++// ++// Complexity: At most `N` applications of the corresponding predicate and any ++// projections. ++// ++// Reference: https://wg21.link/mismatch#:~:text=ranges::mismatch(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>> ++constexpr auto mismatch(ForwardIterator1 first1, ++ ForwardIterator1 last1, ++ ForwardIterator2 first2, ++ ForwardIterator2 last2, ++ Pred pred = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return std::mismatch(first1, last1, first2, last2, ++ internal::ProjectedBinaryPredicate(pred, proj1, proj2)); ++} ++ ++// Let `E(n)` be `!invoke(pred, invoke(proj1, *(begin(range1) + n)), ++// invoke(proj2, *(begin(range2) + n)))`. ++// ++// Let `N` be `min(size(range1), size(range2))`. ++// ++// Returns: `{ begin(range1) + n, begin(range2) + n }`, where `n` is the ++// smallest integer in `[0, N)` such that `E(n)` holds, or `N` if no such ++// integer exists. ++// ++// Complexity: At most `N` applications of the corresponding predicate and any ++// projections. ++// ++// Reference: https://wg21.link/mismatch#:~:text=ranges::mismatch(R1 ++template , ++ typename = internal::range_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>> ++constexpr auto mismatch(Range1&& range1, ++ Range2&& range2, ++ Pred pred = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::mismatch(ranges::begin(range1), ranges::end(range1), ++ ranges::begin(range2), ranges::end(range2), ++ std::move(pred), std::move(proj1), std::move(proj2)); ++} ++ ++// [alg.equal] Equal ++// Reference: https://wg21.link/alg.equal ++ ++// Let `E(i)` be ++// `invoke(pred, invoke(proj1, *i), invoke(proj2, *(first2 + (i - first1))))`. ++// ++// Returns: If `last1 - first1 != last2 - first2`, return `false.` Otherwise ++// return `true` if `E(i)` holds for every iterator `i` in the range `[first1, ++// last1)`. Otherwise, returns `false`. ++// ++// Complexity: If the types of `first1`, `last1`, `first2`, and `last2` meet the ++// `RandomAccessIterator` requirements and `last1 - first1 != last2 - first2`, ++// then no applications of the corresponding predicate and each projection; ++// otherwise, at most `min(last1 - first1, last2 - first2)` applications of the ++// corresponding predicate and any projections. ++// ++// Reference: https://wg21.link/alg.equal#:~:text=ranges::equal(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>> ++constexpr bool equal(ForwardIterator1 first1, ++ ForwardIterator1 last1, ++ ForwardIterator2 first2, ++ ForwardIterator2 last2, ++ Pred pred = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return std::equal(first1, last1, first2, last2, ++ internal::ProjectedBinaryPredicate(pred, proj1, proj2)); ++} ++ ++// Let `E(i)` be ++// `invoke(pred, invoke(proj1, *i), ++// invoke(proj2, *(begin(range2) + (i - begin(range1)))))`. ++// ++// Returns: If `size(range1) != size(range2)`, return `false.` Otherwise return ++// `true` if `E(i)` holds for every iterator `i` in `range1`. Otherwise, returns ++// `false`. ++// ++// Complexity: If the types of `begin(range1)`, `end(range1)`, `begin(range2)`, ++// and `end(range2)` meet the `RandomAccessIterator` requirements and ++// `size(range1) != size(range2)`, then no applications of the corresponding ++// predicate and each projection; ++// otherwise, at most `min(size(range1), size(range2))` applications of the ++// corresponding predicate and any projections. ++// ++// Reference: https://wg21.link/alg.equal#:~:text=ranges::equal(R1 ++template , ++ typename = internal::range_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>> ++constexpr bool equal(Range1&& range1, ++ Range2&& range2, ++ Pred pred = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::equal(ranges::begin(range1), ranges::end(range1), ++ ranges::begin(range2), ranges::end(range2), ++ std::move(pred), std::move(proj1), std::move(proj2)); ++} ++ ++// [alg.is.permutation] Is permutation ++// Reference: https://wg21.link/alg.is.permutation ++ ++// Returns: If `last1 - first1 != last2 - first2`, return `false`. Otherwise ++// return `true` if there exists a permutation of the elements in the range ++// `[first2, last2)`, bounded by `[pfirst, plast)`, such that ++// `ranges::equal(first1, last1, pfirst, plast, pred, proj, proj)` returns ++// `true`; otherwise, returns `false`. ++// ++// Complexity: No applications of the corresponding predicate if ++// ForwardIterator1 and ForwardIterator2 meet the requirements of random access ++// iterators and `last1 - first1 != last2 - first2`. Otherwise, exactly ++// `last1 - first1` applications of the corresponding predicate and projections ++// if `ranges::equal(first1, last1, first2, last2, pred, proj, proj)` would ++// return true; ++// otherwise, at worst `O(N^2)`, where `N` has the value `last1 - first1`. ++// ++// Reference: ++// https://wg21.link/alg.is.permutation#:~:text=ranges::is_permutation(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>> ++constexpr bool is_permutation(ForwardIterator1 first1, ++ ForwardIterator1 last1, ++ ForwardIterator2 first2, ++ ForwardIterator2 last2, ++ Pred pred = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ // Needs to opt-in to all permutations, since std::is_permutation expects ++ // pred(proj1(lhs), proj1(rhs)) to compile. ++ return std::is_permutation( ++ first1, last1, first2, last2, ++ internal::PermutedProjectedBinaryPredicate(pred, proj1, proj2)); ++} ++ ++// Returns: If `size(range1) != size(range2)`, return `false`. Otherwise return ++// `true` if there exists a permutation of the elements in `range2`, bounded by ++// `[pbegin, pend)`, such that ++// `ranges::equal(range1, [pbegin, pend), pred, proj, proj)` returns `true`; ++// otherwise, returns `false`. ++// ++// Complexity: No applications of the corresponding predicate if Range1 and ++// Range2 meet the requirements of random access ranges and ++// `size(range1) != size(range2)`. Otherwise, exactly `size(range1)` ++// applications of the corresponding predicate and projections if ++// `ranges::equal(range1, range2, pred, proj, proj)` would return true; ++// otherwise, at worst `O(N^2)`, where `N` has the value `size(range1)`. ++// ++// Reference: ++// https://wg21.link/alg.is.permutation#:~:text=ranges::is_permutation(R1 ++template , ++ typename = internal::range_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>> ++constexpr bool is_permutation(Range1&& range1, ++ Range2&& range2, ++ Pred pred = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::is_permutation( ++ ranges::begin(range1), ranges::end(range1), ranges::begin(range2), ++ ranges::end(range2), std::move(pred), std::move(proj1), std::move(proj2)); ++} ++ ++// [alg.search] Search ++// Reference: https://wg21.link/alg.search ++ ++// Returns: `i`, where `i` is the first iterator in the range ++// `[first1, last1 - (last2 - first2))` such that for every non-negative integer ++// `n` less than `last2 - first2` the condition ++// `bool(invoke(pred, invoke(proj1, *(i + n)), invoke(proj2, *(first2 + n))))` ++// is `true`. ++// Returns `last1` if no such iterator exists. ++// Note: std::ranges::search(I1 first1,...) returns a range, rather than an ++// iterator. For simplicitly we match std::search's return type instead. ++// ++// Complexity: At most `(last1 - first1) * (last2 - first2)` applications of the ++// corresponding predicate and projections. ++// ++// Reference: https://wg21.link/alg.search#:~:text=ranges::search(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>> ++constexpr auto search(ForwardIterator1 first1, ++ ForwardIterator1 last1, ++ ForwardIterator2 first2, ++ ForwardIterator2 last2, ++ Pred pred = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return std::search(first1, last1, first2, last2, ++ internal::ProjectedBinaryPredicate(pred, proj1, proj2)); ++} ++ ++// Returns: `i`, where `i` is the first iterator in the range ++// `[begin(range1), end(range1) - size(range2))` such that for every ++// non-negative integer `n` less than `size(range2)` the condition ++// `bool(invoke(pred, invoke(proj1, *(i + n)), ++// invoke(proj2, *(begin(range2) + n))))` is `true`. ++// Returns `end(range1)` if no such iterator exists. ++// Note: std::ranges::search(R1&& r1,...) returns a range, rather than an ++// iterator. For simplicitly we match std::search's return type instead. ++// ++// Complexity: At most `size(range1) * size(range2)` applications of the ++// corresponding predicate and projections. ++// ++// Reference: https://wg21.link/alg.search#:~:text=ranges::search(R1 ++template , ++ typename = internal::range_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>> ++constexpr auto search(Range1&& range1, ++ Range2&& range2, ++ Pred pred = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::search(ranges::begin(range1), ranges::end(range1), ++ ranges::begin(range2), ranges::end(range2), ++ std::move(pred), std::move(proj1), std::move(proj2)); ++} ++ ++// Mandates: The type `Size` is convertible to an integral type. ++// ++// Returns: `i` where `i` is the first iterator in the range ++// `[first, last - count)` such that for every non-negative integer `n` less ++// than `count`, the following condition holds: ++// `invoke(pred, invoke(proj, *(i + n)), value)`. ++// Returns `last` if no such iterator is found. ++// Note: std::ranges::search_n(I1 first1,...) returns a range, rather than an ++// iterator. For simplicitly we match std::search_n's return type instead. ++// ++// Complexity: At most `last - first` applications of the corresponding ++// predicate and projection. ++// ++// Reference: https://wg21.link/alg.search#:~:text=ranges::search_n(I ++template > ++constexpr auto search_n(ForwardIterator first, ++ ForwardIterator last, ++ Size count, ++ const T& value, ++ Pred pred = {}, ++ Proj proj = {}) { ++ // The second arg is guaranteed to be `value`, so we'll simply apply the ++ // identity projection. ++ identity value_proj; ++ return std::search_n( ++ first, last, count, value, ++ internal::ProjectedBinaryPredicate(pred, proj, value_proj)); ++} ++ ++// Mandates: The type `Size` is convertible to an integral type. ++// ++// Returns: `i` where `i` is the first iterator in the range ++// `[begin(range), end(range) - count)` such that for every non-negative integer ++// `n` less than `count`, the following condition holds: ++// `invoke(pred, invoke(proj, *(i + n)), value)`. ++// Returns `end(arnge)` if no such iterator is found. ++// Note: std::ranges::search_n(R1&& r1,...) returns a range, rather than an ++// iterator. For simplicitly we match std::search_n's return type instead. ++// ++// Complexity: At most `size(range)` applications of the corresponding predicate ++// and projection. ++// ++// Reference: https://wg21.link/alg.search#:~:text=ranges::search_n(R ++template > ++constexpr auto search_n(Range&& range, ++ Size count, ++ const T& value, ++ Pred pred = {}, ++ Proj proj = {}) { ++ return ranges::search_n(ranges::begin(range), ranges::end(range), count, ++ value, std::move(pred), std::move(proj)); ++} ++ ++// [alg.modifying.operations] Mutating sequence operations ++// Reference: https://wg21.link/alg.modifying.operations ++ ++// [alg.copy] Copy ++// Reference: https://wg21.link/alg.copy ++ ++// Let N be `last - first`. ++// ++// Preconditions: `result` is not in the range `[first, last)`. ++// ++// Effects: Copies elements in the range `[first, last)` into the range ++// `[result, result + N)` starting from `first` and proceeding to `last`. For ++// each non-negative integer `n < N` , performs `*(result + n) = *(first + n)`. ++// ++// Returns: `result + N` ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.copy#:~:text=ranges::copy(I ++template , ++ typename = internal::iterator_category_t> ++constexpr auto copy(InputIterator first, ++ InputIterator last, ++ OutputIterator result) { ++ return std::copy(first, last, result); ++} ++ ++// Let N be `size(range)`. ++// ++// Preconditions: `result` is not in `range`. ++// ++// Effects: Copies elements in `range` into the range `[result, result + N)` ++// starting from `begin(range)` and proceeding to `end(range)`. For each ++// non-negative integer `n < N` , performs ++// *(result + n) = *(begin(range) + n)`. ++// ++// Returns: `result + N` ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.copy#:~:text=ranges::copy(R ++template , ++ typename = internal::iterator_category_t> ++constexpr auto copy(Range&& range, OutputIterator result) { ++ return ranges::copy(ranges::begin(range), ranges::end(range), result); ++} ++ ++// Let `N` be `max(0, n)`. ++// ++// Mandates: The type `Size` is convertible to an integral type. ++// ++// Effects: For each non-negative integer `i < N`, performs ++// `*(result + i) = *(first + i)`. ++// ++// Returns: `result + N` ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.copy#:~:text=ranges::copy_n ++template , ++ typename = internal::iterator_category_t> ++constexpr auto copy_n(InputIterator first, Size n, OutputIterator result) { ++ return std::copy_n(first, n, result); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`, and `N` be the number ++// of iterators `i` in the range `[first, last)` for which the condition `E(i)` ++// holds. ++// ++// Preconditions: The ranges `[first, last)` and ++// `[result, result + (last - first))` do not overlap. ++// ++// Effects: Copies all of the elements referred to by the iterator `i` in the ++// range `[first, last)` for which `E(i)` is true. ++// ++// Returns: `result + N` ++// ++// Complexity: Exactly `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Remarks: Stable. ++// ++// Reference: https://wg21.link/alg.copy#:~:text=ranges::copy_if(I ++template , ++ typename = internal::iterator_category_t> ++constexpr auto copy_if(InputIterator first, ++ InputIterator last, ++ OutputIterator result, ++ Pred pred, ++ Proj proj = {}) { ++ return std::copy_if(first, last, result, ++ internal::ProjectedUnaryPredicate(pred, proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`, and `N` be the number ++// of iterators `i` in `range` for which the condition `E(i)` holds. ++// ++// Preconditions: `range` and `[result, result + size(range))` do not overlap. ++// ++// Effects: Copies all of the elements referred to by the iterator `i` in ++// `range` for which `E(i)` is true. ++// ++// Returns: `result + N` ++// ++// Complexity: Exactly `size(range)` applications of the corresponding predicate ++// and any projection. ++// ++// Remarks: Stable. ++// ++// Reference: https://wg21.link/alg.copy#:~:text=ranges::copy_if(R ++template , ++ typename = internal::iterator_category_t> ++constexpr auto copy_if(Range&& range, ++ OutputIterator result, ++ Pred pred, ++ Proj proj = {}) { ++ return ranges::copy_if(ranges::begin(range), ranges::end(range), result, ++ std::move(pred), std::move(proj)); ++} ++ ++// Let `N` be `last - first`. ++// ++// Preconditions: `result` is not in the range `(first, last]`. ++// ++// Effects: Copies elements in the range `[first, last)` into the range ++// `[result - N, result)` starting from `last - 1` and proceeding to `first`. ++// For each positive integer `n ≤ N`, performs `*(result - n) = *(last - n)`. ++// ++// Returns: `result - N` ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.copy#:~:text=ranges::copy_backward(I1 ++template , ++ typename = internal::iterator_category_t> ++constexpr auto copy_backward(BidirectionalIterator1 first, ++ BidirectionalIterator1 last, ++ BidirectionalIterator2 result) { ++ return std::copy_backward(first, last, result); ++} ++ ++// Let `N` be `size(range)`. ++// ++// Preconditions: `result` is not in the range `(begin(range), end(range)]`. ++// ++// Effects: Copies elements in `range` into the range `[result - N, result)` ++// starting from `end(range) - 1` and proceeding to `begin(range)`. For each ++// positive integer `n ≤ N`, performs `*(result - n) = *(end(range) - n)`. ++// ++// Returns: `result - N` ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.copy#:~:text=ranges::copy_backward(R ++template , ++ typename = internal::iterator_category_t> ++constexpr auto copy_backward(Range&& range, BidirectionalIterator result) { ++ return ranges::copy_backward(ranges::begin(range), ranges::end(range), ++ result); ++} ++ ++// [alg.move] Move ++// Reference: https://wg21.link/alg.move ++ ++// Let `E(n)` be `std::move(*(first + n))`. ++// ++// Let `N` be `last - first`. ++// ++// Preconditions: `result` is not in the range `[first, last)`. ++// ++// Effects: Moves elements in the range `[first, last)` into the range `[result, ++// result + N)` starting from `first` and proceeding to `last`. For each ++// non-negative integer `n < N`, performs `*(result + n) = E(n)`. ++// ++// Returns: `result + N` ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.move#:~:text=ranges::move(I ++template , ++ typename = internal::iterator_category_t> ++constexpr auto move(InputIterator first, ++ InputIterator last, ++ OutputIterator result) { ++ return std::move(first, last, result); ++} ++ ++// Let `E(n)` be `std::move(*(begin(range) + n))`. ++// ++// Let `N` be `size(range)`. ++// ++// Preconditions: `result` is not in `range`. ++// ++// Effects: Moves elements in `range` into the range `[result, result + N)` ++// starting from `begin(range)` and proceeding to `end(range)`. For each ++// non-negative integer `n < N`, performs `*(result + n) = E(n)`. ++// ++// Returns: `result + N` ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.move#:~:text=ranges::move(R ++template , ++ typename = internal::iterator_category_t> ++constexpr auto move(Range&& range, OutputIterator result) { ++ return ranges::move(ranges::begin(range), ranges::end(range), result); ++} ++ ++// Let `E(n)` be `std::move(*(last - n))`. ++// ++// Let `N` be `last - first`. ++// ++// Preconditions: `result` is not in the range `(first, last]`. ++// ++// Effects: Moves elements in the range `[first, last)` into the range ++// `[result - N, result)` starting from `last - 1` and proceeding to `first`. ++// For each positive integer `n ≤ N`, performs `*(result - n) = E(n)`. ++// ++// Returns: `result - N` ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.move#:~:text=ranges::move_backward(I1 ++template , ++ typename = internal::iterator_category_t> ++constexpr auto move_backward(BidirectionalIterator1 first, ++ BidirectionalIterator1 last, ++ BidirectionalIterator2 result) { ++ return std::move_backward(first, last, result); ++} ++ ++// Let `E(n)` be `std::move(*(end(range) - n))`. ++// ++// Let `N` be `size(range)`. ++// ++// Preconditions: `result` is not in the range `(begin(range), end(range)]`. ++// ++// Effects: Moves elements in `range` into the range `[result - N, result)` ++// starting from `end(range) - 1` and proceeding to `begin(range)`. For each ++// positive integer `n ≤ N`, performs `*(result - n) = E(n)`. ++// ++// Returns: `result - N` ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.move#:~:text=ranges::move_backward(R ++template , ++ typename = internal::iterator_category_t> ++constexpr auto move_backward(Range&& range, BidirectionalIterator result) { ++ return ranges::move_backward(ranges::begin(range), ranges::end(range), ++ result); ++} ++ ++// [alg.swap] Swap ++// Reference: https://wg21.link/alg.swap ++ ++// Let `M` be `min(last1 - first1, last2 - first2)`. ++// ++// Preconditions: The two ranges `[first1, last1)` and `[first2, last2)` do not ++// overlap. `*(first1 + n)` is swappable with `*(first2 + n)`. ++// ++// Effects: For each non-negative integer `n < M` performs ++// `swap(*(first1 + n), *(first2 + n))` ++// ++// Returns: `first2 + M` ++// ++// Complexity: Exactly `M` swaps. ++// ++// Reference: https://wg21.link/alg.swap#:~:text=ranges::swap_ranges(I1 ++template , ++ typename = internal::iterator_category_t> ++constexpr auto swap_ranges(ForwardIterator1 first1, ++ ForwardIterator1 last1, ++ ForwardIterator2 first2, ++ ForwardIterator2 last2) { ++ // std::swap_ranges does not have a `last2` overload. Thus we need to ++ // adjust `last1` to ensure to not read past `last2`. ++ last1 = std::next(first1, std::min(std::distance(first1, last1), ++ std::distance(first2, last2))); ++ return std::swap_ranges(first1, last1, first2); ++} ++ ++// Let `M` be `min(size(range1), size(range2))`. ++// ++// Preconditions: The two ranges `range1` and `range2` do not overlap. ++// `*(begin(range1) + n)` is swappable with `*(begin(range2) + n)`. ++// ++// Effects: For each non-negative integer `n < M` performs ++// `swap(*(begin(range1) + n), *(begin(range2) + n))` ++// ++// Returns: `begin(range2) + M` ++// ++// Complexity: Exactly `M` swaps. ++// ++// Reference: https://wg21.link/alg.swap#:~:text=ranges::swap_ranges(R1 ++template , ++ typename = internal::range_category_t> ++constexpr auto swap_ranges(Range1&& range1, Range2&& range2) { ++ return ranges::swap_ranges(ranges::begin(range1), ranges::end(range1), ++ ranges::begin(range2), ranges::end(range2)); ++} ++ ++// [alg.transform] Transform ++// Reference: https://wg21.link/alg.transform ++ ++// Let `N` be `last1 - first1`, ++// `E(i)` be `invoke(op, invoke(proj, *(first1 + (i - result))))`. ++// ++// Preconditions: `op` does not invalidate iterators or subranges, nor modify ++// elements in the ranges `[first1, first1 + N]`, and `[result, result + N]`. ++// ++// Effects: Assigns through every iterator `i` in the range ++// `[result, result + N)` a new corresponding value equal to `E(i)`. ++// ++// Returns: `result + N` ++// ++// Complexity: Exactly `N` applications of `op` and any projections. ++// ++// Remarks: result may be equal to `first1`. ++// ++// Reference: https://wg21.link/alg.transform#:~:text=ranges::transform(I ++template , ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t>> ++constexpr auto transform(InputIterator first1, ++ InputIterator last1, ++ OutputIterator result, ++ UnaryOperation op, ++ Proj proj = {}) { ++ return std::transform(first1, last1, result, [&op, &proj](auto&& arg) { ++ return base::invoke(op, ++ base::invoke(proj, std::forward(arg))); ++ }); ++} ++ ++// Let `N` be `size(range)`, ++// `E(i)` be `invoke(op, invoke(proj, *(begin(range) + (i - result))))`. ++// ++// Preconditions: `op` does not invalidate iterators or subranges, nor modify ++// elements in the ranges `[begin(range), end(range)]`, and ++// `[result, result + N]`. ++// ++// Effects: Assigns through every iterator `i` in the range ++// `[result, result + N)` a new corresponding value equal to `E(i)`. ++// ++// Returns: `result + N` ++// ++// Complexity: Exactly `N` applications of `op` and any projections. ++// ++// Remarks: result may be equal to `begin(range)`. ++// ++// Reference: https://wg21.link/alg.transform#:~:text=ranges::transform(R ++template , ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, Proj>>> ++constexpr auto transform(Range&& range, ++ OutputIterator result, ++ UnaryOperation op, ++ Proj proj = {}) { ++ return ranges::transform(ranges::begin(range), ranges::end(range), result, ++ std::move(op), std::move(proj)); ++} ++ ++// Let: ++// `N` be `min(last1 - first1, last2 - first2)`, ++// `E(i)` be `invoke(binary_op, invoke(proj1, *(first1 + (i - result))), ++// invoke(proj2, *(first2 + (i - result))))`. ++// ++// Preconditions: `binary_op` does not invalidate iterators or subranges, nor ++// modify elements in the ranges `[first1, first1 + N]`, `[first2, first2 + N]`, ++// and `[result, result + N]`. ++// ++// Effects: Assigns through every iterator `i` in the range ++// `[result, result + N)` a new corresponding value equal to `E(i)`. ++// ++// Returns: `result + N` ++// ++// Complexity: Exactly `N` applications of `binary_op`, and any projections. ++// ++// Remarks: `result` may be equal to `first1` or `first2`. ++// ++// Reference: https://wg21.link/alg.transform#:~:text=ranges::transform(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>> ++constexpr auto transform(ForwardIterator1 first1, ++ ForwardIterator1 last1, ++ ForwardIterator2 first2, ++ ForwardIterator2 last2, ++ OutputIterator result, ++ BinaryOperation binary_op, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ // std::transform does not have a `last2` overload. Thus we need to adjust ++ // `last1` to ensure to not read past `last2`. ++ last1 = std::next(first1, std::min(std::distance(first1, last1), ++ std::distance(first2, last2))); ++ return std::transform( ++ first1, last1, first2, result, ++ [&binary_op, &proj1, &proj2](auto&& lhs, auto&& rhs) { ++ return base::invoke( ++ binary_op, base::invoke(proj1, std::forward(lhs)), ++ base::invoke(proj2, std::forward(rhs))); ++ }); ++} ++ ++// Let: ++// `N` be `min(size(range1), size(range2)`, ++// `E(i)` be `invoke(binary_op, invoke(proj1, *(begin(range1) + (i - result))), ++// invoke(proj2, *(begin(range2) + (i - result))))` ++// ++// Preconditions: `binary_op` does not invalidate iterators or subranges, nor ++// modify elements in the ranges `[begin(range1), end(range1)]`, ++// `[begin(range2), end(range2)]`, and `[result, result + N]`. ++// ++// Effects: Assigns through every iterator `i` in the range ++// `[result, result + N)` a new corresponding value equal to `E(i)`. ++// ++// Returns: `result + N` ++// ++// Complexity: Exactly `N` applications of `binary_op`, and any projections. ++// ++// Remarks: `result` may be equal to `begin(range1)` or `begin(range2)`. ++// ++// Reference: https://wg21.link/alg.transform#:~:text=ranges::transform(R1 ++template , ++ typename = internal::range_category_t, ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>> ++constexpr auto transform(Range1&& range1, ++ Range2&& range2, ++ OutputIterator result, ++ BinaryOperation binary_op, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::transform(ranges::begin(range1), ranges::end(range1), ++ ranges::begin(range2), ranges::end(range2), result, ++ std::move(binary_op), std::move(proj1), ++ std::move(proj2)); ++} ++ ++// [alg.replace] Replace ++// Reference: https://wg21.link/alg.replace ++ ++// Let `E(i)` be `bool(invoke(proj, *i) == old_value)`. ++// ++// Mandates: `new_value` is writable to `first`. ++// ++// Effects: Substitutes elements referred by the iterator `i` in the range ++// `[first, last)` with `new_value`, when `E(i)` is true. ++// ++// Returns: `last` ++// ++// Complexity: Exactly `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.replace#:~:text=ranges::replace(I ++template > ++constexpr auto replace(ForwardIterator first, ++ ForwardIterator last, ++ const T& old_value, ++ const T& new_value, ++ Proj proj = {}) { ++ // Note: In order to be able to apply `proj` to each element in [first, last) ++ // we are dispatching to std::replace_if instead of std::replace. ++ std::replace_if( ++ first, last, ++ [&proj, &old_value](auto&& lhs) { ++ return base::invoke(proj, std::forward(lhs)) == ++ old_value; ++ }, ++ new_value); ++ return last; ++} ++ ++// Let `E(i)` be `bool(invoke(proj, *i) == old_value)`. ++// ++// Mandates: `new_value` is writable to `begin(range)`. ++// ++// Effects: Substitutes elements referred by the iterator `i` in `range` with ++// `new_value`, when `E(i)` is true. ++// ++// Returns: `end(range)` ++// ++// Complexity: Exactly `size(range)` applications of the corresponding predicate ++// and any projection. ++// ++// Reference: https://wg21.link/alg.replace#:~:text=ranges::replace(R ++template > ++constexpr auto replace(Range&& range, ++ const T& old_value, ++ const T& new_value, ++ Proj proj = {}) { ++ return ranges::replace(ranges::begin(range), ranges::end(range), old_value, ++ new_value, std::move(proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`. ++// ++// Mandates: `new_value` is writable to `first`. ++// ++// Effects: Substitutes elements referred by the iterator `i` in the range ++// `[first, last)` with `new_value`, when `E(i)` is true. ++// ++// Returns: `last` ++// ++// Complexity: Exactly `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.replace#:~:text=ranges::replace_if(I ++template > ++constexpr auto replace_if(ForwardIterator first, ++ ForwardIterator last, ++ Predicate pred, ++ const T& new_value, ++ Proj proj = {}) { ++ std::replace_if(first, last, internal::ProjectedUnaryPredicate(pred, proj), ++ new_value); ++ return last; ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`. ++// ++// Mandates: `new_value` is writable to `begin(range)`. ++// ++// Effects: Substitutes elements referred by the iterator `i` in `range` with ++// `new_value`, when `E(i)` is true. ++// ++// Returns: `end(range)` ++// ++// Complexity: Exactly `size(range)` applications of the corresponding predicate ++// and any projection. ++// ++// Reference: https://wg21.link/alg.replace#:~:text=ranges::replace_if(R ++template > ++constexpr auto replace_if(Range&& range, ++ Predicate pred, ++ const T& new_value, ++ Proj proj = {}) { ++ return ranges::replace_if(ranges::begin(range), ranges::end(range), ++ std::move(pred), new_value, std::move(proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(proj, *(first + (i - result))) == old_value)`. ++// ++// Mandates: The results of the expressions `*first` and `new_value` are ++// writable to `result`. ++// ++// Preconditions: The ranges `[first, last)` and `[result, result + (last - ++// first))` do not overlap. ++// ++// Effects: Assigns through every iterator `i` in the range `[result, result + ++// (last - first))` a new corresponding value, `new_value` if `E(i)` is true, or ++// `*(first + (i - result))` otherwise. ++// ++// Returns: `result + (last - first)`. ++// ++// Complexity: Exactly `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.replace#:~:text=ranges::replace_copy(I ++template , ++ typename = internal::iterator_category_t> ++constexpr auto replace_copy(InputIterator first, ++ InputIterator last, ++ OutputIterator result, ++ const T& old_value, ++ const T& new_value, ++ Proj proj = {}) { ++ // Note: In order to be able to apply `proj` to each element in [first, last) ++ // we are dispatching to std::replace_copy_if instead of std::replace_copy. ++ std::replace_copy_if( ++ first, last, result, ++ [&proj, &old_value](auto&& lhs) { ++ return base::invoke(proj, std::forward(lhs)) == ++ old_value; ++ }, ++ new_value); ++ return last; ++} ++ ++// Let `E(i)` be ++// `bool(invoke(proj, *(begin(range) + (i - result))) == old_value)`. ++// ++// Mandates: The results of the expressions `*begin(range)` and `new_value` are ++// writable to `result`. ++// ++// Preconditions: The ranges `range` and `[result, result + size(range))` do not ++// overlap. ++// ++// Effects: Assigns through every iterator `i` in the range `[result, result + ++// size(range))` a new corresponding value, `new_value` if `E(i)` is true, or ++// `*(begin(range) + (i - result))` otherwise. ++// ++// Returns: `result + size(range)`. ++// ++// Complexity: Exactly `size(range)` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.replace#:~:text=ranges::replace_copy(R ++template , ++ typename = internal::iterator_category_t> ++constexpr auto replace_copy(Range&& range, ++ OutputIterator result, ++ const T& old_value, ++ const T& new_value, ++ Proj proj = {}) { ++ return ranges::replace_copy(ranges::begin(range), ranges::end(range), result, ++ old_value, new_value, std::move(proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *(first + (i - result)))))`. ++// ++// Mandates: The results of the expressions `*first` and `new_value` are ++// writable to `result`. ++// ++// Preconditions: The ranges `[first, last)` and `[result, result + (last - ++// first))` do not overlap. ++// ++// Effects: Assigns through every iterator `i` in the range `[result, result + ++// (last - first))` a new corresponding value, `new_value` if `E(i)` is true, or ++// `*(first + (i - result))` otherwise. ++// ++// Returns: `result + (last - first)`. ++// ++// Complexity: Exactly `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.replace#:~:text=ranges::replace_copy_if(I ++template , ++ typename = internal::iterator_category_t> ++constexpr auto replace_copy_if(InputIterator first, ++ InputIterator last, ++ OutputIterator result, ++ Predicate pred, ++ const T& new_value, ++ Proj proj = {}) { ++ return std::replace_copy_if(first, last, result, ++ internal::ProjectedUnaryPredicate(pred, proj), ++ new_value); ++} ++ ++// Let `E(i)` be ++// `bool(invoke(pred, invoke(proj, *(begin(range) + (i - result)))))`. ++// ++// Mandates: The results of the expressions `*begin(range)` and `new_value` are ++// writable to `result`. ++// ++// Preconditions: The ranges `range` and `[result, result + size(range))` do not ++// overlap. ++// ++// Effects: Assigns through every iterator `i` in the range `[result, result + ++// size(range))` a new corresponding value, `new_value` if `E(i)` is true, or ++// `*(begin(range) + (i - result))` otherwise. ++// ++// Returns: `result + size(range)`. ++// ++// Complexity: Exactly `size(range)` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.replace#:~:text=ranges::replace_copy_if(R ++template , ++ typename = internal::iterator_category_t> ++constexpr auto replace_copy_if(Range&& range, ++ OutputIterator result, ++ Predicate pred, ++ const T& new_value, ++ Proj proj = {}) { ++ return ranges::replace_copy_if(ranges::begin(range), ranges::end(range), ++ result, pred, new_value, std::move(proj)); ++} ++ ++// [alg.fill] Fill ++// Reference: https://wg21.link/alg.fill ++ ++// Let `N` be `last - first`. ++// ++// Mandates: The expression `value` is writable to the output iterator. ++// ++// Effects: Assigns `value` through all the iterators in the range ++// `[first, last)`. ++// ++// Returns: `last`. ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.fill#:~:text=ranges::fill(O ++template > ++constexpr auto fill(OutputIterator first, OutputIterator last, const T& value) { ++ std::fill(first, last, value); ++ return last; ++} ++ ++// Let `N` be `size(range)`. ++// ++// Mandates: The expression `value` is writable to the output iterator. ++// ++// Effects: Assigns `value` through all the iterators in `range`. ++// ++// Returns: `end(range)`. ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.fill#:~:text=ranges::fill(R ++template > ++constexpr auto fill(Range&& range, const T& value) { ++ return ranges::fill(ranges::begin(range), ranges::end(range), value); ++} ++ ++// Let `N` be `max(0, n)`. ++// ++// Mandates: The expression `value` is writable to the output iterator. ++// The type `Size` is convertible to an integral type. ++// ++// Effects: Assigns `value` through all the iterators in `[first, first + N)`. ++// ++// Returns: `first + N`. ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.fill#:~:text=ranges::fill_n(O ++template > ++constexpr auto fill_n(OutputIterator first, Size n, const T& value) { ++ return std::fill_n(first, n, value); ++} ++ ++// [alg.generate] Generate ++// Reference: https://wg21.link/alg.generate ++ ++// Let `N` be `last - first`. ++// ++// Effects: Assigns the result of successive evaluations of gen() through each ++// iterator in the range `[first, last)`. ++// ++// Returns: `last`. ++// ++// Complexity: Exactly `N` evaluations of `gen()` and assignments. ++// ++// Reference: https://wg21.link/alg.generate#:~:text=ranges::generate(O ++template > ++constexpr auto generate(OutputIterator first, ++ OutputIterator last, ++ Generator gen) { ++ std::generate(first, last, std::move(gen)); ++ return last; ++} ++ ++// Let `N` be `size(range)`. ++// ++// Effects: Assigns the result of successive evaluations of gen() through each ++// iterator in `range`. ++// ++// Returns: `end(range)`. ++// ++// Complexity: Exactly `N` evaluations of `gen()` and assignments. ++// ++// Reference: https://wg21.link/alg.generate#:~:text=ranges::generate(R ++template > ++constexpr auto generate(Range&& range, Generator gen) { ++ return ranges::generate(ranges::begin(range), ranges::end(range), ++ std::move(gen)); ++} ++ ++// Let `N` be `max(0, n)`. ++// ++// Mandates: `Size` is convertible to an integral type. ++// ++// Effects: Assigns the result of successive evaluations of gen() through each ++// iterator in the range `[first, first + N)`. ++// ++// Returns: `first + N`. ++// ++// Complexity: Exactly `N` evaluations of `gen()` and assignments. ++// ++// Reference: https://wg21.link/alg.generate#:~:text=ranges::generate_n(O ++template > ++constexpr auto generate_n(OutputIterator first, Size n, Generator gen) { ++ return std::generate_n(first, n, std::move(gen)); ++} ++ ++// [alg.remove] Remove ++// Reference: https://wg21.link/alg.remove ++ ++// Let `E(i)` be `bool(invoke(proj, *i) == value)`. ++// ++// Effects: Eliminates all the elements referred to by iterator `i` in the range ++// `[first, last)` for which `E(i)` holds. ++// ++// Returns: The end of the resulting range. ++// ++// Remarks: Stable. ++// ++// Complexity: Exactly `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.remove#:~:text=ranges::remove(I ++template > ++constexpr auto remove(ForwardIterator first, ++ ForwardIterator last, ++ const T& value, ++ Proj proj = {}) { ++ // Note: In order to be able to apply `proj` to each element in [first, last) ++ // we are dispatching to std::remove_if instead of std::remove. ++ return std::remove_if(first, last, [&proj, &value](auto&& lhs) { ++ return base::invoke(proj, std::forward(lhs)) == value; ++ }); ++} ++ ++// Let `E(i)` be `bool(invoke(proj, *i) == value)`. ++// ++// Effects: Eliminates all the elements referred to by iterator `i` in `range` ++// for which `E(i)` holds. ++// ++// Returns: The end of the resulting range. ++// ++// Remarks: Stable. ++// ++// Complexity: Exactly `size(range)` applications of the corresponding predicate ++// and any projection. ++// ++// Reference: https://wg21.link/alg.remove#:~:text=ranges::remove(R ++template > ++constexpr auto remove(Range&& range, const T& value, Proj proj = {}) { ++ return ranges::remove(ranges::begin(range), ranges::end(range), value, ++ std::move(proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`. ++// ++// Effects: Eliminates all the elements referred to by iterator `i` in the range ++// `[first, last)` for which `E(i)` holds. ++// ++// Returns: The end of the resulting range. ++// ++// Remarks: Stable. ++// ++// Complexity: Exactly `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Reference: https://wg21.link/alg.remove#:~:text=ranges::remove_if(I ++template > ++constexpr auto remove_if(ForwardIterator first, ++ ForwardIterator last, ++ Predicate pred, ++ Proj proj = {}) { ++ return std::remove_if(first, last, ++ internal::ProjectedUnaryPredicate(pred, proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`. ++// ++// Effects: Eliminates all the elements referred to by iterator `i` in `range`. ++// ++// Returns: The end of the resulting range. ++// ++// Remarks: Stable. ++// ++// Complexity: Exactly `size(range)` applications of the corresponding predicate ++// and any projection. ++// ++// Reference: https://wg21.link/alg.remove#:~:text=ranges::remove_if(R ++template > ++constexpr auto remove_if(Range&& range, Predicate pred, Proj proj = {}) { ++ return ranges::remove_if(ranges::begin(range), ranges::end(range), ++ std::move(pred), std::move(proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(proj, *i) == value)`. ++// ++// Let `N` be the number of elements in `[first, last)` for which `E(i)` is ++// false. ++// ++// Mandates: `*first` is writable to `result`. ++// ++// Preconditions: The ranges `[first, last)` and `[result, result + (last - ++// first))` do not overlap. ++// ++// Effects: Copies all the elements referred to by the iterator `i` in the range ++// `[first, last)` for which `E(i)` is false. ++// ++// Returns: `result + N`. ++// ++// Complexity: Exactly `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Remarks: Stable. ++// ++// Reference: https://wg21.link/alg.remove#:~:text=ranges::remove_copy(I ++template , ++ typename = internal::iterator_category_t> ++constexpr auto remove_copy(InputIterator first, ++ InputIterator last, ++ OutputIterator result, ++ const T& value, ++ Proj proj = {}) { ++ // Note: In order to be able to apply `proj` to each element in [first, last) ++ // we are dispatching to std::remove_copy_if instead of std::remove_copy. ++ return std::remove_copy_if(first, last, result, [&proj, &value](auto&& lhs) { ++ return base::invoke(proj, std::forward(lhs)) == value; ++ }); ++} ++ ++// Let `E(i)` be `bool(invoke(proj, *i) == value)`. ++// ++// Let `N` be the number of elements in `range` for which `E(i)` is false. ++// ++// Mandates: `*begin(range)` is writable to `result`. ++// ++// Preconditions: The ranges `range` and `[result, result + size(range))` do not ++// overlap. ++// ++// Effects: Copies all the elements referred to by the iterator `i` in `range` ++// for which `E(i)` is false. ++// ++// Returns: `result + N`. ++// ++// Complexity: Exactly `size(range)` applications of the corresponding ++// predicate and any projection. ++// ++// Remarks: Stable. ++// ++// Reference: https://wg21.link/alg.remove#:~:text=ranges::remove_copy(R ++template , ++ typename = internal::iterator_category_t> ++constexpr auto remove_copy(Range&& range, ++ OutputIterator result, ++ const T& value, ++ Proj proj = {}) { ++ return ranges::remove_copy(ranges::begin(range), ranges::end(range), result, ++ value, std::move(proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`. ++// ++// Let `N` be the number of elements in `[first, last)` for which `E(i)` is ++// false. ++// ++// Mandates: `*first` is writable to `result`. ++// ++// Preconditions: The ranges `[first, last)` and `[result, result + (last - ++// first))` do not overlap. ++// ++// Effects: Copies all the elements referred to by the iterator `i` in the range ++// `[first, last)` for which `E(i)` is false. ++// ++// Returns: `result + N`. ++// ++// Complexity: Exactly `last - first` applications of the corresponding ++// predicate and any projection. ++// ++// Remarks: Stable. ++// ++// Reference: https://wg21.link/alg.remove#:~:text=ranges::remove_copy_if(I ++template , ++ typename = internal::iterator_category_t> ++constexpr auto remove_copy_if(InputIterator first, ++ InputIterator last, ++ OutputIterator result, ++ Pred pred, ++ Proj proj = {}) { ++ return std::remove_copy_if(first, last, result, ++ internal::ProjectedUnaryPredicate(pred, proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(pred, invoke(proj, *i)))`. ++// ++// Let `N` be the number of elements in `range` for which `E(i)` is false. ++// ++// Mandates: `*begin(range)` is writable to `result`. ++// ++// Preconditions: The ranges `range` and `[result, result + size(range))` do not ++// overlap. ++// ++// Effects: Copies all the elements referred to by the iterator `i` in `range` ++// for which `E(i)` is false. ++// ++// Returns: `result + N`. ++// ++// Complexity: Exactly `size(range)` applications of the corresponding ++// predicate and any projection. ++// ++// Remarks: Stable. ++// ++// Reference: https://wg21.link/alg.remove#:~:text=ranges::remove_copy(R ++template , ++ typename = internal::iterator_category_t> ++constexpr auto remove_copy_if(Range&& range, ++ OutputIterator result, ++ Pred pred, ++ Proj proj = {}) { ++ return ranges::remove_copy_if(ranges::begin(range), ranges::end(range), ++ result, std::move(pred), std::move(proj)); ++} ++ ++// [alg.unique] Unique ++// Reference: https://wg21.link/alg.unique ++ ++// Let `E(i)` be `bool(invoke(comp, invoke(proj, *(i - 1)), invoke(proj, *i)))`. ++// ++// Effects: For a nonempty range, eliminates all but the first element from ++// every consecutive group of equivalent elements referred to by the iterator ++// `i` in the range `[first + 1, last)` for which `E(i)` is true. ++// ++// Returns: The end of the resulting range. ++// ++// Complexity: For nonempty ranges, exactly `(last - first) - 1` applications of ++// the corresponding predicate and no more than twice as many applications of ++// any projection. ++// ++// Reference: https://wg21.link/alg.unique#:~:text=ranges::unique(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto unique(ForwardIterator first, ++ ForwardIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return std::unique(first, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(comp, invoke(proj, *(i - 1)), invoke(proj, *i)))`. ++// ++// Effects: For a nonempty range, eliminates all but the first element from ++// every consecutive group of equivalent elements referred to by the iterator ++// `i` in the range `[begin(range) + 1, end(range))` for which `E(i)` is true. ++// ++// Returns: The end of the resulting range. ++// ++// Complexity: For nonempty ranges, exactly `size(range) - 1` applications of ++// the corresponding predicate and no more than twice as many applications of ++// any projection. ++// ++// Reference: https://wg21.link/alg.unique#:~:text=ranges::unique(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto unique(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::unique(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(comp, invoke(proj, *i), invoke(proj, *(i - 1))))`. ++// ++// Mandates: `*first` is writable to `result`. ++// ++// Preconditions: The ranges `[first, last)` and ++// `[result, result + (last - first))` do not overlap. ++// ++// Effects: Copies only the first element from every consecutive group of equal ++// elements referred to by the iterator `i` in the range `[first, last)` for ++// which `E(i)` holds. ++// ++// Returns: `result + N`. ++// ++// Complexity: Exactly `last - first - 1` applications of the corresponding ++// predicate and no more than twice as many applications of any projection. ++// ++// Reference: https://wg21.link/alg.unique#:~:text=ranges::unique_copy(I ++template , ++ typename = internal::iterator_category_t> ++constexpr auto unique_copy(ForwardIterator first, ++ ForwardIterator last, ++ OutputIterator result, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return std::unique_copy(first, last, result, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Let `E(i)` be `bool(invoke(comp, invoke(proj, *i), invoke(proj, *(i - 1))))`. ++// ++// Mandates: `*begin(range)` is writable to `result`. ++// ++// Preconditions: The ranges `range` and `[result, result + size(range))` do not ++// overlap. ++// ++// Effects: Copies only the first element from every consecutive group of equal ++// elements referred to by the iterator `i` in `range` for which `E(i)` holds. ++// ++// Returns: `result + N`. ++// ++// Complexity: Exactly `size(range) - 1` applications of the corresponding ++// predicate and no more than twice as many applications of any projection. ++// ++// Reference: https://wg21.link/alg.unique#:~:text=ranges::unique_copy(R ++template , ++ typename = internal::iterator_category_t> ++constexpr auto unique_copy(Range&& range, ++ OutputIterator result, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return ranges::unique_copy(ranges::begin(range), ranges::end(range), result, ++ std::move(comp), std::move(proj)); ++} ++ ++// [alg.reverse] Reverse ++// Reference: https://wg21.link/alg.reverse ++ ++// Effects: For each non-negative integer `i < (last - first) / 2`, applies ++// `std::iter_swap` to all pairs of iterators `first + i, (last - i) - 1`. ++// ++// Returns: `last`. ++// ++// Complexity: Exactly `(last - first)/2` swaps. ++// ++// Reference: https://wg21.link/alg.reverse#:~:text=ranges::reverse(I ++template > ++constexpr auto reverse(BidirectionalIterator first, ++ BidirectionalIterator last) { ++ std::reverse(first, last); ++ return last; ++} ++ ++// Effects: For each non-negative integer `i < size(range) / 2`, applies ++// `std::iter_swap` to all pairs of iterators ++// `begin(range) + i, (end(range) - i) - 1`. ++// ++// Returns: `end(range)`. ++// ++// Complexity: Exactly `size(range)/2` swaps. ++// ++// Reference: https://wg21.link/alg.reverse#:~:text=ranges::reverse(R ++template > ++constexpr auto reverse(Range&& range) { ++ return ranges::reverse(ranges::begin(range), ranges::end(range)); ++} ++ ++// Let `N` be `last - first`. ++// ++// Preconditions: The ranges `[first, last)` and `[result, result + N)` do not ++// overlap. ++// ++// Effects: Copies the range `[first, last)` to the range `[result, result + N)` ++// such that for every non-negative integer `i < N` the following assignment ++// takes place: `*(result + N - 1 - i) = *(first + i)`. ++// ++// Returns: `result + N`. ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.reverse#:~:text=ranges::reverse_copy(I ++template , ++ typename = internal::iterator_category_t> ++constexpr auto reverse_copy(BidirectionalIterator first, ++ BidirectionalIterator last, ++ OutputIterator result) { ++ return std::reverse_copy(first, last, result); ++} ++ ++// Let `N` be `size(range)`. ++// ++// Preconditions: The ranges `range` and `[result, result + N)` do not ++// overlap. ++// ++// Effects: Copies `range` to the range `[result, result + N)` such that for ++// every non-negative integer `i < N` the following assignment takes place: ++// `*(result + N - 1 - i) = *(begin(range) + i)`. ++// ++// Returns: `result + N`. ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.reverse#:~:text=ranges::reverse_copy(R ++template , ++ typename = internal::iterator_category_t> ++constexpr auto reverse_copy(Range&& range, OutputIterator result) { ++ return ranges::reverse_copy(ranges::begin(range), ranges::end(range), result); ++} ++ ++// [alg.rotate] Rotate ++// Reference: https://wg21.link/alg.rotate ++ ++// Preconditions: `[first, middle)` and `[middle, last)` are valid ranges. ++// ++// Effects: For each non-negative integer `i < (last - first)`, places the ++// element from the position `first + i` into position ++// `first + (i + (last - middle)) % (last - first)`. ++// ++// Returns: `first + (last - middle)`. ++// ++// Complexity: At most `last - first` swaps. ++// ++// Reference: https://wg21.link/alg.rotate#:~:text=ranges::rotate(I ++template > ++constexpr auto rotate(ForwardIterator first, ++ ForwardIterator middle, ++ ForwardIterator last) { ++ return std::rotate(first, middle, last); ++} ++ ++// Preconditions: `[begin(range), middle)` and `[middle, end(range))` are valid ++// ranges. ++// ++// Effects: For each non-negative integer `i < size(range)`, places the element ++// from the position `begin(range) + i` into position ++// `begin(range) + (i + (end(range) - middle)) % size(range)`. ++// ++// Returns: `begin(range) + (end(range) - middle)`. ++// ++// Complexity: At most `size(range)` swaps. ++// ++// Reference: https://wg21.link/alg.rotate#:~:text=ranges::rotate(R ++template > ++constexpr auto rotate(Range&& range, iterator_t middle) { ++ return ranges::rotate(ranges::begin(range), middle, ranges::end(range)); ++} ++ ++// Let `N` be `last - first`. ++// ++// Preconditions: `[first, middle)` and `[middle, last)` are valid ranges. The ++// ranges `[first, last)` and `[result, result + N)` do not overlap. ++// ++// Effects: Copies the range `[first, last)` to the range `[result, result + N)` ++// such that for each non-negative integer `i < N` the following assignment ++// takes place: `*(result + i) = *(first + (i + (middle - first)) % N)`. ++// ++// Returns: `result + N`. ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.rotate#:~:text=ranges::rotate_copy(I ++template , ++ typename = internal::iterator_category_t> ++constexpr auto rotate_copy(ForwardIterator first, ++ ForwardIterator middle, ++ ForwardIterator last, ++ OutputIterator result) { ++ return std::rotate_copy(first, middle, last, result); ++} ++ ++// Let `N` be `size(range)`. ++// ++// Preconditions: `[begin(range), middle)` and `[middle, end(range))` are valid ++// ranges. The ranges `range` and `[result, result + N)` do not overlap. ++// ++// Effects: Copies `range` to the range `[result, result + N)` such that for ++// each non-negative integer `i < N` the following assignment takes place: ++// `*(result + i) = *(begin(range) + (i + (middle - begin(range))) % N)`. ++// ++// Returns: `result + N`. ++// ++// Complexity: Exactly `N` assignments. ++// ++// Reference: https://wg21.link/alg.rotate#:~:text=ranges::rotate_copy(R ++template , ++ typename = internal::iterator_category_t> ++constexpr auto rotate_copy(Range&& range, ++ iterator_t middle, ++ OutputIterator result) { ++ return ranges::rotate_copy(ranges::begin(range), middle, ranges::end(range), ++ result); ++} ++ ++// [alg.random.sample] Sample ++// Reference: https://wg21.link/alg.random.sample ++ ++// Currently not implemented due to lack of std::sample in C++14. ++// TODO(crbug.com/1071094): Consider implementing a hand-rolled version. ++ ++// [alg.random.shuffle] Shuffle ++// Reference: https://wg21.link/alg.random.shuffle ++ ++// Preconditions: The type `std::remove_reference_t` ++// meets the uniform random bit generator requirements. ++// ++// Effects: Permutes the elements in the range `[first, last)` such that each ++// possible permutation of those elements has equal probability of appearance. ++// ++// Returns: `last`. ++// ++// Complexity: Exactly `(last - first) - 1` swaps. ++// ++// Remarks: To the extent that the implementation of this function makes use of ++// random numbers, the object referenced by g shall serve as the ++// implementation's source of randomness. ++// ++// Reference: https://wg21.link/alg.random.shuffle#:~:text=ranges::shuffle(I ++template > ++constexpr auto shuffle(RandomAccessIterator first, ++ RandomAccessIterator last, ++ UniformRandomBitGenerator&& g) { ++ std::shuffle(first, last, std::forward(g)); ++ return last; ++} ++ ++// Preconditions: The type `std::remove_reference_t` ++// meets the uniform random bit generator requirements. ++// ++// Effects: Permutes the elements in `range` such that each possible permutation ++// of those elements has equal probability of appearance. ++// ++// Returns: `end(range)`. ++// ++// Complexity: Exactly `size(range) - 1` swaps. ++// ++// Remarks: To the extent that the implementation of this function makes use of ++// random numbers, the object referenced by g shall serve as the ++// implementation's source of randomness. ++// ++// Reference: https://wg21.link/alg.random.shuffle#:~:text=ranges::shuffle(R ++template > ++constexpr auto shuffle(Range&& range, UniformRandomBitGenerator&& g) { ++ return ranges::shuffle(ranges::begin(range), ranges::end(range), ++ std::forward(g)); ++} ++ ++// [alg.nonmodifying] Sorting and related operations ++// Reference: https://wg21.link/alg.sorting ++ ++// [alg.sort] Sorting ++// Reference: https://wg21.link/alg.sort ++ ++// [sort] sort ++// Reference: https://wg21.link/sort ++ ++// Effects: Sorts the elements in the range `[first, last)` with respect to ++// `comp` and `proj`. ++// ++// Returns: `last`. ++// ++// Complexity: Let `N` be `last - first`. `O(N log N)` comparisons and ++// projections. ++// ++// Reference: https://wg21.link/sort#:~:text=ranges::sort(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto sort(RandomAccessIterator first, ++ RandomAccessIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ std::sort(first, last, internal::ProjectedBinaryPredicate(comp, proj, proj)); ++ return last; ++} ++ ++// Effects: Sorts the elements in `range` with respect to `comp` and `proj`. ++// ++// Returns: `end(range)`. ++// ++// Complexity: Let `N` be `size(range)`. `O(N log N)` comparisons and ++// projections. ++// ++// Reference: https://wg21.link/sort#:~:text=ranges::sort(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto sort(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::sort(ranges::begin(range), ranges::end(range), std::move(comp), ++ std::move(proj)); ++} ++ ++// [stable.sort] stable_sort ++// Reference: https://wg21.link/stable.sort ++ ++// Effects: Sorts the elements in the range `[first, last)` with respect to ++// `comp` and `proj`. ++// ++// Returns: `last`. ++// ++// Complexity: Let `N` be `last - first`. If enough extra memory is available, ++// `N log (N)` comparisons. Otherwise, at most `N log^2 (N)` comparisons. In ++// either case, twice as many projections as the number of comparisons. ++// ++// Remarks: Stable. ++// ++// Reference: https://wg21.link/stable.sort#:~:text=ranges::stable_sort(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto stable_sort(RandomAccessIterator first, ++ RandomAccessIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ std::stable_sort(first, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++ return last; ++} ++ ++// Effects: Sorts the elements in `range` with respect to `comp` and `proj`. ++// ++// Returns: `end(rang)`. ++// ++// Complexity: Let `N` be `size(range)`. If enough extra memory is available, ++// `N log (N)` comparisons. Otherwise, at most `N log^2 (N)` comparisons. In ++// either case, twice as many projections as the number of comparisons. ++// ++// Remarks: Stable. ++// ++// Reference: https://wg21.link/stable.sort#:~:text=ranges::stable_sort(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto stable_sort(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::stable_sort(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// [partial.sort] partial_sort ++// Reference: https://wg21.link/partial.sort ++ ++// Preconditions: `[first, middle)` and `[middle, last)` are valid ranges. ++// ++// Effects: Places the first `middle - first` elements from the range ++// `[first, last)` as sorted with respect to `comp` and `proj` into the range ++// `[first, middle)`. The rest of the elements in the range `[middle, last)` are ++// placed in an unspecified order. ++// ++// Returns: `last`. ++// ++// Complexity: Approximately `(last - first) * log(middle - first)` comparisons, ++// and twice as many projections. ++// ++// Reference: https://wg21.link/partial.sort#:~:text=ranges::partial_sort(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto partial_sort(RandomAccessIterator first, ++ RandomAccessIterator middle, ++ RandomAccessIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ std::partial_sort(first, middle, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++ return last; ++} ++ ++// Preconditions: `[begin(range), middle)` and `[middle, end(range))` are valid ++// ranges. ++// ++// Effects: Places the first `middle - begin(range)` elements from `range` as ++// sorted with respect to `comp` and `proj` into the range ++// `[begin(range), middle)`. The rest of the elements in the range ++// `[middle, end(range))` are placed in an unspecified order. ++// ++// Returns: `end(range)`. ++// ++// Complexity: Approximately `size(range) * log(middle - begin(range))` ++// comparisons, and twice as many projections. ++// ++// Reference: https://wg21.link/partial.sort#:~:text=ranges::partial_sort(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto partial_sort(Range&& range, ++ iterator_t middle, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return ranges::partial_sort(ranges::begin(range), middle, ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// [partial.sort.copy] partial_sort_copy ++// Reference: https://wg21.link/partial.sort.copy ++ ++// Let `N` be `min(last - first, result_last - result_first)`. ++// ++// Preconditions: For iterators `a1` and `b1` in `[first, last)`, and iterators ++// `x2` and `y2` in `[result_first, result_last)`, after evaluating the ++// assignment `*y2 = *b1`, let `E` be the value of `bool(invoke(comp, ++// invoke(proj1, *a1), invoke(proj2, *y2)))`. Then, after evaluating the ++// assignment `*x2 = *a1`, `E` is equal to `bool(invoke(comp, invoke(proj2, ++// *x2), invoke(proj2, *y2)))`. ++// ++// Effects: Places the first `N` elements as sorted with respect to `comp` and ++// `proj2` into the range `[result_first, result_first + N)`. ++// ++// Returns: `result_first + N`. ++// ++// Complexity: Approximately `(last - first) * log N` comparisons, and twice as ++// many projections. ++// ++// Reference: ++// https://wg21.link/partial.sort.copy#:~:text=ranges::partial_sort_copy(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>, ++ typename = indirect_result_t, ++ projected>> ++constexpr auto partial_sort_copy(InputIterator first, ++ InputIterator last, ++ RandomAccessIterator result_first, ++ RandomAccessIterator result_last, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ // Needs to opt-in to all permutations, since std::partial_sort_copy expects ++ // comp(proj2(lhs), proj1(rhs)) to compile. ++ return std::partial_sort_copy( ++ first, last, result_first, result_last, ++ internal::PermutedProjectedBinaryPredicate(comp, proj1, proj2)); ++} ++ ++// Let `N` be `min(size(range), size(result_range))`. ++// ++// Preconditions: For iterators `a1` and `b1` in `range`, and iterators ++// `x2` and `y2` in `result_range`, after evaluating the assignment ++// `*y2 = *b1`, let `E` be the value of ++// `bool(invoke(comp, invoke(proj1, *a1), invoke(proj2, *y2)))`. Then, after ++// evaluating the assignment `*x2 = *a1`, `E` is equal to ++// `bool(invoke(comp, invoke(proj2, *x2), invoke(proj2, *y2)))`. ++// ++// Effects: Places the first `N` elements as sorted with respect to `comp` and ++// `proj2` into the range `[begin(result_range), begin(result_range) + N)`. ++// ++// Returns: `begin(result_range) + N`. ++// ++// Complexity: Approximately `size(range) * log N` comparisons, and twice as ++// many projections. ++// ++// Reference: ++// https://wg21.link/partial.sort.copy#:~:text=ranges::partial_sort_copy(R1 ++template , ++ typename = internal::range_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>, ++ typename = indirect_result_t, Proj2>, ++ projected, Proj1>>> ++constexpr auto partial_sort_copy(Range1&& range, ++ Range2&& result_range, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::partial_sort_copy(ranges::begin(range), ranges::end(range), ++ ranges::begin(result_range), ++ ranges::end(result_range), std::move(comp), ++ std::move(proj1), std::move(proj2)); ++} ++ ++// [is.sorted] is_sorted ++// Reference: https://wg21.link/is.sorted ++ ++// Returns: Whether the range `[first, last)` is sorted with respect to `comp` ++// and `proj`. ++// ++// Complexity: Linear. ++// ++// Reference: https://wg21.link/is.sorted#:~:text=ranges::is_sorted(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto is_sorted(ForwardIterator first, ++ ForwardIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return std::is_sorted(first, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Returns: Whether `range` is sorted with respect to `comp` and `proj`. ++// ++// Complexity: Linear. ++// ++// Reference: https://wg21.link/is.sorted#:~:text=ranges::is_sorted(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto is_sorted(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::is_sorted(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// Returns: The last iterator `i` in `[first, last]` for which the range ++// `[first, i)` is sorted with respect to `comp` and `proj`. ++// ++// Complexity: Linear. ++// ++// Reference: https://wg21.link/is.sorted#:~:text=ranges::is_sorted_until(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto is_sorted_until(ForwardIterator first, ++ ForwardIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return std::is_sorted_until( ++ first, last, internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Returns: The last iterator `i` in `[begin(range), end(range)]` for which the ++// range `[begin(range), i)` is sorted with respect to `comp` and `proj`. ++// ++// Complexity: Linear. ++// ++// Reference: https://wg21.link/is.sorted#:~:text=ranges::is_sorted_until(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto is_sorted_until(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::is_sorted_until(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// [alg.nth.element] Nth element ++// Reference: https://wg21.link/alg.nth.element ++ ++// Preconditions: `[first, nth)` and `[nth, last)` are valid ranges. ++// ++// Effects: After `nth_element` the element in the position pointed to by `nth` ++// is the element that would be in that position if the whole range were sorted ++// with respect to `comp` and `proj`, unless `nth == last`. Also for every ++// iterator `i` in the range `[first, nth)` and every iterator `j` in the range ++// `[nth, last)` it holds that: ++// `bool(invoke(comp, invoke(proj, *j), invoke(proj, *i)))` is false. ++// ++// Returns: `last`. ++// ++// Complexity: Linear on average. ++// ++// Reference: https://wg21.link/alg.nth.element#:~:text=ranges::nth_element(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto nth_element(RandomAccessIterator first, ++ RandomAccessIterator nth, ++ RandomAccessIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ std::nth_element(first, nth, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++ return last; ++} ++ ++// Preconditions: `[begin(range), nth)` and `[nth, end(range))` are valid ++// ranges. ++// ++// Effects: After `nth_element` the element in the position pointed to by `nth` ++// is the element that would be in that position if the whole range were sorted ++// with respect to `comp` and `proj`, unless `nth == end(range)`. Also for every ++// iterator `i` in the range `[begin(range), nth)` and every iterator `j` in the ++// range `[nth, end(range))` it holds that: ++// `bool(invoke(comp, invoke(proj, *j), invoke(proj, *i)))` is false. ++// ++// Returns: `end(range)`. ++// ++// Complexity: Linear on average. ++// ++// Reference: https://wg21.link/alg.nth.element#:~:text=ranges::nth_element(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto nth_element(Range&& range, ++ iterator_t nth, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return ranges::nth_element(ranges::begin(range), nth, ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// [alg.binary.search] Binary search ++// Reference: https://wg21.link/alg.binary.search ++ ++// [lower.bound] lower_bound ++// Reference: https://wg21.link/lower.bound ++ ++// Preconditions: The elements `e` of `[first, last)` are partitioned with ++// respect to the expression `bool(invoke(comp, invoke(proj, e), value))`. ++// ++// Returns: The furthermost iterator `i` in the range `[first, last]` such that ++// for every iterator `j` in the range `[first, i)`, ++// `bool(invoke(comp, invoke(proj, *j), value))` is true. ++// ++// Complexity: At most `log_2(last - first) + O(1)` comparisons and projections. ++// ++// Reference: https://wg21.link/lower.bound#:~:text=ranges::lower_bound(I ++template > ++constexpr auto lower_bound(ForwardIterator first, ++ ForwardIterator last, ++ const T& value, ++ Comp comp = {}, ++ Proj proj = {}) { ++ // The second arg is guaranteed to be `value`, so we'll simply apply the ++ // identity projection. ++ identity value_proj; ++ return std::lower_bound( ++ first, last, value, ++ internal::ProjectedBinaryPredicate(comp, proj, value_proj)); ++} ++ ++// Preconditions: The elements `e` of `range` are partitioned with respect to ++// the expression `bool(invoke(comp, invoke(proj, e), value))`. ++// ++// Returns: The furthermost iterator `i` in the range ++// `[begin(range), end(range)]` such that for every iterator `j` in the range ++// `[begin(range), i)`, `bool(invoke(comp, invoke(proj, *j), value))` is true. ++// ++// Complexity: At most `log_2(size(range)) + O(1)` comparisons and projections. ++// ++// Reference: https://wg21.link/lower.bound#:~:text=ranges::lower_bound(R ++template > ++constexpr auto lower_bound(Range&& range, ++ const T& value, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return ranges::lower_bound(ranges::begin(range), ranges::end(range), value, ++ std::move(comp), std::move(proj)); ++} ++ ++// [upper.bound] upper_bound ++// Reference: https://wg21.link/upper.bound ++ ++// Preconditions: The elements `e` of `[first, last)` are partitioned with ++// respect to the expression `!bool(invoke(comp, value, invoke(proj, e)))`. ++// ++// Returns: The furthermost iterator `i` in the range `[first, last]` such that ++// for every iterator `j` in the range `[first, i)`, ++// `!bool(invoke(comp, value, invoke(proj, *j)))` is true. ++// ++// Complexity: At most `log_2(last - first) + O(1)` comparisons and projections. ++// ++// Reference: https://wg21.link/upper.bound#:~:text=ranges::upper_bound(I ++template > ++constexpr auto upper_bound(ForwardIterator first, ++ ForwardIterator last, ++ const T& value, ++ Comp comp = {}, ++ Proj proj = {}) { ++ // The first arg is guaranteed to be `value`, so we'll simply apply the ++ // identity projection. ++ identity value_proj; ++ return std::upper_bound( ++ first, last, value, ++ internal::ProjectedBinaryPredicate(comp, value_proj, proj)); ++} ++ ++// Preconditions: The elements `e` of `range` are partitioned with ++// respect to the expression `!bool(invoke(comp, value, invoke(proj, e)))`. ++// ++// Returns: The furthermost iterator `i` in the range ++// `[begin(range), end(range)]` such that for every iterator `j` in the range ++// `[begin(range), i)`, `!bool(invoke(comp, value, invoke(proj, *j)))` is true. ++// ++// Complexity: At most `log_2(size(range)) + O(1)` comparisons and projections. ++// ++// Reference: https://wg21.link/upper.bound#:~:text=ranges::upper_bound(R ++template > ++constexpr auto upper_bound(Range&& range, ++ const T& value, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return ranges::upper_bound(ranges::begin(range), ranges::end(range), value, ++ std::move(comp), std::move(proj)); ++} ++ ++// [equal.range] equal_range ++// Reference: https://wg21.link/equal.range ++ ++// Preconditions: The elements `e` of `[first, last)` are partitioned with ++// respect to the expressions `bool(invoke(comp, invoke(proj, e), value))` and ++// `!bool(invoke(comp, value, invoke(proj, e)))`. ++// ++// Returns: `{ranges::lower_bound(first, last, value, comp, proj), ++// ranges::upper_bound(first, last, value, comp, proj)}`. ++// ++// Complexity: At most 2 ∗ log_2(last - first) + O(1) comparisons and ++// projections. ++// ++// Reference: https://wg21.link/equal.range#:~:text=ranges::equal_range(I ++template > ++constexpr auto equal_range(ForwardIterator first, ++ ForwardIterator last, ++ const T& value, ++ Comp comp = {}, ++ Proj proj = {}) { ++ // Note: This does not dispatch to std::equal_range, as otherwise it would not ++ // be possible to prevent applying `proj` to `value`, which can result in ++ // unintended behavior. ++ return std::make_pair(ranges::lower_bound(first, last, value, comp, proj), ++ ranges::upper_bound(first, last, value, comp, proj)); ++} ++ ++// Preconditions: The elements `e` of `range` are partitioned with ++// respect to the expressions `bool(invoke(comp, invoke(proj, e), value))` and ++// `!bool(invoke(comp, value, invoke(proj, e)))`. ++// ++// Returns: `{ranges::lower_bound(range, value, comp, proj), ++// ranges::upper_bound(range, value, comp, proj)}`. ++// ++// Complexity: At most 2 ∗ log_2(size(range)) + O(1) comparisons and ++// projections. ++// ++// Reference: https://wg21.link/equal.range#:~:text=ranges::equal_range(R ++template > ++constexpr auto equal_range(Range&& range, ++ const T& value, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return ranges::equal_range(ranges::begin(range), ranges::end(range), value, ++ std::move(comp), std::move(proj)); ++} ++ ++// [binary.search] binary_search ++// Reference: https://wg21.link/binary.search ++ ++// Preconditions: The elements `e` of `[first, last)` are partitioned with ++// respect to the expressions `bool(invoke(comp, invoke(proj, e), value))` and ++// `!bool(invoke(comp, value, invoke(proj, e)))`. ++// ++// Returns: `true` if and only if for some iterator `i` in the range ++// `[first, last)`, `!bool(invoke(comp, invoke(proj, *i), value)) && ++// !bool(invoke(comp, value, invoke(proj, *i)))` is true. ++// ++// Complexity: At most `log_2(last - first) + O(1)` comparisons and projections. ++// ++// Reference: https://wg21.link/binary.search#:~:text=ranges::binary_search(I ++template > ++constexpr auto binary_search(ForwardIterator first, ++ ForwardIterator last, ++ const T& value, ++ Comp comp = {}, ++ Proj proj = {}) { ++ first = ranges::lower_bound(first, last, value, comp, proj); ++ return first != last && ++ !base::invoke(comp, value, base::invoke(proj, *first)); ++} ++ ++// Preconditions: The elements `e` of `range` are partitioned with ++// respect to the expressions `bool(invoke(comp, invoke(proj, e), value))` and ++// `!bool(invoke(comp, value, invoke(proj, e)))`. ++// ++// Returns: `true` if and only if for some iterator `i` in `range` ++// `!bool(invoke(comp, invoke(proj, *i), value)) && ++// !bool(invoke(comp, value, invoke(proj, *i)))` is true. ++// ++// Complexity: At most `log_2(size(range)) + O(1)` comparisons and projections. ++// ++// Reference: https://wg21.link/binary.search#:~:text=ranges::binary_search(R ++template > ++constexpr auto binary_search(Range&& range, ++ const T& value, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return ranges::binary_search(ranges::begin(range), ranges::end(range), value, ++ std::move(comp), std::move(proj)); ++} ++ ++// [alg.partitions] Partitions ++// Reference: https://wg21.link/alg.partitions ++ ++// Returns: `true` if and only if the elements `e` of `[first, last)` are ++// partitioned with respect to the expression ++// `bool(invoke(pred, invoke(proj, e)))`. ++// ++// Complexity: Linear. At most `last - first` applications of `pred` and `proj`. ++// ++// Reference: https://wg21.link/alg.partitions#:~:text=ranges::is_partitioned(I ++template > ++constexpr auto is_partitioned(ForwardIterator first, ++ ForwardIterator last, ++ Pred pred, ++ Proj proj = {}) { ++ return std::is_partitioned(first, last, ++ internal::ProjectedUnaryPredicate(pred, proj)); ++} ++ ++// Returns: `true` if and only if the elements `e` of `range` are partitioned ++// with respect to the expression `bool(invoke(pred, invoke(proj, e)))`. ++// ++// Complexity: Linear. At most `size(range)` applications of `pred` and `proj`. ++// ++// Reference: https://wg21.link/alg.partitions#:~:text=ranges::is_partitioned(R ++template > ++constexpr auto is_partitioned(Range&& range, Pred pred, Proj proj = {}) { ++ return ranges::is_partitioned(ranges::begin(range), ranges::end(range), ++ std::move(pred), std::move(proj)); ++} ++ ++// Let `E(x)` be `bool(invoke(pred, invoke(proj, x)))`. ++// ++// Effects: Places all the elements `e` in `[first, last)` that satisfy `E(e)` ++// before all the elements that do not. ++// ++// Returns: Let `i` be an iterator such that `E(*j)` is `true` for every ++// iterator `j` in `[first, i)` and `false` for every iterator `j` in ++// `[i, last)`. Returns: i. ++// ++// Complexity: Let `N = last - first`: ++// Exactly `N` applications of the predicate and projection. At most `N / 2` ++// swaps if the type of `first` models `bidirectional_iterator`, and at most `N` ++// swaps otherwise. ++// ++// Reference: https://wg21.link/alg.partitions#:~:text=ranges::partition(I ++template > ++constexpr auto partition(ForwardIterator first, ++ ForwardIterator last, ++ Pred pred, ++ Proj proj = {}) { ++ return std::partition(first, last, ++ internal::ProjectedUnaryPredicate(pred, proj)); ++} ++ ++// Let `E(x)` be `bool(invoke(pred, invoke(proj, x)))`. ++// ++// Effects: Places all the elements `e` in `range` that satisfy `E(e)` before ++// all the elements that do not. ++// ++// Returns: Let `i` be an iterator such that `E(*j)` is `true` for every ++// iterator `j` in `[begin(range), i)` and `false` for every iterator `j` in ++// `[i, last)`. Returns: i. ++// ++// Complexity: Let `N = size(range)`: ++// Exactly `N` applications of the predicate and projection. At most `N / 2` ++// swaps if the type of `first` models `bidirectional_iterator`, and at most `N` ++// swaps otherwise. ++// ++// Reference: https://wg21.link/alg.partitions#:~:text=ranges::partition(R ++template > ++constexpr auto partition(Range&& range, Pred pred, Proj proj = {}) { ++ return ranges::partition(ranges::begin(range), ranges::end(range), ++ std::move(pred), std::move(proj)); ++} ++ ++// Let `E(x)` be `bool(invoke(pred, invoke(proj, x)))`. ++// ++// Effects: Places all the elements `e` in `[first, last)` that satisfy `E(e)` ++// before all the elements that do not. The relative order of the elements in ++// both groups is preserved. ++// ++// Returns: Let `i` be an iterator such that for every iterator `j` in ++// `[first, i)`, `E(*j)` is `true`, and for every iterator `j` in the range ++// `[i, last)`, `E(*j)` is `false`. Returns: `i`. ++// ++// Complexity: Let `N = last - first`: ++// At most `N log N` swaps, but only `O(N)` swaps if there is enough extra ++// memory. Exactly `N` applications of the predicate and projection. ++// ++// Reference: ++// https://wg21.link/alg.partitions#:~:text=ranges::stable_partition(I ++template > ++constexpr auto stable_partition(BidirectionalIterator first, ++ BidirectionalIterator last, ++ Pred pred, ++ Proj proj = {}) { ++ return std::stable_partition(first, last, ++ internal::ProjectedUnaryPredicate(pred, proj)); ++} ++ ++// Let `E(x)` be `bool(invoke(pred, invoke(proj, x)))`. ++// ++// Effects: Places all the elements `e` in `range` that satisfy `E(e)` before ++// all the elements that do not. The relative order of the elements in both ++// groups is preserved. ++// ++// Returns: Let `i` be an iterator such that for every iterator `j` in ++// `[begin(range), i)`, `E(*j)` is `true`, and for every iterator `j` in the ++// range `[i, end(range))`, `E(*j)` is `false`. Returns: `i`. ++// ++// Complexity: Let `N = size(range)`: ++// At most `N log N` swaps, but only `O(N)` swaps if there is enough extra ++// memory. Exactly `N` applications of the predicate and projection. ++// ++// Reference: ++// https://wg21.link/alg.partitions#:~:text=ranges::stable_partition(R ++template > ++constexpr auto stable_partition(Range&& range, Pred pred, Proj proj = {}) { ++ return ranges::stable_partition(ranges::begin(range), ranges::end(range), ++ std::move(pred), std::move(proj)); ++} ++ ++// Let `E(x)` be `bool(invoke(pred, invoke(proj, x)))`. ++// ++// Mandates: The expression `*first` is writable to `out_true` and `out_false`. ++// ++// Preconditions: The input range and output ranges do not overlap. ++// ++// Effects: For each iterator `i` in `[first, last)`, copies `*i` to the output ++// range beginning with `out_true` if `E(*i)` is `true`, or to the output range ++// beginning with `out_false` otherwise. ++// ++// Returns: Let `o1` be the end of the output range beginning at `out_true`, and ++// `o2` the end of the output range beginning at `out_false`. ++// Returns `{o1, o2}`. ++// ++// Complexity: Exactly `last - first` applications of `pred` and `proj`. ++// ++// Reference: https://wg21.link/alg.partitions#:~:text=ranges::partition_copy(I ++template , ++ typename = internal::iterator_category_t, ++ typename = internal::iterator_category_t> ++constexpr auto partition_copy(InputIterator first, ++ InputIterator last, ++ OutputIterator1 out_true, ++ OutputIterator2 out_false, ++ Pred pred, ++ Proj proj = {}) { ++ return std::partition_copy(first, last, out_true, out_false, ++ internal::ProjectedUnaryPredicate(pred, proj)); ++} ++ ++// Let `E(x)` be `bool(invoke(pred, invoke(proj, x)))`. ++// ++// Mandates: The expression `*begin(range)` is writable to `out_true` and ++// `out_false`. ++// ++// Preconditions: The input range and output ranges do not overlap. ++// ++// Effects: For each iterator `i` in `range`, copies `*i` to the output range ++// beginning with `out_true` if `E(*i)` is `true`, or to the output range ++// beginning with `out_false` otherwise. ++// ++// Returns: Let `o1` be the end of the output range beginning at `out_true`, and ++// `o2` the end of the output range beginning at `out_false`. ++// Returns `{o1, o2}`. ++// ++// Complexity: Exactly `size(range)` applications of `pred` and `proj`. ++// ++// Reference: https://wg21.link/alg.partitions#:~:text=ranges::partition_copy(R ++template , ++ typename = internal::iterator_category_t, ++ typename = internal::iterator_category_t> ++constexpr auto partition_copy(Range&& range, ++ OutputIterator1 out_true, ++ OutputIterator2 out_false, ++ Pred pred, ++ Proj proj = {}) { ++ return ranges::partition_copy(ranges::begin(range), ranges::end(range), ++ out_true, out_false, std::move(pred), ++ std::move(proj)); ++} ++ ++// let `E(x)` be `bool(invoke(pred, invoke(proj, x)))`. ++// ++// Preconditions: The elements `e` of `[first, last)` are partitioned with ++// respect to `E(e)`. ++// ++// Returns: An iterator `mid` such that `E(*i)` is `true` for all iterators `i` ++// in `[first, mid)`, and `false` for all iterators `i` in `[mid, last)`. ++// ++// Complexity: `O(log(last - first))` applications of `pred` and `proj`. ++// ++// Reference: https://wg21.link/alg.partitions#:~:text=ranges::partition_point(I ++template > ++constexpr auto partition_point(ForwardIterator first, ++ ForwardIterator last, ++ Pred pred, ++ Proj proj = {}) { ++ return std::partition_point(first, last, ++ internal::ProjectedUnaryPredicate(pred, proj)); ++} ++ ++// let `E(x)` be `bool(invoke(pred, invoke(proj, x)))`. ++// ++// Preconditions: The elements `e` of `range` are partitioned with respect to ++// `E(e)`. ++// ++// Returns: An iterator `mid` such that `E(*i)` is `true` for all iterators `i` ++// in `[begin(range), mid)`, and `false` for all iterators `i` in ++// `[mid, end(range))`. ++// ++// Complexity: `O(log(size(range)))` applications of `pred` and `proj`. ++// ++// Reference: https://wg21.link/alg.partitions#:~:text=ranges::partition_point(R ++template > ++constexpr auto partition_point(Range&& range, Pred pred, Proj proj = {}) { ++ return ranges::partition_point(ranges::begin(range), ranges::end(range), ++ std::move(pred), std::move(proj)); ++} ++ ++// [alg.merge] Merge ++// Reference: https://wg21.link/alg.merge ++ ++// Let `N` be `(last1 - first1) + (last2 - first2)`. ++// ++// Preconditions: The ranges `[first1, last1)` and `[first2, last2)` are sorted ++// with respect to `comp` and `proj1` or `proj2`, respectively. The resulting ++// range does not overlap with either of the original ranges. ++// ++// Effects: Copies all the elements of the two ranges `[first1, last1)` and ++// `[first2, last2)` into the range `[result, result_last)`, where `result_last` ++// is `result + N`. If an element `a` precedes `b` in an input range, `a` is ++// copied into the output range before `b`. If `e1` is an element of ++// `[first1, last1)` and `e2` of `[first2, last2)`, `e2` is copied into the ++// output range before `e1` if and only if ++// `bool(invoke(comp, invoke(proj2, e2), invoke(proj1, e1)))` is `true`. ++// ++// Returns: `result_last`. ++// ++// Complexity: At most `N - 1` comparisons and applications of each projection. ++// ++// Remarks: Stable. ++// ++// Reference: https://wg21.link/alg.merge#:~:text=ranges::merge(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>, ++ typename = indirect_result_t, ++ projected>> ++constexpr auto merge(InputIterator1 first1, ++ InputIterator1 last1, ++ InputIterator2 first2, ++ InputIterator2 last2, ++ OutputIterator result, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ // Needs to opt-in to all permutations, since std::merge expects ++ // comp(proj2(lhs), proj1(rhs)) to compile. ++ return std::merge( ++ first1, last1, first2, last2, result, ++ internal::PermutedProjectedBinaryPredicate(comp, proj1, proj2)); ++} ++ ++// Let `N` be `size(range1) + size(range2)`. ++// ++// Preconditions: The ranges `range1` and `range2` are sorted with respect to ++// `comp` and `proj1` or `proj2`, respectively. The resulting range does not ++// overlap with either of the original ranges. ++// ++// Effects: Copies all the elements of the two ranges `range1` and `range2` into ++// the range `[result, result_last)`, where `result_last` is `result + N`. If an ++// element `a` precedes `b` in an input range, `a` is copied into the output ++// range before `b`. If `e1` is an element of `range1` and `e2` of `range2`, ++// `e2` is copied into the output range before `e1` if and only if ++// `bool(invoke(comp, invoke(proj2, e2), invoke(proj1, e1)))` is `true`. ++// ++// Returns: `result_last`. ++// ++// Complexity: At most `N - 1` comparisons and applications of each projection. ++// ++// Remarks: Stable. ++// ++// Reference: https://wg21.link/alg.merge#:~:text=ranges::merge(R1 ++template , ++ typename = internal::range_category_t, ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>, ++ typename = indirect_result_t, Proj2>, ++ projected, Proj1>>> ++constexpr auto merge(Range1&& range1, ++ Range2&& range2, ++ OutputIterator result, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::merge(ranges::begin(range1), ranges::end(range1), ++ ranges::begin(range2), ranges::end(range2), result, ++ std::move(comp), std::move(proj1), std::move(proj2)); ++} ++ ++// Preconditions: `[first, middle)` and `[middle, last)` are valid ranges sorted ++// with respect to `comp` and `proj`. ++// ++// Effects: Merges two sorted consecutive ranges `[first, middle)` and ++// `[middle, last)`, putting the result of the merge into the range ++// `[first, last)`. The resulting range is sorted with respect to `comp` and ++// `proj`. ++// ++// Returns: `last`. ++// ++// Complexity: Let `N = last - first`: If enough additional memory is available, ++// exactly `N - 1` comparisons. Otherwise, `O(N log N)` comparisons. In either ++// case, twice as many projections as comparisons. ++// ++// Remarks: Stable. ++// ++// Reference: https://wg21.link/alg.merge#:~:text=ranges::inplace_merge(I ++template > ++constexpr auto inplace_merge(BidirectionalIterator first, ++ BidirectionalIterator middle, ++ BidirectionalIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ std::inplace_merge(first, middle, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++ return last; ++} ++ ++// Preconditions: `[begin(range), middle)` and `[middle, end(range))` are valid ++// ranges sorted with respect to `comp` and `proj`. ++// ++// Effects: Merges two sorted consecutive ranges `[begin(range), middle)` and ++// `[middle, end(range))`, putting the result of the merge into `range`. The ++// resulting range is sorted with respect to `comp` and `proj`. ++// ++// Returns: `end(range)`. ++// ++// Complexity: Let `N = size(range)`: If enough additional memory is available, ++// exactly `N - 1` comparisons. Otherwise, `O(N log N)` comparisons. In either ++// case, twice as many projections as comparisons. ++// ++// Remarks: Stable. ++// ++// Reference: https://wg21.link/alg.merge#:~:text=ranges::inplace_merge(R ++template > ++constexpr auto inplace_merge(Range&& range, ++ iterator_t middle, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return ranges::inplace_merge(ranges::begin(range), middle, ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// [alg.set.operations] Set operations on sorted structures ++// Reference: https://wg21.link/alg.set.operations ++ ++// [includes] includes ++// Reference: https://wg21.link/includes ++ ++// Preconditions: The ranges `[first1, last1)` and `[first2, last2)` are sorted ++// with respect to `comp` and `proj1` or `proj2`, respectively. ++// ++// Returns: `true` if and only if `[first2, last2)` is a subsequence of ++// `[first1, last1)`. ++// ++// Complexity: At most `2 * ((last1 - first1) + (last2 - first2)) - 1` ++// comparisons and applications of each projection. ++// ++// Reference: https://wg21.link/includes#:~:text=ranges::includes(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>, ++ typename = indirect_result_t, ++ projected>> ++constexpr auto includes(InputIterator1 first1, ++ InputIterator1 last1, ++ InputIterator2 first2, ++ InputIterator2 last2, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ // Needs to opt-in to all permutations, since std::includes expects ++ // comp(proj1(lhs), proj2(rhs)) and comp(proj2(lhs), proj1(rhs)) to compile. ++ return std::includes( ++ first1, last1, first2, last2, ++ internal::PermutedProjectedBinaryPredicate(comp, proj1, proj2)); ++} ++ ++// Preconditions: The ranges `range1` and `range2` are sorted with respect to ++// `comp` and `proj1` or `proj2`, respectively. ++// ++// Returns: `true` if and only if `range2` is a subsequence of `range1`. ++// ++// Complexity: At most `2 * (size(range1) + size(range2)) - 1` comparisons and ++// applications of each projection. ++// ++// Reference: https://wg21.link/includes#:~:text=ranges::includes(R1 ++template , ++ typename = internal::range_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>, ++ typename = indirect_result_t, Proj2>, ++ projected, Proj1>>> ++constexpr auto includes(Range1&& range1, ++ Range2&& range2, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::includes(ranges::begin(range1), ranges::end(range1), ++ ranges::begin(range2), ranges::end(range2), ++ std::move(comp), std::move(proj1), std::move(proj2)); ++} ++ ++// [set.union] set_union ++// Reference: https://wg21.link/set.union ++ ++// Preconditions: The ranges `[first1, last1)` and `[first2, last2)` are sorted ++// with respect to `comp` and `proj1` or `proj2`, respectively. The resulting ++// range does not overlap with either of the original ranges. ++// ++// Effects: Constructs a sorted union of the elements from the two ranges; that ++// is, the set of elements that are present in one or both of the ranges. ++// ++// Returns: The end of the constructed range. ++// ++// Complexity: At most `2 * ((last1 - first1) + (last2 - first2)) - 1` ++// comparisons and applications of each projection. ++// ++// Remarks: Stable. If `[first1, last1)` contains `m` elements that are ++// equivalent to each other and `[first2, last2)` contains `n` elements that are ++// equivalent to them, then all `m` elements from the first range are copied to ++// the output range, in order, and then the final `max(n - m , 0)` elements from ++// the second range are copied to the output range, in order. ++// ++// Reference: https://wg21.link/set.union#:~:text=ranges::set_union(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>, ++ typename = indirect_result_t, ++ projected>> ++constexpr auto set_union(InputIterator1 first1, ++ InputIterator1 last1, ++ InputIterator2 first2, ++ InputIterator2 last2, ++ OutputIterator result, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ // Needs to opt-in to all permutations, since std::set_union expects ++ // comp(proj1(lhs), proj2(rhs)) and comp(proj2(lhs), proj1(rhs)) to compile. ++ return std::set_union( ++ first1, last1, first2, last2, result, ++ internal::PermutedProjectedBinaryPredicate(comp, proj1, proj2)); ++} ++ ++// Preconditions: The ranges `range1` and `range2` are sorted with respect to ++// `comp` and `proj1` or `proj2`, respectively. The resulting range does not ++// overlap with either of the original ranges. ++// ++// Effects: Constructs a sorted union of the elements from the two ranges; that ++// is, the set of elements that are present in one or both of the ranges. ++// ++// Returns: The end of the constructed range. ++// ++// Complexity: At most `2 * (size(range1) + size(range2)) - 1` comparisons and ++// applications of each projection. ++// ++// Remarks: Stable. If `range1` contains `m` elements that are equivalent to ++// each other and `range2` contains `n` elements that are equivalent to them, ++// then all `m` elements from the first range are copied to the output range, in ++// order, and then the final `max(n - m , 0)` elements from the second range are ++// copied to the output range, in order. ++// ++// Reference: https://wg21.link/set.union#:~:text=ranges::set_union(R1 ++template , ++ typename = internal::range_category_t, ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>, ++ typename = indirect_result_t, Proj2>, ++ projected, Proj1>>> ++constexpr auto set_union(Range1&& range1, ++ Range2&& range2, ++ OutputIterator result, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::set_union(ranges::begin(range1), ranges::end(range1), ++ ranges::begin(range2), ranges::end(range2), result, ++ std::move(comp), std::move(proj1), std::move(proj2)); ++} ++ ++// [set.intersection] set_intersection ++// Reference: https://wg21.link/set.intersection ++ ++// Preconditions: The ranges `[first1, last1)` and `[first2, last2)` are sorted ++// with respect to `comp` and `proj1` or `proj2`, respectively. The resulting ++// range does not overlap with either of the original ranges. ++// ++// Effects: Constructs a sorted intersection of the elements from the two ++// ranges; that is, the set of elements that are present in both of the ranges. ++// ++// Returns: The end of the constructed range. ++// ++// Complexity: At most `2 * ((last1 - first1) + (last2 - first2)) - 1` ++// comparisons and applications of each projection. ++// ++// Remarks: Stable. If `[first1, last1)` contains `m` elements that are ++// equivalent to each other and `[first2, last2)` contains `n` elements that are ++// equivalent to them, the first `min(m, n)` elements are copied from the first ++// range to the output range, in order. ++// ++// Reference: ++// https://wg21.link/set.intersection#:~:text=ranges::set_intersection(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>, ++ typename = indirect_result_t, ++ projected>> ++constexpr auto set_intersection(InputIterator1 first1, ++ InputIterator1 last1, ++ InputIterator2 first2, ++ InputIterator2 last2, ++ OutputIterator result, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ // Needs to opt-in to all permutations, since std::set_intersection expects ++ // comp(proj1(lhs), proj2(rhs)) and comp(proj2(lhs), proj1(rhs)) to compile. ++ return std::set_intersection( ++ first1, last1, first2, last2, result, ++ internal::PermutedProjectedBinaryPredicate(comp, proj1, proj2)); ++} ++ ++// Preconditions: The ranges `range1` and `range2` are sorted with respect to ++// `comp` and `proj1` or `proj2`, respectively. The resulting range does not ++// overlap with either of the original ranges. ++// ++// Effects: Constructs a sorted intersection of the elements from the two ++// ranges; that is, the set of elements that are present in both of the ranges. ++// ++// Returns: The end of the constructed range. ++// ++// Complexity: At most `2 * (size(range1) + size(range2)) - 1` comparisons and ++// applications of each projection. ++// ++// Remarks: Stable. If `range1` contains `m` elements that are equivalent to ++// each other and `range2` contains `n` elements that are equivalent to them, ++// the first `min(m, n)` elements are copied from the first range to the output ++// range, in order. ++// ++// Reference: ++// https://wg21.link/set.intersection#:~:text=ranges::set_intersection(R1 ++template , ++ typename = internal::range_category_t, ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>, ++ typename = indirect_result_t, Proj2>, ++ projected, Proj1>>> ++constexpr auto set_intersection(Range1&& range1, ++ Range2&& range2, ++ OutputIterator result, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::set_intersection(ranges::begin(range1), ranges::end(range1), ++ ranges::begin(range2), ranges::end(range2), ++ result, std::move(comp), std::move(proj1), ++ std::move(proj2)); ++} ++ ++// [set.difference] set_difference ++// Reference: https://wg21.link/set.difference ++ ++// Preconditions: The ranges `[first1, last1)` and `[first2, last2)` are sorted ++// with respect to `comp` and `proj1` or `proj2`, respectively. The resulting ++// range does not overlap with either of the original ranges. ++// ++// Effects: Copies the elements of the range `[first1, last1)` which are not ++// present in the range `[first2, last2)` to the range beginning at `result`. ++// The elements in the constructed range are sorted. ++// ++// Returns: The end of the constructed range. ++// ++// Complexity: At most `2 * ((last1 - first1) + (last2 - first2)) - 1` ++// comparisons and applications of each projection. ++// ++// Remarks: If `[first1, last1)` contains `m` elements that are equivalent to ++// each other and `[first2, last2)` contains `n` elements that are equivalent to ++// them, the last `max(m - n, 0)` elements from `[first1, last1)` are copied to ++// the output range, in order. ++// ++// Reference: ++// https://wg21.link/set.difference#:~:text=ranges::set_difference(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>, ++ typename = indirect_result_t, ++ projected>> ++constexpr auto set_difference(InputIterator1 first1, ++ InputIterator1 last1, ++ InputIterator2 first2, ++ InputIterator2 last2, ++ OutputIterator result, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ // Needs to opt-in to all permutations, since std::set_difference expects ++ // comp(proj1(lhs), proj2(rhs)) and comp(proj2(lhs), proj1(rhs)) to compile. ++ return std::set_difference( ++ first1, last1, first2, last2, result, ++ internal::PermutedProjectedBinaryPredicate(comp, proj1, proj2)); ++} ++ ++// Preconditions: The ranges `range1` and `range2` are sorted with respect to ++// `comp` and `proj1` or `proj2`, respectively. The resulting range does not ++// overlap with either of the original ranges. ++// ++// Effects: Copies the elements of `range1` which are not present in `range2` ++// to the range beginning at `result`. The elements in the constructed range are ++// sorted. ++// ++// Returns: The end of the constructed range. ++// ++// Complexity: At most `2 * (size(range1) + size(range2)) - 1` comparisons and ++// applications of each projection. ++// ++// Remarks: Stable. If `range1` contains `m` elements that are equivalent to ++// each other and `range2` contains `n` elements that are equivalent to them, ++// the last `max(m - n, 0)` elements from `range1` are copied to the output ++// range, in order. ++// ++// Reference: ++// https://wg21.link/set.difference#:~:text=ranges::set_difference(R1 ++template , ++ typename = internal::range_category_t, ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>, ++ typename = indirect_result_t, Proj2>, ++ projected, Proj1>>> ++constexpr auto set_difference(Range1&& range1, ++ Range2&& range2, ++ OutputIterator result, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::set_difference(ranges::begin(range1), ranges::end(range1), ++ ranges::begin(range2), ranges::end(range2), ++ result, std::move(comp), std::move(proj1), ++ std::move(proj2)); ++} ++ ++// [set.symmetric.difference] set_symmetric_difference ++// Reference: https://wg21.link/set.symmetric.difference ++ ++// Preconditions: The ranges `[first1, last1)` and `[first2, last2)` are sorted ++// with respect to `comp` and `proj1` or `proj2`, respectively. The resulting ++// range does not overlap with either of the original ranges. ++// ++// Effects: Copies the elements of the range `[first1, last1)` that are not ++// present in the range `[first2, last2)`, and the elements of the range ++// `[first2, last2)` that are not present in the range `[first1, last1)` to the ++// range beginning at `result`. The elements in the constructed range are ++// sorted. ++// ++// Returns: The end of the constructed range. ++// ++// Complexity: At most `2 * ((last1 - first1) + (last2 - first2)) - 1` ++// comparisons and applications of each projection. ++// ++// Remarks: Stable. If `[first1, last1)` contains `m` elements that are ++// equivalent to each other and `[first2, last2)` contains `n` elements that are ++// equivalent to them, then `|m - n|` of those elements shall be copied to the ++// output range: the last `m - n` of these elements from `[first1, last1)` if ++// `m > n`, and the last `n - m` of these elements from `[first2, last2)` if ++// `m < n`. In either case, the elements are copied in order. ++// ++// Reference: ++// https://wg21.link/set.symmetric.difference#:~:text=set_symmetric_difference(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>, ++ typename = indirect_result_t, ++ projected>> ++constexpr auto set_symmetric_difference(InputIterator1 first1, ++ InputIterator1 last1, ++ InputIterator2 first2, ++ InputIterator2 last2, ++ OutputIterator result, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ // Needs to opt-in to all permutations, since std::set_symmetric_difference ++ // expects comp(proj1(lhs), proj2(rhs)) and comp(proj2(lhs), proj1(rhs)) to ++ // compile. ++ return std::set_symmetric_difference( ++ first1, last1, first2, last2, result, ++ internal::PermutedProjectedBinaryPredicate(comp, proj1, proj2)); ++} ++ ++// Preconditions: The ranges `range1` and `range2` are sorted with respect to ++// `comp` and `proj1` or `proj2`, respectively. The resulting range does not ++// overlap with either of the original ranges. ++// ++// Effects: Copies the elements of `range1` that are not present in `range2`, ++// and the elements of `range2` that are not present in `range1` to the range ++// beginning at `result`. The elements in the constructed range are sorted. ++// ++// Returns: The end of the constructed range. ++// ++// Complexity: At most `2 * (size(range1) + size(range2)) - 1` comparisons and ++// applications of each projection. ++// ++// Remarks: Stable. If `range1` contains `m` elements that are equivalent to ++// each other and `range2` contains `n` elements that are equivalent to them, ++// then `|m - n|` of those elements shall be copied to the output range: the ++// last `m - n` of these elements from `range1` if `m > n`, and the last `n - m` ++// of these elements from `range2` if `m < n`. In either case, the elements are ++// copied in order. ++// ++// Reference: ++// https://wg21.link/set.symmetric.difference#:~:text=set_symmetric_difference(R1 ++template , ++ typename = internal::range_category_t, ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>, ++ typename = indirect_result_t, Proj2>, ++ projected, Proj1>>> ++constexpr auto set_symmetric_difference(Range1&& range1, ++ Range2&& range2, ++ OutputIterator result, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::set_symmetric_difference( ++ ranges::begin(range1), ranges::end(range1), ranges::begin(range2), ++ ranges::end(range2), result, std::move(comp), std::move(proj1), ++ std::move(proj2)); ++} ++ ++// [alg.heap.operations] Heap operations ++// Reference: https://wg21.link/alg.heap.operations ++ ++// [push.heap] push_heap ++// Reference: https://wg21.link/push.heap ++ ++// Preconditions: The range `[first, last - 1)` is a valid heap with respect to ++// `comp` and `proj`. ++// ++// Effects: Places the value in the location `last - 1` into the resulting heap ++// `[first, last)`. ++// ++// Returns: `last`. ++// ++// Complexity: At most `log(last - first)` comparisons and twice as many ++// projections. ++// ++// Reference: https://wg21.link/push.heap#:~:text=ranges::push_heap(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto push_heap(RandomAccessIterator first, ++ RandomAccessIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ std::push_heap(first, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++ return last; ++} ++ ++// Preconditions: The range `[begin(range), end(range) - 1)` is a valid heap ++// with respect to `comp` and `proj`. ++// ++// Effects: Places the value in the location `end(range) - 1` into the resulting ++// heap `range`. ++// ++// Returns: `end(range)`. ++// ++// Complexity: At most `log(size(range))` comparisons and twice as many ++// projections. ++// ++// Reference: https://wg21.link/push.heap#:~:text=ranges::push_heap(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto push_heap(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::push_heap(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// [pop.heap] pop_heap ++// Reference: https://wg21.link/pop.heap ++ ++// Preconditions: The range `[first, last)` is a valid non-empty heap with ++// respect to `comp` and `proj`. ++// ++// Effects: Swaps the value in the location `first` with the value in the ++// location `last - 1` and makes `[first, last - 1)` into a heap with respect to ++// `comp` and `proj`. ++// ++// Returns: `last`. ++// ++// Complexity: At most `2 log(last - first)` comparisons and twice as many ++// projections. ++// ++// Reference: https://wg21.link/pop.heap#:~:text=ranges::pop_heap(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto pop_heap(RandomAccessIterator first, ++ RandomAccessIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ std::pop_heap(first, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++ return last; ++} ++ ++// Preconditions: `range` is a valid non-empty heap with respect to `comp` and ++// `proj`. ++// ++// Effects: Swaps the value in the location `begin(range)` with the value in the ++// location `end(range) - 1` and makes `[begin(range), end(range) - 1)` into a ++// heap with respect to `comp` and `proj`. ++// ++// Returns: `end(range)`. ++// ++// Complexity: At most `2 log(size(range))` comparisons and twice as many ++// projections. ++// ++// Reference: https://wg21.link/pop.heap#:~:text=ranges::pop_heap(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto pop_heap(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::pop_heap(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// [make.heap] make_heap ++// Reference: https://wg21.link/make.heap ++ ++// Effects: Constructs a heap with respect to `comp` and `proj` out of the range ++// `[first, last)`. ++// ++// Returns: `last`. ++// ++// Complexity: At most `3 log(last - first)` comparisons and twice as many ++// projections. ++// ++// Reference: https://wg21.link/make.heap#:~:text=ranges::make_heap(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto make_heap(RandomAccessIterator first, ++ RandomAccessIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ std::make_heap(first, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++ return last; ++} ++ ++// Effects: Constructs a heap with respect to `comp` and `proj` out of `range`. ++// ++// Returns: `end(range)`. ++// ++// Complexity: At most `3 log(size(range))` comparisons and twice as many ++// projections. ++// ++// Reference: https://wg21.link/make.heap#:~:text=ranges::make_heap(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto make_heap(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::make_heap(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// [sort.heap] sort_heap ++// Reference: https://wg21.link/sort.heap ++ ++// Preconditions: The range `[first, last)` is a valid heap with respect to ++// `comp` and `proj`. ++// ++// Effects: Sorts elements in the heap `[first, last)` with respect to `comp` ++// and `proj`. ++// ++// Returns: `last`. ++// ++// Complexity: At most `2 N log N` comparisons, where `N = last - first`, and ++// twice as many projections. ++// ++// Reference: https://wg21.link/sort.heap#:~:text=ranges::sort_heap(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto sort_heap(RandomAccessIterator first, ++ RandomAccessIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ std::sort_heap(first, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++ return last; ++} ++ ++// Preconditions: `range` is a valid heap with respect to `comp` and `proj`. ++// ++// Effects: Sorts elements in the heap `range` with respect to `comp` and ++// `proj`. ++// ++// Returns: `end(range)`. ++// ++// Complexity: At most `2 N log N` comparisons, where `N = size(range)`, and ++// twice as many projections. ++// ++// Reference: https://wg21.link/sort.heap#:~:text=ranges::sort_heap(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto sort_heap(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::sort_heap(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// [is.heap] is_heap ++// Reference: https://wg21.link/is.heap ++ ++// Returns: Whether the range `[first, last)` is a heap with respect to `comp` ++// and `proj`. ++// ++// Complexity: Linear. ++// ++// Reference: https://wg21.link/is.heap#:~:text=ranges::is_heap(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto is_heap(RandomAccessIterator first, ++ RandomAccessIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return std::is_heap(first, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Returns: Whether `range` is a heap with respect to `comp` and `proj`. ++// ++// Complexity: Linear. ++// ++// Reference: https://wg21.link/is.heap#:~:text=ranges::is_heap(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto is_heap(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::is_heap(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// Returns: The last iterator `i` in `[first, last]` for which the range ++// `[first, i)` is a heap with respect to `comp` and `proj`. ++// ++// Complexity: Linear. ++// ++// Reference: https://wg21.link/is.heap#:~:text=ranges::is_heap_until(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto is_heap_until(RandomAccessIterator first, ++ RandomAccessIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return std::is_heap_until( ++ first, last, internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Returns: The last iterator `i` in `[begin(range), end(range)]` for which the ++// range `[begin(range), i)` is a heap with respect to `comp` and `proj`. ++// ++// Complexity: Linear. ++// ++// Reference: https://wg21.link/is.heap#:~:text=ranges::is_heap_until(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto is_heap_until(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::is_heap_until(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// [alg.min.max] Minimum and maximum ++// Reference: https://wg21.link/alg.min.max ++ ++// Returns: The smaller value. Returns the first argument when the arguments are ++// equivalent. ++// ++// Complexity: Exactly one comparison and two applications of the projection, if ++// any. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::min ++template ++constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}) { ++ return base::invoke(comp, base::invoke(proj, b), base::invoke(proj, a)) ? b ++ : a; ++} ++ ++// Preconditions: `!empty(ilist)`. ++// ++// Returns: The smallest value in the input range. Returns a copy of the ++// leftmost element when several elements are equivalent to the smallest. ++// ++// Complexity: Exactly `size(ilist) - 1` comparisons and twice as many ++// applications of the projection, if any. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::min(initializer_list ++template ++constexpr T min(std::initializer_list ilist, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return *std::min_element( ++ ilist.begin(), ilist.end(), ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Preconditions: `!empty(range)`. ++// ++// Returns: The smallest value in the input range. Returns a copy of the ++// leftmost element when several elements are equivalent to the smallest. ++// ++// Complexity: Exactly `size(range) - 1` comparisons and twice as many ++// applications of the projection, if any. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::min(R ++template > ++constexpr auto min(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return *std::min_element( ++ ranges::begin(range), ranges::end(range), ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Returns: The larger value. Returns the first argument when the arguments are ++// equivalent. ++// ++// Complexity: Exactly one comparison and two applications of the projection, if ++// any. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::max ++template ++constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}) { ++ return base::invoke(comp, base::invoke(proj, a), base::invoke(proj, b)) ? b ++ : a; ++} ++ ++// Preconditions: `!empty(ilist)`. ++// ++// Returns: The largest value in the input range. Returns a copy of the leftmost ++// element when several elements are equivalent to the largest. ++// ++// Complexity: Exactly `size(ilist) - 1` comparisons and twice as many ++// applications of the projection, if any. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::max(initializer_list ++template ++constexpr T max(std::initializer_list ilist, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return *std::max_element( ++ ilist.begin(), ilist.end(), ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Preconditions: `!empty(range)`. ++// ++// Returns: The largest value in the input range. Returns a copy of the leftmost ++// element when several elements are equivalent to the smallest. ++// ++// Complexity: Exactly `size(range) - 1` comparisons and twice as many ++// applications of the projection, if any. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::max(R ++template > ++constexpr auto max(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return *std::max_element( ++ ranges::begin(range), ranges::end(range), ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Returns: `{b, a}` if `b` is smaller than `a`, and `{a, b}` otherwise. ++// ++// Complexity: Exactly one comparison and two applications of the projection, if ++// any. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::minmax ++template ++constexpr auto minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}) { ++ return std::minmax(a, b, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Preconditions: `!empty(ilist)`. ++// ++// Returns: Let `X` be the return type. Returns `X{x, y}`, where `x` is a copy ++// of the leftmost element with the smallest value and `y` a copy of the ++// rightmost element with the largest value in the input range. ++// ++// Complexity: At most `(3/2) size(ilist)` applications of the corresponding ++// predicate and twice as many applications of the projection, if any. ++// ++// Reference: ++// https://wg21.link/alg.min.max#:~:text=ranges::minmax(initializer_list ++template ++constexpr auto minmax(std::initializer_list ilist, ++ Comp comp = {}, ++ Proj proj = {}) { ++ auto it = ++ std::minmax_element(ranges::begin(ilist), ranges::end(ilist), ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++ return std::pair{*it.first, *it.second}; ++} ++ ++// Preconditions: `!empty(range)`. ++// ++// Returns: Let `X` be the return type. Returns `X{x, y}`, where `x` is a copy ++// of the leftmost element with the smallest value and `y` a copy of the ++// rightmost element with the largest value in the input range. ++// ++// Complexity: At most `(3/2) size(range)` applications of the corresponding ++// predicate and twice as many applications of the projection, if any. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::minmax(R ++template > ++constexpr auto minmax(Range&& range, Comp comp = {}, Proj proj = {}) { ++ using T = range_value_t; ++ auto it = ++ std::minmax_element(ranges::begin(range), ranges::end(range), ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++ return std::pair{*it.first, *it.second}; ++} ++ ++// Returns: The first iterator i in the range `[first, last)` such that for ++// every iterator `j` in the range `[first, last)`, ++// `bool(invoke(comp, invoke(proj, *j), invoke(proj, *i)))` is `false`. Returns ++// `last` if `first == last`. ++// ++// Complexity: Exactly `max(last - first - 1, 0)` comparisons and twice as ++// many projections. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::min_element(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto min_element(ForwardIterator first, ++ ForwardIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return std::min_element(first, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Returns: The first iterator i in `range` such that for every iterator `j` in ++// `range`, `bool(invoke(comp, invoke(proj, *j), invoke(proj, *i)))` is `false`. ++// Returns `end(range)` if `empty(range)`. ++// ++// Complexity: Exactly `max(size(range) - 1, 0)` comparisons and twice as many ++// projections. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::min_element(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto min_element(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::min_element(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// Returns: The first iterator i in the range `[first, last)` such that for ++// every iterator `j` in the range `[first, last)`, ++// `bool(invoke(comp, invoke(proj, *i), invoke(proj, *j)))` is `false`. ++// Returns `last` if `first == last`. ++// ++// Complexity: Exactly `max(last - first - 1, 0)` comparisons and twice as ++// many projections. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::max_element(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto max_element(ForwardIterator first, ++ ForwardIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return std::max_element(first, last, ++ internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Returns: The first iterator i in `range` such that for every iterator `j` ++// in `range`, `bool(invoke(comp, invoke(proj, *j), invoke(proj, *j)))` is ++// `false`. Returns `end(range)` if `empty(range)`. ++// ++// Complexity: Exactly `max(size(range) - 1, 0)` comparisons and twice as many ++// projections. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::max_element(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto max_element(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::max_element(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// Returns: `{first, first}` if `[first, last)` is empty, otherwise `{m, M}`, ++// where `m` is the first iterator in `[first, last)` such that no iterator in ++// the range refers to a smaller element, and where `M` is the last iterator ++// in ++// `[first, last)` such that no iterator in the range refers to a larger ++// element. ++// ++// Complexity: Let `N` be `last - first`. At most `max(3/2 (N − 1), 0)` ++// comparisons and twice as many applications of the projection, if any. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::minmax_element(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto minmax_element(ForwardIterator first, ++ ForwardIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return std::minmax_element( ++ first, last, internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Returns: `{begin(range), begin(range)}` if `range` is empty, otherwise ++// `{m, M}`, where `m` is the first iterator in `range` such that no iterator ++// in the range refers to a smaller element, and where `M` is the last ++// iterator in `range` such that no iterator in the range refers to a larger ++// element. ++// ++// Complexity: Let `N` be `size(range)`. At most `max(3/2 (N − 1), 0)` ++// comparisons and twice as many applications of the projection, if any. ++// ++// Reference: https://wg21.link/alg.min.max#:~:text=ranges::minmax_element(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto minmax_element(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::minmax_element(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// [alg.clamp] Bounded value ++// Reference: https://wg21.link/alg.clamp ++ ++// Preconditions: `bool(invoke(comp, invoke(proj, hi), invoke(proj, lo)))` is ++// `false`. ++// ++// Returns: `lo` if `bool(invoke(comp, invoke(proj, v), invoke(proj, lo)))` is ++// `true`, `hi` if `bool(invoke(comp, invoke(proj, hi), invoke(proj, v)))` is ++// `true`, otherwise `v`. ++// ++// Complexity: At most two comparisons and three applications of the ++// projection. ++// ++// Reference: https://wg21.link/alg.clamp#:~:text=ranges::clamp ++template ++constexpr const T& clamp(const T& v, ++ const T& lo, ++ const T& hi, ++ Comp comp = {}, ++ Proj proj = {}) { ++ auto&& projected_v = base::invoke(proj, v); ++ if (base::invoke(comp, projected_v, base::invoke(proj, lo))) ++ return lo; ++ ++ return base::invoke(comp, base::invoke(proj, hi), projected_v) ? hi : v; ++} ++ ++// [alg.lex.comparison] Lexicographical comparison ++// Reference: https://wg21.link/alg.lex.comparison ++ ++// Returns: `true` if and only if the sequence of elements defined by the range ++// `[first1, last1)` is lexicographically less than the sequence of elements ++// defined by the range `[first2, last2)`. ++// ++// Complexity: At most `2 min(last1 - first1, last2 - first2)` applications of ++// the corresponding comparison and each projection, if any. ++// ++// Remarks: If two sequences have the same number of elements and their ++// corresponding elements (if any) are equivalent, then neither sequence is ++// lexicographically less than the other. If one sequence is a proper prefix of ++// the other, then the shorter sequence is lexicographically less than the ++// longer sequence. Otherwise, the lexicographical comparison of the sequences ++// yields the same result as the comparison of the first corresponding pair of ++// elements that are not equivalent. ++// ++// Reference: ++// https://wg21.link/alg.lex.comparison#:~:text=lexicographical_compare(I1 ++template , ++ typename = internal::iterator_category_t, ++ typename = indirect_result_t, ++ projected>, ++ typename = indirect_result_t, ++ projected>> ++constexpr bool lexicographical_compare(ForwardIterator1 first1, ++ ForwardIterator1 last1, ++ ForwardIterator2 first2, ++ ForwardIterator2 last2, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ for (; first1 != last1 && first2 != last2; ++first1, ++first2) { ++ auto&& projected_first1 = base::invoke(proj1, *first1); ++ auto&& projected_first2 = base::invoke(proj2, *first2); ++ if (base::invoke(comp, projected_first1, projected_first2)) ++ return true; ++ if (base::invoke(comp, projected_first2, projected_first1)) ++ return false; ++ } ++ ++ // `first2 != last2` is equivalent to `first1 == last1 && first2 != last2` ++ // here, since we broke out of the loop above. ++ return first2 != last2; ++} ++ ++// Returns: `true` if and only if the sequence of elements defined by `range1` ++// is lexicographically less than the sequence of elements defined by `range2`. ++// ++// Complexity: At most `2 min(size(range1), size(range2))` applications of the ++// corresponding comparison and each projection, if any. ++// ++// Remarks: If two sequences have the same number of elements and their ++// corresponding elements (if any) are equivalent, then neither sequence is ++// lexicographically less than the other. If one sequence is a proper prefix of ++// the other, then the shorter sequence is lexicographically less than the ++// longer sequence. Otherwise, the lexicographical comparison of the sequences ++// yields the same result as the comparison of the first corresponding pair of ++// elements that are not equivalent. ++// ++// Reference: ++// https://wg21.link/alg.lex.comparison#:~:text=lexicographical_compare(R1 ++template , ++ typename = internal::range_category_t, ++ typename = indirect_result_t, Proj1>, ++ projected, Proj2>>, ++ typename = indirect_result_t, Proj2>, ++ projected, Proj1>>> ++constexpr bool lexicographical_compare(Range1&& range1, ++ Range2&& range2, ++ Comp comp = {}, ++ Proj1 proj1 = {}, ++ Proj2 proj2 = {}) { ++ return ranges::lexicographical_compare( ++ ranges::begin(range1), ranges::end(range1), ranges::begin(range2), ++ ranges::end(range2), std::move(comp), std::move(proj1), std::move(proj2)); ++} ++ ++// [alg.permutation.generators] Permutation generators ++// Reference: https://wg21.link/alg.permutation.generators ++ ++// Effects: Takes a sequence defined by the range `[first, last)` and transforms ++// it into the next permutation. The next permutation is found by assuming that ++// the set of all permutations is lexicographically sorted with respect to ++// `comp` and `proj`. If no such permutation exists, transforms the sequence ++// into the first permutation; that is, the ascendingly-sorted one. ++// ++// Returns: `true` if a next permutation was found and otherwise `false`. ++// ++// Complexity: At most `(last - first) / 2` swaps. ++// ++// Reference: ++// https://wg21.link/alg.permutation.generators#:~:text=next_permutation(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto next_permutation(BidirectionalIterator first, ++ BidirectionalIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return std::next_permutation( ++ first, last, internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Effects: Takes a sequence defined by `range` and transforms it into the next ++// permutation. The next permutation is found by assuming that the set of all ++// permutations is lexicographically sorted with respect to `comp` and `proj`. ++// If no such permutation exists, transforms the sequence into the first ++// permutation; that is, the ascendingly-sorted one. ++// ++// Returns: `true` if a next permutation was found and otherwise `false`. ++// ++// Complexity: At most `size(range) / 2` swaps. ++// ++// Reference: ++// https://wg21.link/alg.permutation.generators#:~:text=next_permutation(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto next_permutation(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::next_permutation(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++// Effects: Takes a sequence defined by the range `[first, last)` and transforms ++// it into the previous permutation. The previous permutation is found by ++// assuming that the set of all permutations is lexicographically sorted with ++// respect to `comp` and `proj`. If no such permutation exists, transforms the ++// sequence into the last permutation; that is, the decreasingly-sorted one. ++// ++// Returns: `true` if a next permutation was found and otherwise `false`. ++// ++// Complexity: At most `(last - first) / 2` swaps. ++// ++// Reference: ++// https://wg21.link/alg.permutation.generators#:~:text=prev_permutation(I ++template , ++ typename = indirect_result_t, ++ projected>> ++constexpr auto prev_permutation(BidirectionalIterator first, ++ BidirectionalIterator last, ++ Comp comp = {}, ++ Proj proj = {}) { ++ return std::prev_permutation( ++ first, last, internal::ProjectedBinaryPredicate(comp, proj, proj)); ++} ++ ++// Effects: Takes a sequence defined by `range` and transforms it into the ++// previous permutation. The previous permutation is found by assuming that the ++// set of all permutations is lexicographically sorted with respect to `comp` ++// and `proj`. If no such permutation exists, transforms the sequence into the ++// last permutation; that is, the decreasingly-sorted one. ++// ++// Returns: `true` if a previous permutation was found and otherwise `false`. ++// ++// Complexity: At most `size(range) / 2` swaps. ++// ++// Reference: ++// https://wg21.link/alg.permutation.generators#:~:text=prev_permutation(R ++template , ++ typename = indirect_result_t, Proj>, ++ projected, Proj>>> ++constexpr auto prev_permutation(Range&& range, Comp comp = {}, Proj proj = {}) { ++ return ranges::prev_permutation(ranges::begin(range), ranges::end(range), ++ std::move(comp), std::move(proj)); ++} ++ ++} // namespace ranges ++ ++} // namespace base ++ ++#endif // BASE_RANGES_ALGORITHM_H_ +diff -up chromium-86.0.4240.111/base/ranges/functional.h.a61fb57e chromium-86.0.4240.111/base/ranges/functional.h +--- chromium-86.0.4240.111/base/ranges/functional.h.a61fb57e 2020-10-21 17:45:04.573057952 -0400 ++++ chromium-86.0.4240.111/base/ranges/functional.h 2020-10-21 17:44:05.320578383 -0400 +@@ -0,0 +1,32 @@ ++// Copyright 2020 The Chromium Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++#ifndef BASE_RANGES_FUNCTIONAL_H_ ++#define BASE_RANGES_FUNCTIONAL_H_ ++ ++#include ++#include ++#include ++ ++namespace base { ++ ++namespace ranges { ++ ++// Simplified implementations of C++20's std::ranges comparison function ++// objects. As opposed to the std::ranges implementation, these versions do not ++// constrain the passed-in types. ++// ++// Reference: https://wg21.link/range.cmp ++using equal_to = std::equal_to<>; ++using not_equal_to = std::not_equal_to<>; ++using greater = std::greater<>; ++using less = std::less<>; ++using greater_equal = std::greater_equal<>; ++using less_equal = std::less_equal<>; ++ ++} // namespace ranges ++ ++} // namespace base ++ ++#endif // BASE_RANGES_FUNCTIONAL_H_ +diff -up chromium-86.0.4240.111/base/ranges/ranges.h.a61fb57e chromium-86.0.4240.111/base/ranges/ranges.h +--- chromium-86.0.4240.111/base/ranges/ranges.h.a61fb57e 2020-10-21 17:45:13.828132866 -0400 ++++ chromium-86.0.4240.111/base/ranges/ranges.h 2020-10-21 17:44:37.950842465 -0400 +@@ -0,0 +1,140 @@ ++// Copyright 2020 The Chromium Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style license that can be ++// found in the LICENSE file. ++ ++#ifndef BASE_RANGES_RANGES_H_ ++#define BASE_RANGES_RANGES_H_ ++ ++#include ++#include ++#include ++#include ++ ++#include "base/template_util.h" ++ ++namespace base { ++ ++namespace internal { ++ ++// Overload for C array. ++template ++constexpr T* begin(T (&array)[N], priority_tag<2>) { ++ return array; ++} ++ ++// Overload for mutable std::array. Required since std::array::begin is not ++// constexpr prior to C++17. Needs to dispatch to the const overload since only ++// const operator[] is constexpr in C++14. ++template ++constexpr T* begin(std::array& array, priority_tag<2> tag) { ++ return const_cast(begin(const_cast&>(array), tag)); ++} ++ ++// Overload for const std::array. Required since std::array::begin is not ++// constexpr prior to C++17. ++template ++constexpr const T* begin(const std::array& array, priority_tag<2>) { ++ return N != 0 ? &array[0] : nullptr; ++} ++ ++// Generic container overload. ++template ++constexpr auto begin(Range&& range, priority_tag<1>) ++ -> decltype(std::forward(range).begin()) { ++ return std::forward(range).begin(); ++} ++ ++// Overload for free begin() function. ++template ++constexpr auto begin(Range&& range, priority_tag<0>) ++ -> decltype(begin(std::forward(range))) { ++ return begin(std::forward(range)); ++} ++ ++// Overload for C array. ++template ++constexpr T* end(T (&array)[N], priority_tag<2>) { ++ return array + N; ++} ++ ++// Overload for mutable std::array. Required since std::array::end is not ++// constexpr prior to C++17. Needs to dispatch to the const overload since only ++// const operator[] is constexpr in C++14. ++template ++constexpr T* end(std::array& array, priority_tag<2> tag) { ++ return const_cast(end(const_cast&>(array), tag)); ++} ++ ++// Overload for const std::array. Required since std::array::end is not ++// constexpr prior to C++17. ++template ++constexpr const T* end(const std::array& array, priority_tag<2>) { ++ return N != 0 ? (&array[0]) + N : nullptr; ++} ++ ++// Generic container overload. ++template ++constexpr auto end(Range&& range, priority_tag<1>) ++ -> decltype(std::forward(range).end()) { ++ return std::forward(range).end(); ++} ++ ++// Overload for free end() function. ++template ++constexpr auto end(Range&& range, priority_tag<0>) ++ -> decltype(end(std::forward(range))) { ++ return end(std::forward(range)); ++} ++ ++} // namespace internal ++ ++namespace ranges { ++ ++// Simplified implementation of C++20's std::ranges::begin. ++// As opposed to std::ranges::begin, this implementation does does not check ++// whether begin() returns an iterator and does not inhibit ADL. ++// ++// The trailing return type and dispatch to the internal implementation is ++// necessary to be SFINAE friendly. ++// ++// Reference: https://wg21.link/range.access.begin ++template ++constexpr auto begin(Range&& range) noexcept ++ -> decltype(internal::begin(std::forward(range), ++ internal::priority_tag<2>())) { ++ return internal::begin(std::forward(range), ++ internal::priority_tag<2>()); ++} ++ ++// Simplified implementation of C++20's std::ranges::end. ++// As opposed to std::ranges::end, this implementation does does not check ++// whether end() returns an iterator and does not inhibit ADL. ++// ++// The trailing return type and dispatch to the internal implementation is ++// necessary to be SFINAE friendly. ++// ++// Reference: - https://wg21.link/range.access.end ++template ++constexpr auto end(Range&& range) noexcept ++ -> decltype(internal::end(std::forward(range), ++ internal::priority_tag<2>())) { ++ return internal::end(std::forward(range), internal::priority_tag<2>()); ++} ++ ++// Implementation of C++20's std::ranges::iterator_t. ++// ++// Reference: https://wg21.link/ranges.syn#:~:text=iterator_t ++template ++using iterator_t = decltype(ranges::begin(std::declval())); ++ ++// Implementation of C++20's std::ranges::range_value_t. ++// ++// Reference: https://wg21.link/ranges.syn#:~:text=range_value_t ++template ++using range_value_t = iter_value_t>; ++ ++} // namespace ranges ++ ++} // namespace base ++ ++#endif // BASE_RANGES_RANGES_H_ +diff -up chromium-86.0.4240.111/base/sampling_heap_profiler/poisson_allocation_sampler.cc.a61fb57e chromium-86.0.4240.111/base/sampling_heap_profiler/poisson_allocation_sampler.cc +--- chromium-86.0.4240.111/base/sampling_heap_profiler/poisson_allocation_sampler.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/sampling_heap_profiler/poisson_allocation_sampler.cc 2020-10-21 17:11:20.011228811 -0400 @@ -4,7 +4,6 @@ #include "base/sampling_heap_profiler/poisson_allocation_sampler.h" @@ -939,9 +6087,9 @@ diff -up chromium-86.0.4240.75/base/sampling_heap_profiler/poisson_allocation_sa DCHECK(it != observers_.end()); observers_.erase(it); g_running = !observers_.empty(); -diff -up chromium-86.0.4240.75/base/scoped_observer.h.a61fb57e chromium-86.0.4240.75/base/scoped_observer.h ---- chromium-86.0.4240.75/base/scoped_observer.h.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/scoped_observer.h 2020-10-21 16:47:44.604936721 -0400 +diff -up chromium-86.0.4240.111/base/scoped_observer.h.a61fb57e chromium-86.0.4240.111/base/scoped_observer.h +--- chromium-86.0.4240.111/base/scoped_observer.h.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/scoped_observer.h 2020-10-21 17:11:20.011228811 -0400 @@ -7,11 +7,11 @@ #include @@ -964,9 +6112,9 @@ diff -up chromium-86.0.4240.75/base/scoped_observer.h.a61fb57e chromium-86.0.424 DCHECK(it != sources_.end()); sources_.erase(it); (source->*RemoveObsFn)(observer_); -diff -up chromium-86.0.4240.75/base/strings/abseil_string_conversions.cc.a61fb57e chromium-86.0.4240.75/base/strings/abseil_string_conversions.cc ---- chromium-86.0.4240.75/base/strings/abseil_string_conversions.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/strings/abseil_string_conversions.cc 2020-10-21 16:38:29.007091366 -0400 +diff -up chromium-86.0.4240.111/base/strings/abseil_string_conversions.cc.a61fb57e chromium-86.0.4240.111/base/strings/abseil_string_conversions.cc +--- chromium-86.0.4240.111/base/strings/abseil_string_conversions.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/strings/abseil_string_conversions.cc 2020-10-21 17:11:20.012228820 -0400 @@ -4,10 +4,10 @@ #include "base/strings/abseil_string_conversions.h" @@ -998,9 +6146,9 @@ diff -up chromium-86.0.4240.75/base/strings/abseil_string_conversions.cc.a61fb57 return pieces; } -diff -up chromium-86.0.4240.75/base/strings/string_util_internal.h.a61fb57e chromium-86.0.4240.75/base/strings/string_util_internal.h ---- chromium-86.0.4240.75/base/strings/string_util_internal.h.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/strings/string_util_internal.h 2020-10-21 16:38:29.007091366 -0400 +diff -up chromium-86.0.4240.111/base/strings/string_util_internal.h.a61fb57e chromium-86.0.4240.111/base/strings/string_util_internal.h +--- chromium-86.0.4240.111/base/strings/string_util_internal.h.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/strings/string_util_internal.h 2020-10-21 17:11:20.012228820 -0400 @@ -7,6 +7,7 @@ #include "base/logging.h" @@ -1019,9 +6167,9 @@ diff -up chromium-86.0.4240.75/base/strings/string_util_internal.h.a61fb57e chro r_offset); } if (index < substitutions) -diff -up chromium-86.0.4240.75/base/synchronization/waitable_event_posix.cc.a61fb57e chromium-86.0.4240.75/base/synchronization/waitable_event_posix.cc ---- chromium-86.0.4240.75/base/synchronization/waitable_event_posix.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/synchronization/waitable_event_posix.cc 2020-10-21 16:38:29.008091375 -0400 +diff -up chromium-86.0.4240.111/base/synchronization/waitable_event_posix.cc.a61fb57e chromium-86.0.4240.111/base/synchronization/waitable_event_posix.cc +--- chromium-86.0.4240.111/base/synchronization/waitable_event_posix.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/synchronization/waitable_event_posix.cc 2020-10-21 17:11:20.012228820 -0400 @@ -4,13 +4,13 @@ #include @@ -1046,9 +6194,9 @@ diff -up chromium-86.0.4240.75/base/synchronization/waitable_event_posix.cc.a61f // The set of waitables must be distinct. Since we have just sorted by // address, we can check this cheaply by comparing pairs of consecutive -diff -up chromium-86.0.4240.75/base/task/common/checked_lock_impl.cc.a61fb57e chromium-86.0.4240.75/base/task/common/checked_lock_impl.cc ---- chromium-86.0.4240.75/base/task/common/checked_lock_impl.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/task/common/checked_lock_impl.cc 2020-10-21 16:38:29.008091375 -0400 +diff -up chromium-86.0.4240.111/base/task/common/checked_lock_impl.cc.a61fb57e chromium-86.0.4240.111/base/task/common/checked_lock_impl.cc +--- chromium-86.0.4240.111/base/task/common/checked_lock_impl.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/task/common/checked_lock_impl.cc 2020-10-21 17:11:20.013228828 -0400 @@ -4,12 +4,12 @@ #include "base/task/common/checked_lock_impl.h" @@ -1073,9 +6221,9 @@ diff -up chromium-86.0.4240.75/base/task/common/checked_lock_impl.cc.a61fb57e ch DCHECK(iter_at_lock != acquired_locks->end()); acquired_locks->erase(iter_at_lock); } -diff -up chromium-86.0.4240.75/base/task/common/operations_controller_unittest.cc.a61fb57e chromium-86.0.4240.75/base/task/common/operations_controller_unittest.cc ---- chromium-86.0.4240.75/base/task/common/operations_controller_unittest.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/task/common/operations_controller_unittest.cc 2020-10-21 16:38:29.008091375 -0400 +diff -up chromium-86.0.4240.111/base/task/common/operations_controller_unittest.cc.a61fb57e chromium-86.0.4240.111/base/task/common/operations_controller_unittest.cc +--- chromium-86.0.4240.111/base/task/common/operations_controller_unittest.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/task/common/operations_controller_unittest.cc 2020-10-21 17:11:20.013228828 -0400 @@ -8,6 +8,7 @@ #include #include @@ -1094,9 +6242,9 @@ diff -up chromium-86.0.4240.75/base/task/common/operations_controller_unittest.c break; } } -diff -up chromium-86.0.4240.75/base/task/common/task_annotator.cc.a61fb57e chromium-86.0.4240.75/base/task/common/task_annotator.cc ---- chromium-86.0.4240.75/base/task/common/task_annotator.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/task/common/task_annotator.cc 2020-10-21 16:48:17.376221810 -0400 +diff -up chromium-86.0.4240.111/base/task/common/task_annotator.cc.a61fb57e chromium-86.0.4240.111/base/task/common/task_annotator.cc +--- chromium-86.0.4240.111/base/task/common/task_annotator.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/task/common/task_annotator.cc 2020-10-21 17:11:20.013228828 -0400 @@ -9,6 +9,7 @@ #include "base/debug/activity_tracker.h" #include "base/debug/alias.h" @@ -1115,9 +6263,9 @@ diff -up chromium-86.0.4240.75/base/task/common/task_annotator.cc.a61fb57e chrom task_backtrace[kStackTaskTraceSnapshotSize - 2] = reinterpret_cast(pending_task->ipc_hash); debug::Alias(&task_backtrace); -diff -up chromium-86.0.4240.75/base/task/sequence_manager/sequence_manager_impl.cc.a61fb57e chromium-86.0.4240.75/base/task/sequence_manager/sequence_manager_impl.cc ---- chromium-86.0.4240.75/base/task/sequence_manager/sequence_manager_impl.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/task/sequence_manager/sequence_manager_impl.cc 2020-10-21 16:38:29.008091375 -0400 +diff -up chromium-86.0.4240.111/base/task/sequence_manager/sequence_manager_impl.cc.a61fb57e chromium-86.0.4240.111/base/task/sequence_manager/sequence_manager_impl.cc +--- chromium-86.0.4240.111/base/task/sequence_manager/sequence_manager_impl.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/task/sequence_manager/sequence_manager_impl.cc 2020-10-21 17:11:20.014228837 -0400 @@ -18,6 +18,7 @@ #include "base/no_destructor.h" #include "base/optional.h" @@ -1136,9 +6284,9 @@ diff -up chromium-86.0.4240.75/base/task/sequence_manager/sequence_manager_impl. size_t length = 0; while (length < task_trace.size() && task_trace[length]) ++length; -diff -up chromium-86.0.4240.75/base/task/sequence_manager/task_queue_impl.cc.a61fb57e chromium-86.0.4240.75/base/task/sequence_manager/task_queue_impl.cc ---- chromium-86.0.4240.75/base/task/sequence_manager/task_queue_impl.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/task/sequence_manager/task_queue_impl.cc 2020-10-21 16:38:29.008091375 -0400 +diff -up chromium-86.0.4240.111/base/task/sequence_manager/task_queue_impl.cc.a61fb57e chromium-86.0.4240.111/base/task/sequence_manager/task_queue_impl.cc +--- chromium-86.0.4240.111/base/task/sequence_manager/task_queue_impl.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/task/sequence_manager/task_queue_impl.cc 2020-10-21 17:11:20.014228837 -0400 @@ -10,6 +10,7 @@ #include @@ -1156,9 +6304,9 @@ diff -up chromium-86.0.4240.75/base/task/sequence_manager/task_queue_impl.cc.a61 } Value TaskQueueImpl::DelayedIncomingQueue::AsValue(TimeTicks now) const { -diff -up chromium-86.0.4240.75/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc.a61fb57e chromium-86.0.4240.75/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc ---- chromium-86.0.4240.75/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc 2020-10-21 16:38:29.009091383 -0400 +diff -up chromium-86.0.4240.111/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc.a61fb57e chromium-86.0.4240.111/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc +--- chromium-86.0.4240.111/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/task/thread_pool/pooled_single_thread_task_runner_manager.cc 2020-10-21 17:11:20.015228846 -0400 @@ -4,7 +4,6 @@ #include "base/task/thread_pool/pooled_single_thread_task_runner_manager.h" @@ -1184,9 +6332,9 @@ diff -up chromium-86.0.4240.75/base/task/thread_pool/pooled_single_thread_task_r DCHECK(worker_iter != workers_.end()); worker_to_destroy = std::move(*worker_iter); workers_.erase(worker_iter); -diff -up chromium-86.0.4240.75/base/task/thread_pool/thread_group_impl.cc.a61fb57e chromium-86.0.4240.75/base/task/thread_pool/thread_group_impl.cc ---- chromium-86.0.4240.75/base/task/thread_pool/thread_group_impl.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/task/thread_pool/thread_group_impl.cc 2020-10-21 16:38:29.009091383 -0400 +diff -up chromium-86.0.4240.111/base/task/thread_pool/thread_group_impl.cc.a61fb57e chromium-86.0.4240.111/base/task/thread_pool/thread_group_impl.cc +--- chromium-86.0.4240.111/base/task/thread_pool/thread_group_impl.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/task/thread_pool/thread_group_impl.cc 2020-10-21 17:11:20.015228846 -0400 @@ -22,6 +22,7 @@ #include "base/metrics/histogram.h" #include "base/numerics/clamped_math.h" @@ -1220,9 +6368,9 @@ diff -up chromium-86.0.4240.75/base/task/thread_pool/thread_group_impl.cc.a61fb5 DCHECK(worker_iter != outer_->workers_.end()); outer_->workers_.erase(worker_iter); } -diff -up chromium-86.0.4240.75/base/task/thread_pool/worker_thread_stack.cc.a61fb57e chromium-86.0.4240.75/base/task/thread_pool/worker_thread_stack.cc ---- chromium-86.0.4240.75/base/task/thread_pool/worker_thread_stack.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/task/thread_pool/worker_thread_stack.cc 2020-10-21 16:38:29.009091383 -0400 +diff -up chromium-86.0.4240.111/base/task/thread_pool/worker_thread_stack.cc.a61fb57e chromium-86.0.4240.111/base/task/thread_pool/worker_thread_stack.cc +--- chromium-86.0.4240.111/base/task/thread_pool/worker_thread_stack.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/task/thread_pool/worker_thread_stack.cc 2020-10-21 17:11:20.016228854 -0400 @@ -4,9 +4,8 @@ #include "base/task/thread_pool/worker_thread_stack.h" @@ -1243,9 +6391,9 @@ diff -up chromium-86.0.4240.75/base/task/thread_pool/worker_thread_stack.cc.a61f DCHECK(it != stack_.end()); DCHECK_NE(TimeTicks(), (*it)->GetLastUsedTime()); stack_.erase(it); -diff -up chromium-86.0.4240.75/base/test/launcher/test_launcher.cc.a61fb57e chromium-86.0.4240.75/base/test/launcher/test_launcher.cc ---- chromium-86.0.4240.75/base/test/launcher/test_launcher.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/test/launcher/test_launcher.cc 2020-10-21 16:38:29.009091383 -0400 +diff -up chromium-86.0.4240.111/base/test/launcher/test_launcher.cc.a61fb57e chromium-86.0.4240.111/base/test/launcher/test_launcher.cc +--- chromium-86.0.4240.111/base/test/launcher/test_launcher.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/test/launcher/test_launcher.cc 2020-10-21 17:11:20.016228854 -0400 @@ -30,6 +30,7 @@ #include "base/numerics/safe_conversions.h" #include "base/process/kill.h" @@ -1272,9 +6420,9 @@ diff -up chromium-86.0.4240.75/base/test/launcher/test_launcher.cc.a61fb57e chro fprintf(stdout, "Randomizing with seed %u\n", shuffle_seed); fflush(stdout); -diff -up chromium-86.0.4240.75/base/test/scoped_feature_list.cc.a61fb57e chromium-86.0.4240.75/base/test/scoped_feature_list.cc ---- chromium-86.0.4240.75/base/test/scoped_feature_list.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/test/scoped_feature_list.cc 2020-10-21 16:38:29.009091383 -0400 +diff -up chromium-86.0.4240.111/base/test/scoped_feature_list.cc.a61fb57e chromium-86.0.4240.111/base/test/scoped_feature_list.cc +--- chromium-86.0.4240.111/base/test/scoped_feature_list.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/test/scoped_feature_list.cc 2020-10-21 17:11:20.017228863 -0400 @@ -4,12 +4,12 @@ #include "base/test/scoped_feature_list.h" @@ -1304,9 +6452,9 @@ diff -up chromium-86.0.4240.75/base/test/scoped_feature_list.cc.a61fb57e chromiu return iter != feature_vector.end(); } -diff -up chromium-86.0.4240.75/base/test/trace_event_analyzer.cc.a61fb57e chromium-86.0.4240.75/base/test/trace_event_analyzer.cc ---- chromium-86.0.4240.75/base/test/trace_event_analyzer.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/test/trace_event_analyzer.cc 2020-10-21 16:38:29.010091392 -0400 +diff -up chromium-86.0.4240.111/base/test/trace_event_analyzer.cc.a61fb57e chromium-86.0.4240.111/base/test/trace_event_analyzer.cc +--- chromium-86.0.4240.111/base/test/trace_event_analyzer.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/test/trace_event_analyzer.cc 2020-10-21 17:11:20.017228863 -0400 @@ -14,6 +14,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" @@ -1344,9 +6492,9 @@ diff -up chromium-86.0.4240.75/base/test/trace_event_analyzer.cc.a61fb57e chromi stats->mean_us = delta_sum / static_cast(num_deltas); double sum_mean_offsets_squared = 0.0; -diff -up chromium-86.0.4240.75/base/threading/hang_watcher.cc.a61fb57e chromium-86.0.4240.75/base/threading/hang_watcher.cc ---- chromium-86.0.4240.75/base/threading/hang_watcher.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/threading/hang_watcher.cc 2020-10-21 16:38:29.010091392 -0400 +diff -up chromium-86.0.4240.111/base/threading/hang_watcher.cc.a61fb57e chromium-86.0.4240.111/base/threading/hang_watcher.cc +--- chromium-86.0.4240.111/base/threading/hang_watcher.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/threading/hang_watcher.cc 2020-10-21 17:11:20.018228872 -0400 @@ -4,7 +4,6 @@ #include "base/threading/hang_watcher.h" @@ -1408,9 +6556,9 @@ diff -up chromium-86.0.4240.75/base/threading/hang_watcher.cc.a61fb57e chromium- // Thread should be registered to get unregistered. DCHECK(it != watch_states_.end()); -diff -up chromium-86.0.4240.75/base/trace_event/trace_log.cc.a61fb57e chromium-86.0.4240.75/base/trace_event/trace_log.cc ---- chromium-86.0.4240.75/base/trace_event/trace_log.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/trace_event/trace_log.cc 2020-10-21 16:38:29.010091392 -0400 +diff -up chromium-86.0.4240.111/base/trace_event/trace_log.cc.a61fb57e chromium-86.0.4240.111/base/trace_event/trace_log.cc +--- chromium-86.0.4240.111/base/trace_event/trace_log.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/trace_event/trace_log.cc 2020-10-21 17:11:20.018228872 -0400 @@ -4,7 +4,6 @@ #include "base/trace_event/trace_log.h" @@ -1437,9 +6585,9 @@ diff -up chromium-86.0.4240.75/base/trace_event/trace_log.cc.a61fb57e chromium-8 enabled_state_observers_.end()); } -diff -up chromium-86.0.4240.75/base/values.cc.a61fb57e chromium-86.0.4240.75/base/values.cc ---- chromium-86.0.4240.75/base/values.cc.a61fb57e 2020-10-07 12:38:34.000000000 -0400 -+++ chromium-86.0.4240.75/base/values.cc 2020-10-21 16:38:29.010091392 -0400 +diff -up chromium-86.0.4240.111/base/values.cc.a61fb57e chromium-86.0.4240.111/base/values.cc +--- chromium-86.0.4240.111/base/values.cc.a61fb57e 2020-10-20 20:14:18.000000000 -0400 ++++ chromium-86.0.4240.111/base/values.cc 2020-10-21 17:11:20.019228880 -0400 @@ -6,7 +6,6 @@ #include @@ -1474,9 +6622,9 @@ diff -up chromium-86.0.4240.75/base/values.cc.a61fb57e chromium-86.0.4240.75/bas } void ListValue::Swap(ListValue* other) { -diff -up chromium-86.0.4240.75/content/public/browser/content_browser_client.cc.a61fb57e chromium-86.0.4240.75/content/public/browser/content_browser_client.cc ---- chromium-86.0.4240.75/content/public/browser/content_browser_client.cc.a61fb57e 2020-10-21 16:38:29.011091401 -0400 -+++ chromium-86.0.4240.75/content/public/browser/content_browser_client.cc 2020-10-21 16:48:43.858452175 -0400 +diff -up chromium-86.0.4240.111/content/public/browser/content_browser_client.cc.a61fb57e chromium-86.0.4240.111/content/public/browser/content_browser_client.cc +--- chromium-86.0.4240.111/content/public/browser/content_browser_client.cc.a61fb57e 2020-10-20 20:14:33.000000000 -0400 ++++ chromium-86.0.4240.111/content/public/browser/content_browser_client.cc 2020-10-21 17:11:20.019228880 -0400 @@ -9,7 +9,7 @@ // declarations instead of including more headers. If that is infeasible, adjust // the limit. For more info, see @@ -1486,9 +6634,9 @@ diff -up chromium-86.0.4240.75/content/public/browser/content_browser_client.cc. #include -diff -up chromium-86.0.4240.75/third_party/blink/renderer/core/dom/document.cc.a61fb57e chromium-86.0.4240.75/third_party/blink/renderer/core/dom/document.cc ---- chromium-86.0.4240.75/third_party/blink/renderer/core/dom/document.cc.a61fb57e 2020-10-21 16:38:29.013091419 -0400 -+++ chromium-86.0.4240.75/third_party/blink/renderer/core/dom/document.cc 2020-10-21 16:49:03.209620502 -0400 +diff -up chromium-86.0.4240.111/third_party/blink/renderer/core/dom/document.cc.a61fb57e chromium-86.0.4240.111/third_party/blink/renderer/core/dom/document.cc +--- chromium-86.0.4240.111/third_party/blink/renderer/core/dom/document.cc.a61fb57e 2020-10-20 20:14:40.000000000 -0400 ++++ chromium-86.0.4240.111/third_party/blink/renderer/core/dom/document.cc 2020-10-21 17:11:20.021228898 -0400 @@ -33,7 +33,7 @@ // instead of including more headers. If that is infeasible, adjust the limit. // For more info, see