From 73f2de5ef9912a180f099a14ff1966572b626de4 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 14 Jan 2024 17:46:41 +0800 Subject: [PATCH 1/4] Remove `zip_view` dependency and allow permissive modes --- stl/inc/flat_map | 142 +++++++++++++---------- tests/std/tests/P0429R9_flat_map/env.lst | 2 +- 2 files changed, 80 insertions(+), 64 deletions(-) diff --git a/stl/inc/flat_map b/stl/inc/flat_map index 52e35f8a7bf..95da35930fe 100644 --- a/stl/inc/flat_map +++ b/stl/inc/flat_map @@ -14,15 +14,11 @@ _EMIT_STL_WARNING(STL4038, "The contents of are available only with C #include #include #include -#include #include -#include -#include #include #include #include #include -#include #pragma pack(push, _CRT_PACKING) #pragma warning(push, _STL_WARNING_LEVEL) @@ -102,27 +98,34 @@ struct _NODISCARD _Clear_flat_map_scope_guard { // Implementation -template -class _Flat_map_iterator_Impl { -public: - using _Key_iterator_t = typename _KeyContainer::const_iterator; - using _Mapped_iterator_t = - conditional_t<_IsConst, typename _MappedContainer::const_iterator, typename _MappedContainer::iterator>; - class type { +enum class _Paring_iterator_kind : unsigned char { + _Sort, + _Mutable, + _Const, +}; + +template +struct _Paring_iterator_provider { + using _Key_iterator_t = conditional_t<_Kind == _Paring_iterator_kind::_Sort, typename _KeyContainer::iterator, + typename _KeyContainer::const_iterator>; + using _Mapped_iterator_t = conditional_t<_Kind == _Paring_iterator_kind::_Const, + typename _MappedContainer::const_iterator, typename _MappedContainer::iterator>; + + class _Iterator { public: template requires same_as<_FlatMap_Key, typename _FlatMap_KeyContainer::value_type> && same_as<_FlatMap_T, typename _FlatMap_MappedContainer::value_type> friend class _Flat_Map_Base; - type() = default; - type(_Key_iterator_t _Key_it, _Mapped_iterator_t _Mapped_it) : _Key_it(_Key_it), _Mapped_it(_Mapped_it) {} + _Iterator() = default; + _Iterator(_Key_iterator_t _Key_it, _Mapped_iterator_t _Mapped_it) : _Key_it(_Key_it), _Mapped_it(_Mapped_it) {} using iterator_category = input_iterator_tag; using iterator_concept = random_access_iterator_tag; using difference_type = ptrdiff_t; using value_type = pair, iter_value_t<_Mapped_iterator_t>>; - using reference = pair, iter_reference_t<_Mapped_iterator_t>>; + using reference = pair, iter_reference_t<_Mapped_iterator_t>>; private: class _Arrow_proxy { @@ -148,76 +151,80 @@ public: return pointer{*(*this)}; } - type& operator++() { + _Iterator& operator++() { ++_Key_it; ++_Mapped_it; return *this; } - type operator++(int) { - type _Tmp = *this; + _Iterator operator++(int) { + auto _Old = *this; ++*this; - return _Tmp; + return _Old; } - bool operator==(const type& _Right) const { + bool operator==(const _Iterator& _Right) const { return _Key_it == _Right._Key_it; } - auto operator<=>(const type& _Right) const { + auto operator<=>(const _Iterator& _Right) const { return _Key_it <=> _Right._Key_it; } - type& operator--() { + _Iterator& operator--() { --_Key_it; --_Mapped_it; return *this; } - type operator--(int) { - type _Tmp = *this; + _Iterator operator--(int) { + auto _Old = *this; --*this; - return _Tmp; + return _Old; } - type& operator+=(difference_type _Off) { + _Iterator& operator+=(const difference_type _Off) { _Key_it += _Off; _Mapped_it += _Off; return *this; } - type& operator-=(difference_type _Off) { + _Iterator& operator-=(const difference_type _Off) { _Key_it -= _Off; _Mapped_it -= _Off; return *this; } - type operator+(difference_type _Off) const { - type _Tmp = *this; - return _Tmp += _Off; + _Iterator operator+(const difference_type _Off) const { + auto _Old = *this; + _Old += _Off; + return _Old; } - type operator-(difference_type _Off) const { - type _Tmp = *this; - return _Tmp -= _Off; + _Iterator operator-(const difference_type _Off) const { + auto _Old = *this; + _Old -= _Off; + return _Old; } - reference operator[](difference_type _Off) const { + reference operator[](const difference_type _Off) const { return *(*this + _Off); } - difference_type operator-(const type& _Right) const { + difference_type operator-(const _Iterator& _Right) const { return _Key_it - _Right._Key_it; } - friend type operator+(difference_type _Off, const type& _Right) { + friend _Iterator operator+(const difference_type _Off, const _Iterator& _Right) { return _Right + _Off; } - operator typename _Flat_map_iterator_Impl<_KeyContainer, _MappedContainer, true>::type() const - requires (!_IsConst) + operator typename _Paring_iterator_provider<_KeyContainer, _MappedContainer, + _Paring_iterator_kind::_Const>::_Iterator() const + requires (_Kind == _Paring_iterator_kind::_Mutable) { - return typename _Flat_map_iterator_Impl<_KeyContainer, _MappedContainer, true>::type{_Key_it, _Mapped_it}; + return typename _Paring_iterator_provider<_KeyContainer, _MappedContainer, + _Paring_iterator_kind::_Const>::_Iterator{_Key_it, _Mapped_it}; } private: @@ -225,7 +232,7 @@ public: _Mapped_iterator_t _Mapped_it; }; - static_assert(swappable); + _STL_INTERNAL_STATIC_ASSERT(swappable<_Iterator>); }; _EXPORT_STD @@ -238,23 +245,25 @@ private: using _Sorted_t = conditional_t<_Is_Multi, sorted_equivalent_t, sorted_unique_t>; public: - using key_type = _FlatMap_Key; - using mapped_type = _FlatMap_T; - using value_type = pair; - using key_compare = _FlatMap_Compare; - using reference = pair; - using const_reference = pair; - using size_type = size_t; - using difference_type = ptrdiff_t; - using key_container_type = _FlatMap_KeyContainer; - using mapped_container_type = _FlatMap_MappedContainer; - using iterator = _Flat_map_iterator_Impl::type; - using const_iterator = _Flat_map_iterator_Impl::type; + using key_type = _FlatMap_Key; + using mapped_type = _FlatMap_T; + using value_type = pair; + using key_compare = _FlatMap_Compare; + using reference = pair; + using const_reference = pair; + using size_type = size_t; + using difference_type = ptrdiff_t; + using key_container_type = _FlatMap_KeyContainer; + using mapped_container_type = _FlatMap_MappedContainer; + using iterator = _Paring_iterator_provider::_Iterator; + using const_iterator = + _Paring_iterator_provider::_Iterator; using reverse_iterator = _STD reverse_iterator; using const_reverse_iterator = _STD reverse_iterator; - static_assert(random_access_iterator); - static_assert(convertible_to); + _STL_INTERNAL_STATIC_ASSERT(random_access_iterator); + _STL_INTERNAL_STATIC_ASSERT(convertible_to); using value_compare = _Flat_value_compare::value_compare; using containers = _Flat_Container::container; @@ -833,19 +842,25 @@ private: && !_Key_compare(_STD forward<_K2>(_Y), _STD forward<_K1>(_X)); } + auto _View_to_sort() { + using _Sorting_iterator = _Paring_iterator_provider::_Iterator; + return _RANGES subrange<_Sorting_iterator>{_Sorting_iterator{_Data.keys.begin(), _Data.values.begin()}, + _Sorting_iterator{_Data.keys.end(), _Data.values.end()}}; + } + void _Sort() { _Clear_flat_map_scope_guard _Guard{this}; - auto _Zip_view = _RANGES views::zip(_Data.keys, _Data.values); - _RANGES sort(_Zip_view, value_compare(_Key_compare)); + _RANGES sort(_View_to_sort(), value_compare(_Key_compare)); _Guard._Clearable = nullptr; } void _Dedup() { _Clear_flat_map_scope_guard _Guard{this}; - auto _Zip_view = _RANGES views::zip(_Data.keys, _Data.values); - auto _Subrange = _RANGES unique( - _Zip_view, [this](const_reference _X, const_reference _Y) { return this->_Key_equal(_X.first, _Y.first); }); - auto _Remaining_count = _STD distance(_Zip_view.begin(), _Subrange.begin()); + auto _Sorted_view = _View_to_sort(); + auto _Subrange = _RANGES unique(_Sorted_view, + [this](const_reference _X, const_reference _Y) { return this->_Key_equal(_X.first, _Y.first); }); + auto _Remaining_count = _STD distance(_Sorted_view.begin(), _Subrange.begin()); _Data.keys.erase(_Data.keys.begin() + _Remaining_count, _Data.keys.end()); _Data.values.erase(_Data.values.begin() + _Remaining_count, _Data.values.end()); _Guard._Clearable = nullptr; @@ -928,14 +943,15 @@ private: } // Sort the newly inserted elements - auto _Zip_view = _RANGES views::zip(_Data.keys, _Data.values); + auto _Sorted_view = _View_to_sort(); if constexpr (_NeedSorting) { - auto _Zip_view_new_elements = _Zip_view | _RANGES views::drop(_OldSize); - _RANGES sort(_Zip_view_new_elements, value_compare(_Key_compare)); + auto _Sorted_new_elements = _Sorted_view; + _Sorted_new_elements.advance(_OldSize); + _RANGES sort(_Sorted_new_elements, value_compare(_Key_compare)); } // Merge the newly inserted elements with the existing elements - _RANGES inplace_merge(_Zip_view, _Zip_view.begin() + _OldSize, value_compare(_Key_compare)); + _RANGES inplace_merge(_Sorted_view, _Sorted_view.begin() + _OldSize, value_compare(_Key_compare)); if constexpr (_NeedDeduping) { _Dedup(); diff --git a/tests/std/tests/P0429R9_flat_map/env.lst b/tests/std/tests/P0429R9_flat_map/env.lst index 8ac7033b206..18e2d7c71ec 100644 --- a/tests/std/tests/P0429R9_flat_map/env.lst +++ b/tests/std/tests/P0429R9_flat_map/env.lst @@ -1,4 +1,4 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -RUNALL_INCLUDE ..\strict_concepts_latest_matrix.lst +RUNALL_INCLUDE ..\concepts_latest_matrix.lst From 5da9197c55fea937f3e721dd88c41b2c040f513a Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 14 Jan 2024 17:53:10 +0800 Subject: [PATCH 2/4] Other cleanups: drop `_STD` for variable templates --- stl/inc/flat_map | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stl/inc/flat_map b/stl/inc/flat_map index 95da35930fe..11059c8298b 100644 --- a/stl/inc/flat_map +++ b/stl/inc/flat_map @@ -415,15 +415,15 @@ public: .values = _STD make_obj_using_allocator(_Alloc, _Other._Data.values)} {} // Move constructors - _Flat_Map_Base(_Derived&& _Other) noexcept(_STD is_nothrow_move_constructible_v - && _STD is_nothrow_move_constructible_v - && _STD is_nothrow_move_constructible_v) + _Flat_Map_Base(_Derived&& _Other) noexcept(is_nothrow_move_constructible_v + && is_nothrow_move_constructible_v + && is_nothrow_move_constructible_v) : _Key_compare(move(_Other._Key_compare)), _Data(move(_Other).extract()) {} template <_Valid_Allocator_for_flat_map _Allocator> _Flat_Map_Base(_Derived&& _Other, const _Allocator& _Alloc) noexcept( - _STD is_nothrow_move_constructible_v && _STD is_nothrow_move_constructible_v - && _STD is_nothrow_move_constructible_v) + is_nothrow_move_constructible_v && is_nothrow_move_constructible_v + && is_nothrow_move_constructible_v) : _Key_compare(move(_Other._Key_compare)), _Data{.keys = _STD make_obj_using_allocator(_Alloc, move(_Other._Data.keys)), .values = _STD make_obj_using_allocator(_Alloc, move(_Other._Data.values))} {} From fec2965ea75617d388fcc51864923f9df8500edc Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 14 Jan 2024 17:54:05 +0800 Subject: [PATCH 3/4] Other cleanups: use `auto` for iterator types --- stl/inc/flat_map | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/stl/inc/flat_map b/stl/inc/flat_map index 11059c8298b..facdd5474e5 100644 --- a/stl/inc/flat_map +++ b/stl/inc/flat_map @@ -1014,10 +1014,9 @@ private: iterator _Lower_bound(const _K& _X) requires same_as<_K, key_type> || _Is_transparent_v { - typename key_container_type::const_iterator _Key_it = - _STD lower_bound(_Data.keys.cbegin(), _Data.keys.cend(), _X, _Key_compare); - auto _Dist = _STD distance(_Data.keys.cbegin(), _Key_it); - typename mapped_container_type::iterator _Val_it = _Data.values.begin() + _Dist; + auto _Key_it = _STD lower_bound(_Data.keys.cbegin(), _Data.keys.cend(), _X, _Key_compare); + auto _Dist = _STD distance(_Data.keys.cbegin(), _Key_it); + auto _Val_it = _Data.values.begin() + _Dist; return iterator{_STD move(_Key_it), _STD move(_Val_it)}; } @@ -1025,10 +1024,9 @@ private: const_iterator _Lower_bound(const _K& _X) const requires same_as<_K, key_type> || _Is_transparent_v { - typename key_container_type::const_iterator _Key_it = - _STD lower_bound(_Data.keys.cbegin(), _Data.keys.cend(), _X, _Key_compare); - auto _Dist = _STD distance(_Data.keys.cbegin(), _Key_it); - typename mapped_container_type::const_iterator _Val_it = _Data.values.cbegin() + _Dist; + auto _Key_it = _STD lower_bound(_Data.keys.cbegin(), _Data.keys.cend(), _X, _Key_compare); + auto _Dist = _STD distance(_Data.keys.cbegin(), _Key_it); + auto _Val_it = _Data.values.cbegin() + _Dist; return const_iterator{_STD move(_Key_it), _STD move(_Val_it)}; } @@ -1036,10 +1034,9 @@ private: iterator _Upper_bound(const _K& _X) requires same_as<_K, key_type> || _Is_transparent_v { - typename key_container_type::const_iterator _Key_it = - _STD upper_bound(_Data.keys.cbegin(), _Data.keys.cend(), _X, _Key_compare); - auto _Dist = _STD distance(_Data.keys.cbegin(), _Key_it); - typename mapped_container_type::iterator _Val_it = _Data.values.begin() + _Dist; + auto _Key_it = _STD upper_bound(_Data.keys.cbegin(), _Data.keys.cend(), _X, _Key_compare); + auto _Dist = _STD distance(_Data.keys.cbegin(), _Key_it); + auto _Val_it = _Data.values.begin() + _Dist; return iterator{_STD move(_Key_it), _STD move(_Val_it)}; } @@ -1047,10 +1044,9 @@ private: const_iterator _Upper_bound(const _K& _X) const requires same_as<_K, key_type> || _Is_transparent_v { - typename key_container_type::const_iterator _Key_it = - _STD upper_bound(_Data.keys.cbegin(), _Data.keys.cend(), _X, _Key_compare); - auto _Dist = _STD distance(_Data.keys.cbegin(), _Key_it); - typename mapped_container_type::const_iterator _Val_it = _Data.values.cbegin() + _Dist; + auto _Key_it = _STD upper_bound(_Data.keys.cbegin(), _Data.keys.cend(), _X, _Key_compare); + auto _Dist = _STD distance(_Data.keys.cbegin(), _Key_it); + auto _Val_it = _Data.values.cbegin() + _Dist; return const_iterator{_STD move(_Key_it), _STD move(_Val_it)}; } From de2d7597f62334c8a9ba02559c2170adf25561fe Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 14 Jan 2024 17:48:10 +0800 Subject: [PATCH 4/4] Test cleanups (redundant `remove_cvref_t`, `std::` etc.) --- tests/std/tests/P0429R9_flat_map/test.cpp | 170 ++++++++++------------ 1 file changed, 80 insertions(+), 90 deletions(-) diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index d3d10569eab..b5cfda070f3 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -12,8 +12,13 @@ using namespace std; +template class Tmpl> +constexpr bool is_specialization_v = false; +template