mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-31 17:52:27 +00:00
Introduce Cosmopolitan Templates Library (CTL)
This commit is contained in:
parent
b003888696
commit
4937843f70
16 changed files with 7054 additions and 12 deletions
242
ctl/vector.h
Normal file
242
ctl/vector.h
Normal file
|
@ -0,0 +1,242 @@
|
|||
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
|
||||
// vi: set et ft=c++ ts=4 sts=4 sw=4 fenc=utf-8 :vi
|
||||
#ifndef COSMOPOLITAN_CTL_OPTIONAL_H_
|
||||
#define COSMOPOLITAN_CTL_OPTIONAL_H_
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/swap.h>
|
||||
|
||||
template<typename T>
|
||||
struct Vector
|
||||
{
|
||||
size_t n = 0;
|
||||
size_t c = 0;
|
||||
T* p = nullptr;
|
||||
|
||||
using iterator = T*;
|
||||
using const_iterator = const T*;
|
||||
|
||||
Vector() = default;
|
||||
|
||||
~Vector()
|
||||
{
|
||||
delete[] p;
|
||||
}
|
||||
|
||||
Vector(const Vector& other)
|
||||
{
|
||||
n = other.n;
|
||||
c = other.c;
|
||||
p = new T[c];
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
new (&p[i]) T(other.p[i]);
|
||||
}
|
||||
|
||||
Vector(Vector&& other) noexcept
|
||||
{
|
||||
n = other.n;
|
||||
c = other.c;
|
||||
p = other.p;
|
||||
other.n = 0;
|
||||
other.c = 0;
|
||||
other.p = nullptr;
|
||||
}
|
||||
|
||||
explicit Vector(size_t count, const T& value = T())
|
||||
{
|
||||
n = count;
|
||||
c = count;
|
||||
p = new T[c];
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
new (&p[i]) T(value);
|
||||
}
|
||||
|
||||
Vector& operator=(const Vector& other)
|
||||
{
|
||||
if (this != &other) {
|
||||
T* newData = new T[other.c];
|
||||
for (size_t i = 0; i < other.n; ++i) {
|
||||
newData[i] = other.p[i];
|
||||
}
|
||||
delete[] p;
|
||||
p = newData;
|
||||
n = other.n;
|
||||
c = other.c;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Vector& operator=(Vector&& other) noexcept
|
||||
{
|
||||
if (this != &other) {
|
||||
delete[] p;
|
||||
p = other.p;
|
||||
n = other.n;
|
||||
c = other.c;
|
||||
other.p = nullptr;
|
||||
other.n = 0;
|
||||
other.c = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return !n;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t capacity() const
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
T& operator[](size_t i)
|
||||
{
|
||||
if (i >= n)
|
||||
__builtin_trap();
|
||||
return p[i];
|
||||
}
|
||||
|
||||
const T& operator[](size_t i) const
|
||||
{
|
||||
if (i >= n)
|
||||
__builtin_trap();
|
||||
return p[i];
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return p + n;
|
||||
}
|
||||
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
const_iterator cend() const
|
||||
{
|
||||
return p + n;
|
||||
}
|
||||
|
||||
T& front()
|
||||
{
|
||||
if (!n)
|
||||
__builtin_trap();
|
||||
return p[0];
|
||||
}
|
||||
|
||||
const T& front() const
|
||||
{
|
||||
if (!n)
|
||||
__builtin_trap();
|
||||
return p[0];
|
||||
}
|
||||
|
||||
T& back()
|
||||
{
|
||||
if (!n)
|
||||
__builtin_trap();
|
||||
return p[n - 1];
|
||||
}
|
||||
|
||||
const T& back() const
|
||||
{
|
||||
if (!n)
|
||||
__builtin_trap();
|
||||
return p[n - 1];
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
p[i].~T();
|
||||
n = 0;
|
||||
}
|
||||
|
||||
void reserve(size_t c2)
|
||||
{
|
||||
if (c2 <= c)
|
||||
return;
|
||||
T* newP = new T[c2];
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
newP[i] = std::move(p[i]);
|
||||
delete[] p;
|
||||
p = newP;
|
||||
c = c2;
|
||||
}
|
||||
|
||||
void push_back(const T& e)
|
||||
{
|
||||
if (n == c) {
|
||||
size_t c2 = c + 1;
|
||||
c2 += c2 >> 1;
|
||||
reserve(c2);
|
||||
}
|
||||
new (&p[n]) T(e);
|
||||
++n;
|
||||
}
|
||||
|
||||
void push_back(T&& e)
|
||||
{
|
||||
if (n == c) {
|
||||
size_t c2 = c + 1;
|
||||
c2 += c2 >> 1;
|
||||
reserve(c2);
|
||||
}
|
||||
new (&p[n]) T(std::forward<T>(e));
|
||||
++n;
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void emplace_back(Args&&... args)
|
||||
{
|
||||
if (n == c) {
|
||||
size_t c2 = c + 1;
|
||||
c2 += c2 >> 1;
|
||||
reserve(c2);
|
||||
}
|
||||
new (&p[n]) T(std::forward<Args>(args)...);
|
||||
++n;
|
||||
}
|
||||
|
||||
void pop_back()
|
||||
{
|
||||
if (n > 0) {
|
||||
--n;
|
||||
p[n].~T();
|
||||
}
|
||||
}
|
||||
|
||||
void resize(size_t n2)
|
||||
{
|
||||
if (n2 > n) {
|
||||
reserve(n2);
|
||||
for (size_t i = n; i < n2; ++i)
|
||||
new (&p[i]) T();
|
||||
} else if (n2 < n) {
|
||||
for (size_t i = n2; i < n; ++i)
|
||||
p[i].~T();
|
||||
}
|
||||
n = n2;
|
||||
}
|
||||
|
||||
void swap(Vector& other) noexcept
|
||||
{
|
||||
std::swap(n, other.n);
|
||||
std::swap(c, other.c);
|
||||
std::swap(p, other.p);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // COSMOPOLITAN_CTL_OPTIONAL_H_
|
Loading…
Add table
Add a link
Reference in a new issue