//===-- 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 // For size_t. #include // 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 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() : array_size{DEFAULT_SIZE} { data_array = static_cast(malloc(DEFAULT_SIZE * sizeof(T))); } constexpr vector(const vector &other) = delete; constexpr vector(const vector &&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(realloc(data_array, array_size * sizeof(T))); } }; } // namespace cpp } // namespace __llvm_libc #endif // LLVM_LIBC_SRC_SUPPORT_CPP_VECTOR_H