[libc-commits] [libc] [libc][FixedVector] Add more helper methods (PR #94278)

via libc-commits libc-commits at lists.llvm.org
Mon Jun 3 13:27:48 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: None (PiJoules)

<details>
<summary>Changes</summary>

This adds:
- A ctor accepting a start and end iterator
- A ctor accepting a count and const T&
- size()
- subscript operators
- begin() and end() iterators

---
Full diff: https://github.com/llvm/llvm-project/pull/94278.diff


3 Files Affected:

- (modified) libc/src/__support/fixedvector.h (+20) 
- (modified) libc/test/src/__support/CMakeLists.txt (+1) 
- (modified) libc/test/src/__support/fixedvector_test.cpp (+35) 


``````````diff
diff --git a/libc/src/__support/fixedvector.h b/libc/src/__support/fixedvector.h
index 81747ee10067c..b06321887e7a1 100644
--- a/libc/src/__support/fixedvector.h
+++ b/libc/src/__support/fixedvector.h
@@ -24,6 +24,16 @@ template <typename T, size_t CAPACITY> class FixedVector {
 public:
   constexpr FixedVector() = default;
 
+  template <typename It> constexpr FixedVector(It begin, It end) {
+    for (; begin != end; ++begin)
+      push_back(*begin);
+  }
+
+  constexpr FixedVector(size_t count, const T &value) {
+    for (size_t i = 0; i < count; ++i)
+      push_back(value);
+  }
+
   bool push_back(const T &obj) {
     if (item_count == CAPACITY)
       return false;
@@ -43,8 +53,14 @@ template <typename T, size_t CAPACITY> class FixedVector {
     return true;
   }
 
+  T &operator[](size_t idx) { return store[idx]; }
+
+  const T &operator[](size_t idx) const { return store[idx]; }
+
   bool empty() const { return item_count == 0; }
 
+  size_t size() const { return item_count; }
+
   // Empties the store for all practical purposes.
   void reset() { item_count = 0; }
 
@@ -63,6 +79,10 @@ template <typename T, size_t CAPACITY> class FixedVector {
     return reverse_iterator{&store[item_count]};
   }
   LIBC_INLINE constexpr reverse_iterator rend() { return store.rend(); }
+
+  using iterator = typename cpp::array<T, CAPACITY>::iterator;
+  LIBC_INLINE constexpr iterator begin() { return store.begin(); }
+  LIBC_INLINE constexpr iterator end() { return iterator{&store[item_count]}; }
 };
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt
index 663aa2bb82cae..936cfe4e2a20c 100644
--- a/libc/test/src/__support/CMakeLists.txt
+++ b/libc/test/src/__support/CMakeLists.txt
@@ -132,6 +132,7 @@ add_libc_test(
   SRCS
     fixedvector_test.cpp
   DEPENDS
+    libc.src.__support.CPP.array
     libc.src.__support.fixedvector
 )
 
diff --git a/libc/test/src/__support/fixedvector_test.cpp b/libc/test/src/__support/fixedvector_test.cpp
index 4e92081321de7..c61b9ca815643 100644
--- a/libc/test/src/__support/fixedvector_test.cpp
+++ b/libc/test/src/__support/fixedvector_test.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "src/__support/CPP/array.h"
 #include "src/__support/fixedvector.h"
 #include "test/UnitTest/Test.h"
 
@@ -59,3 +60,37 @@ TEST(LlvmLibcFixedVectorTest, Iteration) {
   for (auto it = v.rbegin(), e = v.rend(); it != e; ++it)
     ASSERT_GT(*it, -1);
 }
+
+TEST(LlvmLibcFixedVectorTest, ConstructionFromIterators) {
+  LIBC_NAMESPACE::cpp::array<int, 4> arr{1, 2, 3, 4};
+  LIBC_NAMESPACE::FixedVector<int, 5> vec(arr.begin(), arr.end());
+  ASSERT_EQ(vec.size(), arr.size());
+  for (size_t i = 0; i < arr.size(); ++i)
+    ASSERT_EQ(vec[i], arr[i]);
+}
+
+TEST(LlvmLibcFixedVectorTest, ConstructionFromCountAndValue) {
+  constexpr int kVal = 10;
+  // TODO: If the first argument here were just `4`, then we'd have no way to
+  // disambiguate between the FixedVector ctor that uses iterators vs the one
+  // taking a count and `cosnt T &`. Using `4` would result in a compile error.
+  // Formally, we can ensure the count + reference ctor is used if we gate the
+  // iterator ctor on checking if the type has the `input_iterator_tag` via
+  // iterator_traits, but we'd have to plumb that through which can be done
+  // separately. Note the snafu we hit here only happens because we happen to
+  // test with containters using integral types.
+  LIBC_NAMESPACE::FixedVector<int, 5> vec(size_t(4), kVal);
+  ASSERT_EQ(vec.size(), size_t(4));
+  for (size_t i = 0; i < vec.size(); ++i)
+    ASSERT_EQ(vec[i], kVal);
+}
+
+TEST(LlvmLibcFixedVectorTest, ForwardIteration) {
+  LIBC_NAMESPACE::cpp::array<int, 4> arr{1, 2, 3, 4};
+  LIBC_NAMESPACE::FixedVector<int, 5> vec(arr.begin(), arr.end());
+  ASSERT_EQ(vec.size(), arr.size());
+  for (auto it = vec.begin(); it != vec.end(); ++it) {
+    auto idx = it - vec.begin();
+    ASSERT_EQ(*it, arr[idx]);
+  }
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/94278


More information about the libc-commits mailing list