Squash commits for public release

This commit is contained in:
2025-02-12 09:54:05 -05:00
commit 7118adc514
1108 changed files with 80873 additions and 0 deletions

40
libs/libcxx/BUILD.gn Normal file
View File

@@ -0,0 +1,40 @@
import("//build/libs/TEMPLATE.gni")
import("//libs/libc/LIBC_SOURCES.gni")
libcxxabi_sources = [
"abi/cxa_runtime.cpp",
"abi/dynamic_cast.cpp",
"abi/type_info_defs.cpp",
]
if (target_arch == "arm32") {
libcxxabi_sources += [ "abi/aeabi_runtime.cpp" ]
}
xOS_static_library("libcxx") {
sources = libc_sources_for_libcxx
# Private LibCxx sources.
sources += [
"init/_init.cpp",
"init/_lib.cpp",
"src/iostream.cpp",
"src/typeinfo.cpp",
]
sources += libcxxabi_sources
if (target_arch == "arm32") {
sources += [ "../libc/string/routines/arm32/memset.S" ]
}
include_dirs = [
"include/",
"//libs/libc/include/",
"//libs/",
]
configs = [ "//build/libs:libcxx_flags" ]
if (host == "llvm") {
cflags = [ "-flto" ]
}
}

View File

@@ -0,0 +1,13 @@
extern "C" {
extern int __cxa_atexit(void (*)(void*), void*, void*);
int __aeabi_atexit(void* arg, void (*func)(void*), void* dso_handle)
{
return __cxa_atexit(func, arg, dso_handle);
}
int __aeabi_unwind_cpp_pr0()
{
return 0;
}
}

View File

@@ -0,0 +1,40 @@
#include "cxxabi.h"
#define __EXIT_ENTRIES_COUNT (64)
extern "C" {
VIS_HIDDEN void* __dso_handle;
struct VIS_HIDDEN __termination_info {
void (*func)(void*);
void* arg;
void* dso_handle;
};
static struct __termination_info __exit_info[__EXIT_ENTRIES_COUNT];
static int __exit_counter = 0;
int __cxa_atexit(void (*func)(void*), void* arg, void* dso_handle)
{
if (__exit_counter >= __EXIT_ENTRIES_COUNT) {
return -1;
}
__exit_info[__exit_counter++] = {
.func = func,
.arg = arg,
.dso_handle = dso_handle,
};
return 0;
}
void __cxa_finalize(void* dso_handle)
{
for (int i = __exit_counter - 1; i >= 0; i--) {
if (dso_handle && __exit_info[i].dso_handle != dso_handle) {
continue;
}
__exit_info[i].func(__exit_info[i].arg);
}
}
}

119
libs/libcxx/abi/cxxabi.h Normal file
View File

@@ -0,0 +1,119 @@
#ifndef _CXXABI_H
#define _CXXABI_H
#include <stdint.h>
#include <typeinfo>
#define VIS_HIDDEN __attribute__((visibility("hidden")))
#define VIS_INTERNAL __attribute__((visibility("internal")))
extern "C" {
int __cxa_atexit(void (*)(void*), void*, void*);
void __cxa_finalize(void*);
}
namespace __cxxabiv1 {
// Defenitions from https://itanium-cxx-abi.github.io/cxx-abi/abi.html
class __fundamental_type_info : public std::type_info {
public:
~__fundamental_type_info();
};
class __array_type_info : public std::type_info {
public:
~__array_type_info();
};
class __function_type_info : public std::type_info {
public:
~__function_type_info();
};
class __enum_type_info : public std::type_info {
public:
~__enum_type_info();
};
class __class_type_info : public std::type_info {
public:
~__class_type_info();
enum __class_type_info_codes {
CLASS_TYPE_INFO_CODE,
SI_CLASS_TYPE_INFO_CODE,
VMI_CLASS_TYPE_INFO_CODE,
};
virtual __class_type_info_codes class_type_info_code() const { return CLASS_TYPE_INFO_CODE; }
};
class __si_class_type_info : public __class_type_info {
public:
~__si_class_type_info();
const __class_type_info* __base_type;
virtual __class_type_info_codes class_type_info_code() const { return SI_CLASS_TYPE_INFO_CODE; }
};
struct __base_class_type_info {
public:
const __class_type_info* __base_type;
long __offset_flags;
enum __offset_flags_masks {
__virtual_mask = 0x1,
__public_mask = 0x2,
__offset_shift = 8
};
inline bool is_virtual() const { return (__offset_flags & __virtual_mask) != 0; }
inline bool is_public() const { return (__offset_flags & __public_mask) != 0; }
inline long offset() const { return __offset_flags >> __offset_shift; }
inline long flags() const { return __offset_flags & ((1L << __offset_shift) - 1); }
};
class __vmi_class_type_info : public __class_type_info {
public:
~__vmi_class_type_info();
uint32_t m_flags;
uint32_t m_base_count;
__base_class_type_info m_base_info[1];
enum __flags_masks {
__non_diamond_repeat_mask = 0x1,
__diamond_shaped_mask = 0x2
};
virtual __class_type_info_codes class_type_info_code() const { return SI_CLASS_TYPE_INFO_CODE; }
};
class __pbase_type_info : public std::type_info {
public:
~__pbase_type_info();
unsigned int __flags;
const std::type_info* __pointee;
enum __masks {
__const_mask = 0x1,
__volatile_mask = 0x2,
__restrict_mask = 0x4,
__incomplete_mask = 0x8,
__incomplete_class_mask = 0x10,
__transaction_safe_mask = 0x20,
__noexcept_mask = 0x40
};
};
class __pointer_type_info : public __pbase_type_info {
public:
~__pointer_type_info();
};
class __pointer_to_member_type_info : public __pbase_type_info {
public:
~__pointer_to_member_type_info();
};
}
namespace abi = __cxxabiv1;
#endif /* _CXXABI_H */

View File

@@ -0,0 +1,9 @@
#include "cxxabi.h"
#include "stdio.h"
#include <cstddef>
#include <typeinfo>
extern "C" void* __dynamic_cast(const void* v, const abi::__class_type_info* src, const abi::__class_type_info* dst, std::ptrdiff_t src2dst_offset)
{
return NULL;
}

View File

@@ -0,0 +1,46 @@
#include "cxxabi.h"
#include <new>
namespace __cxxabiv1 {
__fundamental_type_info::~__fundamental_type_info()
{
}
__array_type_info::~__array_type_info()
{
}
__function_type_info::~__function_type_info()
{
}
__enum_type_info::~__enum_type_info()
{
}
__class_type_info::~__class_type_info()
{
}
__si_class_type_info::~__si_class_type_info()
{
}
__vmi_class_type_info::~__vmi_class_type_info()
{
}
__pbase_type_info::~__pbase_type_info()
{
}
__pointer_type_info::~__pointer_type_info()
{
}
__pointer_to_member_type_info::~__pointer_to_member_type_info()
{
}
}

View File

@@ -0,0 +1,14 @@
#pragma GCC system_header
#ifndef _LIBCXX___CONFIG
#define _LIBCXX___CONFIG
#define _LIBCXX_BEGIN_NAMESPACE_STD namespace std {
#define _LIBCXX_END_NAMESPACE_STD }
#define _LIBCXX_BEGIN_XOS_EXTENSION inline namespace xos {
#define _LIBCXX_END_XOS_EXTENSION }
#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(alignof(x))))
#endif // _LIBCXX___CONFIG

View File

@@ -0,0 +1,509 @@
#pragma GCC system_header
#ifndef _LIBCXX___RBTREE
#define _LIBCXX___RBTREE
#include <__config>
#include <functional>
#include <memory>
#include <type_traits>
template <class, class, class>
class __rbtree;
template <typename T>
class __rbtree_node {
template <class, class, class>
friend class __rbtree;
public:
enum class Color {
Red = 0,
Black,
};
using node_type = __rbtree_node;
using node_pointer = node_type*;
using value_type = T;
using color_type = Color;
using const_reference = const value_type&;
explicit __rbtree_node(const value_type& value)
: m_value(value)
{
}
explicit __rbtree_node(value_type&& value)
: m_value(std::move(value))
{
}
~__rbtree_node() = default;
void set_parent(node_pointer pc) { m_parent = pc; }
void set_left_child(node_pointer lc) { m_left_child = lc; }
void set_right_child(node_pointer rc) { m_right_child = rc; }
void set_color(color_type cl) { m_color = cl; }
void set_value(const_reference val) { m_value = val; }
void set_value(value_type&& val) { m_value = std::move(val); }
node_pointer left_child() const { return m_left_child; }
node_pointer right_child() const { return m_right_child; }
node_pointer parent() const { return m_parent; }
color_type color() const { return m_color; }
bool is_red() const { return color() == color_type::Red; }
bool is_black() const { return color() == color_type::Black; }
bool is_nil_node() const { return m_is_nil_node; }
const_reference value() const { return m_value; }
value_type& value() { return m_value; }
protected:
__rbtree_node(bool is_nil_node, color_type color)
: m_is_nil_node(is_nil_node)
, m_color(color)
{
}
private:
color_type m_color { Color::Red };
node_pointer m_parent { nullptr };
node_pointer m_left_child { nullptr };
node_pointer m_right_child { nullptr };
value_type m_value;
bool m_is_nil_node { false };
};
template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>>
class __rbtree {
public:
using key_type = Key;
using value_type = Key;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using key_compare = Compare;
using value_compare = Compare;
using allocator_type = Allocator;
using refernce = value_type&;
using const_reference = const value_type&;
using pointer = value_type*;
using const_pointer = const value_type*;
using node_type = __rbtree_node<value_type>;
private:
using node_pointer = node_type*;
using node_const_pointer = const node_type*;
typedef typename std::__rebind_alloc_helper<allocator_type, node_type>::type node_alloc_type;
public:
__rbtree()
: m_nil_node(true, node_type::Color::Black)
{
m_root = nil_node();
}
__rbtree(const Compare& comp, const Allocator& alloc = Allocator())
: m_comp(comp)
, m_allocator(alloc)
, m_nil_node(true, node_type::Color::Black)
{
m_root = nil_node();
}
explicit __rbtree(const Allocator& alloc)
: m_allocator(alloc)
, m_nil_node(true, node_type::Color::Black)
{
m_root = nil_node();
}
// TODO: Return std::pair<iterator, bool>
inline bool insert(const value_type& value) { return insert(value_type(value)); }
inline bool insert(value_type&& value)
{
node_pointer new_node = _btree_insert(std::move(value));
if (!new_node) {
return false;
}
m_size++;
balance_after_insert(new_node);
return true;
}
template <class EqComp>
size_type erase(const_reference value, EqComp comp) { return erase_node(_btree_find(value, comp)); }
size_type erase(const_reference value) { return erase_node(_btree_find(value)); }
pointer find(const_reference value)
{
node_pointer res = _btree_find(value);
if (!res) {
return nullptr;
}
return &res->m_value;
}
template <class EqComp>
pointer find(const_reference value, EqComp comp)
{
node_pointer res = _btree_find(value, comp);
if (!res) {
return nullptr;
}
return &res->m_value;
}
allocator_type get_allocator() const noexcept { return m_allocator; }
size_type size() const { return m_size; }
bool empty() const { return size() == 0; }
private:
bool is_root(node_pointer node) const { return node == m_root; }
inline bool is_left_child(node_pointer of_node) const
{
if (!of_node->parent()) {
return false;
}
return of_node->parent()->left_child() == of_node;
}
inline bool is_right_child(node_pointer of_node) const
{
if (!of_node->parent()) {
return false;
}
return of_node->parent()->right_child() == of_node;
}
// Warning: it does NOT check correctness!
inline bool has_uncle(node_pointer of_node) const { return !!uncle(of_node); }
inline node_pointer uncle(node_pointer of_node) const
{
if (of_node->parent()->parent()->left_child() == of_node->parent()) {
return of_node->parent()->parent()->right_child();
} else {
return of_node->parent()->parent()->left_child();
}
}
void balance_after_insert(node_pointer new_node)
{
while (!is_root(new_node) && new_node->parent()->is_red()) {
if (has_uncle(new_node) && uncle(new_node)->is_red()) {
new_node->parent()->set_color(node_type::Color::Black);
new_node->parent()->parent()->set_color(node_type::Color::Red);
uncle(new_node)->set_color(node_type::Color::Black);
new_node = new_node->parent()->parent();
} else {
if (is_left_child(new_node->parent())) {
if (is_right_child(new_node)) {
new_node = new_node->parent();
rotate<RotateType::Left>(new_node);
}
new_node->parent()->set_color(node_type::Color::Black);
new_node->parent()->parent()->set_color(node_type::Color::Red);
rotate<RotateType::Right>(new_node->parent()->parent());
} else {
if (is_left_child(new_node)) {
new_node = new_node->parent();
rotate<RotateType::Right>(new_node);
}
new_node->parent()->set_color(node_type::Color::Black);
new_node->parent()->parent()->set_color(node_type::Color::Red);
rotate<RotateType::Left>(new_node->parent()->parent());
}
}
}
m_root->set_color(node_type::Color::Black);
}
void balance_after_delete(node_pointer node)
{
while (!is_root(node) && node->is_black()) {
if (is_left_child(node)) {
node_pointer brother = node->parent()->right_child();
if (brother && brother->is_red()) {
brother->set_color(node_type::Color::Black);
node->parent()->set_color(node_type::Color::Red);
rotate<RotateType::Left>(node->parent());
brother = node->parent()->right_child();
}
if (brother->left_child()->is_black() && brother->right_child()->is_black()) {
brother->set_color(node_type::Color::Red);
node = node->parent();
} else {
if (brother->right_child()->is_black()) {
brother->left_child()->set_color(node_type::Color::Black);
brother->set_color(node_type::Color::Red);
rotate<RotateType::Right>(brother);
brother = node->parent()->right_child();
}
brother->set_color(node->parent()->color());
node->parent()->set_color(node_type::Color::Black);
brother->right_child()->set_color(node_type::Color::Black);
rotate<RotateType::Left>(node->parent());
node = m_root;
}
} else {
node_pointer brother = node->parent()->left_child();
if (brother && brother->is_red()) {
brother->set_color(node_type::Color::Black);
node->parent()->set_color(node_type::Color::Red);
rotate<RotateType::Right>(node->parent());
brother = node->parent()->left_child();
}
if (brother->left_child()->is_black() && brother->right_child()->is_black()) {
brother->set_color(node_type::Color::Red);
node = node->parent();
} else {
if (brother->left_child()->is_black()) {
brother->right_child()->set_color(node_type::Color::Black);
brother->set_color(node_type::Color::Red);
rotate<RotateType::Left>(brother);
brother = node->parent()->left_child();
}
brother->set_color(node->parent()->color());
node->parent()->set_color(node_type::Color::Black);
brother->left_child()->set_color(node_type::Color::Black);
rotate<RotateType::Right>(node->parent());
node = m_root;
}
}
}
m_root->set_color(node_type::Color::Black);
}
enum class RotateType {
Left,
Right,
};
template <RotateType rt>
constexpr void rotate(node_pointer node)
{
if constexpr (rt == RotateType::Left) {
// p <-(node) b
// a b ----> p d
// c d c a
if (node->right_child()->is_nil_node()) {
return;
}
node_pointer node_p = node;
node_pointer node_a = node->left_child();
node_pointer node_b = node->right_child();
node_pointer node_c = node_b->left_child();
node_b->set_left_child(node_p);
node_b->set_parent(node_p->parent());
if (node_p->parent()) {
if (is_left_child(node_p)) {
node_p->parent()->set_left_child(node_b);
} else {
node_p->parent()->set_right_child(node_b);
}
}
node_p->set_parent(node_b);
node_p->set_right_child(node_c);
node_c->set_parent(node_p);
if (is_root(node_p)) {
m_root = node_b;
}
} else if constexpr (rt == RotateType::Right) {
// p <-(node) a
// a b ----> c p
// c d d b
if (node->left_child()->is_nil_node()) {
return;
}
node_pointer node_p = node;
node_pointer node_a = node->left_child();
node_pointer node_c = node_a->left_child();
node_pointer node_d = node_a->right_child();
node_a->set_right_child(node_p);
node_a->set_parent(node_p->parent());
if (node_p->parent()) {
if (is_left_child(node_p)) {
node_p->parent()->set_left_child(node_a);
} else {
node_p->parent()->set_right_child(node_a);
}
}
node_p->set_parent(node_a);
node->set_left_child(node_d);
node_d->set_parent(node_p);
if (is_root(node_p)) {
m_root = node_a;
}
}
}
size_type erase_node(node_pointer node_to_delete)
{
if (!node_to_delete || node_to_delete->is_nil_node()) {
return 0;
}
m_size--;
auto children_count = [](node_pointer node) -> size_t {
return (size_t)(!node->left_child()->is_nil_node()) + (size_t)(!node->right_child()->is_nil_node());
};
auto destroy_node = [this](node_pointer node) {
if (node && node->is_nil_node()) {
return;
}
std::destroy_at(node);
this->m_node_allocator.deallocate(node, 1);
};
if (children_count(node_to_delete) == 0) {
if (is_root(node_to_delete)) {
m_root = nil_node();
} else {
if (is_left_child(node_to_delete)) {
node_to_delete->parent()->set_left_child(nil_node());
} else {
node_to_delete->parent()->set_right_child(nil_node());
}
}
return 1;
}
node_pointer left_most = _btree_left_most(node_to_delete->right_child());
node_pointer child = left_most->right_child();
if (left_most == nil_node()) {
child = nil_node();
left_most = node_to_delete->left_child();
}
child->set_parent(left_most->parent());
if (is_root(left_most)) {
m_root = child;
} else {
if (is_left_child(left_most)) {
left_most->parent()->set_left_child(child);
} else {
left_most->parent()->set_right_child(child);
}
}
if (node_to_delete != left_most) {
node_to_delete->set_value(std::move(left_most->value()));
}
if (left_most->is_black()) {
balance_after_delete(child);
}
destroy_node(left_most);
return 1;
}
node_pointer _btree_insert(value_type&& value)
{
node_pointer new_node = m_node_allocator.allocate(1);
if (!new_node) {
return nullptr;
}
std::construct_at(new_node, std::move(value));
new_node->set_parent(nil_node());
new_node->set_left_child(nil_node());
new_node->set_right_child(nil_node());
if (m_root->is_nil_node()) {
m_root = new_node;
return new_node;
}
node_pointer cur_node = m_root;
while (cur_node) {
if (m_comp(new_node->value(), cur_node->value())) {
if (cur_node->left_child()->is_nil_node()) {
new_node->set_parent(cur_node);
cur_node->set_left_child(new_node);
return new_node;
}
cur_node = cur_node->left_child();
} else {
if (cur_node->right_child()->is_nil_node()) {
new_node->set_parent(cur_node);
cur_node->set_right_child(new_node);
return new_node;
}
cur_node = cur_node->right_child();
}
}
return nullptr;
}
node_pointer _btree_find(const_reference value)
{
node_pointer cur_node = m_root;
while (cur_node && !cur_node->is_nil_node()) {
if (cur_node->value() == value) {
return cur_node;
}
if (m_comp(value, cur_node->value())) {
cur_node = cur_node->left_child();
} else {
cur_node = cur_node->right_child();
}
}
return nullptr;
}
template <class EqComp>
node_pointer _btree_find(const_reference value, EqComp eq_comp)
{
node_pointer cur_node = m_root;
while (cur_node && !cur_node->is_nil_node()) {
if (eq_comp(cur_node->value(), value)) {
return cur_node;
}
if (m_comp(value, cur_node->value())) {
cur_node = cur_node->left_child();
} else {
cur_node = cur_node->right_child();
}
}
return nullptr;
}
node_pointer _btree_left_most(node_pointer node)
{
if (!node) {
return nullptr;
}
if (node->is_nil_node()) {
return nil_node();
}
while (!node->left_child()->is_nil_node()) {
node = node->left_child();
}
return node;
}
node_pointer nil_node() const { return (node_pointer)&m_nil_node; }
node_pointer m_root { nullptr };
size_type m_size { 0 };
key_compare m_comp {};
allocator_type m_allocator {};
node_alloc_type m_node_allocator {};
node_type m_nil_node;
};
#endif // _LIBCXX___RBTREE

View File

@@ -0,0 +1,56 @@
#pragma GCC system_header
#ifndef _LIBCXX___STREAMBUFFER
#define _LIBCXX___STREAMBUFFER
#include <__config>
#include <cstdio>
#include <streambuf>
#include <string>
_LIBCXX_BEGIN_NAMESPACE_STD
template <class CharT>
class __stdoutbuf : public basic_streambuf<CharT> {
public:
using char_type = CharT;
using traits_type = std::char_traits<char_type>;
using int_type = typename traits_type::int_type;
using pos_type = typename traits_type::pos_type;
using off_type = typename traits_type::off_type;
__stdoutbuf(FILE* file)
: basic_streambuf<char_type>()
, m_file(file)
{
}
~__stdoutbuf() = default;
virtual int_type overflow(int_type c = traits_type::eof()) override
{
char_type ch = traits_type::to_char_type(c);
if (traits_type::eq_int_type(c, traits_type::eof())) {
return traits_type::eof();
}
if (fwrite(&ch, sizeof(char_type), 1, m_file) != sizeof(char_type)) {
return traits_type::eof();
}
return c;
}
virtual int sync() override
{
if (fflush(m_file) != 0) {
return -1;
}
return 0;
}
private:
FILE* m_file;
};
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX___STREAMBUFFER

View File

@@ -0,0 +1,16 @@
#pragma GCC system_header
#ifndef _LIBCXX___UNDEF_MACROS
#define _LIBCXX___UNDEF_MACROS
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#define NOMINMAX
#endif // _LIBCXX___UNDEF_MACROS

View File

@@ -0,0 +1,45 @@
#pragma GCC system_header
#ifndef _LIBCXX_ALGORITHM
#define _LIBCXX_ALGORITHM
#include <__config>
#include <__undef_macros>
_LIBCXX_BEGIN_NAMESPACE_STD
template <typename T>
static inline constexpr T min(const T& a, const T& b)
{
return a < b ? a : b;
}
template <typename T>
static inline constexpr T max(const T& a, const T& b)
{
return a < b ? b : a;
}
template <class Iter, class T>
static constexpr Iter find(Iter first, Iter last, const T& value)
{
for (; first != last; ++first) {
if (*first == value) {
return first;
}
}
return last;
}
template <class InputIter, class OutputIter>
static constexpr OutputIter copy(InputIter first, InputIter last, OutputIter dist)
{
for (; first != last; ++first) {
*dist++ = *first;
}
return dist;
}
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_ALGORITHM

20
libs/libcxx/include/bit Normal file
View File

@@ -0,0 +1,20 @@
#pragma GCC system_header
#ifndef _LIBCXX_BIT
#define _LIBCXX_BIT
#include <__config>
#include <__undef_macros>
#include <type_traits>
_LIBCXX_BEGIN_NAMESPACE_STD
enum class endian {
little = __ORDER_LITTLE_ENDIAN__,
big = __ORDER_BIG_ENDIAN__,
native = __BYTE_ORDER__
};
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_BIT

View File

@@ -0,0 +1,8 @@
#pragma GCC system_header
#ifndef _LIBCXX_CASSERT
#define _LIBCXX_CASSERT
#include <assert.h>
#endif // _LIBCXX_CASSERT

View File

@@ -0,0 +1,27 @@
#pragma GCC system_header
#ifndef _LIBCXX_CCTYPE
#define _LIBCXX_CCTYPE
#include <__config>
#include <ctype.h>
_LIBCXX_BEGIN_NAMESPACE_STD
using ::isalnum;
using ::isalpha;
using ::iscntrl;
using ::isdigit;
using ::isgraph;
using ::islower;
using ::isprint;
using ::ispunct;
using ::isspace;
using ::isupper;
using ::isxdigit;
using ::tolower;
using ::toupper;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_CCTYPE

View File

@@ -0,0 +1,16 @@
#pragma GCC system_header
#ifndef _LIBCXX_CSETJMP
#define _LIBCXX_CSETJMP
#include <__config>
#include <setjmp.h>
_LIBCXX_BEGIN_NAMESPACE_STD
using ::jmp_buf;
using ::longjmp;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_CSETJMP

View File

@@ -0,0 +1,17 @@
#pragma GCC system_header
#ifndef _LIBCXX_CSIGNAL
#define _LIBCXX_CSIGNAL
#include <__config>
#include <signal.h>
_LIBCXX_BEGIN_NAMESPACE_STD
using ::kill;
using ::raise;
using ::sigaction;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_CSIGNAL

View File

@@ -0,0 +1,18 @@
#pragma GCC system_header
#ifndef _LIBCXX_CSTDDEF
#define _LIBCXX_CSTDDEF
#include <__config>
#include <stddef.h>
_LIBCXX_BEGIN_NAMESPACE_STD
using ::ptrdiff_t;
using ::size_t;
using ::ssize_t;
typedef decltype(nullptr) nullptr_t;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_CSTDDEF

View File

@@ -0,0 +1,40 @@
#pragma GCC system_header
#ifndef _LIBCXX_CSTDINT
#define _LIBCXX_CSTDINT
#include <__config>
#include <stdint.h>
_LIBCXX_BEGIN_NAMESPACE_STD
using ::int8_t;
using ::int16_t;
using ::int32_t;
using ::int64_t;
using ::uint8_t;
using ::uint16_t;
using ::uint32_t;
using ::uint64_t;
using ::int_least8_t;
using ::int_least16_t;
using ::int_least32_t;
using ::int_least64_t;
using ::uint_least8_t;
using ::uint_least16_t;
using ::uint_least32_t;
using ::uint_least64_t;
using ::int_fast8_t;
using ::int_fast16_t;
using ::int_fast32_t;
using ::int_fast64_t;
using ::uint_fast8_t;
using ::uint_fast16_t;
using ::uint_fast32_t;
using ::uint_fast64_t;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_CSTDINT

View File

@@ -0,0 +1,33 @@
#pragma GCC system_header
#ifndef _LIBCXX_CSTDIO
#define _LIBCXX_CSTDIO
#include <__config>
#include <stddef.h>
#include <stdio.h>
_LIBCXX_BEGIN_NAMESPACE_STD
using ::fclose;
using ::FILE;
using ::fopen;
using ::setbuf;
using ::setlinebuf;
using ::setvbuf;
using ::fprintf;
using ::printf;
using ::snprintf;
using ::sprintf;
using ::vsnprintf;
using ::vsprintf;
using ::scanf;
using ::sscanf;
using ::vsscanf;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_CSTDIO

View File

@@ -0,0 +1,27 @@
#pragma GCC system_header
#ifndef _LIBCXX_CSTDLIB
#define _LIBCXX_CSTDLIB
#include <__config>
#include <stdlib.h>
_LIBCXX_BEGIN_NAMESPACE_STD
using ::abort;
using ::abs;
using ::atoi;
using ::calloc;
using ::exit;
using ::free;
using ::malloc;
using ::posix_openpt;
using ::ptsname;
using ::ptsname_r;
using ::qsort;
using ::realloc;
using ::strtol;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_CSTDLIB

View File

@@ -0,0 +1,31 @@
#pragma GCC system_header
#ifndef _LIBCXX_CSTRING
#define _LIBCXX_CSTRING
#include <__config>
#include <string.h>
_LIBCXX_BEGIN_NAMESPACE_STD
using ::memccpy;
using ::memchr;
using ::memcmp;
using ::memcpy;
using ::memmove;
using ::memset;
using ::strcat;
using ::strchr;
using ::strcmp;
using ::strcpy;
using ::strlen;
using ::strncmp;
using ::strncpy;
using ::strrchr;
using ::strstr;
using ::strtok;
using ::strtok_r;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_CSTRING

27
libs/libcxx/include/ctime Normal file
View File

@@ -0,0 +1,27 @@
#pragma GCC system_header
#ifndef _LIBCXX_CTIME
#define _LIBCXX_CTIME
#include <__config>
#include <time.h>
_LIBCXX_BEGIN_NAMESPACE_STD
using ::clock_getres;
using ::clock_gettime;
using ::clock_settime;
using ::gmtime;
using ::gmtime_r;
using ::localtime;
using ::localtime_r;
using ::mktime;
using ::nanosleep;
using ::strftime;
using ::time;
using ::time_t;
using ::timespec;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_CTIME

View File

@@ -0,0 +1,154 @@
#pragma GCC system_header
#ifndef _LIBCXX_FUNCTIONAL
#define _LIBCXX_FUNCTIONAL
#include <__config>
#include <memory>
_LIBCXX_BEGIN_NAMESPACE_STD
template <typename>
class function;
template <typename R, typename... Args>
class function<R(Args...)> {
public:
using result_type = R;
function() = default;
function(std::nullptr_t) { }
template <typename Functor>
function(Functor f)
: m_constructor(reinterpret_cast<_constructor>(construct_functor<Functor>))
, m_destroyer(reinterpret_cast<_destroyer>(destroy_functor<Functor>))
, m_invoker(reinterpret_cast<_invoker>(invoke_functor<Functor>))
, m_functor_size(sizeof(Functor))
{
m_functor.reset(m_allocator.allocate(m_functor_size));
m_constructor(m_functor.get(), &f);
}
function(const function& other)
: m_constructor(other.m_constructor)
, m_destroyer(other.m_destroyer)
, m_invoker(other.m_invoker)
, m_functor_size(other.m_functor_size)
{
if (m_invoker && m_functor_size) {
m_functor.reset(m_allocator.allocate(m_functor_size));
m_constructor(m_functor.get(), other.m_functor.get());
}
}
function& operator=(const function& other)
{
m_constructor = other.m_constructor;
m_destroyer = other.m_destroyer;
m_invoker = other.m_invoker;
m_functor_size = other.m_functor_size;
if (m_invoker && m_functor_size) {
m_functor.reset(m_allocator.allocate(m_functor_size));
m_constructor(m_functor.get(), other.m_functor.get());
}
return *this;
}
~function()
{
if (m_functor) {
m_destroyer(m_functor.get());
}
}
result_type operator()(Args&&... args)
{
return m_invoker(m_functor.get(), std::forward<Args>(args)...);
}
operator bool() { return !!m_functor; }
private:
using _alloc_type = char;
using _invoker = R (*)(void*, Args&&...);
using _constructor = void (*)(void*, void*);
using _destroyer = void (*)(void*);
template <typename Functor>
static void construct_functor(Functor* at, Functor* other)
{
construct_at(at, *other);
}
template <typename Functor>
static void destroy_functor(Functor* p)
{
destroy_at(p);
}
template <typename Functor>
static result_type invoke_functor(Functor* functor, Args&&... args)
{
return (*functor)(std::forward<Args>(args)...);
}
_invoker m_invoker { nullptr };
_constructor m_constructor { nullptr };
_destroyer m_destroyer { nullptr };
std::unique_ptr<_alloc_type> m_functor { nullptr };
size_t m_functor_size { 0 };
std::allocator<_alloc_type> m_allocator {};
};
template <class T = void>
struct less {
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs < rhs;
}
};
template <class T = void>
struct greater {
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs > rhs;
}
};
template <class T = void>
struct equal_to {
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs == rhs;
}
};
template <class T = void>
struct less_equal {
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs <= rhs;
}
};
template <class T = void>
struct greater_equal {
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs >= rhs;
}
};
template <class T = void>
struct not_equal_to {
constexpr bool operator()(const T& lhs, const T& rhs) const
{
return lhs != rhs;
}
};
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_FUNCTIONAL

122
libs/libcxx/include/ios Normal file
View File

@@ -0,0 +1,122 @@
#pragma GCC system_header
#ifndef _LIBCXX_IOS
#define _LIBCXX_IOS
#include <__config>
#include <iosfwd>
_LIBCXX_BEGIN_NAMESPACE_STD
typedef size_t streamsize;
class ios_base {
public:
typedef uint32_t openmode;
static constexpr openmode app = 0x1;
static constexpr openmode binary = 0x2;
static constexpr openmode in = 0x4;
static constexpr openmode out = 0x8;
static constexpr openmode trunc = 0x10;
static constexpr openmode ate = 0x20;
typedef uint32_t fmtflags;
static constexpr fmtflags dec = 0x1;
static constexpr fmtflags oct = 0x2;
static constexpr fmtflags hex = 0x4;
static constexpr fmtflags basefield = dec | oct | hex;
static constexpr fmtflags left = 0x8;
static constexpr fmtflags right = 0x10;
static constexpr fmtflags internal = 0x20;
static constexpr fmtflags adjustfield = left | right | internal;
static constexpr fmtflags scientific = 0x40;
static constexpr fmtflags fixed = 0x80;
static constexpr fmtflags floatfield = scientific | fixed;
static constexpr fmtflags boolalpha = 0x100;
static constexpr fmtflags showbase = 0x200;
static constexpr fmtflags showpoint = 0x400;
static constexpr fmtflags showpos = 0x800;
static constexpr fmtflags skipws = 0x1000;
static constexpr fmtflags unitbuf = 0x2000;
static constexpr fmtflags uppercase = 0x4000;
typedef uint32_t iostate;
static constexpr iostate goodbit = 0x0;
static constexpr iostate badbit = 0x1;
static constexpr iostate failbit = 0x2;
static constexpr iostate eofbit = 0x4;
typedef uint32_t seekdir;
static constexpr seekdir beg = 0x1;
static constexpr seekdir end = 0x2;
static constexpr seekdir cur = 0x4;
ios_base() = default;
virtual ~ios_base() = default;
fmtflags flags() const { return m_fl; }
fmtflags flags(fmtflags flags) { return m_fl = flags; }
fmtflags setf(fmtflags flags) { return m_fl |= flags; }
fmtflags setf(fmtflags flags, fmtflags mask) { return m_fl = (m_fl & ~mask) | (flags & mask); }
void unsetf(fmtflags flags) { m_fl = (m_fl & ~flags); }
streamsize precision() const { return m_precision; }
streamsize precision(streamsize n_p) { return m_precision = n_p; }
streamsize width() const { return m_width; }
streamsize width(streamsize n_w) { return m_width = n_w; }
bool good() const { return rdstate() == goodbit; }
bool eof() const { return (m_rdstate & eofbit) != 0; }
bool fail() const { return (m_rdstate & failbit) != 0; }
bool bad() const { return (m_rdstate & badbit) != 0; }
bool operator!() const { return fail(); }
explicit operator bool() const { return !fail(); }
iostate rdstate() const { return m_rdstate; }
void setstate(iostate state) { m_rdstate = state; }
void clear(iostate state = goodbit) { m_rdstate = state; }
// TODO: Support locales
private:
fmtflags m_fl { 0 };
iostate m_rdstate { 0 };
iostate m_state { 0 };
streamsize m_precision { 0 };
streamsize m_width { 0 };
};
template <class CharT, class Traits>
class basic_ios : public ios_base {
public:
using char_type = CharT;
using traits_type = Traits;
using int_type = typename traits_type::int_type;
using pos_type = typename traits_type::pos_type;
using off_type = typename traits_type::off_type;
explicit basic_ios(basic_streambuf<char_type, traits_type>* rdbuf)
: ios_base()
, m_rdbuf(rdbuf)
{
}
virtual ~basic_ios() = default;
basic_streambuf<CharT, Traits>* rdbuf() const { return m_rdbuf; }
basic_streambuf<CharT, Traits>* rdbuf(basic_streambuf<CharT, Traits>* sb) { return m_rdbuf = sb; }
// TODO: Add more API to match C++20 standard.
protected:
basic_ios() = default;
private:
basic_streambuf<char_type, traits_type>* m_rdbuf { nullptr };
};
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_IOS

View File

@@ -0,0 +1,21 @@
#pragma GCC system_header
#ifndef _LIBCXX_IOSFWD
#define _LIBCXX_IOSFWD
#include <__config>
#include <string>
_LIBCXX_BEGIN_NAMESPACE_STD
class ios_base;
template <typename CharT, typename Traits = char_traits<CharT>>
class basic_ios;
template <typename CharT, typename Traits = char_traits<CharT>>
class basic_streambuf;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_IOSFWD

View File

@@ -0,0 +1,17 @@
#pragma GCC system_header
#ifndef _LIBCXX_IOSTREAM
#define _LIBCXX_IOSTREAM
#include <__config>
#include <ostream>
_LIBCXX_BEGIN_NAMESPACE_STD
extern ostream cout;
extern ostream cerr;
// extern ostream clog;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_IOSTREAM

View File

@@ -0,0 +1,230 @@
#pragma GCC system_header
#ifndef _LIBCXX_ITERATOR
#define _LIBCXX_ITERATOR
#include <__config>
#include <stddef.h>
#include <type_traits>
_LIBCXX_BEGIN_NAMESPACE_STD
struct input_iterator_tag {
};
struct output_iterator_tag {
};
struct forward_iterator_tag : public input_iterator_tag {
};
struct bidirectional_iterator_tag : public forward_iterator_tag {
};
struct random_access_iterator_tag : public bidirectional_iterator_tag {
};
template <class Iter>
struct iterator_traits {
using value_type = typename Iter::value_type;
using difference_type = typename Iter::difference_type;
using pointer = typename Iter::pointer;
using reference = typename Iter::reference;
using iterator_category = typename Iter::iterator_category;
};
template <class T>
struct iterator_traits<T*> {
using value_type = T;
using difference_type = ptrdiff_t;
using pointer = T*;
using reference = T&;
using iterator_category = std::random_access_iterator_tag;
};
template <class T>
class __legacy_iter {
};
template <class T>
class __legacy_iter<T*> {
public:
using value_type = T;
using difference_type = ptrdiff_t;
using pointer = T*;
using reference = T&;
using iterator_category = std::random_access_iterator_tag;
__legacy_iter() = default;
__legacy_iter(pointer p)
: m_p(p)
{
}
~__legacy_iter() = default;
bool operator!=(const __legacy_iter& other) const { return m_p != other.m_p; }
bool operator==(const __legacy_iter& other) const { return m_p == other.m_p; }
bool operator<(const __legacy_iter& other) const { return m_p < other.m_p; }
bool operator>(const __legacy_iter& other) const { return m_p > other.m_p; }
bool operator>=(const __legacy_iter& other) const { return m_p >= other.m_p; }
__legacy_iter& operator++()
{
++m_p;
return *this;
}
__legacy_iter& operator--()
{
--m_p;
return *this;
}
__legacy_iter operator++(int)
{
auto tmp = *this;
++m_p;
return tmp;
}
__legacy_iter operator--(int)
{
auto tmp = *this;
--m_p;
return tmp;
}
__legacy_iter operator-(difference_type value) { return { m_p - value }; }
__legacy_iter operator+(difference_type value) { return { m_p + value }; }
__legacy_iter& operator+=(difference_type value)
{
m_p += value;
return *this;
}
__legacy_iter& operator-=(difference_type value)
{
m_p -= value;
return *this;
}
__legacy_iter& operator=(const __legacy_iter& other)
{
m_p = other.m_p;
return *this;
}
reference operator*() { return *m_p; }
difference_type operator-(const __legacy_iter& other) { return m_p - other.m_p; }
constexpr reference operator[](difference_type n) const { return m_p[n]; }
private:
pointer m_p = nullptr;
};
template <class Iter>
class reverse_iterator {
public:
using iterator_type = Iter;
using value_type = typename Iter::value_type;
using difference_type = typename Iter::difference_type;
using pointer = typename Iter::pointer;
using reference = typename Iter::reference;
using iterator_category = typename Iter::iterator_category;
constexpr reverse_iterator() = default;
~reverse_iterator() = default;
constexpr explicit reverse_iterator(iterator_type base_iter)
: m_base(base_iter)
{
}
constexpr iterator_type base() const { return m_base; }
bool operator!=(const reverse_iterator& other) const { return m_base != other.m_base; }
bool operator==(const reverse_iterator& other) const { return m_base == other.m_base; }
bool operator<(const reverse_iterator& other) const { return m_base < other.m_base; }
bool operator>(const reverse_iterator& other) const { return m_base > other.m_base; }
bool operator>=(const reverse_iterator& other) const { return m_base >= other.m_base; }
reverse_iterator& operator++()
{
--m_base;
return *this;
}
reverse_iterator& operator--()
{
++m_base;
return *this;
}
reverse_iterator operator++(int)
{
auto tmp = *this;
--m_base;
return tmp;
}
reverse_iterator operator--(int)
{
auto tmp = *this;
++m_base;
return tmp;
}
reverse_iterator operator-(difference_type value) { return { m_base + value }; }
reverse_iterator operator+(difference_type value) { return { m_base - value }; }
reverse_iterator& operator+=(difference_type value)
{
m_base -= value;
return *this;
}
reverse_iterator& operator-=(difference_type value)
{
m_base += value;
return *this;
}
reverse_iterator& operator=(const reverse_iterator& other)
{
m_base = other.m_base;
return *this;
}
reference operator*() { return *m_base; }
difference_type operator-(const reverse_iterator& other) { return other.m_base - m_base; }
constexpr reference operator[](difference_type n) const { return m_base[-n]; }
private:
iterator_type m_base;
};
template <class Iter>
constexpr typename iterator_traits<Iter>::difference_type distance(Iter first, Iter last)
{
typename iterator_traits<Iter>::difference_type res;
while (first != last) {
first++;
res++;
}
return res;
};
template <class Iter, class Distance>
constexpr void advance(Iter& it, Distance n)
{
if (n > 0) {
while (n--) {
it++;
}
} else if (n < 0) {
while (n++) {
it--;
}
}
}
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_ITERATOR

271
libs/libcxx/include/list Normal file
View File

@@ -0,0 +1,271 @@
#pragma GCC system_header
#ifndef _LIBCXX_LIST
#define _LIBCXX_LIST
#include <__config>
#include <memory>
#include <stddef.h>
#include <type_traits>
_LIBCXX_BEGIN_NAMESPACE_STD
namespace details {
template <class T>
class list_node {
public:
using value_type = T;
using pointer = T*;
using reference = T&;
using const_reference = const T&;
private:
using __node_type = details::list_node<value_type>;
using __node_pointer = __node_type*;
public:
list_node(const_reference elem, __node_pointer next = nullptr, __node_pointer prev = nullptr)
: m_elem(elem)
, m_next(next)
, m_prev(prev)
{
}
list_node(value_type&& elem, __node_pointer next = nullptr, __node_pointer prev = nullptr)
: m_elem(std::move(elem))
, m_next(next)
, m_prev(prev)
{
}
~list_node() = default;
inline reference get() { return m_elem; }
inline const_reference get() const { return m_elem; }
inline reference operator*() { return m_elem; }
inline __node_pointer next() const { return m_next; }
inline __node_pointer prev() const { return m_prev; }
inline void set_prev(__node_pointer prev) { m_prev = prev; };
inline void set_next(__node_pointer next) { m_next = next; };
private:
value_type m_elem;
__node_pointer m_prev { nullptr };
__node_pointer m_next { nullptr };
};
}
template <class T, class Alloc>
class list;
template <class T>
class list_iter {
template <class U, class Alloctor>
friend class list;
public:
using value_type = T;
using size_type = size_t;
using difference_type = ptrdiff_t;
using pointer = T*;
using reference = T&;
using const_reference = const T&;
using iterator_category = std::bidirectional_iterator_tag;
private:
using __node_type = details::list_node<value_type>;
using __node_pointer = __node_type*;
public:
list_iter() = default;
list_iter(nullptr_t) { }
list_iter(__node_pointer v)
: m_value(v)
{
}
~list_iter() = default;
bool operator!=(const list_iter& other) const { return m_value != other.m_value; }
bool operator==(const list_iter& other) const { return m_value == other.m_value; }
list_iter& operator++()
{
if (m_value) {
m_prev_value = m_value;
m_value = m_value->next();
}
return *this;
}
list_iter& operator--()
{
if (m_value == end()) {
m_value = m_prev_value;
} else {
m_value = m_value->prev();
}
return *this;
}
list_iter operator++(int)
{
auto tmp = *this;
operator++();
return tmp;
}
list_iter operator--(int)
{
auto tmp = *this;
operator--();
return tmp;
}
list_iter& operator=(const list_iter& other)
{
m_value = other.m_value;
m_prev_value = other.m_prev_value;
return *this;
}
reference operator*() { return m_value->get(); }
__node_pointer end() { return nullptr; }
private:
__node_pointer get_value() { return m_value; }
__node_pointer m_value { nullptr };
__node_pointer m_prev_value { nullptr };
};
template <class T, class Allocator = std::allocator<T>>
class list {
public:
using value_type = T;
using pointer = T*;
using reference = T&;
using const_reference = const T&;
using allocator_type = Allocator;
using size_type = size_t;
using iterator = list_iter<value_type>;
using const_iterator = list_iter<const value_type>;
using reverse_iterator = std::reverse_iterator<iterator>;
private:
using __node_type = details::list_node<value_type>;
using __node_pointer = __node_type*;
typedef typename __rebind_alloc_helper<allocator_type, __node_type>::type __node_alloc_type;
public:
list() = default;
~list() = default;
iterator insert(iterator pos, value_type&& value)
{
__node_pointer next_elem = pos.get_value();
__node_pointer prev_elem = m_tail;
if (next_elem) {
prev_elem = next_elem->prev();
}
__node_pointer new_elem = m_node_allocator.allocate(1);
construct_at(new_elem, std::move(value));
new_elem->set_prev(prev_elem);
if (!prev_elem) {
m_head = new_elem;
} else {
prev_elem->set_next(new_elem);
}
new_elem->set_next(next_elem);
if (!next_elem) {
m_tail = new_elem;
} else {
next_elem->set_prev(new_elem);
}
++m_size;
return iterator(new_elem);
}
iterator insert(iterator pos, const_reference value)
{
return insert(pos, value_type(value));
}
void push_back(const_reference value) { insert(end(), value); }
void push_back(value_type&& value) { insert(end(), std::move(value)); }
void push_front(const_reference value) { insert(begin(), value); }
void push_front(value_type&& value) { insert(begin(), std::move(value)); }
iterator erase(iterator pos)
{
__node_pointer this_elem = pos.get_value();
if (!this_elem) {
return end();
}
__node_pointer next_elem = this_elem->next();
__node_pointer prev_elem = this_elem->prev();
if (m_head == this_elem) {
m_head = next_elem;
}
if (m_tail == this_elem) {
m_tail = prev_elem;
}
if (next_elem) {
next_elem->set_prev(prev_elem);
}
if (prev_elem) {
prev_elem->set_next(next_elem);
}
destroy_at(this_elem);
m_node_allocator.deallocate(this_elem, 1);
--m_size;
return iterator(next_elem);
}
void pop_back() { erase(--end()); }
void pop_front() { erase(begin()); }
inline reference front() { return m_head->get(); }
inline const_reference front() const { return m_head->get(); }
inline reference back() { return m_tail->get(); }
inline const_reference back() const { return m_tail->get(); }
inline size_type size() const { return m_size; }
inline bool empty() const { return size() == 0; }
inline iterator begin() const { return iterator(m_head); }
inline iterator end() const { return ++iterator(m_tail); }
inline reverse_iterator rbegin() const { return reverse_iterator(m_tail); }
inline reverse_iterator rend() const { return ++reverse_iterator(m_head); }
allocator_type allocator() const { return m_allocator; }
private:
__node_alloc_type node_allocator() { return m_node_allocator; }
__node_pointer m_head { nullptr };
__node_pointer m_tail { nullptr };
size_type m_size { 0 };
__node_alloc_type m_node_allocator {};
allocator_type m_allocator {};
};
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_LIST

106
libs/libcxx/include/map Normal file
View File

@@ -0,0 +1,106 @@
#pragma GCC system_header
#ifndef _LIBCXX_MAP
#define _LIBCXX_MAP
#include <__config>
#include <__rbtree>
#include <functional>
#include <memory>
#include <type_traits>
_LIBCXX_BEGIN_NAMESPACE_STD
namespace details {
template <class Key, class T>
struct map_key_finder {
constexpr bool operator()(const std::pair<Key, T>& lhs, const std::pair<Key, T>& rhs) const
{
return lhs.first == rhs.first;
}
};
};
template <class Key, class T, class Compare = std::less<std::pair<Key, T>>, class Allocator = std::allocator<std::pair<Key, T>>>
class map {
private:
using __value_type = std::pair<Key, T>;
using __tree_type = __rbtree<__value_type, Compare, Allocator>;
public:
using key_type = Key;
using mapped_type = T;
using value_type = std::pair<key_type, mapped_type>;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using key_compare = Compare;
using value_compare = Compare;
using allocator_type = Allocator;
using refernce = value_type&;
using const_reference = const value_type&;
using pointer = value_type*;
using const_pointer = const value_type*;
using node_type = typename __tree_type::node_type;
map()
: m_tree()
{
}
map(const Compare& comp, const Allocator& alloc = Allocator())
: m_tree(comp, alloc)
{
}
explicit map(const Allocator& alloc)
: m_tree(alloc)
{
}
// TODO: Return std::pair<iterator, bool>
inline bool insert(const_reference value) { return m_tree.insert(value); }
inline bool insert(value_type&& value) { return m_tree.insert(std::move(value)); }
inline size_type erase(const key_type& key) { return m_tree.erase({ key, T() }, details::map_key_finder<Key, T>()); }
inline allocator_type get_allocator() const noexcept { return m_tree.get_allocator(); }
inline size_type size() const { return m_tree.size(); }
inline bool empty() const { return size() == 0; }
T& at(const Key& key)
{
// TODO: Exceptions are not supported
pointer res = m_tree.find({ key, T() }, details::map_key_finder<Key, T>());
if (!res) {
m_tree.insert({ key, T() });
res = m_tree.find({ key, T() }, details::map_key_finder<Key, T>());
}
return res->second;
}
const T& at(const Key& key) const
{
pointer res = m_tree.find({ key, T() }, details::map_key_finder<Key, T>());
// TODO: Exceptions are not supported, so we simply add this element for now
if (!res) {
m_tree.insert({ key, T() });
res = m_tree.find({ key, T() }, details::map_key_finder<Key, T>());
}
return res->second;
}
T& operator[](const Key& key)
{
return at(key);
}
private:
__tree_type m_tree;
};
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_MAP

203
libs/libcxx/include/memory Normal file
View File

@@ -0,0 +1,203 @@
#pragma GCC system_header
#ifndef _LIBCXX_MEMORY
#define _LIBCXX_MEMORY
#include <__config>
#include <cstddef>
#include <new>
#include <type_traits>
#include <utility>
_LIBCXX_BEGIN_NAMESPACE_STD
template <typename T>
class unique_ptr {
public:
unique_ptr()
: m_data(nullptr)
{
}
unique_ptr(T* data)
: m_data(data)
{
}
unique_ptr(std::nullptr_t)
: m_data(nullptr)
{
}
unique_ptr& operator=(std::nullptr_t)
{
reset();
return *this;
}
unique_ptr(unique_ptr&& moving) noexcept
: m_data(nullptr)
{
moving.swap(*this);
}
unique_ptr& operator=(unique_ptr&& moving) noexcept
{
moving.swap(*this);
return *this;
}
template <typename U>
unique_ptr(unique_ptr<U>&& moving)
{
unique_ptr<T> tmp((T*)moving.release());
tmp.swap(*this);
}
template <typename U>
unique_ptr& operator=(unique_ptr<U>&& moving)
{
unique_ptr<T> tmp((T*)moving.release());
tmp.swap(*this);
return *this;
}
T* release() noexcept
{
T* result = m_data;
m_data = nullptr;
return result;
}
void swap(unique_ptr& src) noexcept
{
T* tmp_data = m_data;
m_data = src.m_data;
src.m_data = tmp_data;
}
void reset()
{
T* tmp = release();
delete tmp;
}
void reset(T* new_ptr)
{
T* tmp = release();
delete tmp;
m_data = new_ptr;
}
~unique_ptr()
{
delete m_data;
}
unique_ptr(unique_ptr const&) = delete;
unique_ptr& operator=(unique_ptr const&) = delete;
T* operator->() const { return m_data; }
T& operator*() const { return *m_data; }
T* get() const { return m_data; }
explicit operator bool() const { return m_data; }
private:
T* m_data { nullptr };
};
template <class Alloc>
struct allocator_traits {
using allocator_type = Alloc;
using value_type = typename Alloc::value_type;
using pointer = typename Alloc::pointer;
using const_pointer = typename Alloc::const_pointer;
using void_pointer = typename Alloc::void_pointer;
using const_void_pointer = typename Alloc::const_void_pointer;
using difference_type = typename Alloc::difference_type;
using size_type = typename Alloc::size_type;
};
template <class _Alloc, class S>
struct __rebind_alloc_helper;
template <template <class, class...> class _Alloc, class New, class Old, class... OtherArgs>
struct __rebind_alloc_helper<_Alloc<Old, OtherArgs...>, New> {
typedef typename std::allocator_traits<_Alloc<New, OtherArgs...>>::allocator_type type;
};
template <class T>
struct allocator {
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
using void_pointer = void*;
using const_void_pointer = const void*;
using difference_type = ptrdiff_t;
using size_type = size_t;
allocator() = default;
~allocator() = default;
pointer allocate(size_t n)
{
return reinterpret_cast<pointer>(operator new(n * sizeof(T)));
}
void deallocate(pointer p, size_t n)
{
return operator delete(p, n);
}
};
template <class T, class... Args>
static constexpr unique_ptr<T> make_unique(Args&&... args)
{
return new T(forward<Args>(args)...);
}
template <class T, class... Args>
static constexpr T* construct_at(T* p, Args&&... args)
{
return reinterpret_cast<T*>(new (static_cast<void*>(p)) T(forward<Args>(args)...));
}
template <class T>
static constexpr void destroy_at(T* p)
{
if constexpr (is_array_v<T>) {
static_assert(true, "Not implemented destroy_at for arrays");
}
return p->~T();
}
#if defined(_LIBCXX_BUILD_XOS_EXTENSIONS)
_LIBCXX_BEGIN_XOS_EXTENSION
template <class T, class... Args>
static constexpr T& construct(Args&&... args)
{
T* newobject = new T(forward<Args>(args)...);
return *newobject;
}
_LIBCXX_END_XOS_EXTENSION
#endif
template <class T>
T* to_address(T* p)
{
static_assert(!is_function_v<T>);
return p;
}
template <class T>
T* to_address(const T& p)
{
return to_address(p.operator->());
}
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_MEMORY

106
libs/libcxx/include/new Normal file
View File

@@ -0,0 +1,106 @@
#pragma GCC system_header
#ifndef _LIBCXX_NEW
#define _LIBCXX_NEW
#include <cstddef>
#include <cstdlib>
_LIBCXX_BEGIN_NAMESPACE_STD
enum class nothrow_t {};
enum class align_val_t : std::size_t {};
_LIBCXX_END_NAMESPACE_STD
inline void* operator new(size_t size)
{
return std::malloc(size);
}
inline void* operator new[](size_t size)
{
return std::malloc(size);
}
inline void* operator new(size_t size, const std::nothrow_t&) noexcept
{
return std::malloc(size);
}
inline void* operator new[](size_t size, const std::nothrow_t&) noexcept
{
return std::malloc(size);
}
inline void* operator new(size_t size, std::align_val_t alignment)
{
size_t aln = static_cast<size_t>(alignment);
void* ptr = std::malloc(size + sizeof(void*) + aln);
size_t max_addr = (size_t)ptr + sizeof(void*) + aln;
void* aligned_ptr = (void*)(max_addr - (max_addr % aln));
((void**)aligned_ptr)[-1] = ptr;
return aligned_ptr;
}
inline void* operator new[](size_t size, std::align_val_t alignment)
{
return ::operator new(size, alignment);
}
inline void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
{
size_t aln = static_cast<size_t>(alignment);
void* ptr = std::malloc(size + sizeof(void*) + aln);
size_t max_addr = (size_t)ptr + sizeof(void*) + aln;
void* aligned_ptr = (void*)(max_addr - (max_addr % aln));
((void**)aligned_ptr)[-1] = ptr;
return aligned_ptr;
}
inline void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t& nothrow) noexcept
{
return ::operator new(size, alignment, nothrow);
}
inline void* operator new(size_t, void* ptr) noexcept
{
return ptr;
}
inline void* operator new[](size_t, void* ptr) noexcept
{
return ptr;
}
inline void operator delete(void* ptr) noexcept
{
return std::free(ptr);
}
inline void operator delete(void* ptr, size_t) noexcept
{
return std::free(ptr);
}
inline void operator delete[](void* ptr) noexcept
{
return std::free(ptr);
}
inline void operator delete[](void* ptr, size_t) noexcept
{
return std::free(ptr);
}
inline void operator delete(void* ptr, std::align_val_t alignment) noexcept
{
std::free(((void**)ptr)[-1]);
}
inline void operator delete[](void* ptr, std::align_val_t alignment) noexcept
{
::operator delete(ptr, alignment);
}
#endif // _LIBCXX_NEW

View File

@@ -0,0 +1,70 @@
#pragma GCC system_header
#ifndef _LIBCXX_NUMBERS
#define _LIBCXX_NUMBERS
#include <__config>
#include <type_traits>
_LIBCXX_BEGIN_NAMESPACE_STD
namespace Math::Numbers {
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T e_v = 2.718281828459045235360287471352662;
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T log2e_v = 1.442695040888963407359924681001892;
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T log10e_v = 0.434294481903251827651128918916605;
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T pi_v = 3.141592653589793238462643383279502;
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T inv_pi_v = 0.318309886183790671537767526745028;
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T inv_sqrtpi_v = 0.564189583547756286948079451560772;
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T ln2_v = 0.693147180559945309417232121458176;
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T ln10_v = 2.302585092994045684017991454684364;
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T sqrt2_v = 1.414213562373095048801688724209698;
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T sqrt3_v = 1.732050807568877293527446341505872;
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T inv_sqrt3_v = 0.577350269189625764509148780501957;
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T egamma_v = 0.577215664901532860606512090082402;
template <typename T, typename = std::enable_if_t<is_floating_point_v<T>>>
inline constexpr T phi_v = 1.618033988749894848204586834365638;
inline constexpr double e = e_v<double>;
inline constexpr double log2e = log2e_v<double>;
inline constexpr double log10e = log10e_v<double>;
inline constexpr double pi = pi_v<double>;
inline constexpr double inv_pi = inv_pi_v<double>;
inline constexpr double inv_sqrtpi = inv_sqrtpi_v<double>;
inline constexpr double ln2 = ln2_v<double>;
inline constexpr double ln10 = ln10_v<double>;
inline constexpr double sqrt2 = sqrt2_v<double>;
inline constexpr double sqrt3 = sqrt3_v<double>;
inline constexpr double inv_sqrt3 = inv_sqrt3_v<double>;
inline constexpr double egamma = egamma_v<double>;
inline constexpr double phi = phi_v<double>;
}
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_NUMBERS

View File

@@ -0,0 +1,81 @@
#pragma GCC system_header
#ifndef _LIBCXX_OPTIONAL
#define _LIBCXX_OPTIONAL
#include <__config>
#include <type_traits>
_LIBCXX_BEGIN_NAMESPACE_STD
struct nullopt_t {
explicit constexpr nullopt_t() { }
};
inline constexpr nullopt_t nullopt {};
template <typename T>
class optional {
public:
using value_type = T;
optional() = default;
optional(nullopt_t)
: m_has_value(false)
, m_value()
{
}
template <class U = T>
optional(U&& value)
: m_value(std::forward<U>(value))
, m_has_value(true)
{
}
template <class... Args>
optional(in_place_t, Args&&... args)
: m_value(std::forward<Args>(args)...)
, m_has_value(true)
{
}
~optional() = default;
bool has_value() const { return m_has_value; }
operator bool() const { return has_value(); }
T* operator->() { return &m_value; }
const T* operator->() const { return &m_value; }
T& operator*() { return m_value; }
const T& operator*() const { return m_value; }
T& value() { return m_value; }
const T& value() const { return m_value; }
template <class U>
T value_or(U&& def)
{
if (has_value()) {
return m_value;
}
return def;
}
template <class U>
T value_or(U&& def) const
{
if (has_value()) {
return m_value;
}
return def;
}
private:
bool m_has_value { false };
T m_value;
};
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_OPTIONAL

161
libs/libcxx/include/ostream Normal file
View File

@@ -0,0 +1,161 @@
#pragma GCC system_header
#ifndef _LIBCXX_OSTREAM
#define _LIBCXX_OSTREAM
#include <cstdlib>
#include <ios>
#include <streambuf>
#include <string>
_LIBCXX_BEGIN_NAMESPACE_STD
template <typename CharT, typename Traits = char_traits<CharT>>
class basic_ostream : public basic_ios<CharT, Traits> {
public:
using char_type = CharT;
using traits_type = Traits;
using int_type = typename traits_type::int_type;
using pos_type = typename traits_type::pos_type;
using off_type = typename traits_type::off_type;
class sentry {
public:
explicit sentry(basic_ostream<char_type, traits_type>& os)
: m_os(os)
{
}
explicit operator bool() const { return true; }
~sentry() = default;
private:
basic_ostream<char_type, traits_type>& m_os;
};
explicit basic_ostream(basic_streambuf<char_type, traits_type>* rdbuf)
: basic_ios<char_type, traits_type>(rdbuf)
{
}
virtual ~basic_ostream() = default;
basic_ostream& put(char_type ch)
{
sentry sen(*this);
if (sen) {
if (this->rdbuf()->sputc(ch) == traits_type::eof()) {
this->setstate(ios_base::badbit);
}
}
return *this;
}
basic_ostream& write(const char_type* s, streamsize count)
{
sentry sen(*this);
if (sen && count) {
if (this->rdbuf()->sputn(s, count) != count) {
this->setstate(ios_base::badbit);
}
}
return *this;
}
basic_ostream& flush()
{
sentry sen(*this);
if (sen) {
if (this->rdbuf()->pubsync() == -1) {
this->setstate(ios_base::badbit);
}
}
return *this;
}
inline basic_ostream& operator<<(basic_ostream& (*callback)(basic_ostream&)) { return callback(*this); }
private:
};
template <class CharT, class Traits>
basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, int value)
{
char buf[16];
std::sprintf(buf, "%d", value);
size_t len = std::strlen(buf);
os.write(buf, len);
return os;
}
template <class CharT, class Traits>
basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, long value)
{
char buf[16];
std::sprintf(buf, "%d", value);
size_t len = std::strlen(buf);
os.write(buf, len);
return os;
}
template <class CharT, class Traits>
basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, unsigned int value)
{
char buf[16];
std::sprintf(buf, "%u", value);
size_t len = std::strlen(buf);
os.write(buf, len);
return os;
}
template <class CharT, class Traits>
basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, unsigned long value)
{
char buf[16];
std::sprintf(buf, "%u", value);
size_t len = std::strlen(buf);
os.write(buf, len);
return os;
}
template <class CharT, class Traits>
basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, const char* value)
{
size_t len = std::strlen(value);
os.write(value, len);
return os;
}
template <class CharT, class Traits>
basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, char value)
{
os.put(value);
return os;
}
template <class CharT, class Traits, class Allocator>
basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, std::basic_string<CharT, Traits, Allocator> const& value)
{
os.write(value.data(), value.size());
return os;
}
template <class CharT, class Traits>
basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, std::basic_string_view<CharT, Traits> const& value)
{
os.write(value.data(), value.size());
return os;
}
template <class CharT, class Traits>
basic_ostream<CharT, Traits>& endl(basic_ostream<CharT, Traits>& os)
{
os.put('\n');
os.flush();
return os;
}
typedef basic_ostream<char> ostream;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_OSTREAM

64
libs/libcxx/include/set Normal file
View File

@@ -0,0 +1,64 @@
#pragma GCC system_header
#ifndef _LIBCXX_SET
#define _LIBCXX_SET
#include <__config>
#include <__rbtree>
#include <functional>
#include <memory>
#include <type_traits>
_LIBCXX_BEGIN_NAMESPACE_STD
template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>>
class set {
private:
using __tree_type = __rbtree<Key, Compare, Allocator>;
public:
using key_type = Key;
using value_type = Key;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using key_compare = Compare;
using value_compare = Compare;
using allocator_type = Allocator;
using refernce = value_type&;
using const_reference = const value_type&;
using pointer = value_type*;
using const_pointer = const value_type*;
using node_type = typename __tree_type::node_type;
set()
: m_tree()
{
}
set(const Compare& comp, const Allocator& alloc = Allocator())
: m_tree(comp, alloc)
{
}
explicit set(const Allocator& alloc)
: m_tree(alloc)
{
}
// TODO: Return std::pair<iterator, bool>
inline bool insert(const_reference value) { return m_tree.insert(value); }
inline bool insert(value_type&& value) { return m_tree.insert(std::move(value)); }
inline size_type erase(const_reference value) { return m_tree.erase(value); }
inline allocator_type get_allocator() const noexcept { return m_tree.get_allocator(); }
inline size_type size() const { return m_tree.size(); }
inline bool empty() const { return size() == 0; }
private:
__tree_type m_tree;
};
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_SET

View File

@@ -0,0 +1,193 @@
#pragma GCC system_header
#ifndef _LIBCXX_STREAMBUF
#define _LIBCXX_STREAMBUF
#include <__config>
#include <algorithm>
#include <cstdlib>
#include <ios>
#include <iosfwd>
#include <string>
_LIBCXX_BEGIN_NAMESPACE_STD
template <class CharT, class Traits>
class basic_streambuf {
public:
using char_type = CharT;
using traits_type = Traits;
using int_type = typename traits_type::int_type;
using pos_type = typename traits_type::pos_type;
using off_type = typename traits_type::off_type;
virtual ~basic_streambuf() = default;
// TODO: Add locales
basic_streambuf* pubsetbuf(char_type* s, streamsize n) { return setbuf(s, n); }
pos_type pubseekoff(off_type off, ios_base::seekdir dir, ios_base::openmode which = ios_base::in | ios_base::out) { return seekoff(off, dir, which); }
pos_type pubseekpos(pos_type pos, ios_base::openmode which = ios_base::in | ios_base::out) { return seekpos(pos, which); }
int pubsync() { return sync(); }
streamsize in_avail()
{
if (egptr() - gptr() > 0) {
return egptr() - gptr();
}
return showmanyc();
}
int_type snextc()
{
if (sbumpc() == traits_type::eof()) {
return traits_type::eof();
}
return sgetc();
}
int_type sbumpc()
{
if (gptr() == egptr()) {
return uflow();
}
return Traits::to_int_type(*m_gptr++);
}
int_type sgetc()
{
if (gptr() == egptr()) {
return underflow();
}
return Traits::to_int_type(*gptr());
}
streamsize sgetn(char_type* s, streamsize n) { return xsgetn(s, n); }
int_type sputc(char_type c)
{
if (pptr() == epptr()) {
return overflow(c);
}
*pptr() = c;
m_pptr++;
return Traits::to_int_type(c);
}
streamsize sputn(const char_type* s, streamsize n) { return xsputn(s, n); }
int_type sputbackc(char_type c)
{
if (eback() == egptr() || traits_type::eq(c, egptr()[-1])) {
return pbackfail(c);
}
return traits_type::to_int_type(*(--m_gptr));
}
int_type sungetc()
{
if (eback() == egptr())
return pbackfail();
return traits_type::to_int_type(*(--m_gptr));
}
protected:
basic_streambuf() = default;
virtual basic_streambuf* setbuf(char_type* s, streamsize n) { return this; }
virtual pos_type seekoff(off_type off, ios_base::seekdir dir, ios_base::openmode which) { return pos_type(off_type(-1)); }
virtual pos_type seekpos(pos_type pos, ios_base::openmode which) { return pos_type(off_type(-1)); }
virtual int sync() { return 0; }
virtual streamsize showmanyc() { return 0; }
virtual int_type underflow() { return traits_type::eof(); }
virtual int_type uflow()
{
if (underflow() == traits_type::eof()) {
return traits_type::eof();
}
return traits_type::to_int_type(*m_gptr++);
}
virtual streamsize xsgetn(char_type* s, streamsize count)
{
auto eof = traits_type::eof();
int_type tmpcint;
for (streamsize i = 0; i < count;) {
if (gptr() < egptr()) {
streamsize can_get = std::min(static_cast<streamsize>(egptr() - gptr()), count);
traits_type::copy(s, gptr(), can_get);
this->gbump(can_get);
s += can_get;
i += can_get;
} else if ((tmpcint = uflow()) != eof) {
*s = traits_type::to_char_type(tmpcint);
s++;
i++;
} else {
return i;
}
}
return count;
}
char_type* eback() const { return m_eback; }
char_type* gptr() const { return m_gptr; }
char_type* egptr() const { return m_egptr; }
void gbump(int n) { m_gptr += n; }
void setg(char_type* gbeg, char_type* gcurr, char_type* gend)
{
m_eback = gbeg;
m_gptr = gcurr;
m_egptr = gend;
}
virtual streamsize xsputn(const char_type* s, streamsize count)
{
auto eof = traits_type::eof();
int_type tmpcint;
for (streamsize i = 0; i < count;) {
if (pptr() < epptr()) {
streamsize can_put = std::min(static_cast<streamsize>(egptr() - gptr()), count);
traits_type::copy(pptr(), s, can_put);
this->pbump(can_put);
s += can_put;
i += can_put;
} else if ((tmpcint = overflow(*s)) != eof) {
s++;
i++;
} else {
return i;
}
}
return count;
}
virtual int_type overflow(int_type ch = traits_type::eof()) { return traits_type::eof(); }
char_type* pbase() const { return m_pbase; }
char_type* pptr() const { return m_pptr; }
char_type* epptr() const { return m_epptr; }
void pbump(int n) { m_pptr += n; }
void setg(char_type* pbeg, char_type* pend)
{
m_pbase = m_pptr = pbeg;
m_epptr = pend;
}
virtual int_type pbackfail(int_type c = traits_type::eof()) { return traits_type::eof(); }
private:
char_type* m_eback { nullptr };
char_type* m_gptr { nullptr };
char_type* m_egptr { nullptr };
char_type* m_pbase { nullptr };
char_type* m_pptr { nullptr };
char_type* m_epptr { nullptr };
};
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_STREAMBUF

362
libs/libcxx/include/string Normal file
View File

@@ -0,0 +1,362 @@
#pragma GCC system_header
#ifndef _LIBCXX_STRING
#define _LIBCXX_STRING
#include <__config>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iterator>
#include <memory>
#include <new>
#include <utility>
_LIBCXX_BEGIN_NAMESPACE_STD
static char __null_char = '\0';
template <class CharT>
class char_traits {
public:
using char_type = CharT;
using int_type = int;
using pos_type = int;
using off_type = int;
using state_type = int;
static constexpr void assign(char_type& r, const char_type& a) { r = a; }
static constexpr char_type* assign(char_type* p, size_t count, char_type a)
{
for (size_t sz = 0; sz < count; sz++) {
assign(p[sz], a);
}
return p;
}
static constexpr char_type* move(char_type* dest, const char_type* src, size_t count)
{
for (size_t sz = 0; sz < count; sz++) {
dest[sz] = std::move(src[sz]);
}
return dest;
}
static constexpr size_t length(const char_type* s)
{
return strlen(s);
}
static constexpr char_type* copy(char_type* dest, const char_type* src, size_t count)
{
for (size_t sz = 0; sz < count; sz++) {
dest[sz] = src[sz];
}
return dest;
}
static constexpr int compare(const char_type* a, const char_type* b, size_t count)
{
return strncmp(a, b, count);
}
static constexpr char_type to_char_type(int_type c) { return static_cast<char_type>(c); }
static constexpr int_type to_int_type(char_type c) { return static_cast<int_type>(c); }
static constexpr bool eq_int_type(int_type c1, int_type c2) { return c1 == c2; }
static constexpr int_type eof() { return -1; }
static constexpr bool not_eof(int_type a) { return a != eof(); }
static constexpr bool eq(char_type a, char_type b) { return a == b; }
static constexpr bool lt(char_type a, char_type b) { return a < b; }
};
template <class CharT, class Traits>
class basic_string_view;
template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT>>
class basic_string {
public:
using value_type = CharT;
using allocator_type = Allocator;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = CharT*;
using const_pointer = const CharT*;
using reference = CharT&;
using const_reference = const CharT&;
using iterator = std::__legacy_iter<pointer>;
using const_iterator = std::__legacy_iter<const_pointer>;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
basic_string() = default;
basic_string(const value_type* str)
{
m_size = Traits::length(str);
ensure_capacity(m_size + 1);
Traits::copy(m_str, str, m_size);
Traits::assign(m_str[m_size], '\0');
}
basic_string(const value_type* str, size_t size)
{
m_size = size;
ensure_capacity(m_size + 1);
Traits::copy(m_str, str, m_size);
Traits::assign(m_str[m_size], '\0');
}
template <class Iter>
constexpr basic_string(Iter first, Iter last)
{
m_size = std::distance(first, last);
ensure_capacity(m_size + 1);
for (size_t i = 0; first != last; ++first, ++i) {
Traits::assign(at(i), *first);
}
}
basic_string(const basic_string& s)
{
m_size = s.m_size;
ensure_capacity(m_size + 1);
Traits::copy(m_str, s.m_str, m_size);
Traits::assign(m_str[m_size], '\0');
}
basic_string(basic_string&& s)
{
m_size = s.m_size;
m_capacity = s.m_capacity;
m_str = s.m_str;
s.m_size = s.m_capacity = 0;
s.m_str = &__null_char;
}
~basic_string()
{
clear();
}
basic_string& operator=(const basic_string& s)
{
m_size = s.m_size;
ensure_capacity(m_size + 1);
Traits::copy(m_str, s.m_str, m_size);
Traits::assign(m_str[m_size], '\0');
return *this;
}
basic_string& operator=(basic_string&& s)
{
if (this != &s) {
clear();
m_size = s.m_size;
m_capacity = s.m_capacity;
m_str = s.m_str;
s.m_size = s.m_capacity = 0;
s.m_str = &__null_char;
}
return *this;
}
basic_string& operator+=(const basic_string& s)
{
ensure_capacity(size() + s.size() + 1);
Traits::copy(&m_str[m_size], s.m_str, s.m_size);
m_size += s.size();
Traits::assign(m_str[m_size], '\0');
return *this;
}
basic_string operator+(const basic_string& s) const
{
basic_string res(*this);
res += s;
return res;
}
basic_string operator+(const value_type* s) const
{
basic_string res(*this);
res += basic_string(s);
return res;
}
constexpr allocator_type get_allocator() const { return m_allocator; }
inline void push_back(const value_type& c)
{
ensure_capacity(size() + 2);
Traits::assign(m_str[m_size], c);
m_size++;
Traits::assign(m_str[m_size], '\0');
}
inline void pop_back()
{
--m_size;
Traits::assign(m_str[m_size], '\0');
}
inline const_reference at(size_t i) const
{
return m_str[i];
}
inline reference at(size_t i)
{
return m_str[i];
}
void clear()
{
if (m_capacity && m_str != &__null_char) {
free(m_str);
m_str = &__null_char;
}
m_size = 0;
m_capacity = 0;
}
void resize(size_t count, const value_type& c)
{
ensure_capacity(count + 1);
Traits::assign(&m_str[m_size], count - size(), c);
m_size = count;
Traits::assign(m_str[m_size], '\0');
}
void resize(size_t count) { resize(count, '\0'); }
inline size_t size() const { return m_size; }
inline size_t length() const { return m_size; }
inline bool empty() const { return size() == 0; }
inline const_reference operator[](size_t i) const { return at(i); }
inline reference operator[](size_t i) { return at(i); }
inline const_reference front() const { return at(0); }
inline reference front() { return at(0); }
inline const_reference back() const { return at(size() - 1); }
inline reference back() { return at(size() - 1); }
inline const_pointer c_str() const { return m_str; }
inline const_pointer data() const { return m_str; }
inline iterator begin() { return iterator(&m_str[0]); }
inline iterator end() { return iterator(&m_str[m_size]); }
inline const_iterator cbegin() const { return const_iterator(&m_str[0]); }
inline const_iterator cend() const { return const_iterator(&m_str[m_size]); }
inline reverse_iterator rbegin() { return reverse_iterator(&m_str[m_size - 1]); }
inline reverse_iterator rend() { return reverse_iterator(&m_str[-1]); }
inline const_reverse_iterator crbegin() const { return const_reverse_iterator(&m_str[m_size - 1]); }
inline const_reverse_iterator crend() const { return const_reverse_iterator(&m_str[-1]); }
inline operator std::basic_string_view<CharT, Traits>() const { return std::basic_string_view<CharT, Traits>(data(), size()); }
bool starts_with(value_type c) const
{
if (size() == 0) {
return false;
}
return Traits::eq(at(0), c) == 0;
}
bool starts_with(const value_type* s) const
{
size_t len = Traits::length(s);
if (size() < len) {
return false;
}
return Traits::compare(c_str(), s, len) == 0;
}
private:
inline void ensure_capacity(size_t new_size)
{
int capacity = 4;
while (new_size > capacity) {
capacity *= 2;
}
grow(capacity);
}
void grow(size_t capacity)
{
if (capacity < m_capacity) {
return;
}
if (!m_capacity) {
m_str = m_allocator.allocate(capacity);
} else {
auto new_str = m_allocator.allocate(capacity);
Traits::move(new_str, m_str, m_capacity);
m_allocator.deallocate(m_str, m_capacity);
m_str = new_str;
}
m_capacity = capacity;
}
size_t m_size { 0 };
size_t m_capacity { 0 };
value_type* m_str { &__null_char };
allocator_type m_allocator;
};
typedef basic_string<char> string;
static std::string to_string(int a)
{
char buf[32];
std::sprintf(buf, "%d", a);
return std::string(buf);
}
static std::string to_string(unsigned a)
{
char buf[32];
std::sprintf(buf, "%u", a);
return std::string(buf);
}
template <class CharT, class Traits, class Allocator>
bool operator==(const std::basic_string<CharT, Traits, Allocator>& a, const std::basic_string<CharT, Traits, Allocator>& b)
{
if (a.size() != b.size()) {
return false;
}
return Traits::compare(a.c_str(), b.c_str(), a.size()) == 0;
}
template <class CharT, class Traits, class Allocator>
bool operator==(const std::basic_string<CharT, Traits, Allocator>& a, const CharT* cstr)
{
size_t bsize = Traits::length(cstr);
if (a.size() != bsize) {
return false;
}
return Traits::compare(a.c_str(), cstr, a.size()) == 0;
}
template <class CharT, class Traits, class Allocator>
bool operator<(const std::basic_string<CharT, Traits, Allocator>& a, const std::basic_string<CharT, Traits, Allocator>& b)
{
int eq = Traits::compare(a.c_str(), b.c_str(), std::min(a.size(), b.size()));
if (!eq) {
return eq == -1;
}
return a.size() < b.size();
}
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_STRING

View File

@@ -0,0 +1,90 @@
#pragma GCC system_header
#ifndef _LIBCXX_STRING_VIEW
#define _LIBCXX_STRING_VIEW
#include <__config>
#include <string>
_LIBCXX_BEGIN_NAMESPACE_STD
template <class CharT, class Traits = std::char_traits<CharT>>
class basic_string_view {
public:
using value_type = CharT;
using pointer = CharT*;
using const_pointer = const CharT*;
using reference = CharT&;
using const_reference = const CharT&;
using iterator = std::__legacy_iter<pointer>;
using const_iterator = std::__legacy_iter<const_pointer>;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
basic_string_view() = default;
basic_string_view(const value_type* str)
: m_str(str)
, m_size(Traits::length(str))
{
}
basic_string_view(const value_type* str, size_t size)
: m_str(str)
, m_size(size)
{
}
template <class Iter>
basic_string_view(Iter first, Iter last)
: m_str(std::to_address(first))
, m_size(std::distance(first, last))
{
}
~basic_string_view() = default;
inline size_t size() const { return m_size; }
inline size_t length() const { return m_size; }
inline bool empty() const { return size() == 0; }
inline const_reference operator[](size_t i) const { return at(i); }
inline const_reference at(size_t i) const { return m_str[i]; }
inline const_reference front() const { return at(0); }
inline const_reference back() const { return at(size() - 1); }
inline const_pointer data() const { return m_str; }
inline const_iterator begin() const { return const_iterator(&m_str[0]); }
inline const_iterator end() const { return const_iterator(&m_str[m_size]); }
inline const_iterator cbegin() const { return const_iterator(&m_str[0]); }
inline const_iterator cend() const { return const_iterator(&m_str[m_size]); }
inline const_reverse_iterator rbegin() const { return const_reverse_iterator(&m_str[m_size - 1]); }
inline const_reverse_iterator rend() const { return const_reverse_iterator(&m_str[-1]); }
inline const_reverse_iterator crbegin() const { return const_reverse_iterator(&m_str[m_size - 1]); }
inline const_reverse_iterator crend() const { return const_reverse_iterator(&m_str[-1]); }
private:
size_t m_size { 0 };
const value_type* m_str { &__null_char };
};
typedef basic_string_view<char> string_view;
template <class CharT, class Traits>
bool operator==(const std::basic_string_view<CharT, Traits>& a, const std::basic_string_view<CharT, Traits>& b)
{
if (a.size() != b.size()) {
return false;
}
return Traits::compare(a.c_str(), b.c_str(), a.size()) == 0;
}
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_STRING_VIEW

View File

@@ -0,0 +1,248 @@
#pragma GCC system_header
#ifndef _LIBCXX_TYPE_TRAITS
#define _LIBCXX_TYPE_TRAITS
#include <__config>
#include <cstddef>
_LIBCXX_BEGIN_NAMESPACE_STD
// Helper Classes
template <class T, T v>
struct integral_constant {
static constexpr T value = v;
constexpr operator T() const { return value; }
constexpr T operator()() const { return value; }
};
template <bool v>
using bool_constant = integral_constant<bool, v>;
using true_type = integral_constant<bool, true>;
using false_type = integral_constant<bool, false>;
// Type relationships
template <class T>
struct type_identity {
using type = T;
};
template <class T>
using type_identity_t = typename type_identity<T>::type;
template <class T, class U>
struct is_same : false_type {
};
template <class T>
struct is_same<T, T> : true_type {
};
template <class T, class U>
inline constexpr bool is_same_v = is_same<T, U>::value;
// Const-volatility specifiers
template <class T>
struct remove_const {
typedef T type;
};
template <class T>
struct remove_const<const T> {
typedef T type;
};
template <class T>
using remove_const_t = typename remove_const<T>::type;
template <class T>
struct remove_volatile {
typedef T type;
};
template <class T>
struct remove_volatile<volatile T> {
typedef T type;
};
template <class T>
using remove_volatile_t = typename remove_volatile<T>::type;
template <class T>
struct remove_cv {
typedef T type;
};
template <class T>
struct remove_cv<const T> {
typedef T type;
};
template <class T>
struct remove_cv<volatile T> {
typedef T type;
};
template <class T>
struct remove_cv<const volatile T> {
typedef T type;
};
template <class T>
using remove_cv_t = typename remove_cv<T>::type;
template <class T>
struct add_const {
typedef const T type;
};
template <class T>
using add_const_t = typename add_const<T>::type;
template <class T>
struct add_volatile {
typedef volatile T type;
};
template <class T>
using add_volatile_t = typename add_volatile<T>::type;
template <class T>
struct add_cv {
typedef const volatile T type;
};
template <class T>
using add_cv_t = typename add_cv<T>::type;
template <class T>
struct add_pointer {
typedef T* type;
};
template <class T>
using add_pointer_t = typename add_pointer<T>::type;
template <class T>
struct remove_reference {
typedef T type;
};
template <class T>
struct remove_reference<T&> {
typedef T type;
};
template <class T>
struct remove_reference<T&&> {
typedef T type;
};
template <class T>
using remove_reference_t = typename remove_reference<T>::type;
template <class T>
struct remove_pointer {
typedef T type;
};
template <class T>
struct remove_pointer<T*> {
typedef T type;
};
template <class T>
struct remove_pointer<T* const> {
typedef T type;
};
template <class T>
struct remove_pointer<T* volatile> {
typedef T type;
};
template <class T>
struct remove_pointer<T* const volatile> {
typedef T type;
};
template <class T>
using remove_pointer_t = typename remove_pointer<T>::type;
template <class T>
struct remove_extent {
typedef T type;
};
template <class T>
struct remove_extent<T[]> {
typedef T type;
};
template <class T, std::size_t N>
struct remove_extent<T[N]> {
typedef T type;
};
template <class T>
using remove_extent_t = typename remove_extent<T>::type;
// Primary type categories
template <class T>
struct is_void : is_same<void, typename remove_cv<T>::type> {
};
template <class T>
inline constexpr bool is_void_v = is_void<T>::value;
template <class T>
struct is_pointer_h : false_type {
};
template <class T>
struct is_pointer_h<T*> : true_type {
};
template <class T>
struct is_pointer : is_pointer_h<typename std::remove_cv<T>::type> {
};
template <class T>
struct is_array : false_type {
};
template <class T>
struct is_array<T[]> : true_type {
};
template <class T, size_t N>
struct is_array<T[N]> : true_type {
};
template <class T>
inline constexpr bool is_array_v = is_array<T>::value;
template <class T>
struct is_const : false_type {
};
template <class T>
struct is_const<const T> : true_type {
};
template <class T>
inline constexpr bool is_const_v = is_const<T>::value;
template <class T>
struct is_floating_point : integral_constant<bool, is_same_v<float, remove_cv_t<T>> || is_same_v<double, remove_cv_t<T>> || is_same_v<long double, remove_cv_t<T>>> {
};
template <class T>
inline constexpr bool is_floating_point_v = is_floating_point<T>::value;
template <class T>
struct is_function : bool_constant<!is_const_v<const T>> {
};
template <class T>
inline constexpr bool is_function_v = is_function<T>::value;
template <bool B, class T = void>
struct enable_if {
};
template <class T>
struct enable_if<true, T> {
typedef T type;
};
template <bool B, class T = void>
using enable_if_t = typename enable_if<B, T>::type;
template <bool B, class T, class F>
struct conditional {
typedef T type;
};
template <class T, class F>
struct conditional<false, T, F> {
typedef F type;
};
template <bool B, class T, class F>
using conditional_t = typename conditional<B, T, F>::type;
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_TYPE_TRAITS

View File

@@ -0,0 +1,28 @@
#pragma GCC system_header
#ifndef _LIBCXX_TYPEINFO
#define _LIBCXX_TYPEINFO
#include <__config>
_LIBCXX_BEGIN_NAMESPACE_STD
class type_info {
public:
virtual ~type_info();
bool operator==(const type_info& rhs) const;
bool operator!=(const type_info& rhs) const;
bool before(const type_info& rhs) const;
const char* name() const { return m_type_name; }
private:
type_info(const type_info& rhs) = delete;
type_info& operator=(const type_info& rhs) = delete;
const char* m_type_name;
};
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_TYPEINFO

119
libs/libcxx/include/utility Normal file
View File

@@ -0,0 +1,119 @@
#pragma GCC system_header
#ifndef _LIBCXX_UTILITY
#define _LIBCXX_UTILITY
#include <__config>
#include <type_traits>
_LIBCXX_BEGIN_NAMESPACE_STD
template <typename T>
inline T&& move(T& arg)
{
return static_cast<T&&>(arg);
}
template <typename T, typename U>
inline void swap(T& a, U& b)
{
U tmp = move((U&)a);
a = (T &&) move(b);
b = move(tmp);
}
template <class T>
static constexpr T&& forward(std::remove_reference_t<T>& t) { return static_cast<T&&>(t); }
template <class T>
static constexpr T&& forward(std::remove_reference_t<T>&& t) { return static_cast<T&&>(t); }
struct in_place_t {
explicit in_place_t() = default;
};
inline constexpr in_place_t in_place {};
template <class T1, class T2>
struct pair {
using first_type = T1;
using second_type = T2;
constexpr pair() = default;
constexpr ~pair() = default;
constexpr pair(const T1& x, const T2& y)
: first(x)
, second(y)
{
}
template <class U1 = T1, class U2 = T2>
constexpr pair(U1&& x, U2&& y)
: first(std::forward<U1>(x))
, second(std::forward<U2>(y))
{
}
constexpr pair(const pair<T1, T2>& p)
: first(p.first)
, second(p.second)
{
}
template <class U1 = T1, class U2 = T2>
constexpr pair(pair<U1, U2>&& p)
: first(std::move(p.first))
, second(std::move(p.second))
{
}
T1 first {};
T2 second {};
};
template <class T1, class T2>
constexpr bool operator==(const std::pair<T1, T2>& lhs, const std::pair<T1, T2>& rhs)
{
return lhs.first == rhs.first && lhs.second == rhs.second;
}
template <class T1, class T2>
constexpr bool operator!=(const std::pair<T1, T2>& lhs, const std::pair<T1, T2>& rhs)
{
return !(lhs == rhs);
}
template <class T1, class T2>
constexpr bool operator<(const std::pair<T1, T2>& lhs, const std::pair<T1, T2>& rhs)
{
return (lhs.first < rhs.first) || (lhs.first == rhs.first && lhs.second < rhs.second);
}
template <class T1, class T2>
constexpr bool operator<=(const std::pair<T1, T2>& lhs, const std::pair<T1, T2>& rhs)
{
return (lhs < rhs) || (lhs == rhs);
}
template <class T1, class T2>
constexpr bool operator>(const std::pair<T1, T2>& lhs, const std::pair<T1, T2>& rhs)
{
return (lhs.first > rhs.first) || (lhs.first == rhs.first && lhs.second > rhs.second);
}
template <class T1, class T2>
constexpr bool operator>=(const std::pair<T1, T2>& lhs, const std::pair<T1, T2>& rhs)
{
return (lhs > rhs) || (lhs == rhs);
}
// TODO: Use decay for return types
template <class T1, class T2>
std::pair<T1, T2> make_pair(T1&& l, T2&& r)
{
return std::pair<T1, T2>(std::forward<T1>(l), std::forward<T2>(r));
}
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_UTILITY

216
libs/libcxx/include/vector Normal file
View File

@@ -0,0 +1,216 @@
#pragma GCC system_header
#ifndef _LIBCXX_VECTOR
#define _LIBCXX_VECTOR
#include <__config>
#include <iterator>
#include <memory>
#include <utility>
_LIBCXX_BEGIN_NAMESPACE_STD
template <class T, class Allocator = std::allocator<T>>
class vector {
public:
using value_type = T;
using allocator_type = Allocator;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using reference = T&;
using const_reference = const T&;
using pointer = T*;
using const_pointer = const T*;
using iterator = std::__legacy_iter<pointer>;
using const_iterator = std::__legacy_iter<const_pointer>;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
vector()
{
grow(16);
}
explicit vector(size_type capacity)
{
grow(capacity);
}
vector(const vector& v)
{
grow(v.m_capacity);
m_size = v.m_size;
copy(m_data, v.m_data, m_size);
}
vector(vector&& v)
{
m_size = v.m_size;
m_capacity = v.m_capacity;
m_data = v.m_data;
v.m_size = v.m_capacity = 0;
v.m_data = nullptr;
}
~vector()
{
clear();
}
vector& operator=(const vector& v)
{
grow(v.m_capacity);
m_size = v.m_size;
copy(m_data, v.m_data, m_size);
return *this;
}
vector& operator=(vector&& v)
{
if (this != &v) {
clear();
m_size = v.m_size;
m_capacity = v.m_capacity;
m_data = v.m_data;
v.m_size = 0;
v.m_capacity = 0;
v.m_data = nullptr;
}
return *this;
}
inline void push_back(value_type&& el)
{
ensure_capacity(size() + 1);
construct_at(&m_data[m_size], std::move(el));
m_size++;
}
inline void push_back(const_reference el)
{
push_back(T(el));
}
inline void pop_back()
{
back().~T();
--m_size;
}
inline const_reference at(size_type i) const
{
return data()[i];
}
inline reference at(size_type i)
{
return data()[i];
}
void clear()
{
clear_remain_capacity();
if (m_data) {
m_allocator.deallocate(m_data, m_capacity);
m_data = nullptr;
}
m_capacity = 0;
}
void clear_remain_capacity()
{
if (m_data) {
for (size_type i = 0; i < m_size; ++i) {
destroy_at(&m_data[i]);
}
}
m_size = 0;
}
inline void resize(size_type new_size)
{
ensure_capacity(new_size);
m_size = new_size;
}
inline size_t size() const { return m_size; }
inline size_t capacity() const { return m_capacity; }
inline bool empty() const { return size() == 0; }
inline reference operator[](size_t i) { return at(i); }
inline const_reference operator[](size_t i) const { return at(i); }
inline reference front() { return at(0); }
inline const_reference front() const { return at(0); }
inline reference back() { return at(size() - 1); }
inline const_reference back() const { return at(size() - 1); }
inline pointer data() { return m_data; }
inline const_pointer data() const { return m_data; }
inline iterator begin() { return iterator(&m_data[0]); }
inline iterator end() { return iterator(&m_data[m_size]); }
inline const_iterator cbegin() const { return const_iterator(&m_data[0]); }
inline const_iterator cend() const { return const_iterator(&m_data[m_size]); }
inline reverse_iterator rbegin() { return reverse_iterator(&m_data[m_size - 1]); }
inline reverse_iterator rend() { return reverse_iterator(&m_data[-1]); }
inline const_reverse_iterator crbegin() const { return const_reverse_iterator(&m_data[m_size - 1]); }
inline const_reverse_iterator crend() const { return const_reverse_iterator(&m_data[-1]); }
private:
inline void ensure_capacity(size_type new_size)
{
size_type capacity = 16;
while (new_size > capacity) {
capacity *= 2;
}
grow(capacity);
}
void grow(size_type capacity)
{
if (capacity <= m_capacity) {
return;
}
if (!m_data) {
m_data = m_allocator.allocate(capacity);
} else {
retry:
auto new_buf = m_allocator.allocate(capacity);
if (!new_buf) {
goto retry;
}
for (size_t i = 0; i < m_size; i++) {
construct_at(&new_buf[i], std::move(at(i)));
destroy_at(&m_data[i]);
}
m_allocator.deallocate(m_data, m_capacity);
m_data = new_buf;
}
m_capacity = capacity;
}
void copy(pointer to, const_pointer from, size_type len)
{
for (size_type i = 0; i < len; i++) {
construct_at(to, T(*from));
to++;
from++;
}
}
size_type m_size { 0 };
size_type m_capacity { 0 };
pointer m_data { nullptr };
allocator_type m_allocator;
};
_LIBCXX_END_NAMESPACE_STD
#endif // _LIBCXX_VECTOR

View File

@@ -0,0 +1,23 @@
#include <cstddef>
#include <sys/types.h>
extern "C" {
extern void _libc_init(int argc, char* argv[], char* envp[]);
extern void _libc_deinit();
extern void _Z12_libcpp_initv();
extern void _Z14_libcpp_deinitv();
extern void __cxa_finalize(void*);
void _init(int argc, char* argv[], char* envp[])
{
_libc_init(argc, argv, envp);
_Z12_libcpp_initv();
}
void _deinit()
{
__cxa_finalize(nullptr);
_Z14_libcpp_deinitv();
_libc_deinit();
}
}

14
libs/libcxx/init/_lib.cpp Normal file
View File

@@ -0,0 +1,14 @@
namespace std {
extern int _ios_init();
extern int _ios_deinit();
} // namespace std
void _libcpp_init()
{
std::_ios_init();
}
void _libcpp_deinit()
{
std::_ios_deinit();
}

View File

@@ -0,0 +1,35 @@
#include <__config>
#include <__std_streambuffer>
#include <cstdio>
#include <new>
#include <ostream>
_LIBCXX_BEGIN_NAMESPACE_STD
_ALIGNAS_TYPE(ostream)
char cout[sizeof(ostream)];
_ALIGNAS_TYPE(__stdoutbuf<char>)
static char cout_buf[sizeof(__stdoutbuf<char>)];
static ostream* cout_ptr;
_ALIGNAS_TYPE(ostream)
char cerr[sizeof(ostream)];
_ALIGNAS_TYPE(__stdoutbuf<char>)
static char cerr_buf[sizeof(__stdoutbuf<char>)];
static ostream* cerr_ptr;
int _ios_init()
{
cout_ptr = new (cout) ostream(new (cout_buf) __stdoutbuf<char>(stdout));
cerr_ptr = new (cerr) ostream(new (cerr_buf) __stdoutbuf<char>(stderr));
return 0;
}
int _ios_deinit()
{
cout_ptr->flush();
cerr_ptr->flush();
return 0;
}
_LIBCXX_END_NAMESPACE_STD

View File

@@ -0,0 +1,36 @@
#include <cstring>
#include <new>
#include <typeinfo>
_LIBCXX_BEGIN_NAMESPACE_STD
type_info::~type_info()
{
}
bool type_info::operator==(const type_info& rhs) const
{
// GCC has a convention where the typeinfo name for a class which
// is declared in an anonymous namespace begins with '*'.
if (name()[0] == '*' || rhs.name()[0] == '*') {
return false;
}
return this == &rhs || strcmp(name(), rhs.name()) == 0;
}
bool type_info::operator!=(const type_info& rhs) const
{
return !operator==(rhs);
}
bool type_info::before(const type_info& rhs) const
{
// GCC has a convention where the typeinfo name for a class which
// is declared in an anonymous namespace begins with '*'.
if (name()[0] == '*' && rhs.name()[0] == '*') {
return name() < rhs.name();
}
return strcmp(name(), rhs.name()) < 0;
}
_LIBCXX_END_NAMESPACE_STD