瀏覽代碼

AK+LibRegex: Move COWVector to AK

This is about to gain a new user, so move it to AK.
Ali Mohammad Pur 1 年之前
父節點
當前提交
cefe177a56
共有 2 個文件被更改,包括 180 次插入129 次删除
  1. 179 0
      AK/COWVector.h
  2. 1 129
      Userland/Libraries/LibRegex/RegexMatch.h

+ 179 - 0
AK/COWVector.h

@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2021-2024, Ali Mohammad Pur <mpfard@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/NonnullRefPtr.h>
+#include <AK/RefCounted.h>
+#include <AK/Vector.h>
+
+namespace AK {
+
+template<typename T>
+class COWVector {
+    struct Detail : RefCounted<Detail> {
+        Vector<T> m_members;
+    };
+
+public:
+    COWVector()
+        : m_detail(make_ref_counted<Detail>())
+    {
+    }
+
+    COWVector(std::initializer_list<T> entries)
+        : m_detail(make_ref_counted<Detail>())
+    {
+        for (auto& entry : entries)
+            m_detail->m_members.append(entry);
+    }
+
+    COWVector(COWVector const&) = default;
+    COWVector(COWVector&&) = default;
+
+    COWVector& operator=(COWVector const&) = default;
+    COWVector& operator=(COWVector&&) = default;
+
+    Vector<T> release() &&
+    {
+        if (m_detail->ref_count() == 1)
+            return exchange(m_detail->m_members, Vector<T>());
+
+        return m_detail->m_members;
+    }
+
+    void append(T const& value)
+    {
+        return append(T { value });
+    }
+
+    void append(T&& value)
+    {
+        copy();
+        m_detail->m_members.append(move(value));
+    }
+
+    void extend(Vector<T>&& values)
+    {
+        copy();
+        m_detail->m_members.extend(move(values));
+    }
+
+    void extend(Vector<T> const& values)
+    {
+        copy();
+        m_detail->m_members.extend(values);
+    }
+
+    void extend(COWVector<T> const& values)
+    {
+        copy();
+        m_detail->m_members.extend(values.m_detail->m_members);
+    }
+
+    void resize(size_t size)
+    {
+        copy();
+        m_detail->m_members.resize(size);
+    }
+
+    void ensure_capacity(size_t capacity)
+    {
+        if (m_detail->m_members.capacity() >= capacity)
+            return;
+
+        copy();
+        m_detail->m_members.ensure_capacity(capacity);
+    }
+
+    void prepend(T value)
+    {
+        copy();
+        m_detail->m_members.prepend(move(value));
+    }
+
+    template<typename... Args>
+    void empend(Args&&... args)
+    {
+        copy();
+        m_detail->m_members.empend(forward<Args>(args)...);
+    }
+
+    void clear()
+    {
+        if (m_detail->ref_count() > 1)
+            m_detail = make_ref_counted<Detail>();
+        else
+            m_detail->m_members.clear();
+    }
+
+    T& at(size_t index)
+    {
+        // We're handing out a mutable reference, so make sure we own the data exclusively.
+        copy();
+        return m_detail->m_members.at(index);
+    }
+
+    T const& at(size_t index) const
+    {
+        return m_detail->m_members.at(index);
+    }
+
+    T& operator[](size_t index)
+    {
+        // We're handing out a mutable reference, so make sure we own the data exclusively.
+        copy();
+        return m_detail->m_members[index];
+    }
+
+    T const& operator[](size_t index) const
+    {
+        return m_detail->m_members[index];
+    }
+
+    size_t capacity() const
+    {
+        return m_detail->m_members.capacity();
+    }
+
+    size_t size() const
+    {
+        return m_detail->m_members.size();
+    }
+
+    bool is_empty() const
+    {
+        return m_detail->m_members.is_empty();
+    }
+
+    T const& first() const
+    {
+        return m_detail->m_members.first();
+    }
+
+    T const& last() const
+    {
+        return m_detail->m_members.last();
+    }
+
+private:
+    void copy()
+    {
+        if (m_detail->ref_count() <= 1)
+            return;
+        auto new_detail = make_ref_counted<Detail>();
+        new_detail->m_members = m_detail->m_members;
+        m_detail = new_detail;
+    }
+
+    NonnullRefPtr<Detail> m_detail;
+};
+
+}
+
+#if USING_AK_GLOBALLY
+using AK::COWVector;
+#endif

+ 1 - 129
Userland/Libraries/LibRegex/RegexMatch.h

@@ -11,6 +11,7 @@
 #include <AK/Error.h>
 
 #include <AK/ByteString.h>
+#include <AK/COWVector.h>
 #include <AK/DeprecatedFlyString.h>
 #include <AK/HashMap.h>
 #include <AK/MemMem.h>
@@ -25,135 +26,6 @@
 
 namespace regex {
 
-template<typename T>
-class COWVector {
-    struct Detail : RefCounted<Detail> {
-        Vector<T> m_members;
-    };
-
-public:
-    COWVector()
-        : m_detail(make_ref_counted<Detail>())
-    {
-    }
-
-    COWVector(COWVector const&) = default;
-    COWVector(COWVector&&) = default;
-
-    COWVector& operator=(COWVector const&) = default;
-    COWVector& operator=(COWVector&&) = default;
-
-    Vector<T> release() &&
-    {
-        if (m_detail->ref_count() == 1)
-            return exchange(m_detail->m_members, Vector<T>());
-
-        return m_detail->m_members;
-    }
-
-    void append(T const& value)
-    {
-        return append(T { value });
-    }
-
-    void append(T&& value)
-    {
-        copy();
-        m_detail->m_members.append(move(value));
-    }
-
-    void resize(size_t size)
-    {
-        copy();
-        m_detail->m_members.resize(size);
-    }
-
-    void ensure_capacity(size_t capacity)
-    {
-        if (m_detail->m_members.capacity() >= capacity)
-            return;
-
-        copy();
-        m_detail->m_members.ensure_capacity(capacity);
-    }
-
-    template<typename... Args>
-    void empend(Args&&... args)
-    {
-        copy();
-        m_detail->m_members.empend(forward<Args>(args)...);
-    }
-
-    void clear()
-    {
-        if (m_detail->ref_count() > 1)
-            m_detail = make_ref_counted<Detail>();
-        else
-            m_detail->m_members.clear();
-    }
-
-    T& at(size_t index)
-    {
-        // We're handing out a mutable reference, so make sure we own the data exclusively.
-        copy();
-        return m_detail->m_members.at(index);
-    }
-
-    T const& at(size_t index) const
-    {
-        return m_detail->m_members.at(index);
-    }
-
-    T& operator[](size_t index)
-    {
-        // We're handing out a mutable reference, so make sure we own the data exclusively.
-        copy();
-        return m_detail->m_members[index];
-    }
-
-    T const& operator[](size_t index) const
-    {
-        return m_detail->m_members[index];
-    }
-
-    size_t capacity() const
-    {
-        return m_detail->m_members.capacity();
-    }
-
-    size_t size() const
-    {
-        return m_detail->m_members.size();
-    }
-
-    bool is_empty() const
-    {
-        return m_detail->m_members.is_empty();
-    }
-
-    T const& first() const
-    {
-        return m_detail->m_members.first();
-    }
-
-    T const& last() const
-    {
-        return m_detail->m_members.last();
-    }
-
-private:
-    void copy()
-    {
-        if (m_detail->ref_count() <= 1)
-            return;
-        auto new_detail = make_ref_counted<Detail>();
-        new_detail->m_members = m_detail->m_members;
-        m_detail = new_detail;
-    }
-
-    NonnullRefPtr<Detail> m_detail;
-};
-
 class RegexStringView {
 public:
     RegexStringView() = default;