[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