summaryrefslogtreecommitdiff
path: root/euler/include
diff options
context:
space:
mode:
Diffstat (limited to 'euler/include')
-rw-r--r--euler/include/algorithm12
-rw-r--r--euler/include/cctype3
-rw-r--r--euler/include/cstdio22
-rw-r--r--euler/include/cstring11
-rw-r--r--euler/include/euler/heap.hpp10
-rw-r--r--euler/include/euler/start_process.hpp30
-rw-r--r--euler/include/euler/stream.hpp47
-rw-r--r--euler/include/euler/syscall.hpp234
-rw-r--r--euler/include/std/allocator.hpp30
-rw-r--r--euler/include/std/string.hpp80
-rw-r--r--euler/include/std/vector.hpp191
-rw-r--r--euler/include/string13
-rw-r--r--euler/include/type_traits23
-rw-r--r--euler/include/utility12
-rw-r--r--euler/include/vector61
15 files changed, 497 insertions, 282 deletions
diff --git a/euler/include/algorithm b/euler/include/algorithm
deleted file mode 100644
index 08702f9..0000000
--- a/euler/include/algorithm
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-namespace std {
-
- template <class t>
- void swap(t &a, t &b) {
- t tmp = a;
- a = b;
- b = tmp;
- }
-
-}
diff --git a/euler/include/cctype b/euler/include/cctype
new file mode 100644
index 0000000..2afc53d
--- /dev/null
+++ b/euler/include/cctype
@@ -0,0 +1,3 @@
+#pragma once
+
+extern "C" int isspace(int ch);
diff --git a/euler/include/cstdio b/euler/include/cstdio
index 75472c1..0dc42d0 100644
--- a/euler/include/cstdio
+++ b/euler/include/cstdio
@@ -1,20 +1,16 @@
#pragma once
#include <euler/stream.hpp>
-#include <stddef.h>
+#include <cstddef>
-namespace std {
+typedef euler::stream FILE;
- typedef euler::stream FILE;
+extern "C" FILE *fopen(const char *filename, const char *mode);
+extern "C" void fclose(FILE *stream);
- FILE *fopen(const char *filename, const char *mode);
- int fclose(FILE *stream);
+#define SEEK_CUR 2
+#define SEEK_END 1
+#define SEEK_SET 0
- int fseek(FILE *stream, long offset, int origin);
- #define SEEK_SET 0
- #define SEEK_CUR 2
- #define SEEK_END 1
-
- size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
-
-}
+extern "C" int fseek(FILE *stream, long offset, int origin);
+extern "C" size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
diff --git a/euler/include/cstring b/euler/include/cstring
index 45bc94e..cba5eb2 100644
--- a/euler/include/cstring
+++ b/euler/include/cstring
@@ -1,8 +1,9 @@
#pragma once
-#include <stddef.h>
+#include <cstddef>
-namespace std {
- size_t strlen(const char *str);
- void *memcpy(void *dest, const void *src, size_t count);
-}
+extern "C" void *memset(void *dest, int ch, size_t count);
+extern "C" void *memcpy(void *dest, const void *src, size_t count);
+
+extern "C" int strcmp(const char *lhs, const char *rhs);
+extern "C" size_t strlen(const char *str);
diff --git a/euler/include/euler/heap.hpp b/euler/include/euler/heap.hpp
index e2a4852..ce94eef 100644
--- a/euler/include/euler/heap.hpp
+++ b/euler/include/euler/heap.hpp
@@ -1,8 +1,10 @@
#pragma once
-#include <stdint.h>
+#include <cstddef>
+
+namespace euler::heap {
+
+ void *get_block(size_t length);
+ void return_block(void *start, size_t length);
-namespace euler {
- void *alloc(uint64_t bytes);
- void dealloc(void *start, uint64_t bytes);
}
diff --git a/euler/include/euler/start_process.hpp b/euler/include/euler/start_process.hpp
deleted file mode 100644
index 00ebbab..0000000
--- a/euler/include/euler/start_process.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include <euler/syscall.hpp>
-#include <vector>
-
-namespace euler {
-
- struct start_process {
-
- private:
- const char *path;
- uint64_t path_len;
- std::vector<__euler_env_var_spec> env_var_specs;
- std::vector<__euler_gift_stream_spec> gift_stream_specs;
-
- public:
- //path needs to stay valid through any call to start
- start_process(const char *path);
-
- //name and value need to stay valid through any call to start
- void add_env_variable(const char *name, const char *value);
-
- void gift_stream(
- __euler_stream_handle to_gifter, __euler_stream_handle to_giftee);
-
- __euler_stream_result start(__euler_process_handle &handle_out);
-
- };
-
-}
diff --git a/euler/include/euler/stream.hpp b/euler/include/euler/stream.hpp
index a364ec4..741d863 100644
--- a/euler/include/euler/stream.hpp
+++ b/euler/include/euler/stream.hpp
@@ -7,41 +7,42 @@ namespace euler {
class stream {
public:
- virtual ~stream();
- virtual bool try_read(void *into, uint64_t bytes) = 0;
- virtual bool try_seek(__euler_seek_from from, int64_t offset) = 0;
+ virtual ~stream() {}
- };
+ virtual syscall::stream_result seek(
+ euler::syscall::seek_from from, int64_t offset) = 0;
- class file_stream : public stream {
+ virtual std::pair<uint64_t, syscall::stream_result>
+ read(uint64_t bytes, void *into) = 0;
- private:
+ virtual void close() = 0;
- __euler_stream_handle handle;
- bool is_readable;
- bool is_writable;
- uint64_t length;
- uint64_t offset;
+ };
- uint8_t *buffer;
- uint64_t buffer_offset;
- uint64_t buffer_size;
- bool buffer_dirty;
+ class file_stream : public stream {
- void write_buffer();
+ syscall::stream_handle handle;
+ bool may_read;
- public:
+ bool buffer_loaded;
+ uint64_t buffer_start;
+ uint8_t buffer[1024];
- bool good;
+ uint64_t length;
+ uint64_t position;
+ public:
file_stream(
- __euler_stream_handle handle, bool is_readable, bool is_writable,
- bool clear, bool seek_to_end);
+ syscall::stream_handle handle, bool may_read,
+ uint64_t length, uint64_t position);
+
+ virtual syscall::stream_result seek(
+ syscall::seek_from from, int64_t offset) override;
- ~file_stream();
+ virtual std::pair<uint64_t, syscall::stream_result>
+ read(uint64_t bytes, void *into) override;
- bool try_read(void *into, uint64_t bytes) override;
- bool try_seek(__euler_seek_from from, int64_t offset) override;
+ virtual void close() override;
};
diff --git a/euler/include/euler/syscall.hpp b/euler/include/euler/syscall.hpp
index 981925f..64456ae 100644
--- a/euler/include/euler/syscall.hpp
+++ b/euler/include/euler/syscall.hpp
@@ -1,102 +1,136 @@
#pragma once
-#include <stdint.h>
-
-enum __euler_stream_result : uint64_t {
- __EULER_SR_SUCCESS = 0,
- __EULER_SR_BAD_HANDLE,
- __EULER_SR_IO_ERROR,
- __EULER_SR_OUT_OF_BOUNDS,
- __EULER_SR_DOES_NOT_EXIST,
- __EULER_SR_NOT_A_REGULAR_FILE,
- __EULER_SR_NOT_AN_EXECUTABLE,
- __EULER_SR_NOT_WRITABLE,
- __EULER_SR_NOT_SEEKABLE,
- __EULER_SR_SOCKET_ID_ALREADY_IN_USE,
- __EULER_SR_SOCKET_ID_NOT_IN_USE,
- __EULER_SR_SOCKET_LISTENER_CLOSED,
- __EULER_SR_OTHER_END_CLOSED,
- __EULER_SR_ALREADY_EXISTS,
- __EULER_SR_NOT_SIZED
-};
-
-enum __euler_seek_from : uint8_t {
- __EULER_SF_BEGINNING = 0,
- __EULER_SF_END,
- __EULER_SF_CURRENT_POSITION
-};
-
-typedef uint64_t __euler_stream_handle;
-typedef uint64_t __euler_process_handle;
-
-extern "C" __euler_stream_result __euler_open_file(
- const char *path, uint64_t path_len, __euler_stream_handle &handle_out,
- bool allow_creation, bool only_allow_creation);
-
-extern "C" [[noreturn]] void __euler_end_this_thread(int32_t exit_code);
-
-extern "C" __euler_stream_result __euler_seek_stream(
- __euler_stream_handle handle, __euler_seek_from from, int64_t offset);
-
-extern "C" __euler_stream_result __euler_set_stream_length(
- __euler_stream_handle handle, uint64_t new_length);
-
-extern "C" void __euler_close_stream(__euler_stream_handle handle);
-
-extern "C" __euler_stream_result __euler_get_stream_length(
- __euler_stream_handle handle, uint64_t &length_out);
-
-extern "C" void *__euler_get_new_pages(uint64_t count);
-
-extern "C" __euler_stream_result __euler_write_to_stream(
- __euler_stream_handle handle, uint64_t count, const void *buffer);
-
-extern "C" __euler_stream_result __euler_read_from_stream(
- __euler_stream_handle handle, uint64_t count, void *buffer);
-
-extern "C" uint32_t *__euler_get_framebuffer(
- uint32_t &width_out, uint32_t &height_out, uint32_t &pitch_out);
-
-extern "C" uint32_t __euler_encode_color(uint8_t r, uint8_t g, uint8_t b);
-
-enum __euler_mouse_buttons : uint8_t {
- __EULER_MB_LEFT = 1,
- __EULER_MB_RIGHT = 2,
- __EULER_MB_MIDDLE = 4
-};
-
-enum __euler_input_packet_type : uint8_t {
- __EULER_IPT_MOUSE = 1,
- __EULER_IPT_KEYBOARD = 2
-};
-
-extern "C" __euler_input_packet_type __euler_get_input_packet(
- __euler_mouse_buttons &buttons_out, int16_t &x_change_out,
- int16_t &y_change_out, uint32_t &keyboard_packet_out);
-
-struct [[gnu::packed]] __euler_env_var_spec {
- uint64_t name_len;
- const char *name;
- uint64_t value_len;
- const char *value;
-};
-
-struct [[gnu::packed]] __euler_gift_stream_spec {
- __euler_stream_handle stream_handle_to_gifter;
- __euler_stream_handle stream_handle_to_giftee;
-};
-
-struct [[gnu::packed]] __euler_process_start_info {
- uint64_t file_path_length;
- const char *file_path;
- uint64_t env_var_count;
- const __euler_env_var_spec *env_vars;
- uint64_t gift_stream_count;
- const __euler_gift_stream_spec *gift_streams;
-};
-
-extern "C" __euler_stream_result __euler_start_process(
- const __euler_process_start_info &info, __euler_process_handle &handle_out);
-
-extern "C" __euler_stream_result __euler_get_other_end_process_handle(
- __euler_stream_handle handle_in, __euler_process_handle &handle_out);
+#include <optional>
+#include <cstdint>
+#include <utility>
+#include <variant>
+#include <string>
+#include <vector>
+
+namespace euler::syscall {
+
+ enum class stream_result : uint64_t {
+ success,
+ bad_handle,
+ io_error,
+ out_of_bounds,
+ does_not_exist,
+ not_a_regular_file,
+ not_an_executable,
+ not_writable,
+ not_seekable,
+ socket_id_already_used,
+ socket_id_not_in_use,
+ socket_listener_closed,
+ other_end_closed,
+ already_exists,
+ not_sized,
+ not_readable
+ };
+
+ enum class seek_from : uint8_t {
+ beginning,
+ end,
+ current_position
+ };
+
+ struct mouse_packet {
+ bool left_button_down;
+ bool right_button_down;
+ bool middle_button_down;
+ int16_t x_changed;
+ int16_t y_changed;
+ };
+
+ struct key_packet {
+ bool was_key_up_event;
+ bool num_lock;
+ bool caps_lock;
+ bool right_win;
+ bool left_win;
+ bool right_alt;
+ bool left_alt;
+ bool right_ctrl;
+ bool left_ctrl;
+ bool right_shift;
+ bool left_shift;
+ uint8_t key_code;
+ };
+
+ typedef uint32_t encoded_color;
+ typedef uint64_t stream_handle;
+ typedef uint64_t listener_handle;
+ typedef uint64_t process_handle;
+
+ encoded_color encode_color(
+ uint8_t r, uint8_t g, uint8_t b);
+
+ void get_framebuffer(
+ encoded_color *&buffer_out, uint32_t &width_out,
+ uint32_t &height_out, uint32_t &pitch_out);
+
+ stream_result open_file(
+ const std::string &file_path, bool allow_creation,
+ bool only_allow_creation, stream_handle &handle_out);
+
+ [[noreturn]] void end_this_thread(int32_t exit_code);
+
+ void *get_new_pages(uint64_t n_pages);
+
+ std::variant<mouse_packet, key_packet> get_input_packet();
+
+ void create_private_socket(
+ stream_handle &end_1_out, stream_handle &end_2_out);
+
+ stream_result create_socket_listener(
+ const std::string &id, listener_handle &handle_out);
+
+ void stop_socket_listener(listener_handle handle);
+
+ stream_result accept_socket_connection(
+ listener_handle listener, stream_handle &stream_out);
+
+ stream_result connect_to_socket(
+ const std::string &id, stream_handle &handle_out);
+
+ void close_stream(stream_handle handle);
+
+ stream_result seek_stream(
+ stream_handle handle, seek_from from, int64_t offset);
+
+ stream_result read_from_stream(
+ stream_handle handle, uint64_t bytes, void *into);
+
+ stream_result write_to_stream(
+ stream_handle handle, uint64_t bytes, const void *from);
+
+ stream_result get_stream_length(
+ stream_handle handle, uint64_t &length_out);
+
+ stream_result start_process(
+ const std::string &file_path,
+ const std::vector<std::pair<std::string, std::string>> &environment_variables,
+ const std::vector<std::pair<stream_handle, stream_result>> &gifted_streams,
+ process_handle &handle_out);
+
+ [[noreturn]] void end_this_process(int32_t exit_code);
+
+ stream_result set_stream_length(
+ stream_handle handle, uint64_t new_length);
+
+ stream_result get_other_end_process_handle(
+ stream_handle stream, process_handle &process_out);
+
+ //entry_point must not return
+ void start_thread(void (*entry_point)(uint64_t), uint64_t arg);
+
+ //entry_point must not return
+ void start_thread(void (*entry_point)());
+
+ //return value is number of bytes cleared
+ uint64_t clear_socket_read_queue(stream_handle handle);
+
+ std::optional<std::string> try_get_environment_variable(
+ const std::string &name);
+
+}
diff --git a/euler/include/std/allocator.hpp b/euler/include/std/allocator.hpp
new file mode 100644
index 0000000..32ba005
--- /dev/null
+++ b/euler/include/std/allocator.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <euler/heap.hpp>
+
+namespace std {
+
+ template <class T>
+ struct allocator {
+
+ using value_type = T;
+
+ constexpr allocator() noexcept {}
+ constexpr allocator(const allocator &other) noexcept {}
+
+ template <class U>
+ constexpr allocator(const allocator<U> &other) noexcept {}
+
+ constexpr ~allocator() {}
+
+ constexpr T *allocate(size_t n) {
+ return (T *)euler::heap::get_block(n * sizeof(T));
+ }
+
+ constexpr void deallocate(T *p, size_t n) {
+ euler::heap::return_block(p, n * sizeof(T));
+ }
+
+ };
+
+}
diff --git a/euler/include/std/string.hpp b/euler/include/std/string.hpp
new file mode 100644
index 0000000..7ccdbc2
--- /dev/null
+++ b/euler/include/std/string.hpp
@@ -0,0 +1,80 @@
+#pragma once
+
+#include <cstddef>
+#include <vector>
+
+namespace std {
+
+ class string {
+
+ std::vector<char> characters;
+
+ public:
+ constexpr string() : characters({'\0'}) {}
+
+ constexpr string(const string &other)
+ : characters(other.characters) {}
+
+ constexpr string(string &&other) noexcept
+ : characters(std::move(other.characters)) {
+ other.characters.push_back('\0');
+ }
+
+ constexpr string(const char *s) {
+ size_t count = 0;
+ while (s[count] != '\0')
+ ++count;
+ characters.resize(count + 1);
+ for (size_t i = 0; i <= count; ++i)
+ characters[i] = s[i];
+ }
+
+ constexpr ~string() {}
+
+ constexpr string &operator =(const string &str) {
+ characters = str.characters;
+ return *this;
+ }
+
+ constexpr string &operator =(string &&str) noexcept {
+ characters = std::move(str.characters);
+ str.characters.push_back('\0');
+ return *this;
+ }
+
+ constexpr size_t size() const noexcept {
+ return characters.size() - 1;
+ }
+
+ constexpr void resize(size_t count) {
+ if (count < characters.size() - 1) {
+ characters.resize(count + 1);
+ characters[count] = '\0';
+ }
+ else if (count > characters.size() - 1)
+ characters.resize(count + 1);
+ }
+
+ constexpr void clear() noexcept {
+ resize(0);
+ }
+
+ constexpr const char *data() const noexcept {
+ return characters.data();
+ }
+
+ constexpr char *data() noexcept {
+ return characters.data();
+ }
+
+ constexpr char &operator[](size_t pos) {
+ return characters[pos];
+ }
+
+ constexpr const char &operator[](size_t pos) const {
+ return characters[pos];
+ }
+
+ };
+
+}
diff --git a/euler/include/std/vector.hpp b/euler/include/std/vector.hpp
new file mode 100644
index 0000000..a1ac21d
--- /dev/null
+++ b/euler/include/std/vector.hpp
@@ -0,0 +1,191 @@
+#pragma once
+
+#include <memory>
+
+namespace std {
+
+ template <class T, class Allocator = std::allocator<T>>
+ class vector {
+
+ public:
+ using size_type = size_t;
+ using value_type = T;
+ using reference = value_type &;
+ using const_reference = const value_type &;
+
+ private:
+ Allocator _alloc;
+ size_type _capacity;
+ size_type _size;
+ T *_data;
+
+ constexpr void expand_capacity_to(size_type at_least) {
+
+ size_type new_capacity = _capacity == 0 ? 1 : _capacity;
+ while (new_capacity < at_least)
+ new_capacity *= 2;
+ if (new_capacity == _capacity)
+ return;
+
+ T *new_data = _alloc.allocate(new_capacity);
+ for (size_type i = 0; i < _size; ++i) {
+ std::construct_at(new_data + i, std::move(_data[i]));
+ std::destroy_at(_data + i);
+ }
+ if (_capacity > 0)
+ _alloc.deallocate(_data, _capacity);
+
+ _capacity = new_capacity;
+ _data = new_data;
+
+ }
+
+ public:
+ constexpr vector() noexcept(noexcept(Allocator()))
+ : _alloc(), _capacity(0), _size(0), _data(0) {}
+
+ constexpr vector(const vector &other)
+ : _alloc(), _capacity(other._size), _size(other._size),
+ _data(_alloc.allocate(_capacity)) {
+ for (size_type i = 0; i < _size; ++i)
+ std::construct_at(_data + i, other._data[i]);
+ }
+
+ constexpr vector(vector &&other) noexcept
+ : _alloc(std::move(other._alloc)), _capacity(other._capacity),
+ _size(other._size), _data(other._data) {
+ other._capacity = 0;
+ other._size = 0;
+ }
+
+ constexpr vector(
+ std::initializer_list<T> init, const Allocator &alloc = Allocator())
+ : _alloc(alloc), _capacity(init.size()),
+ _size(init.size()), _data(_alloc.allocate(_capacity)) {
+ for (size_type i = 0; i < _size; ++i)
+ std::construct_at(_data + i, init.begin()[i]);
+ }
+
+ explicit vector(size_type count)
+ : _alloc(), _capacity(count), _size(count),
+ _data(_alloc.allocate(_capacity)) {
+ for (size_type i = 0; i < _size; ++i)
+ std::construct_at(_data + i);
+ }
+
+ constexpr ~vector() {
+ if (_capacity > 0) {
+ for (size_type i = 0; i < _size; ++i)
+ std::destroy_at(_data + i);
+ _alloc.deallocate(_data, _capacity);
+ }
+ }
+
+ constexpr vector &operator =(const vector &other) {
+
+ if (&other == this)
+ return *this;
+
+ expand_capacity_to(other._size);
+
+ for (size_type i = 0; i < _size; ++i)
+ std::destroy_at(_data + i);
+
+ for (size_type i = 0; i < other._size; ++i) {
+ std::construct_at(_data + i, std::move(other._data[i]));
+ std::destroy_at(other._data + i);
+ }
+
+ _size = other._size;
+ return *this;
+
+ }
+
+ constexpr vector &operator =(vector &&other)
+ noexcept(
+ std::allocator_traits<Allocator>::
+ propagate_on_container_move_assignment::value ||
+ std::allocator_traits<Allocator>::
+ is_always_equal::value) {
+
+ if (&other == this)
+ return *this;
+
+ if (_capacity > 0) {
+ for (size_type i = 0; i < _size; ++i)
+ std::destroy_at(_data + i);
+ _alloc.deallocate(_data, _capacity);
+ }
+
+ _alloc = std::move(other._alloc);
+ _capacity = other._capacity;
+ _size = other._size;
+ _data = other._data;
+
+ other._capacity = 0;
+ other._size = 0;
+
+ return *this;
+
+ }
+
+ constexpr size_type size() const noexcept {
+ return _size;
+ }
+
+ constexpr T *data() noexcept {
+ return _data;
+ }
+
+ constexpr const T *data() const noexcept {
+ return _data;
+ }
+
+ constexpr reference operator[](size_type pos) {
+ return _data[pos];
+ }
+
+ constexpr const_reference operator[](size_type pos) const {
+ return _data[pos];
+ }
+
+ constexpr reference back() {
+ return _data[_size - 1];
+ }
+
+ constexpr const_reference back() const {
+ return _data[_size - 1];
+ }
+
+ constexpr void resize(size_type count) {
+
+ if (count < _size) {
+ for (size_type i = count; i < _size; ++i)
+ std::destroy_at(_data + i);
+ _size = count;
+ }
+
+ else if (count > _size) {
+ expand_capacity_to(count);
+ for (size_type i = _size; i < count; ++i)
+ std::construct_at(_data + i);
+ _size = count;
+ }
+
+ }
+
+ constexpr void push_back(const T &value) {
+ expand_capacity_to(_size + 1);
+ std::construct_at(_data + _size, value);
+ ++_size;
+ }
+
+ constexpr void push_back(T &&value) {
+ expand_capacity_to(_size + 1);
+ std::construct_at(_data + _size, std::move(value));
+ ++_size;
+ }
+
+ };
+
+}
diff --git a/euler/include/string b/euler/include/string
new file mode 100644
index 0000000..ce42b9e
--- /dev/null
+++ b/euler/include/string
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <std/string.hpp>
+
+namespace std {
+
+ int stoi(const std::string &str, size_t *pos = 0, int base = 10);
+
+ std::string to_string(int value);
+
+ std::string operator +(std::string &&lhs, std::string &&rhs);
+
+}
diff --git a/euler/include/type_traits b/euler/include/type_traits
deleted file mode 100644
index fcea013..0000000
--- a/euler/include/type_traits
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-namespace std {
-
- 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;
-
-}
diff --git a/euler/include/utility b/euler/include/utility
deleted file mode 100644
index 23648c4..0000000
--- a/euler/include/utility
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-#include <type_traits>
-
-namespace std {
-
- template <class t>
- constexpr std::remove_reference_t<t> &&move(t &&x) {
- return static_cast<std::remove_reference_t<t> &&>(x);
- }
-
-}
diff --git a/euler/include/vector b/euler/include/vector
index f5083ed..2184475 100644
--- a/euler/include/vector
+++ b/euler/include/vector
@@ -1,62 +1,3 @@
#pragma once
-#include <stddef.h>
-#include <utility>
-
-namespace std {
-
- template <class t>
- class vector {
-
- t *buffer;
- size_t buffer_length;//always positive
- size_t count;
-
- public:
- vector() : buffer(new t[16]), buffer_length(16), count(0) {}
-
- ~vector() {
- delete[] buffer;
- }
-
- t &operator[](size_t pos) {
- return buffer[pos];
- }
-
- const t &operator[](size_t pos) const {
- return buffer[pos];
- }
-
- t *data() {
- return buffer;
- }
-
- const t *data() const {
- return buffer;
- }
-
- size_t size() const {
- return count;
- }
-
- void reserve(size_t new_length) {
- if (new_length <= buffer_length)
- return;
- t *new_buffer = new t[new_length];
- for (size_t i = 0; i < count; ++i)
- new_buffer[i] = std::move(buffer[i]);
- delete[] buffer;
- buffer = new_buffer;
- buffer_length = new_length;
- }
-
- void push_back(t &&value) {
- if (count == buffer_length)
- reserve(count * 2);
- buffer[count++] = std::move(value);
- }
-
- //TODO
- };
-
-}
+#include <std/vector.hpp>