-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[libc++] implement std::flat_multimap
#113835
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
c929bc1
to
9066da5
Compare
@llvm/pr-subscribers-libcxx Author: Hui (huixie90) Changesfixes #105190 Patch is 418.31 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/113835.diff 90 Files Affected:
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index 6f1626da73507e..d6d45051cca283 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -52,7 +52,7 @@
"`P2443R1 <https://wg21.link/P2443R1>`__","``views::chunk_by``","2022-02 (Virtual)","|Complete|","18.0",""
"","","","","",""
"`P0009R18 <https://wg21.link/P0009R18>`__","mdspan: A Non-Owning Multidimensional Array Reference","2022-07 (Virtual)","|Complete|","18.0",""
-"`P0429R9 <https://wg21.link/P0429R9>`__","A Standard ``flat_map``","2022-07 (Virtual)","|In progress|","",""
+"`P0429R9 <https://wg21.link/P0429R9>`__","A Standard ``flat_map``","2022-07 (Virtual)","|Complete|","20.0",""
"`P1169R4 <https://wg21.link/P1169R4>`__","``static operator()``","2022-07 (Virtual)","|Complete|","16.0",""
"`P1222R4 <https://wg21.link/P1222R4>`__","A Standard ``flat_set``","2022-07 (Virtual)","","",""
"`P1223R5 <https://wg21.link/P1223R5>`__","``ranges::find_last()``, ``ranges::find_last_if()``, and ``ranges::find_last_if_not()``","2022-07 (Virtual)","|Complete|","19.0",""
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 87eaf64b245017..f8aaa1027034ce 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -359,7 +359,9 @@ set(files
__filesystem/space_info.h
__filesystem/u8path.h
__flat_map/flat_map.h
+ __flat_map/flat_multimap.h
__flat_map/sorted_unique.h
+ __flat_map/sorted_equivalent.h
__format/buffer.h
__format/concepts.h
__format/container_adaptor.h
diff --git a/libcxx/include/__flat_map/flat_multimap.h b/libcxx/include/__flat_map/flat_multimap.h
new file mode 100644
index 00000000000000..ac46a8597e3780
--- /dev/null
+++ b/libcxx/include/__flat_map/flat_multimap.h
@@ -0,0 +1,1182 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___FLAT_MAP_FLAT_MULTIMAP_H
+#define _LIBCPP___FLAT_MAP_FLAT_MULTIMAP_H
+
+#include <__algorithm/lexicographical_compare_three_way.h>
+#include <__algorithm/ranges_equal.h>
+#include <__algorithm/ranges_equal_range.h>
+#include <__algorithm/ranges_inplace_merge.h>
+#include <__algorithm/ranges_is_sorted.h>
+#include <__algorithm/ranges_lower_bound.h>
+#include <__algorithm/ranges_partition_point.h>
+#include <__algorithm/ranges_stable_sort.h>
+#include <__algorithm/ranges_unique.h>
+#include <__algorithm/ranges_upper_bound.h>
+#include <__compare/synth_three_way.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/swappable.h>
+#include <__config>
+#include <__flat_map/sorted_equivalent.h>
+#include <__functional/invoke.h>
+#include <__functional/is_transparent.h>
+#include <__functional/operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/distance.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/ranges_iterator_traits.h>
+#include <__iterator/reverse_iterator.h>
+#include <__memory/allocator_traits.h>
+#include <__memory/uses_allocator.h>
+#include <__memory/uses_allocator_construction.h>
+#include <__ranges/concepts.h>
+#include <__ranges/container_compatible_range.h>
+#include <__ranges/drop_view.h>
+#include <__ranges/ref_view.h>
+#include <__ranges/subrange.h>
+#include <__ranges/zip_view.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/container_traits.h>
+#include <__type_traits/invoke.h>
+#include <__type_traits/is_allocator.h>
+#include <__type_traits/is_nothrow_constructible.h>
+#include <__type_traits/is_same.h>
+#include <__type_traits/maybe_const.h>
+#include <__utility/exception_guard.h>
+#include <__utility/pair.h>
+#include <initializer_list>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Key,
+ class _Tp,
+ class _Compare = less<_Key>,
+ class _KeyContainer = vector<_Key>,
+ class _MappedContainer = vector<_Tp>>
+class flat_multimap {
+ template <bool _Const>
+ struct __iterator;
+
+ template <class, class, class, class, class>
+ friend class flat_multimap;
+
+ static_assert(is_same_v<_Key, typename _KeyContainer::value_type>);
+ static_assert(is_same_v<_Tp, typename _MappedContainer::value_type>);
+ static_assert(!is_same_v<_KeyContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
+ static_assert(!is_same_v<_MappedContainer, std::vector<bool>>, "vector<bool> is not a sequence container");
+
+public:
+ // types
+ using key_type = _Key;
+ using mapped_type = _Tp;
+ using value_type = pair<key_type, mapped_type>;
+ using key_compare = __type_identity_t<_Compare>;
+ using reference = pair<const key_type&, mapped_type&>;
+ using const_reference = pair<const key_type&, const mapped_type&>;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+ using iterator = __iterator<false>; // see [container.requirements]
+ using const_iterator = __iterator<true>; // see [container.requirements]
+ using reverse_iterator = std::reverse_iterator<iterator>;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+ using key_container_type = _KeyContainer;
+ using mapped_container_type = _MappedContainer;
+
+ class value_compare {
+ private:
+ key_compare __comp_;
+ value_compare(key_compare __c) : __comp_(__c) {}
+ friend flat_multimap;
+
+ public:
+ _LIBCPP_HIDE_FROM_ABI bool operator()(const_reference __x, const_reference __y) const {
+ return __comp_(__x.first, __y.first);
+ }
+ };
+
+ struct containers {
+ key_container_type keys;
+ mapped_container_type values;
+ };
+
+private:
+ template <class _Allocator>
+ _LIBCPP_HIDE_FROM_ABI static constexpr bool __allocator_ctor_constraint =
+ _And<uses_allocator<key_container_type, _Allocator>, uses_allocator<mapped_container_type, _Allocator>>::value;
+
+ _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_compare_transparent = __is_transparent_v<_Compare, _Compare>;
+
+ template <bool _Const>
+ struct __iterator {
+ private:
+ using __key_iterator = ranges::iterator_t<const key_container_type>;
+ using __mapped_iterator = ranges::iterator_t<__maybe_const<_Const, mapped_container_type>>;
+ using __reference = pair<iter_reference_t<__key_iterator>, iter_reference_t<__mapped_iterator>>;
+
+ struct __arrow_proxy {
+ __reference __ref_;
+ _LIBCPP_HIDE_FROM_ABI __reference* operator->() { return std::addressof(__ref_); }
+ };
+
+ __key_iterator __key_iter_;
+ __mapped_iterator __mapped_iter_;
+
+ friend flat_multimap;
+
+ public:
+ using iterator_concept = random_access_iterator_tag;
+ // `flat_multimap::iterator` only satisfy "Cpp17InputIterator" named requirements, because
+ // its `reference` is not a reference type.
+ // However, to avoid surprising runtime behaviour when it is used with the
+ // Cpp17 algorithms or operations, iterator_category is set to random_access_iterator_tag.
+ using iterator_category = random_access_iterator_tag;
+ using value_type = flat_multimap::value_type;
+ using difference_type = flat_multimap::difference_type;
+
+ _LIBCPP_HIDE_FROM_ABI __iterator() = default;
+
+ _LIBCPP_HIDE_FROM_ABI __iterator(__iterator<!_Const> __i)
+ requires _Const && convertible_to<ranges::iterator_t<key_container_type>, __key_iterator> &&
+ convertible_to<ranges::iterator_t<mapped_container_type>, __mapped_iterator>
+ : __key_iter_(std::move(__i.__key_iter_)), __mapped_iter_(std::move(__i.__mapped_iter_)) {}
+
+ _LIBCPP_HIDE_FROM_ABI __iterator(__key_iterator __key_iter, __mapped_iterator __mapped_iter)
+ : __key_iter_(std::move(__key_iter)), __mapped_iter_(std::move(__mapped_iter)) {}
+
+ _LIBCPP_HIDE_FROM_ABI __reference operator*() const { return __reference(*__key_iter_, *__mapped_iter_); }
+ _LIBCPP_HIDE_FROM_ABI __arrow_proxy operator->() const { return __arrow_proxy(**this); }
+
+ _LIBCPP_HIDE_FROM_ABI __iterator& operator++() {
+ ++__key_iter_;
+ ++__mapped_iter_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __iterator operator++(int) {
+ __iterator __tmp(*this);
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __iterator& operator--() {
+ --__key_iter_;
+ --__mapped_iter_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __iterator operator--(int) {
+ __iterator __tmp(*this);
+ --*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __iterator& operator+=(difference_type __x) {
+ __key_iter_ += __x;
+ __mapped_iter_ += __x;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __iterator& operator-=(difference_type __x) {
+ __key_iter_ -= __x;
+ __mapped_iter_ -= __x;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __reference operator[](difference_type __n) const { return *(*this + __n); }
+
+ _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
+ return __x.__key_iter_ == __y.__key_iter_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend bool operator<(const __iterator& __x, const __iterator& __y) {
+ return __x.__key_iter_ < __y.__key_iter_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend bool operator>(const __iterator& __x, const __iterator& __y) { return __y < __x; }
+
+ _LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __iterator& __x, const __iterator& __y) { return !(__y < __x); }
+
+ _LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __iterator& __x, const __iterator& __y) { return !(__x < __y); }
+
+ _LIBCPP_HIDE_FROM_ABI friend auto operator<=>(const __iterator& __x, const __iterator& __y)
+ requires three_way_comparable<__key_iterator>
+ {
+ return __x.__key_iter_ <=> __y.__key_iter_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend __iterator operator+(const __iterator& __i, difference_type __n) {
+ auto __tmp = __i;
+ __tmp += __n;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend __iterator operator+(difference_type __n, const __iterator& __i) { return __i + __n; }
+
+ _LIBCPP_HIDE_FROM_ABI friend __iterator operator-(const __iterator& __i, difference_type __n) {
+ auto __tmp = __i;
+ __tmp -= __n;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend difference_type operator-(const __iterator& __x, const __iterator& __y) {
+ return difference_type(__x.__key_iter_ - __y.__key_iter_);
+ }
+ };
+
+public:
+ // [flat.map.cons], construct/copy/destroy
+ _LIBCPP_HIDE_FROM_ABI flat_multimap() noexcept(
+ is_nothrow_default_constructible_v<_KeyContainer> && is_nothrow_default_constructible_v<_MappedContainer> &&
+ is_nothrow_default_constructible_v<_Compare>)
+ : __containers_(), __compare_() {}
+
+ _LIBCPP_HIDE_FROM_ABI flat_multimap(const flat_multimap&) = default;
+
+ // The copy/move constructors are not specified in the spec, which means they should be defaulted.
+ // However, the move constructor can potentially leave a moved-from object in an inconsistent
+ // state if an exception is thrown.
+ _LIBCPP_HIDE_FROM_ABI flat_multimap(flat_multimap&& __other) noexcept(
+ is_nothrow_move_constructible_v<_KeyContainer> && is_nothrow_move_constructible_v<_MappedContainer> &&
+ is_nothrow_move_constructible_v<_Compare>)
+# if _LIBCPP_HAS_EXCEPTIONS
+ try
+# endif // _LIBCPP_HAS_EXCEPTIONS
+ : __containers_(std::move(__other.__containers_)), __compare_(std::move(__other.__compare_)) {
+ __other.clear();
+# if _LIBCPP_HAS_EXCEPTIONS
+ } catch (...) {
+ __other.clear();
+ // gcc does not like the `throw` keyword in a conditional noexcept function
+ if constexpr (!(is_nothrow_move_constructible_v<_KeyContainer> &&
+ is_nothrow_move_constructible_v<_MappedContainer> && is_nothrow_move_constructible_v<_Compare>)) {
+ throw;
+ }
+# endif // _LIBCPP_HAS_EXCEPTIONS
+ }
+
+ template <class _Allocator>
+ requires __allocator_ctor_constraint<_Allocator>
+ _LIBCPP_HIDE_FROM_ABI flat_multimap(const flat_multimap& __other, const _Allocator& __alloc)
+ : flat_multimap(__ctor_uses_allocator_tag{},
+ __alloc,
+ __other.__containers_.keys,
+ __other.__containers_.values,
+ __other.__compare_) {}
+
+ template <class _Allocator>
+ requires __allocator_ctor_constraint<_Allocator>
+ _LIBCPP_HIDE_FROM_ABI flat_multimap(flat_multimap&& __other, const _Allocator& __alloc)
+# if _LIBCPP_HAS_EXCEPTIONS
+ try
+# endif // _LIBCPP_HAS_EXCEPTIONS
+ : flat_multimap(__ctor_uses_allocator_tag{},
+ __alloc,
+ std::move(__other.__containers_.keys),
+ std::move(__other.__containers_.values),
+ std::move(__other.__compare_)) {
+ __other.clear();
+# if _LIBCPP_HAS_EXCEPTIONS
+ } catch (...) {
+ __other.clear();
+ throw;
+# endif // _LIBCPP_HAS_EXCEPTIONS
+ }
+
+ _LIBCPP_HIDE_FROM_ABI flat_multimap(
+ key_container_type __key_cont, mapped_container_type __mapped_cont, const key_compare& __comp = key_compare())
+ : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) {
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
+ "flat_multimap keys and mapped containers have different size");
+ __sort();
+ }
+
+ template <class _Allocator>
+ requires __allocator_ctor_constraint<_Allocator>
+ _LIBCPP_HIDE_FROM_ABI flat_multimap(
+ const key_container_type& __key_cont, const mapped_container_type& __mapped_cont, const _Allocator& __alloc)
+ : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) {
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
+ "flat_multimap keys and mapped containers have different size");
+ __sort();
+ }
+
+ template <class _Allocator>
+ requires __allocator_ctor_constraint<_Allocator>
+ _LIBCPP_HIDE_FROM_ABI
+ flat_multimap(const key_container_type& __key_cont,
+ const mapped_container_type& __mapped_cont,
+ const key_compare& __comp,
+ const _Allocator& __alloc)
+ : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) {
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
+ "flat_multimap keys and mapped containers have different size");
+ __sort();
+ }
+
+ _LIBCPP_HIDE_FROM_ABI
+ flat_multimap(sorted_equivalent_t,
+ key_container_type __key_cont,
+ mapped_container_type __mapped_cont,
+ const key_compare& __comp = key_compare())
+ : __containers_{.keys = std::move(__key_cont), .values = std::move(__mapped_cont)}, __compare_(__comp) {
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
+ "flat_multimap keys and mapped containers have different size");
+ _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__containers_.keys), "Key container is not sorted");
+ }
+
+ template <class _Allocator>
+ requires __allocator_ctor_constraint<_Allocator>
+ _LIBCPP_HIDE_FROM_ABI
+ flat_multimap(sorted_equivalent_t,
+ const key_container_type& __key_cont,
+ const mapped_container_type& __mapped_cont,
+ const _Allocator& __alloc)
+ : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont) {
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
+ "flat_multimap keys and mapped containers have different size");
+ _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__containers_.keys), "Key container is not sorted");
+ }
+
+ template <class _Allocator>
+ requires __allocator_ctor_constraint<_Allocator>
+ _LIBCPP_HIDE_FROM_ABI
+ flat_multimap(sorted_equivalent_t,
+ const key_container_type& __key_cont,
+ const mapped_container_type& __mapped_cont,
+ const key_compare& __comp,
+ const _Allocator& __alloc)
+ : flat_multimap(__ctor_uses_allocator_tag{}, __alloc, __key_cont, __mapped_cont, __comp) {
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(__containers_.keys.size() == __containers_.values.size(),
+ "flat_multimap keys and mapped containers have different size");
+ _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(__is_sorted(__containers_.keys), "Key container is not sorted");
+ }
+
+ _LIBCPP_HIDE_FROM_ABI explicit flat_multimap(const key_compare& __comp) : __containers_(), __compare_(__comp) {}
+
+ template <class _Allocator>
+ requires __allocator_ctor_constraint<_Allocator>
+ _LIBCPP_HIDE_FROM_ABI flat_multimap(const key_compare& __comp, const _Allocator& __alloc)
+ : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {}
+
+ template <class _Allocator>
+ requires __allocator_ctor_constraint<_Allocator>
+ _LIBCPP_HIDE_FROM_ABI explicit flat_multimap(const _Allocator& __alloc)
+ : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {}
+
+ template <class _InputIterator>
+ requires __has_input_iterator_category<_InputIterator>::value
+ _LIBCPP_HIDE_FROM_ABI
+ flat_multimap(_InputIterator __first, _InputIterator __last, const key_compare& __comp = key_compare())
+ : __containers_(), __compare_(__comp) {
+ insert(__first, __last);
+ }
+
+ template <class _InputIterator, class _Allocator>
+ requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)
+ _LIBCPP_HIDE_FROM_ABI
+ flat_multimap(_InputIterator __first, _InputIterator __last, const key_compare& __comp, const _Allocator& __alloc)
+ : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {
+ insert(__first, __last);
+ }
+
+ template <class _InputIterator, class _Allocator>
+ requires(__has_input_iterator_category<_InputIterator>::value && __allocator_ctor_constraint<_Allocator>)
+ _LIBCPP_HIDE_FROM_ABI flat_multimap(_InputIterator __first, _InputIterator __last, const _Allocator& __alloc)
+ : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {
+ insert(__first, __last);
+ }
+
+ template <_ContainerCompatibleRange<value_type> _Range>
+ _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t __fr, _Range&& __rg)
+ : flat_multimap(__fr, std::forward<_Range>(__rg), key_compare()) {}
+
+ template <_ContainerCompatibleRange<value_type> _Range, class _Allocator>
+ requires __allocator_ctor_constraint<_Allocator>
+ _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const _Allocator& __alloc)
+ : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc) {
+ insert_range(std::forward<_Range>(__rg));
+ }
+
+ template <_ContainerCompatibleRange<value_type> _Range>
+ _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp) : flat_multimap(__comp) {
+ insert_range(std::forward<_Range>(__rg));
+ }
+
+ template <_ContainerCompatibleRange<value_type> _Range, class _Allocator>
+ requires __allocator_ctor_constraint<_Allocator>
+ _LIBCPP_HIDE_FROM_ABI flat_multimap(from_range_t, _Range&& __rg, const key_compare& __comp, const _Allocator& __alloc)
+ : flat_multimap(__ctor_uses_allocator_empty_tag{}, __alloc, __comp) {
+ insert_range(std::forward<_Range>(__rg));
+ }
+
+ template <class _InputIterator>
+ requires __has_input_iterator_category<_InputIterator>::value
+ _LIBCPP_HIDE_F...
[truncated]
|
_LIBCPP_HIDE_FROM_ABI typename flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>::size_type | ||
erase_if(flat_multimap<_Key, _Tp, _Compare, _KeyContainer, _MappedContainer>& __flat_multimap, _Predicate __pred) { | ||
// todo | ||
auto __zv = ranges::views::zip(__flat_multimap.__containers_.keys, __flat_multimap.__containers_.values); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No change requested - I failed to find a way to implementing erase_if
for flat_meow
without touching implementation-specific internal names, which means that erase_if
is unlikely or even impossible to work with user-defined specializations of flat_meow
.
Do you think there should be an LWG issue for this, possibly forbidding program-defined specializations?
9066da5
to
5dfffc2
Compare
e597720
to
dff7d3e
Compare
404a0f3
to
65fb506
Compare
1a23afe
to
b57f250
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM with some review comments applied and CI passing. Thanks!
...test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/empty.verify.cpp
Outdated
Show resolved
Hide resolved
...test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/empty.verify.cpp
Outdated
Show resolved
Hide resolved
...x/test/std/containers/container.adaptors/flat.multimap/flat.multimap.capacity/empty.pass.cpp
Outdated
Show resolved
Hide resolved
libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp
Outdated
Show resolved
Hide resolved
...xx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.verify.cpp
Show resolved
Hide resolved
...std/containers/container.adaptors/flat.multimap/flat.multimap.cons/default_noexcept.pass.cpp
Show resolved
Hide resolved
...st/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/dtor_noexcept.pass.cpp
Show resolved
Hide resolved
e30e412
to
ca71ba3
Compare
fixes #105190