commit 74620e64e747e2ce97f498b1ae2a75ef1ff42dc5 Author: Phuntsok Drak-pa Date: Tue Oct 10 02:30:17 2017 +0200 initial comit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6740124 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 2.8 FATAL_ERROR) +set(CMAKE_LEGACY_CYGWIN_WIN32 0) +set(CMAKE_BUILD_TYPE Debug) + +project("PhundrakSTL") + +set(TGT "PhundrakSTL") +set(${TGT}_VERSION_MAJOR 0) +set(${TGT}_VERSION_MINOR 1) + +set(CXX_COVERAGE_COMPILE_FLAGS "-pedantic -Wall -Wextra -Wold-style-cast -Woverloaded-virtual -Wfloat-equal -Wwrite-strings -Wpointer-arith -Wcast-qual -Wcast-align -Wconversion -Wsign-conversion -Wshadow -Weffc++ -Wredundant-decls -Wdouble-promotion -Winit-self -Wswitch-default -Wswitch-enum -Wundef -Winline -Wunused -Wnon-virtual-dtor -std=c++17") +# set(CXX_COVERAGE_COMPILE_FLAGS "-Weverything") +set(CMAKE_CXX_FLAGS_DEBUG "${CXX_COVERAGE_COMPILE_FLAGS} -g3 -pg") +set(CMAKE_CXX_FLAGS_RELEASE "${CXX_COVERAGE_COMPILE_FLAGS} -O3") + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED YES) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../bin/") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "../debug/") + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_COVERAGE_COMPILE_FLAGS}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CXX_COVERAGE_COMPILE_FLAGS}") + +include_directories(include) +file(GLOB SOURCES "src/*") +add_executable(${TGT} ${SOURCES}) diff --git a/debug/PhundrakSTL b/debug/PhundrakSTL new file mode 100755 index 0000000..8ee3a1e Binary files /dev/null and b/debug/PhundrakSTL differ diff --git a/src/list.hh b/src/list.hh new file mode 100644 index 0000000..1ec587d --- /dev/null +++ b/src/list.hh @@ -0,0 +1,254 @@ +#include +#include +#include + +namespace phundrak { + +using size_type = size_t; + +template > class list { +private: + struct cell { + cell() = default; + cell *p; + cell *n; + T x; + }; + cell *sentry; + +public: + class iterator; + class const_iterator; + + // Member types ////////////////////////////////////////////////////////////// + + list() : list{Allocator()}, sentry{new cell} {} + + explicit list(const Allocator &alloc) { + sentry = new cell; + sentry->p = sentry; + sentry->n = sentry; + } + + list(size_type count, const T &value, const Allocator &alloc = Allocator()) + : list(alloc) { + while (size() < count) + push_back(value); + } + + explicit list(size_type count, const Allocator &alloc = Allocator()) + : list(alloc) { + while (size() < count) + push_back(T()); + } + + template + list(InputIt first, InputIt last, const Allocator &alloc = Allocator()) + : list(alloc) { + while (first != last) + push_back(*first); + } + + list(const list &other) : list() { + for (auto elem : other) + push_back(elem); + } + + list(const list &other, const Allocator &alloc) : list(alloc) { + for (auto elem : other) + push_back(elem); + } + + list(list &&other) : list() { std::swap(other.sentry, sentry); } + + list(list &&other, const Allocator &alloc) : list(alloc) { + std::swap(other.sentry, sentry); + } + + list(std::initializer_list init, const Allocator &alloc = Allocator()) + : list(alloc) { + for (auto elem : init) + push_back(elem); + } + + virtual ~list() { + clear(); + delete sentry; + } + + // Element access //////////////////////////////////////////////////////////// + + T &front() const { return sentry->n->x; } + T &back() const { return sentry->p->x; } + + // Iterators ///////////////////////////////////////////////////////////////// + + iterator begin() noexcept { return iterator{sentry->n}; } + + const_iterator begin() const noexcept { return const_iterator{sentry->n}; } + const_iterator cbegin() const noexcept { return const_iterator{sentry->n}; } + + iterator end() noexcept { return iterator{sentry}; } + const_iterator end() const noexcept { return const_iterator{sentry}; } + const_iterator cend() const noexcept { return const_iterator{sentry}; } + + // Capacity ////////////////////////////////////////////////////////////////// + + // Modifiers ///////////////////////////////////////////////////////////////// + + void clear() { + cell *it = sentry->n; + while (it != sentry) { + cell *todel = it; + it = it->n; + delete todel; + } + } + + list &operator=(const list &other) { + cell *it = other.sentry->n; + while (it != other.sentry) { + push_back(it->x); + it = it->n; + } + return *this; + } + + list &operator=(list &&other) noexcept { + std::swap(other.sentry, sentry); + return *this; + } + + list &operator=(std::initializer_list ilist) { + for (auto elem : ilist) + push_back(elem); + return *this; + } + + bool empty() { return sentry->p == sentry; } + + size_type size() const { + cell *it = sentry->n; + size_type n = 0; + while (it != sentry) { + ++n; + it = it->n; + } + return n; + } + + void push_front(const T &v) { + cell *c = new cell; + c->x = v; + c->n = sentry->n; + c->p = sentry; + sentry->n->p = c; + sentry->n = c; + } + + void push_back(const T &v) { + cell *c = new cell; + c->x = v; + c->p = sentry->p; + c->n = sentry; + sentry->p->n = c; + sentry->p = c; + } + + void pop_front() { + cell *c = sentry->n; + sentry->n = c->n; + c->n->p = sentry; + delete c; + } + + void pop_back() { + cell *c = sentry->p; + sentry->p = c->p; + c->p->n = sentry; + delete c; + } + + class iterator { + public: + iterator() : it{nullptr} {} + explicit iterator(cell *point) : it{point} {} + + iterator(const iterator &other) : it{other.it} {} + + iterator(iterator &&other) { std::swap(it, other.it); } + + iterator &operator=(cell *point) { + it = point; + return *this; + } + iterator &operator=(const iterator &other) { + it = other.it; + return *this; + } + iterator &operator=(iterator &&other) { + std::swap(it, other.it); + return *this; + } + + ~iterator() {} + + iterator &operator++() { // ++i + it = it->n; + return *this; + } + iterator &operator++(int) { // i++ + iterator t; + t.it = it; + // iterator t{*this}; + it = it->n; + return t; + } + + iterator &operator--() { // --i + it = it->p; + return *this; + } + + iterator &operator--(int) { // i-- + iterator t; + t.it = it; + it = it->n; + return t; + } + + bool operator==(cell *point) { return point == it; } + bool operator==(const iterator &other) { return other.it = it; } + bool operator==(iterator &&other) { return other.it == it; } + + bool operator!=(cell *point) { return point != it; } + bool operator!=(const iterator &other) { return other.it != it; } + bool operator!=(iterator &&other) { return other.it != it; } + + T operator*() { return it->x; } + + protected: + cell *it; + }; + + class const_iterator : protected iterator { + public: + const_iterator() : iterator() {} + explicit const_iterator(T *point) : iterator(point) {} + + explicit const_iterator(const iterator &other) : iterator(other) {} + const_iterator(const const_iterator &other) : iterator(other) {} + + explicit const_iterator(iterator &&other) : iterator(std::move(other)) {} + const_iterator(const_iterator &&other) : iterator(std::move(other)) {} + + const_iterator &operator++() = delete; + const_iterator &operator++(int) = delete; + const_iterator &operator--() = delete; + const_iterator &operator--(int) = delete; + + ~const_iterator() {} + }; +}; + +} // namespace phundrak diff --git a/src/test.cc b/src/test.cc new file mode 100644 index 0000000..fffb4fd --- /dev/null +++ b/src/test.cc @@ -0,0 +1,18 @@ +#include "list.hh" +#include "vector.hh" +#include + +using namespace phundrak; + +int main(void) { + + printf("Hello 1!\n"); + list test {'C', 'a', 'r', 't', 'i', 'e', 'r'}; + printf("Hello !\n"); + + for(auto c : test) { + printf("%c\n", c); + } + + return 0; +} diff --git a/src/vector.hh b/src/vector.hh new file mode 100644 index 0000000..9b599b9 --- /dev/null +++ b/src/vector.hh @@ -0,0 +1,214 @@ +#include +#include +#include +#include +#include + +namespace phundrak { + + template + class vector { + public: + + // Member functions /////////////////////////////////////////////////////// + + //! Default constructor + vector() : data_{nullptr}, size_{0}, capacity_{0} {} + + //! Copy constructor + vector(const vector &other) + : data_{new T[other.size_]}, size_{other.size_}, + capacity_{other.capacity_} { + for (size_t i = 0; i < size_; ++i) { + data_[i] = other.data_[i]; + } + } + + //! Move constructor + vector(vector &&other) noexcept { + std::swap(data_, other.data_); + std::swap(size_, other.size_); + std::swap(capacity_, other.capacity_); + } + + //! Destructor + virtual ~vector() noexcept { + delete[] data_; + } + + //! Copy assignment operator + vector& operator=(const vector &other) { + vector w{other}; + std::swap(data_, w.data_); + std::swap(size_, w.size_); + std::swap(capacity_, w.capacity_); + return *this; + } + + //! Move assignment operator + vector &operator=(vector &&other) noexcept { + std::swap(data_, other.data_); + std::swap(size_, other.size_); + std::swap(capacity_, other.capacity_); + return *this; + } + + T &operator=(size_t pos) { return data_[pos]; } + const T &operator=(size_t pos) const { return data_[pos]; } + + void assign(size_t count, const T &value) { + clear(); + reserve(count); + for (size_t i = 0; i < count; ++i) + push_back(value); + } + + template void assign(InputIt first, InputIt last) { + clear(); + capacity_ = std::distance(first, last); + size_ = std::distance(first, last); + data_ = new T[size_]; + for (int i = 0; first != last; ++first, ++i) + data_[i] = *first; + } + + // Element access ///////////////////////////////////////////////////////// + + T &at(size_t pos) { + try { + if (pos >= size_ || pos < 0) + throw std::out_of_range("Out of range"); + } catch (std::out_of_range e) { + std::cout << e.what() << " in phundrak::vector " << this << '\n'; + std::terminate(); + } + return data_[pos]; + } + + const T &at(size_t pos) const { + try { + if (pos >= size_ || pos < 0) + throw std::out_of_range("Out of range"); + } catch (std::out_of_range e) { + std::cout << e.what() << " in phundrak::vector " << this << '\n'; + std::terminate(); + } + + return data_[pos]; + } + + T &operator[](size_t pos) { return data_[pos]; } + const T &operator[](size_t pos) const { return data_[pos]; } + + T &front() { return data_[0]; } + const T &front() const { return data_[0]; } + + T &back() { return data_[size_ - 1]; } + const T &back() const { return data_[size_ - 1]; } + + T *data() noexcept { return data_; } + const T *data() const noexcept { return data_; } + + // Iterators ////////////////////////////////////////////////////////////// + + // I don't know how to create custom iterators :( + + // Capacity /////////////////////////////////////////////////////////////// + + bool empty() const noexcept { + return (size_ <= 0 || data_ == nullptr) ? true : false; + } + + size_t size() const noexcept { return size_; } + + void reserve(size_t new_cap) { + while (capacity_ < new_cap) + double_capacity(); + } + + size_t capacity() const noexcept { return capacity_; } + + void shrink_to_fit() { + T *olddata = data_; + capacity_ = size_; + data_ = new T[capacity_]; + for (size_t i = 0; i < size_; ++i) + data_[i] = olddata[i]; + delete[] olddata; + } + + // Modifiers ////////////////////////////////////////////////////////////// + + void clear() noexcept { + delete[] data_; + data_ = new T[capacity_]; + size_ = 0; + } + + // insert: can't do iterators :( + // emplace: can't do iterators :( + // erase: can't do iterators :( + + void push_back(const T &value) { + ++size_; + reserve(size_); + data_[size_ - 1] = value; + } + + void push_back(T &&value) { + ++size_; + reserve(size_); + data_[size_ - 1] = std::move(value); + } + + // emplace_back: don't know how to use std::allocator_traits + + void pop_back() { + if (size_ > 0) + --size_; + } + + void resize(size_t count, T value = T()) { + if (count < size_) + size_ = count; + else if (count > size_) + reserve(count); + while (size_ < count) + push_back(value); + } + + void swap(vector& other) { + std::swap(capacity_, other.capacity_); + std::swap(size_, other.size_); + std::swap(data_, other.data_); + } + + protected: + + + private: + void double_capacity() { + if(data_) { + T *olddata = data_; + capacity_ <<= 1; + data_ = new T[capacity_]; + for(size_t i = 0; i < size_; ++i) + data_[i] = olddata[i]; + delete[] olddata; + } else { + data_ = new T[1]; + capacity_ = 1; + } + } + + + + T * data_; + size_t size_; + size_t capacity_; + + }; + + + +} // phundrak namespace