initial comit
This commit is contained in:
commit
74620e64e7
0
.gitignore
vendored
Normal file
0
.gitignore
vendored
Normal file
28
CMakeLists.txt
Normal file
28
CMakeLists.txt
Normal file
@ -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})
|
BIN
debug/PhundrakSTL
Executable file
BIN
debug/PhundrakSTL
Executable file
Binary file not shown.
254
src/list.hh
Normal file
254
src/list.hh
Normal file
@ -0,0 +1,254 @@
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace phundrak {
|
||||
|
||||
using size_type = size_t;
|
||||
|
||||
template <class T, class Allocator = std::allocator<T>> 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 <class InputIt>
|
||||
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<T> 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<T> 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
|
18
src/test.cc
Normal file
18
src/test.cc
Normal file
@ -0,0 +1,18 @@
|
||||
#include "list.hh"
|
||||
#include "vector.hh"
|
||||
#include <cstdio>
|
||||
|
||||
using namespace phundrak;
|
||||
|
||||
int main(void) {
|
||||
|
||||
printf("Hello 1!\n");
|
||||
list<char> test {'C', 'a', 'r', 't', 'i', 'e', 'r'};
|
||||
printf("Hello !\n");
|
||||
|
||||
for(auto c : test) {
|
||||
printf("%c\n", c);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
214
src/vector.hh
Normal file
214
src/vector.hh
Normal file
@ -0,0 +1,214 @@
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
namespace phundrak {
|
||||
|
||||
template<class T>
|
||||
class vector {
|
||||
public:
|
||||
|
||||
// Member functions ///////////////////////////////////////////////////////
|
||||
|
||||
//! Default constructor
|
||||
vector() : data_{nullptr}, size_{0}, capacity_{0} {}
|
||||
|
||||
//! Copy constructor
|
||||
vector(const vector<T> &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<T> &&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<T> &other) {
|
||||
vector<T> 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 <class InputIt> 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<T>& 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
|
Loading…
Reference in New Issue
Block a user