[libcxx-commits] [libcxx] [libc++] Move out (for reusing it in flat_multimap) (PR #117445)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Nov 23 10:58:31 PST 2024
https://github.com/huixie90 created https://github.com/llvm/llvm-project/pull/117445
None
>From a3dadd67fa45ca14e251f26cf63ea7217a857a85 Mon Sep 17 00:00:00 2001
From: Hui Xie <huixie at Mac.broadband>
Date: Sat, 23 Nov 2024 18:54:14 +0000
Subject: [PATCH] [libc++] Move out (for reusing it in flat_multimap)
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__flat_map/flat_map.h | 147 ++-------------
.../include/__flat_map/key_value_iterator.h | 170 ++++++++++++++++++
libcxx/include/flat_map | 1 +
libcxx/include/module.modulemap | 1 +
.../iter_iter_stability.pass.cpp | 1 +
.../reverse_iterator.pass.cpp | 2 +-
.../flat.map/incomplete_type.pass.cpp | 1 +
8 files changed, 191 insertions(+), 133 deletions(-)
create mode 100644 libcxx/include/__flat_map/key_value_iterator.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 0ae031e5365aef..b37b00165fd6ac 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -358,6 +358,7 @@ set(files
__filesystem/space_info.h
__filesystem/u8path.h
__flat_map/flat_map.h
+ __flat_map/key_value_iterator.h
__flat_map/sorted_unique.h
__format/buffer.h
__format/concepts.h
diff --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h
index 58b362ad7a706f..6bc8608ecf1902 100644
--- a/libcxx/include/__flat_map/flat_map.h
+++ b/libcxx/include/__flat_map/flat_map.h
@@ -23,11 +23,11 @@
#include <__algorithm/remove_if.h>
#include <__assert>
#include <__compare/synth_three_way.h>
-#include <__concepts/convertible_to.h>
#include <__concepts/swappable.h>
#include <__config>
#include <__cstddef/byte.h>
#include <__cstddef/ptrdiff_t.h>
+#include <__flat_map/key_value_iterator.h>
#include <__flat_map/sorted_unique.h>
#include <__functional/invoke.h>
#include <__functional/is_transparent.h>
@@ -38,7 +38,6 @@
#include <__iterator/next.h>
#include <__iterator/ranges_iterator_traits.h>
#include <__iterator/reverse_iterator.h>
-#include <__memory/addressof.h>
#include <__memory/allocator_traits.h>
#include <__memory/uses_allocator.h>
#include <__memory/uses_allocator_construction.h>
@@ -57,8 +56,8 @@
#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/move.h>
#include <__utility/pair.h>
#include <__utility/scope_guard.h>
#include <__vector/vector.h>
@@ -82,8 +81,6 @@ template <class _Key,
class _KeyContainer = vector<_Key>,
class _MappedContainer = vector<_Tp>>
class flat_map {
- template <bool _Const>
- struct __iterator;
template <class, class, class, class, class>
friend class flat_map;
@@ -93,6 +90,9 @@ class flat_map {
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");
+ template <bool _Const>
+ using __iterator = __key_value_iterator<flat_map, _KeyContainer, _MappedContainer, _Const>;
+
public:
// types
using key_type = _Key;
@@ -134,123 +134,6 @@ class flat_map {
_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_map;
-
- public:
- using iterator_concept = random_access_iterator_tag;
- // `flat_map::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_map::value_type;
- using difference_type = flat_map::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_map() noexcept(
@@ -1309,20 +1192,20 @@ template <ranges::input_range _Range,
class = __enable_if_t<!__is_allocator<_Compare>::value && __is_allocator<_Allocator>::value>>
flat_map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())
-> flat_map<
- __range_key_type<_Range>,
- __range_mapped_type<_Range>,
- _Compare,
- vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>,
- vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
+ __range_key_type<_Range>,
+ __range_mapped_type<_Range>,
+ _Compare,
+ vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>,
+ vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
template <ranges::input_range _Range, class _Allocator, class = __enable_if_t<__is_allocator<_Allocator>::value>>
flat_map(from_range_t, _Range&&, _Allocator)
-> flat_map<
- __range_key_type<_Range>,
- __range_mapped_type<_Range>,
- less<__range_key_type<_Range>>,
- vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>,
- vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
+ __range_key_type<_Range>,
+ __range_mapped_type<_Range>,
+ less<__range_key_type<_Range>>,
+ vector<__range_key_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_key_type<_Range>>>,
+ vector<__range_mapped_type<_Range>, __allocator_traits_rebind_t<_Allocator, __range_mapped_type<_Range>>>>;
template <class _Key, class _Tp, class _Compare = less<_Key>>
requires(!__is_allocator<_Compare>::value)
diff --git a/libcxx/include/__flat_map/key_value_iterator.h b/libcxx/include/__flat_map/key_value_iterator.h
new file mode 100644
index 00000000000000..a88ab1bbce32af
--- /dev/null
+++ b/libcxx/include/__flat_map/key_value_iterator.h
@@ -0,0 +1,170 @@
+// -*- 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_KEY_VALUE_ITERATOR_H
+#define _LIBCPP___FLAT_MAP_KEY_VALUE_ITERATOR_H
+
+#include <__compare/three_way_comparable.h>
+#include <__concepts/convertible_to.h>
+#include <__config>
+#include <__iterator/iterator_traits.h>
+#include <__memory/addressof.h>
+#include <__ranges/access.h>
+#include <__type_traits/maybe_const.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
+
+#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 _Owner, class _KeyContainer, class _MappedContainer, bool _Const>
+struct __key_value_iterator {
+private:
+ using __key_iterator = ranges::iterator_t<const _KeyContainer>;
+ using __mapped_iterator = ranges::iterator_t<__maybe_const<_Const, _MappedContainer>>;
+ 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 _Owner;
+
+ template <class, class, class, bool>
+ friend struct __key_value_iterator;
+
+public:
+ using iterator_concept = random_access_iterator_tag;
+ // `flat_map::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 = typename _Owner::value_type;
+ using difference_type = typename _Owner::difference_type;
+
+ _LIBCPP_HIDE_FROM_ABI __key_value_iterator() = default;
+
+ _LIBCPP_HIDE_FROM_ABI __key_value_iterator(__key_value_iterator<_Owner, _KeyContainer, _MappedContainer, !_Const> __i)
+ requires _Const && convertible_to<ranges::iterator_t<_KeyContainer>, __key_iterator> &&
+ convertible_to<ranges::iterator_t<_MappedContainer>, __mapped_iterator>
+ : __key_iter_(std::move(__i.__key_iter_)), __mapped_iter_(std::move(__i.__mapped_iter_)) {}
+
+ _LIBCPP_HIDE_FROM_ABI __key_value_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 __key_value_iterator& operator++() {
+ ++__key_iter_;
+ ++__mapped_iter_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __key_value_iterator operator++(int) {
+ __key_value_iterator __tmp(*this);
+ ++*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator--() {
+ --__key_iter_;
+ --__mapped_iter_;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __key_value_iterator operator--(int) {
+ __key_value_iterator __tmp(*this);
+ --*this;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator+=(difference_type __x) {
+ __key_iter_ += __x;
+ __mapped_iter_ += __x;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __key_value_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 __key_value_iterator& __x, const __key_value_iterator& __y) {
+ return __x.__key_iter_ == __y.__key_iter_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend bool operator<(const __key_value_iterator& __x, const __key_value_iterator& __y) {
+ return __x.__key_iter_ < __y.__key_iter_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend bool operator>(const __key_value_iterator& __x, const __key_value_iterator& __y) {
+ return __y < __x;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend bool operator<=(const __key_value_iterator& __x, const __key_value_iterator& __y) {
+ return !(__y < __x);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend bool operator>=(const __key_value_iterator& __x, const __key_value_iterator& __y) {
+ return !(__x < __y);
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend auto operator<=>(const __key_value_iterator& __x, const __key_value_iterator& __y)
+ requires three_way_comparable<__key_iterator>
+ {
+ return __x.__key_iter_ <=> __y.__key_iter_;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(const __key_value_iterator& __i, difference_type __n) {
+ auto __tmp = __i;
+ __tmp += __n;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(difference_type __n, const __key_value_iterator& __i) {
+ return __i + __n;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator-(const __key_value_iterator& __i, difference_type __n) {
+ auto __tmp = __i;
+ __tmp -= __n;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend difference_type
+ operator-(const __key_value_iterator& __x, const __key_value_iterator& __y) {
+ return difference_type(__x.__key_iter_ - __y.__key_iter_);
+ }
+};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___FLAT_MAP_KEY_VALUE_ITERATOR_H
diff --git a/libcxx/include/flat_map b/libcxx/include/flat_map
index 15d79dd1ddca34..e96af677a7eed9 100644
--- a/libcxx/include/flat_map
+++ b/libcxx/include/flat_map
@@ -40,6 +40,7 @@ namespace std {
#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
#include <__flat_map/flat_map.h>
+#include <__flat_map/key_value_iterator.h>
#include <__flat_map/sorted_unique.h>
#include <version>
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 4e06a68c6a6b61..52e13aebc2187c 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1229,6 +1229,7 @@ module std [system] {
module flat_map {
module flat_map { header "__flat_map/flat_map.h" }
+ module key_value_iterator { header "__flat_map/key_value_iterator.h" }
module sorted_unique { header "__flat_map/sorted_unique.h" }
header "flat_map"
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter_stability.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter_stability.pass.cpp
index 1ce859f6c737ea..14189840ce6605 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter_stability.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter_stability.pass.cpp
@@ -23,6 +23,7 @@
#include <flat_map>
#include <random>
#include <map>
+#include <vector>
#include "test_macros.h"
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.iterators/reverse_iterator.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.iterators/reverse_iterator.pass.cpp
index 09e18986a7e813..fc3949d70745fc 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.iterators/reverse_iterator.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.iterators/reverse_iterator.pass.cpp
@@ -23,7 +23,7 @@
#include <deque>
#include <flat_map>
#include <functional>
-#include <string>
+#include <vector>
#include <iterator>
diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/incomplete_type.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/incomplete_type.pass.cpp
index 81c590ba73a157..76461951f0d3d8 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.map/incomplete_type.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.map/incomplete_type.pass.cpp
@@ -14,6 +14,7 @@
// type.
#include <flat_map>
+#include <vector>
struct A {
using Map = std::flat_map<A, A>;
More information about the libcxx-commits
mailing list