[libcxx-commits] [libcxx] f22ecdd - [libc++] Move out `flat_map::iterator` (for reusing it in flat_multimap) (#117445)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Dec 9 06:22:32 PST 2024
Author: Hui
Date: 2024-12-09T09:22:27-05:00
New Revision: f22ecdd9b99485fe73822e44282ae6eb3cc9561b
URL: https://github.com/llvm/llvm-project/commit/f22ecdd9b99485fe73822e44282ae6eb3cc9561b
DIFF: https://github.com/llvm/llvm-project/commit/f22ecdd9b99485fe73822e44282ae6eb3cc9561b.diff
LOG: [libc++] Move out `flat_map::iterator` (for reusing it in flat_multimap) (#117445)
Added:
libcxx/include/__flat_map/key_value_iterator.h
Modified:
libcxx/include/CMakeLists.txt
libcxx/include/__flat_map/flat_map.h
libcxx/include/module.modulemap
libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter_stability.pass.cpp
libcxx/test/std/containers/container.adaptors/flat.map/flat.map.iterators/reverse_iterator.pass.cpp
libcxx/test/std/containers/container.adaptors/flat.map/incomplete_type.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index ee19f771c655ef..561ce4b42fb250 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -360,6 +360,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..b66bc1cb66fc1a 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/ptr
diff _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,9 +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 +89,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 +133,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
diff erence_type = flat_map::
diff erence_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+=(
diff erence_type __x) {
- __key_iter_ += __x;
- __mapped_iter_ += __x;
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI __iterator& operator-=(
diff erence_type __x) {
- __key_iter_ -= __x;
- __mapped_iter_ -= __x;
- return *this;
- }
-
- _LIBCPP_HIDE_FROM_ABI __reference operator[](
diff erence_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,
diff erence_type __n) {
- auto __tmp = __i;
- __tmp += __n;
- return __tmp;
- }
-
- _LIBCPP_HIDE_FROM_ABI friend __iterator operator+(
diff erence_type __n, const __iterator& __i) { return __i + __n; }
-
- _LIBCPP_HIDE_FROM_ABI friend __iterator operator-(const __iterator& __i,
diff erence_type __n) {
- auto __tmp = __i;
- __tmp -= __n;
- return __tmp;
- }
-
- _LIBCPP_HIDE_FROM_ABI friend
diff erence_type operator-(const __iterator& __x, const __iterator& __y) {
- return
diff erence_type(__x.__key_iter_ - __y.__key_iter_);
- }
- };
-
public:
// [flat.map.cons], construct/copy/destroy
_LIBCPP_HIDE_FROM_ABI flat_map() noexcept(
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..987ac677a41303
--- /dev/null
+++ b/libcxx/include/__flat_map/key_value_iterator.h
@@ -0,0 +1,177 @@
+// -*- 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/conditional.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
+
+/**
+ * __key_value_iterator is a proxy iterator which zips the underlying
+ * _KeyContainer::iterator and the underlying _MappedContainer::iterator.
+ * The two underlying iterators will be incremented/decremented together.
+ * And the reference is a pair of the const key reference and the value reference.
+ */
+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 = _If<_Const, typename _Owner::const_reference, typename _Owner::reference>;
+
+ 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;
+ // `__key_value_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
diff erence_type = typename _Owner::
diff erence_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+=(
diff erence_type __x) {
+ __key_iter_ += __x;
+ __mapped_iter_ += __x;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __key_value_iterator& operator-=(
diff erence_type __x) {
+ __key_iter_ -= __x;
+ __mapped_iter_ -= __x;
+ return *this;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI __reference operator[](
diff erence_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,
diff erence_type __n) {
+ auto __tmp = __i;
+ __tmp += __n;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator+(
diff erence_type __n, const __key_value_iterator& __i) {
+ return __i + __n;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend __key_value_iterator operator-(const __key_value_iterator& __i,
diff erence_type __n) {
+ auto __tmp = __i;
+ __tmp -= __n;
+ return __tmp;
+ }
+
+ _LIBCPP_HIDE_FROM_ABI friend
diff erence_type
+ operator-(const __key_value_iterator& __x, const __key_value_iterator& __y) {
+ return
diff erence_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/module.modulemap b/libcxx/include/module.modulemap
index 1ef214465e8379..81621f467aba71 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1235,6 +1235,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