[libc-commits] [libc] 06cfb7a - [libc] add a vector internal class
Michael Jones via libc-commits
libc-commits at lists.llvm.org
Thu Feb 10 11:04:22 PST 2022
Author: Michael Jones
Date: 2022-02-10T11:04:18-08:00
New Revision: 06cfb7a3456b6e657047c31b4b4c57006d5fc9d1
URL: https://github.com/llvm/llvm-project/commit/06cfb7a3456b6e657047c31b4b4c57006d5fc9d1
DIFF: https://github.com/llvm/llvm-project/commit/06cfb7a3456b6e657047c31b4b4c57006d5fc9d1.diff
LOG: [libc] add a vector internal class
Add a basic implementation of the vector class for use internally to
LLVM-libc.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D118954
Added:
libc/src/__support/CPP/vector.h
libc/test/utils/CPP/vector_test.cpp
Modified:
libc/src/__support/CPP/CMakeLists.txt
libc/test/utils/CPP/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/src/__support/CPP/CMakeLists.txt b/libc/src/__support/CPP/CMakeLists.txt
index 78f6cf2cd2c3f..b591734a6b6f6 100644
--- a/libc/src/__support/CPP/CMakeLists.txt
+++ b/libc/src/__support/CPP/CMakeLists.txt
@@ -1,3 +1,4 @@
+# TODO(michaelrj): separate the standalone_cpp library into individual targets.
add_header_library(
standalone_cpp
HDRS
@@ -10,3 +11,11 @@ add_header_library(
StringView.h
TypeTraits.h
)
+
+add_header_library(
+ vector
+ HDRS
+ vector.h
+ DEPENDS
+ libc.include.stdlib
+)
diff --git a/libc/src/__support/CPP/vector.h b/libc/src/__support/CPP/vector.h
new file mode 100644
index 0000000000000..e8873d1c14ad2
--- /dev/null
+++ b/libc/src/__support/CPP/vector.h
@@ -0,0 +1,92 @@
+//===-- A self contained equivalent of std::vector --------------*- 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 LLVM_LIBC_SRC_SUPPORT_CPP_VECTOR_H
+#define LLVM_LIBC_SRC_SUPPORT_CPP_VECTOR_H
+
+#include <stddef.h> // For size_t.
+
+#include <stdlib.h> // For malloc/realloc/free
+
+namespace __llvm_libc {
+namespace cpp {
+
+// This implementation does not have a templated allocator since that feature
+// isn't relevant for a libc setting.
+
+// Vector is a templated dynamically resizable array. This implementation is
+// only meant for primitives or structs, and will not call destructors on held
+// objects.
+template <class T> class vector {
+ T *data_array;
+ size_t array_size;
+ size_t num_elements = 0;
+ static constexpr size_t DEFAULT_SIZE = 16;
+ static constexpr size_t GROWTH_FACTOR = 2;
+ static constexpr size_t MAX_SIZE = ~size_t(0);
+
+public:
+ constexpr vector<T>() : array_size{DEFAULT_SIZE} {
+ data_array = static_cast<T *>(malloc(DEFAULT_SIZE * sizeof(T)));
+ }
+
+ constexpr vector<T>(const vector<T> &other) = delete;
+ constexpr vector<T>(const vector<T> &&other) = delete;
+
+ ~vector() { free(data_array); }
+
+ constexpr vector &operator=(vector &other) = delete;
+ constexpr vector &operator=(vector &&other) = delete;
+
+ constexpr void reserve(size_t new_size) {
+ if (new_size >= array_size)
+ increase_size(new_size + 1);
+ }
+
+ constexpr void push_back(const T &value) {
+ if (num_elements >= array_size)
+ increase_size(num_elements + 1);
+ data_array[num_elements] = value;
+ ++num_elements;
+ }
+
+ constexpr T &operator[](size_t pos) { return data_array[pos]; }
+ constexpr T *data() { return data_array; }
+ constexpr const T *data() const { return data_array; }
+
+ constexpr bool empty() const { return num_elements == 0; }
+
+ constexpr size_t size() const { return num_elements; }
+ constexpr size_t max_size() const { return MAX_SIZE; }
+
+ constexpr size_t capacity() const { return array_size; }
+
+private:
+ static constexpr size_t MAX_DIV_BY_GROWTH = MAX_SIZE / GROWTH_FACTOR;
+
+ // new_size is treated as the minimum size for the new array. This function
+ // will increase array_size by GROWTH_FACTOR until there is space for new_size
+ // items.
+ constexpr void increase_size(size_t new_size) {
+ size_t temp_size = array_size;
+ if (new_size >= MAX_DIV_BY_GROWTH) {
+ temp_size = new_size;
+ } else {
+ if (temp_size == 0)
+ temp_size = 1;
+ while (temp_size <= new_size)
+ temp_size = temp_size * GROWTH_FACTOR;
+ }
+ array_size = temp_size;
+ data_array = static_cast<T *>(realloc(data_array, array_size * sizeof(T)));
+ }
+};
+} // namespace cpp
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SUPPORT_CPP_VECTOR_H
diff --git a/libc/test/utils/CPP/CMakeLists.txt b/libc/test/utils/CPP/CMakeLists.txt
index a4a0eed0c9c74..7d4f15b7af5c5 100644
--- a/libc/test/utils/CPP/CMakeLists.txt
+++ b/libc/test/utils/CPP/CMakeLists.txt
@@ -39,3 +39,13 @@ add_libc_unittest(
DEPENDS
libc.src.__support.CPP.standalone_cpp
)
+
+add_libc_unittest(
+ vector_test
+ SUITE
+ libc_cpp_utils_unittests
+ SRCS
+ vector_test.cpp
+ DEPENDS
+ libc.src.__support.CPP.vector
+)
diff --git a/libc/test/utils/CPP/vector_test.cpp b/libc/test/utils/CPP/vector_test.cpp
new file mode 100644
index 0000000000000..a27eafa151bc6
--- /dev/null
+++ b/libc/test/utils/CPP/vector_test.cpp
@@ -0,0 +1,37 @@
+//===-- Unittests for vector ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/CPP/vector.h"
+#include "utils/UnitTest/Test.h"
+
+TEST(LlvmLibcVectorTest, SimpleConstructor) {
+ __llvm_libc::cpp::vector<int> vec;
+}
+
+TEST(LlvmLibcVectorTest, OrderedWriteOrderedReadTest) {
+ __llvm_libc::cpp::vector<size_t> vec;
+
+ for (size_t i = 0; i < 100; i = i + 2) {
+ vec.push_back(i);
+ }
+ ASSERT_EQ(vec.size(), size_t(50));
+ ASSERT_GE(vec.capacity(), vec.size());
+ for (size_t j = 0; j < vec.size(); ++j) {
+ ASSERT_EQ(vec[j], j * 2);
+ }
+}
+
+TEST(LlvmLibcVectorTest, ReserveTest) {
+ __llvm_libc::cpp::vector<bool> vec;
+
+ size_t prev_capacity = vec.capacity();
+
+ vec.reserve(prev_capacity * 2);
+
+ ASSERT_GT(vec.capacity(), prev_capacity * 2);
+}
More information about the libc-commits
mailing list