Also added a pretty much untested and totally incomplete STL string type.
This commit is contained in:
12
bastl/include/algorithm
Normal file
12
bastl/include/algorithm
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_ALGORITHM_INCLUDED)
|
||||
#define BAD_APPLE_OS_ALGORITHM_INCLUDED
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_ALGORITHM_INCLUDED)
|
||||
146
bastl/include/array
Normal file
146
bastl/include/array
Normal file
@@ -0,0 +1,146 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_ARRAY_INCLUDED)
|
||||
#define BAD_APPLE_OS_ARRAY_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename T, std::size_t N>
|
||||
class array
|
||||
{
|
||||
public:
|
||||
using value_type = T;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using pointer = value_type*;
|
||||
using const_pointer = const value_type*;
|
||||
using iterator = pointer;
|
||||
using const_iterator = const_pointer;
|
||||
|
||||
T _elements;
|
||||
|
||||
constexpr reference operator[](size_type pos) noexcept
|
||||
{
|
||||
return _elements[pos];
|
||||
}
|
||||
|
||||
constexpr const_reference operator[](size_type pos) const noexcept
|
||||
{
|
||||
return _elements[pos];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr reference at(size_type pos)
|
||||
{
|
||||
if (pos >= N) {
|
||||
__ba_throw out_of_range();
|
||||
}
|
||||
return _elements[pos];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_reference at(size_type pos) const
|
||||
{
|
||||
if (pos >= N) {
|
||||
__ba_throw out_of_range();
|
||||
}
|
||||
return _elements[pos];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr reference front() noexcept
|
||||
{
|
||||
return _elements[0];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_reference front() const noexcept
|
||||
{
|
||||
return _elements[0];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr reference back() noexcept
|
||||
{
|
||||
return _elements[N - 1];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_reference back() const noexcept
|
||||
{
|
||||
return _elements[N - 1];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr pointer data() noexcept
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_pointer data() const noexcept
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr iterator begin() noexcept
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_iterator begin() const noexcept
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_iterator cbegin() const noexcept
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr iterator end() noexcept
|
||||
{
|
||||
return &_elements[N];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_iterator end() const noexcept
|
||||
{
|
||||
return &_elements[N];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_iterator cend() const noexcept
|
||||
{
|
||||
return &_elements[N];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool empty() const noexcept
|
||||
{
|
||||
return N == 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr size_type size() const noexcept
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr size_type max_size() const noexcept
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
constexpr void fill(const T& value)
|
||||
{
|
||||
for (T& ele : *this) {
|
||||
ele = value;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr void swap(array& other)
|
||||
{
|
||||
for (size_type idx = 0; idx < N; ++idx) {
|
||||
std::swap((*this)[idx], other[idx]);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_ARRAY_INCLUDED)
|
||||
9
bastl/include/cassert
Normal file
9
bastl/include/cassert
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_CASSERT_INCLUDED)
|
||||
#define BAD_APPLE_OS_CASSERT_INCLUDED
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_CASSERT_INCLUDED)
|
||||
13
bastl/include/cstdarg
Normal file
13
bastl/include/cstdarg
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
#if !defined(BAD_APPLE_OS_CSTDARG_INCLUDED)
|
||||
#define BAD_APPLE_OS_CSTDARG_INCLUDED
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
using ::va_list;
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_CSTDARG_INCLUDED)
|
||||
16
bastl/include/cstddef
Normal file
16
bastl/include/cstddef
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_CSTDDEF_INCLUDED)
|
||||
#define BAD_APPLE_OS_CSTDDEF_INCLUDED
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
using ::nullptr_t;
|
||||
using ::ptrdiff_t;
|
||||
using ::size_t;
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_CSTDDEF_INCLUDED)
|
||||
17
bastl/include/cstdio
Normal file
17
bastl/include/cstdio
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_CSTDIO_INCLUDED)
|
||||
#define BAD_APPLE_OS_CSTDIO_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
using ::putchar;
|
||||
using ::puts;
|
||||
using ::printf;
|
||||
using ::vprintf;
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_CSTDIO_INCLUDED)
|
||||
18
bastl/include/cstdlib
Normal file
18
bastl/include/cstdlib
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_CSTDLIB_INCLUDED)
|
||||
#define BAD_APPLE_OS_CSTDLIB_INCLUDED
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
using ::abort;
|
||||
using ::malloc;
|
||||
using ::free;
|
||||
}
|
||||
|
||||
void __ba_registerAllocatableMemory(void* memory, size_t size) noexcept;
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_CSTDLIB_INCLUDED)
|
||||
19
bastl/include/cstring
Normal file
19
bastl/include/cstring
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_CSTRING_INCLUDED)
|
||||
#define BAD_APPLE_OS_CSTRING_INCLUDED
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
using ::strlen;
|
||||
|
||||
using ::memcmp;
|
||||
using ::memcpy;
|
||||
using ::memmove;
|
||||
using ::memset;
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_CSTRING_INCLUDED)
|
||||
50
bastl/include/exception
Normal file
50
bastl/include/exception
Normal file
@@ -0,0 +1,50 @@
|
||||
|
||||
#if !defined(BAD_APPLE_OS_EXCEPTION_INCLUDED)
|
||||
#define BAD_APPLE_OS_EXCEPTION_INCLUDED
|
||||
|
||||
#include <cstdlib>
|
||||
#include "os/panic.hpp"
|
||||
|
||||
#if defined(__cpp_exceptions)
|
||||
#define __ba_throw throw
|
||||
#else
|
||||
#define __ba_throw ba::impl::gAbortHelper(__FILE__, __LINE__) =
|
||||
#endif
|
||||
|
||||
namespace std
|
||||
{
|
||||
class exception
|
||||
{
|
||||
public:
|
||||
virtual ~exception() noexcept = default;
|
||||
virtual const char* what() const noexcept;
|
||||
};
|
||||
}
|
||||
|
||||
#if !defined(__cpp_exceptions)
|
||||
namespace ba::impl
|
||||
{
|
||||
struct ExceptionAbortHelper
|
||||
{
|
||||
private:
|
||||
const char* mFile = "<unknown>";
|
||||
int mLine = -1;
|
||||
public:
|
||||
[[noreturn]] ExceptionAbortHelper& operator=(const std::exception& ex) noexcept
|
||||
{
|
||||
panicf("Uncaught exception with message \"%s\" at %s:%d.", ex.what(), mFile, mLine);
|
||||
}
|
||||
|
||||
ExceptionAbortHelper& operator()(const char* file, int line) noexcept
|
||||
{
|
||||
mFile = file;
|
||||
mLine = line;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
extern ExceptionAbortHelper gAbortHelper;
|
||||
}
|
||||
#endif // !defined(__cpp_exceptions)
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_EXCEPTION_INCLUDED)
|
||||
30
bastl/include/new
Normal file
30
bastl/include/new
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
#if !defined(BAD_APPLE_OS_NEW_INCLUDED)
|
||||
#define BAD_APPLE_OS_NEW_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
#include <exception>
|
||||
|
||||
namespace std
|
||||
{
|
||||
class bad_alloc : public std::exception
|
||||
{
|
||||
public:
|
||||
bad_alloc() noexcept = default;
|
||||
bad_alloc(const bad_alloc&) noexcept = default;
|
||||
|
||||
const char * what() const noexcept override;
|
||||
};
|
||||
}
|
||||
|
||||
inline void* operator new(std::size_t, void* placement) noexcept
|
||||
{
|
||||
return placement;
|
||||
}
|
||||
|
||||
inline void* operator new[](std::size_t, void* placement) noexcept
|
||||
{
|
||||
return placement;
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_NEW_INCLUDED)
|
||||
23
bastl/include/stdexcept
Normal file
23
bastl/include/stdexcept
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_STDEXCEPT_INCLUDED)
|
||||
#define BAD_APPLE_OS_STDEXCEPT_INCLUDED
|
||||
|
||||
#include "exception"
|
||||
|
||||
namespace std
|
||||
{
|
||||
class logic_error : public exception
|
||||
{
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
class out_of_range : public logic_error
|
||||
{
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_STDEXCEPT_INCLUDED)
|
||||
125
bastl/include/string
Normal file
125
bastl/include/string
Normal file
@@ -0,0 +1,125 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_STRING_INCLUDED)
|
||||
#define BAD_APPLE_OS_STRING_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename CharT>
|
||||
class char_traits {};
|
||||
|
||||
template<>
|
||||
class char_traits<char>
|
||||
{
|
||||
public:
|
||||
using char_type = char;
|
||||
using int_type = int;
|
||||
using off_type = std::ptrdiff_t; // TODO: should be std::streamoff?
|
||||
// TODO: ??
|
||||
};
|
||||
|
||||
template<typename CharT, typename Traits = char_traits<CharT>> // TODO: Allocator
|
||||
class basic_string
|
||||
{
|
||||
public:
|
||||
using traits_type = Traits;
|
||||
using value_type = CharT;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using pointer = value_type*;
|
||||
using const_pointer = const value_type*;
|
||||
using iterator = pointer;
|
||||
using const_iterator = const_pointer;
|
||||
private:
|
||||
vector<value_type> _data;
|
||||
public:
|
||||
constexpr basic_string() noexcept : basic_string("") {}
|
||||
constexpr basic_string(const basic_string& other) = default;
|
||||
constexpr basic_string(basic_string&& other) = default;
|
||||
constexpr basic_string(size_type count, value_type chr) : _data(count, chr) {}
|
||||
constexpr basic_string(const basic_string& other, size_type pos, size_type count = npos)
|
||||
: basic_string(other.substr(pos, count)) {}
|
||||
constexpr basic_string(const value_type* str, size_type count)
|
||||
{
|
||||
_data.resize(count + 1);
|
||||
for (size_type idx = 0; idx < count; ++idx) {
|
||||
_data[idx] = str[idx];
|
||||
}
|
||||
_data[count] = value_type(0);
|
||||
}
|
||||
constexpr basic_string(const value_type* str) : basic_string(str, strlen(str)) {} // NOLINT
|
||||
// TODO: all the other constructors
|
||||
constexpr basic_string& operator=(const basic_string& other) = default;
|
||||
constexpr basic_string& operator=(basic_string&& other) = default;
|
||||
constexpr basic_string& operator=(const value_type* str)
|
||||
{
|
||||
const size_t count = strlen(str);
|
||||
_data.resize(count + 1);
|
||||
for (size_type idx = 0; idx < count; ++idx) {
|
||||
_data[idx] = str[idx];
|
||||
}
|
||||
_data[count] = value_type(0);
|
||||
return *this;
|
||||
}
|
||||
constexpr basic_string& operator=(value_type chr)
|
||||
{
|
||||
_data.resize(2);
|
||||
_data[0] = chr;
|
||||
_data[1] = value_type(0);
|
||||
return *this;
|
||||
}
|
||||
constexpr basic_string& operator=(std::nullptr_t) = delete;
|
||||
|
||||
[[nodiscard]] constexpr reference operator[](size_type pos) noexcept { return _data[pos]; }
|
||||
[[nodiscard]] constexpr const_reference operator[](size_type pos) const noexcept { return _data[pos]; }
|
||||
|
||||
// TODO: the range check should actually also fail for the \0 in the end
|
||||
[[nodiscard]] constexpr reference at(size_type pos) { return _data.at(pos); }
|
||||
[[nodiscard]] constexpr const_reference at(size_type pos) const { return _data.at(pos); }
|
||||
|
||||
[[nodiscard]] constexpr reference front() noexcept { return _data.front(); }
|
||||
[[nodiscard]] constexpr const_reference front() const noexcept { return _data.front(); }
|
||||
|
||||
[[nodiscard]] constexpr reference back() noexcept { return _data.back(); }
|
||||
[[nodiscard]] constexpr const_reference back() const noexcept { return _data.back(); }
|
||||
|
||||
[[nodiscard]] constexpr pointer data() noexcept { return _data.data(); }
|
||||
[[nodiscard]] constexpr const_pointer data() const noexcept { return _data.data(); }
|
||||
|
||||
[[nodiscard]] constexpr const_pointer c_str() const noexcept { return data(); }
|
||||
|
||||
[[nodiscard]] constexpr iterator begin() noexcept { return _data.begin(); }
|
||||
[[nodiscard]] constexpr const_iterator begin() const noexcept { return _data.begin(); }
|
||||
[[nodiscard]] constexpr const_iterator cbegin() const noexcept { return _data.begin(); }
|
||||
[[nodiscard]] constexpr iterator end() noexcept { return _data.end() - 1; }
|
||||
[[nodiscard]] constexpr const_iterator end() const noexcept { return _data.end() - 1; }
|
||||
[[nodiscard]] constexpr const_iterator cend() const noexcept { return _data.end() - 1; }
|
||||
|
||||
[[nodiscard]] constexpr bool empty() const noexcept { return size() == 0; }
|
||||
[[nodiscard]] constexpr size_type size() const noexcept { return _data.size() - 1; }
|
||||
[[nodiscard]] constexpr size_type max_size() const noexcept { return _data.max_size() - 1; }
|
||||
constexpr void reserve(size_type newCapacity) noexcept { _data.reserve(newCapacity + 1); }
|
||||
[[nodiscard]] constexpr size_type capacity() const noexcept { return _data.capacity() - 1; }
|
||||
constexpr void shrink_to_fit() noexcept { _data.shrink_to_fit(); }
|
||||
|
||||
constexpr void clear() { *this = ""; }
|
||||
constexpr void resize(size_type count, value_type chr = value_type())
|
||||
{
|
||||
_data.resize(count + 1, chr);
|
||||
_data.back() = value_type(0);
|
||||
}
|
||||
|
||||
static inline size_type npos = size_type(-1);
|
||||
};
|
||||
using string = basic_string<char>;
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_STRING_INCLUDED)
|
||||
31
bastl/include/type_traits
Normal file
31
bastl/include/type_traits
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_TYPE_TRAITS_INCLUDED)
|
||||
#define BAD_APPLE_OS_TYPE_TRAITS_INCLUDED
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename T>
|
||||
struct remove_reference
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct remove_reference<T&>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct remove_reference<T&&>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using remove_reference_t = typename remove_reference<T>::type;
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_TYPE_TRAITS_INCLUDED)
|
||||
40
bastl/include/utility
Normal file
40
bastl/include/utility
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_UTILITY_INCLUDED)
|
||||
#define BAD_APPLE_OS_UTILITY_INCLUDED
|
||||
|
||||
#include "type_traits"
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename T>
|
||||
constexpr remove_reference_t<T>&& move(T&& val) noexcept
|
||||
{
|
||||
return static_cast<remove_reference_t<T>&&>(val);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr void swap(T& first, T& second)
|
||||
{
|
||||
T temp = std::move(first);
|
||||
first = std::move(second);
|
||||
second = std::move(temp);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] constexpr T&& forward(remove_reference_t<T>& value)
|
||||
{
|
||||
return static_cast<T&&>(value);
|
||||
}
|
||||
|
||||
template<typename T, typename U = T>
|
||||
[[nodiscard]] constexpr T exchange(T& obj, U&& newValue)
|
||||
{
|
||||
T oldValue = std::move(obj);
|
||||
obj = std::forward<U>(newValue);
|
||||
return oldValue;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_UTILITY_INCLUDED)
|
||||
291
bastl/include/vector
Normal file
291
bastl/include/vector
Normal file
@@ -0,0 +1,291 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_VECTOR_INCLUDED)
|
||||
#define BAD_APPLE_OS_VECTOR_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
#include <new>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename T> // TODO: allocator
|
||||
class vector
|
||||
{
|
||||
public:
|
||||
using value_type = T;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using pointer = value_type*;
|
||||
using const_pointer = const value_type*;
|
||||
using iterator = pointer;
|
||||
using const_iterator = const_pointer;
|
||||
private:
|
||||
T* _elements = nullptr;
|
||||
size_type _size = 0;
|
||||
size_type _capacity = 0;
|
||||
public:
|
||||
constexpr vector() noexcept = default;
|
||||
constexpr vector(const vector& other) noexcept
|
||||
{
|
||||
resize(other.size());
|
||||
for (size_type idx = 0; idx < size(); ++idx)
|
||||
{
|
||||
(*this)[idx] = other[idx];
|
||||
}
|
||||
}
|
||||
constexpr vector(vector&& other) noexcept
|
||||
: _elements(exchange(other._elements, nullptr)),
|
||||
_size(exchange(other._size, 0)),
|
||||
_capacity(exchange(other._capacity, 0))
|
||||
{
|
||||
}
|
||||
constexpr explicit vector(size_type count, const value_type& value = value_type())
|
||||
{
|
||||
resize(count, value);
|
||||
}
|
||||
constexpr ~vector() noexcept
|
||||
{
|
||||
delete _elements;
|
||||
}
|
||||
constexpr vector& operator=(const vector& other)
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
resize(other.size());
|
||||
for (size_type idx = 0; idx < size(); ++idx)
|
||||
{
|
||||
(*this)[idx] = other[idx];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
constexpr vector& operator=(vector&& other)
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
clear();
|
||||
_elements = exchange(other._elements, nullptr);
|
||||
_size = exchange(other._size, 0);
|
||||
_capacity = exchange(other._capacity, 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr reference operator[](size_type pos) noexcept
|
||||
{
|
||||
return _elements[pos];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_reference operator[](size_type pos) const noexcept
|
||||
{
|
||||
return _elements[pos];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr reference at(size_type pos)
|
||||
{
|
||||
if (pos >= size()) {
|
||||
__ba_throw out_of_range();
|
||||
}
|
||||
return _elements[pos];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_reference at(size_type pos) const
|
||||
{
|
||||
if (pos >= size()) {
|
||||
__ba_throw out_of_range();
|
||||
}
|
||||
return _elements[pos];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr reference front() noexcept
|
||||
{
|
||||
return _elements[0];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_reference front() const noexcept
|
||||
{
|
||||
return _elements[0];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr reference back() noexcept
|
||||
{
|
||||
return _elements[size() - 1];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_reference back() const noexcept
|
||||
{
|
||||
return _elements[size() - 1];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr pointer data() noexcept
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_pointer data() const noexcept
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr iterator begin() noexcept
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_iterator begin() const noexcept
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_iterator cbegin() const noexcept
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr iterator end() noexcept
|
||||
{
|
||||
return &_elements[size()];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_iterator end() const noexcept
|
||||
{
|
||||
return &_elements[size()];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr const_iterator cend() const noexcept
|
||||
{
|
||||
return &_elements[size()];
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool empty() const noexcept
|
||||
{
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr size_type size() const noexcept
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr size_type max_size() const noexcept
|
||||
{
|
||||
return size_type(-1);
|
||||
}
|
||||
|
||||
constexpr void reserve(size_type newCapacity)
|
||||
{
|
||||
if (newCapacity <= capacity()) {
|
||||
return;
|
||||
}
|
||||
updateCapacity(newCapacity);
|
||||
}
|
||||
|
||||
[[nodiscard]] size_type capacity() const noexcept
|
||||
{
|
||||
return _capacity;
|
||||
}
|
||||
|
||||
constexpr void shrink_to_fit()
|
||||
{
|
||||
updateCapacity(size());
|
||||
}
|
||||
|
||||
constexpr void clear()
|
||||
{
|
||||
resize(0);
|
||||
}
|
||||
|
||||
constexpr void push_back(const value_type& value)
|
||||
{
|
||||
reserve(size() + 1);
|
||||
::new (&_elements[size()]) T(value);
|
||||
++_size;
|
||||
}
|
||||
|
||||
constexpr void push_back(value_type&& value)
|
||||
{
|
||||
reserve(size() + 1);
|
||||
::new (&_elements[size()]) T(std::move(value));
|
||||
++_size;
|
||||
}
|
||||
|
||||
template<typename... TArgs>
|
||||
constexpr reference emplace_back(TArgs&&... args)
|
||||
{
|
||||
reserve(size() + 1);
|
||||
::new (&_elements[size()]) T(std::forward<TArgs>(args)...);
|
||||
++_size;
|
||||
}
|
||||
|
||||
constexpr void resize(size_type newSize)
|
||||
{
|
||||
if (newSize == size()) {
|
||||
return;
|
||||
}
|
||||
reserve(newSize);
|
||||
|
||||
if (newSize > size())
|
||||
{
|
||||
for (size_type idx = size(); idx < newSize; ++idx)
|
||||
{
|
||||
::new (&_elements[idx]) T();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_type idx = newSize; idx < size(); ++idx)
|
||||
{
|
||||
_elements[idx].~T();
|
||||
}
|
||||
}
|
||||
_size = newSize;
|
||||
}
|
||||
|
||||
constexpr void resize(size_type newSize, const value_type& initValue)
|
||||
{
|
||||
if (newSize == size()) {
|
||||
return;
|
||||
}
|
||||
reserve(newSize);
|
||||
|
||||
if (newSize > size())
|
||||
{
|
||||
for (size_type idx = size(); idx < newSize; ++idx)
|
||||
{
|
||||
::new (&_elements[idx]) T(initValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_type idx = newSize; idx < size(); ++idx)
|
||||
{
|
||||
_elements[idx].~T();
|
||||
}
|
||||
}
|
||||
_size = newSize;
|
||||
}
|
||||
private:
|
||||
void updateCapacity(size_type newCapacity)
|
||||
{
|
||||
if (capacity() == newCapacity) {
|
||||
return;
|
||||
}
|
||||
T* newElements = static_cast<T*>(malloc(newCapacity * sizeof(T)));
|
||||
for (size_type idx = 0; idx < size(); ++idx)
|
||||
{
|
||||
::new (&newElements[idx]) T(move(_elements[idx]));
|
||||
_elements[idx].~T();
|
||||
}
|
||||
free(_elements);
|
||||
_elements = newElements;
|
||||
_capacity = newCapacity;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_VECTOR_INCLUDED)
|
||||
Reference in New Issue
Block a user