initial commit

This commit is contained in:
2026-07-18 20:34:55 +02:00
commit 59ad004c96
474 changed files with 226635 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
#ifndef OPP_ALGORITHM_H
#define OPP_ALGORITHM_H
#include "utility.h"
namespace opp {
template<class T, class LT>
void sort(T s, T e)
{
while (s != e)
{
auto p = s;
auto q = s;
q++;
while (q != e)
{
if (LT(*q, *p))
{
swap(*q, *p);
p++;
swap(*q, *p);
}
q++;
}
sort<T, LT>(s, p);
p++;
s = p;
}
}
template<class T, class LF>
void sort(T s, T e, LF lt)
{
while (s != e)
{
auto p = s;
auto q = s;
q++;
while (q != e)
{
if (lt(*q, *p))
{
swap(*q, *p);
p++;
swap(*q, *p);
}
q++;
}
sort(s, p, lt);
p++;
s = p;
}
}
template<class II, class OI>
OI copy(II first, II last, OI result)
{
while (first != last)
{
*result = *first;
++result; ++first;
}
return result;
}
template<class II, class T>
II find (II first, II last, const T& val)
{
while (first != last)
{
if (*first == val) return first;
++first;
}
return last;
}
}
#endif
+122
View File
@@ -0,0 +1,122 @@
#ifndef OPP_ARRAY_H
#define OPP_ARRAY_H
#include <stddef.h>
namespace opp {
template <class T, int n>
class array
{
protected:
T _data[n];
public:
typedef T element_type;
size_t size(void) const
{
return n;
}
size_t max_size(void) const
{
return n;
}
bool empty(void) const
{
return n == 0;
}
const T & at(size_t at) const
{
return _data[at];
}
T & at(size_t at)
{
return _data[at];
}
T & operator[] (size_t at)
{
return _data[at];
}
const T & operator[] (size_t at) const
{
return _data[at];
}
T * begin(void)
{
return _data;
}
const T * begin(void) const
{
return _data;
}
const T * cbegin(void) const
{
return _data;
}
T * end(void)
{
return _data + n;
}
const T * end(void) const
{
return _data + n;
}
const T * cend(void) const
{
return _data + n;
}
T & back(void)
{
return _data[n - 1];
}
const T & back(void) const
{
return _data[n - 1];
}
T & front(void)
{
return _data[0];
}
const T & front(void) const
{
return _data[0];
}
T * data(void)
{
return _data;
}
const T * data(void) const
{
return _data;
}
void fill(const T & t)
{
for(int i=0; i<n; i++)
_data[i] = t;
}
};
}
#endif
+207
View File
@@ -0,0 +1,207 @@
#ifndef OPP_BIDXLIST_H
#ifndef OPP_BIDXLIST_H
template <class T, int n>
class bindexlist
{
public:
char _free;
char _pred[n], _succ[n];
T _data[n];
class iterator
{
public:
bindexlist * _l;
char _i;
iterator(void) : _l(nullptr) {}
iterator(bindexlist * l, char i)
: _l(l), _i(i) {}
iterator(const iterator & li) : _l(li._l), _i(li._i) {}
iterator & operator=(const iterator & li)
{
_l = li._l;
_i = li._i;
return *this;
}
T & operator*()
{
return _l->_data[_i];
}
T * operator->()
{
return _l->_data + _i;
}
iterator & operator++(void)
{
_i = _l->_succ[_i];
return *this;
}
iterator operator++(int)
{
char i = _i;
_i = _l->_succ[_i];
return bindexlist::iterator(_l, i);
}
iterator & operator+=(char n)
{
while (n--)
_i = _l->_succ[_i];
return *this;
}
iterator & operator--(void)
{
_i = _l->_pred[_i];
return *this;
}
iterator operator++(int)
{
char i = _i;
_i = _l->_pred[_i];
return bindexlist::iterator(_l, i);
}
iterator & operator-=(char n)
{
while (n--)
_i = _l->_pred[_i];
return *this;
}
bool operator==(const iterator & li)
{
return _i == li._i;
}
bool operator!=(const iterator & li)
{
return _i != li._i;
}
};
public:
typedef T element_type;
typedef iterator iterator_type;
bindexlist(void)
{
_succ[0] = 0;
_pred[0] = 0;
for(char i=1; i<n; i++)
_succ[i] = i + 1;
_free = 1;
}
~bindexlist(void)
{
}
iterator begin(void)
{
return iterator(this, _succ[0]);
}
iterator end(void)
{
return iterator(this, 0);
}
T & front(void)
{
return _data[_succ[0]];
}
const T & front(void) const
{
return _data[_succ[0]];
}
T & back(void)
{
return _data[_pred[0]];
}
const T & back(void) const
{
return _data[_pred[0]];
}
iterator erase(iterator it)
{
char s = _succ[it._i];
_succ[_pred[it._i]] = _pred[it._i];
_pred[_succ[it._i]] = s;
_succ[it._i] = _free;
_free = it._i;
return iterator(this, s);
}
iterator erase(iterator first, iterator last)
{
char s = _succ[last._i];
_succ[_pred[last._i]] = _pred[first._i];
_pred[_succ[first._i]] = s;
_succ[last._i] = _free;
_free = first._i;
return iterator(this, s);
}
void pop_front(void)
{
char i = _succ[0];
char s = _succ[i];
_pred[s] = 0;
_succ[0] = s;
_succ[i] = _free;
_free = i;
}
void pop_back(void)
{
char i = _pred[0];
char p = _pred[i];
_succ[p] = 0;
_pred[0] = p;
_pred[i] = _free;
_free = i;
}
void push_back(const T & t)
{
char i = _free;
_data[i] = t;
_free = _succ[_free];
_succ[i] = 0;
_pred[i] = _pred[0];
_succ[_pred[0]] = i;
_pred[0] = i;
}
void push_front(const T & t)
{
char i = _free;
_data[i] = t;
_free = _succ[_free];
_succ[i] = 0;
_succ[i] = _succ[0];
_pred[_succ[0]] = i;
_succ[0] = i;
}
};
#endif
+59
View File
@@ -0,0 +1,59 @@
#ifndef OPP_BOUNDINT_H
#define OPP_BOUNDINT_H
namespace opp {
template<int tmin, int tmax>
constexpr auto boundinttype(void)
{
if constexpr (tmin >= 0 && tmax <= 255)
return (char)0;
else if constexpr (tmin >= -128 && tmax <= 127)
return (signed char)0;
else
return (int)0;
}
template<int tmin, int tmax>
class boundint
{
protected:
decltype(boundinttype<tmin, tmax>()) v;
public:
boundint(int i)
: v(i)
{
__assume(i >= tmin && i <= tmax);
}
void operator=(int k)
{
__assume(k >= tmin && k <= tmax);
v = k;
}
void operator+=(int k)
{
k += v;
__assume(k >= tmin && k <= tmax);
v = k;
}
void operator-=(int k)
{
k = v - k;
__assume(k >= tmin && k <= tmax);
v = k;
}
operator int() const
{
int k = v;
__assume(k >= tmin && k <= tmax);
return k;
}
};
}
#endif
+93
View File
@@ -0,0 +1,93 @@
#ifndef OPP_FUNCTIONAL_H
#define OPP_FUNCTIONAL_H
namespace opp
{
template <class F>
class function;
template <class R, class ... P>
class function<R(P...)>
{
private:
struct callif
{
virtual R call(P...) = 0;
virtual ~callif() {}
virtual callif * clone(void) const = 0;
};
template<class CA>
struct callable : callif
{
CA ca;
callable(CA ca_) : ca(ca_) {}
R call(P... p) {return ca(p...);}
callif * clone(void) const
{
return new callable(ca);
}
};
callif * c;
public:
template <class F>
function(F f)
{
c = new callable<F>(f);
}
function(const function & f)
{
c = f.c->clone();
}
function(function && f)
{
c = f.c;
f.c = nullptr;
}
function(void)
{
c = nullptr;
}
function & operator=(const function & f)
{
if (c != f.c)
{
delete c;
c = f.c;
}
return *this;
}
function & operator=(function && f)
{
if (c != f.c)
{
c = f.c;
f.c = nullptr;
}
return *this;
}
~function(void)
{
delete c;
}
R operator()(P ... p) const
{
return c->call(p...);
}
};
}
#endif
+180
View File
@@ -0,0 +1,180 @@
#ifndef HASHMAP_H
#define HASHMAP_H
#include <opp/list.h>
#include <opp/string.h>
namespace opp {
template<class T>
struct Hash
{};
template<>
struct Hash<int> {
unsigned operator()(const int & k)
{
return k;
}
};
template<>
struct Hash<string> {
unsigned operator()(const string & k)
{
const char * cp = k.begin();
if (cp)
{
unsigned hash = 0;
while (*cp)
hash = hash * 17 + *cp++;
return hash;
}
else
return 0;
}
};
template <class K, class T>
struct hashpair
{
K key;
T value;
unsigned hash;
hashpair(void) {}
hashpair(const K & k, unsigned h) : key(k), hash(h) {}
hashpair(const hashpair<K, T> & p)
: key(p.key), value(p.value), hash(p.hash) {}
};
template<class K, class T>
class hashmap
{
public:
hashmap(void);
~hashmap(void);
typedef hashpair<K, T> N;
typedef list_iterator<N> I;
T & at(const K & key);
void insert(const K & key, const T & value);
void erase(const K & key);
list_iterator<hashpair<K, T> > erase(list_iterator<hashpair<K, T> > iter);
I begin(void);
I end(void);
I find(const K & key);
private:
unsigned mapsize;
unsigned size;
list<N> list;
I * map;
};
template<class K, class T>
hashmap<K, T>::hashmap(void)
: mapsize(0), size(0), map(nullptr)
{}
template<class K, class T>
hashmap<K, T>::~hashmap(void)
{
delete[] map;
}
template<class K, class T>
hashmap<K, T>::I hashmap<K, T>::begin(void)
{
return list.begin();
}
template<class K, class T>
hashmap<K, T>::I hashmap<K, T>::end(void)
{
return list.end();
}
template<class K, class T>
T & hashmap<K, T>::at(const K & key)
{
if (mapsize == 0)
{
mapsize = 16;
map = new I[16];
for(unsigned i=0; i<16; i++)
map[i] = list.end();
}
unsigned m = mapsize - 1;
unsigned h = Hash<K>()(key);
unsigned hi = h & m;
I p = map[hi];
while (p != list.end() && (p->hash & m) == hi)
{
if (p->key == key) return p->value;
p++;
}
p = list.insert(map[hi], N(key, h));
map[hi] = p;
return p->value;
}
template<class K, class T>
hashmap<K, T>::I hashmap<K, T>::find(const K & key)
{
if (mapsize)
{
unsigned m = mapsize - 1;
unsigned h = Hash<K>()(key);
unsigned hi = h & m;
I p = map[hi];
while (p != list.end() && (p->hash & m) == hi)
{
if (p->key == key) return p;
p++;
}
}
return list.end();
}
template<class K, class T>
void hashmap<K, T>::insert(const K & key, const T & value)
{
this->at(key) = value;
}
template<class K, class T>
void hashmap<K, T>::erase(const K & key)
{
erase(find(key));
}
template<class K, class T>
list_iterator<hashpair<K, T> > hashmap<K, T>::erase(list_iterator<hashpair<K, T> > iter)
{
if (iter != list.end())
{
unsigned hi = iter->hash & (mapsize - 1);
bool first = iter == map[hi];
iter = list.erase(iter);
if (first)
map[hi] = iter;
}
return iter;
}
}
#endif
+24
View File
@@ -0,0 +1,24 @@
#include "ifstream.h"
#include <c64/kernalio.h>
namespace opp {
ifstream::ifstream(char fnum, char device, char channel, const string & name)
{
this->fnum = fnum;
krnio_setnam(name.tocstr());
krnio_open(fnum, device, channel);
}
ifstream::~ifstream(void)
{
krnio_close(fnum);
}
void ifstream::refill(void)
{
mBufferPos = 0;
mBufferFill = krnio_read(fnum, mBuffer, 32);
}
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef OPP_IFSTREAM_H
#define OPP_IFSTREAM_H
#include "iostream.h"
#include "string.h"
namespace opp {
class ifstream : public istream
{
public:
ifstream(char fnum, char device, char channel, const string & name);
~ifstream(void);
protected:
virtual void refill(void);
char fnum;
};
}
#pragma compile("ifstream.cpp")
#endif
File diff suppressed because it is too large Load Diff
+217
View File
@@ -0,0 +1,217 @@
#ifndef OPP_IOSTREAM_H
#define OPP_IOSTREAM_H
#include <opp/string.h>
namespace opp {
class ios
{
public:
constexpr ios(void);
virtual ~ios(void);
char fill() const;
char fill(char cillch);
char width() const;
char width(char wide);
char precision() const;
char precision(char prec);
enum fmtflags
{
boolalpha = 0x0001,
dec = 0x0002,
fixed = 0x0004,
hex = 0x0008,
internal = 0x0010,
left = 0x0020,
oct = 0x0040,
right = 0x0080,
scientific = 0x0100,
showbase = 0x0200,
showpoint = 0x0400,
showpos = 0x0800,
skipws = 0x1000,
unitbuf = 0x2000,
uppercase = 0x4000,
adjustfield = 0x00b0,
basefield = 0x004a,
floatfield = 0x0104
};
enum statebits
{
goodbit = 0,
badbit = 1,
eofbit = 2,
failbit = 4,
};
fmtflags flags(void) const;
fmtflags flags(fmtflags f);
fmtflags setf(fmtflags f);
fmtflags setf(fmtflags f, fmtflags m);
fmtflags unsetf(fmtflags f);
bool good(void) const;
bool eof(void) const;
bool fail(void) const;
bool bad(void) const;
bool operator!(void) const;
operator bool(void);
statebits rdstate(void) const;
void clear(void);
protected:
fmtflags mFlags;
statebits mState;
char mWidth;
char mPrecision;
char mFill;
};
class ostream;
typedef ostream & (* manip)(ostream &);
class ostream : public ios
{
public:
constexpr ostream(void);
ostream & put(char c);
ostream & write(const char * s, int n);
ostream & operator<<(bool val);
ostream & operator<<(char val);
ostream & operator<<(int val);
ostream & operator<<(unsigned val);
ostream & operator<<(long val);
ostream & operator<<(unsigned long val);
ostream & operator<<(float val);
ostream & operator<<(const char * p);
ostream & operator<<(const string & s);
ostream & operator<<(manip m);
protected:
void putnum(const char * buffer, char prefix, char size);
void numput(unsigned n, char sign);
void numput(unsigned long n, char sign);
virtual void bput(char ch);
};
class istream : public ios
{
public:
char get(void);
istream & get(char & c);
istream & get(char * s, char size);
istream & get(char * s, char size, char delim);
istream & getline(char * s, char size);
istream & getline(char * s, char size, char delim);
istream & ignore(char size);
istream & ignore(char size, char delim);
istream & putback(char c);
istream & unget(void);
istream & operator>>(char & val);
istream & operator>>(bool & val);
istream & operator>>(int & val);
istream & operator>>(unsigned & val);
istream & operator>>(long & val);
istream & operator>>(unsigned long & val);
istream & operator>>(float & val);
istream & operator>>(char * p);
istream & operator>>(string & s);
istream(void);
protected:
char mBuffer[32];
char mBufferPos, mBufferFill;
virtual void refill(void);
unsigned getnum(void);
unsigned long getnuml(void);
float getnumf(void);
void doskipws(void);
};
class costream : public ostream
{
public:
constexpr costream(void);
protected:
void bput(char ch);
};
class cistream : public istream
{
public:
cistream(void);
protected:
void refill(void);
};
ostream & endl(ostream & os);
struct iosetf {
ios::fmtflags flags;
iosetf(ios::fmtflags flags_) : flags(flags_) {}
};
ostream & operator<<(ostream & os, const iosetf & s);
iosetf setf(ios::fmtflags flags);
struct iosetw {
char width;
iosetw(char width_) : width(width_) {}
};
iosetw setw(char width);
ostream & operator<<(ostream & os, const iosetw & s);
struct iosetprecision {
char precision;
iosetprecision(char precision_) : precision(precision_) {}
};
iosetprecision setprecision(char precision);
ostream & operator<<(ostream & os, const iosetprecision & s);
struct iosetfill {
char fill;
iosetfill(char fill_) : fill(fill_) {}
};
iosetfill setfill(char fill);
ostream & operator<<(ostream & os, const iosetfill & s);
extern cistream cin;
extern costream cout;
}
#pragma compile("iostream.cpp");
#endif
+201
View File
@@ -0,0 +1,201 @@
#ifndef OPP_ITERATOR_H
#define OPP_ITERATOR_H
namespace opp
{
template <class CT>
class back_insert_iterator
{
protected:
CT * co;
public:
back_insert_iterator (CT & c) : co(&c) {}
back_insert_iterator & operator= (const CT::element_type & t)
{
co->push_back(t);
return *this;
}
back_insert_iterator & operator= (CT::element_type && t)
{
co->push_back(t);
return *this;
}
back_insert_iterator & operator* (void)
{
return *this;
}
back_insert_iterator & operator++ (void)
{
return *this;
}
back_insert_iterator operator++ (int)
{
return *this;
}
};
template <class CT>
class front_insert_iterator
{
protected:
CT * co;
public:
front_insert_iterator (CT & c) : co(&c) {}
front_insert_iterator & operator= (const CT::element_type & t)
{
co->push_front(t);
return *this;
}
front_insert_iterator & operator= (CT::element_type && t)
{
co->push_front(t);
return *this;
}
front_insert_iterator & operator* (void)
{
return *this;
}
front_insert_iterator & operator++ (void)
{
return *this;
}
front_insert_iterator operator++ (int)
{
return *this;
}
};
template <class CT>
class insert_iterator
{
protected:
CT * co;
CT::iterator_type ci;
public:
insert_iterator (CT & c, const CT::iterator_type & i) : co(&c), ci(i) {}
insert_iterator & operator= (const CT::element_type & t)
{
ci = co->insert(ci, t); ++ci;
return *this;
}
insert_iterator & operator= (CT::element_type && t)
{
ci = co->insert(ci, t); ++ci;
return *this;
}
insert_iterator & operator* (void)
{
return *this;
}
insert_iterator & operator++ (void)
{
return *this;
}
insert_iterator operator++ (int)
{
return *this;
}
};
template <class T>
class ostream_iterator
{
protected:
ostream & stream;
const char * str;
public:
ostream_iterator(ostream & stream_, const char * str_)
: stream(stream_), str(str_) {}
ostream_iterator & operator= (const T & t)
{
stream << t;
if (str)
stream << str;
return *this;
}
ostream_iterator & operator= (T && t)
{
stream << t;
if (str)
stream << str;
return *this;
}
ostream_iterator & operator* (void)
{
return *this;
}
ostream_iterator & operator++ (void)
{
return *this;
}
ostream_iterator operator++ (int)
{
return *this;
}
};
template <class CT>
front_insert_iterator<CT> front_inserter (CT & c)
{
return front_insert_iterator<CT>(c);
}
template <class CT>
back_insert_iterator<CT> back_inserter (CT & c)
{
return back_insert_iterator<CT>(c);
}
template <class CT>
insert_iterator<CT> inserter (CT & c, const CT::iterator_type & i)
{
return insert_iterator<CT>(c, i);
}
template <class CT>
CT next(CT it, int n = 1)
{
while (n > 0)
{
it++;
n--;
}
return it;
}
template <class CT>
CT prev(CT it, int n = 1)
{
while (n > 0)
{
it--;
n--;
}
return it;
}
}
+370
View File
@@ -0,0 +1,370 @@
#ifndef OPP_LIST
#define OPP_LIST
namespace opp
{
template <class T>
class listhead
{
public:
listnode<T> * succ, * pred;
listhead()
{
succ = (listnode<T> *)this;
pred = (listnode<T> *)this;
}
};
template <class T>
class listnode : public listhead<T>
{
public:
T data;
listnode(const T & t) : data(t) {}
listnode(T && t) : data(t) {}
};
template <class T>
class list_iterator
{
public:
listnode<T> * node;
public:
list_iterator(void) : node(nullptr) {}
list_iterator(listnode<T> * n) : node(n) {}
list_iterator(const list_iterator & li) : node(li.node) {}
list_iterator & operator=(const list_iterator & li)
{
node = li.node;
return *this;
}
T & operator*()
{
return node->data;
}
T * operator->()
{
return &(node->data);
}
list_iterator & operator++(void)
{
node = node->succ;
return *this;
}
list_iterator operator++(int)
{
listnode<T> * n = node;
node = node->succ;
return list_iterator(n);
}
list_iterator & operator+=(int n)
{
while (n--)
node = node->succ;
return *this;
}
list_iterator & operator--(void)
{
node = node->pred;
return *this;
}
list_iterator operator++(int)
{
listnode<T> * n = node;
node = node->pred;
return list_iterator(n);
}
list_iterator & operator-=(int n)
{
while (n--)
node = node->pred;
return *this;
}
bool operator==(const list_iterator & li)
{
return node == li.node;
}
bool operator!=(const list_iterator & li)
{
return node != li.node;
}
};
template <class T>
class list
{
private:
typedef listnode<T> ln;
listhead<T> head;
public:
typedef T element_type;
typedef list_iterator<T> iterator_type;
list(void)
{}
list(const list & l);
list(list && l)
{
head.succ = l.head.succ;
head.pred = l.head.pred;
head.succ->pred = (listnode<T> *)&head;
head.pred->succ = (listnode<T> *)&head;
l.head.succ = (listnode<T> *)&(l.head);
l.head.pred = (listnode<T> *)&(l.head);
}
list & operator=(const list & l);
list & operator=(list && l)
{
head.succ = l.head.succ;
head.pred = l.head.pred;
head.succ->pred = (listnode<T> *)&head;
head.pred->succ = (listnode<T> *)&head;
l.head.succ = (listnode<T> *)&(l.head);
l.head.pred = (listnode<T> *)&(l.head);
return *this;
}
~list(void)
{
listnode<T> * n = head.succ;
while (n != &head)
{
listnode<T> * m = n->succ;
delete n;
n = m;
}
}
list_iterator<T> begin(void)
{
return list_iterator<T>(head.succ);
}
list_iterator<T> end(void)
{
return list_iterator<T>((listnode<T> *)&head);
}
T & front(void)
{
return head.succ->data;
}
const T & front(void) const
{
return head.succ->data;
}
T & back(void)
{
return head.pred->data;
}
const T & back(void) const
{
return head.pred->data;
}
list_iterator<T> erase(list_iterator<T> it);
list_iterator<T> erase(list_iterator<T> first, list_iterator<T> last);
void pop_front(void);
void pop_back(void);
void push_front(const T & t);
void push_front(T && t);
void push_back(const T & t);
void push_back(T && t);
void clear(void);
void append(const list & l);
list_iterator<T> insert(list_iterator<T> it, const T & t);
list_iterator<T> insert(list_iterator<T> it, T && t);
};
template <class T>
list<T>::list(const list<T> & l)
{
append(l);
}
template <class T>
list<T> & list<T>::operator=(const list<T> & l)
{
if (&l != this)
{
clear();
append(l);
}
return *this;
}
template <class T>
void list<T>::pop_front(void)
{
listnode<T> * n = head.succ;
head.succ = n->succ;
n->succ->pred = (listnode<T> *)&head;
delete n;
}
template <class T>
void list<T>::pop_back(void)
{
listnode<T> * n = head.pred;
head.pred = n->pred;
n->pred->succ = (listnode<T> *)&head;
delete n;
}
template <class T>
void list<T>::push_front(const T & t)
{
listnode<T> * n = new listnode<T>(t);
n->pred = (listnode<T> *)&head;
n->succ = head.succ;
head.succ->pred = n;
head.succ = n;
}
template <class T>
void list<T>::push_front(T && t)
{
listnode<T> * n = new listnode<T>(t);
n->pred = (listnode<T> *)&head;
n->succ = head.succ;
head.succ->pred = n;
head.succ = n;
}
template <class T>
void list<T>::push_back(const T & t)
{
listnode<T> * n = new listnode<T>(t);
n->succ = (listnode<T> *)&head;
n->pred = head.pred;
head.pred->succ = n;
head.pred = n;
}
template <class T>
void list<T>::push_back(T && t)
{
listnode<T> * n = new listnode<T>(t);
n->succ = (listnode<T> *)&head;
n->pred = head.pred;
head.pred->succ = n;
head.pred = n;
}
template <class T>
list_iterator<T> list<T>::erase(list_iterator<T> it)
{
listnode<T> * n = it.node;
listnode<T> * s = n->succ;
n->succ->pred = n->pred;
n->pred->succ = n->succ;
delete n;
return list_iterator<T>(s);
}
template <class T>
list_iterator<T> list<T>::erase(list_iterator<T> first, list_iterator<T> last)
{
listnode<T> * n = first.node;
listnode<T> * s = last.node;
n->pred->succ = s;
s->pred = n->pred;
while (n != s)
{
listnode<T> * m = n->succ;
delete n;
n = m;
}
return list_iterator<T>(s);
}
template <class T>
list_iterator<T> list<T>::insert(list_iterator<T> it, const T & t)
{
listnode<T> * n = new listnode<T>(t);
n->succ = it.node;
n->pred = it.node->pred;
it.node->pred->succ = n;
it.node->pred = n;
return list_iterator<T>(n);
}
template <class T>
list_iterator<T> list<T>::insert(list_iterator<T> it, T && t)
{
listnode<T> * n = new listnode<T>(t);
n->succ = it.node;
n->pred = it.node->pred;
it.node->pred->succ = n;
it.node->pred = n;
return list_iterator<T>(n);
}
template <class T>
void list<T>::clear(void)
{
listnode<T> * n = head.succ;
while (n != &head)
{
listnode<T> * m = n->succ;
delete n;
n = m;
}
head.succ = (listnode<T> *)&head;
head.pred = (listnode<T> *)&head;
}
template <class T>
void list<T>::append(const list<T> & l)
{
listnode<T> * n = l.head.succ;
while (n != &(l.head))
{
push_back(n->data);
n = n->succ;
}
}
}
#endif
+122
View File
@@ -0,0 +1,122 @@
#ifndef OPP_NUMERIC_H
#define OPP_NUMERIC_H
namespace opp {
template<class InputIt, class T>
constexpr T accumulate( InputIt first, InputIt last, T init)
{
for (; first != last; ++first)
init = opp::move(init) + *first;
return init;
}
template<class InputIt, class T, class BinaryOperator>
constexpr T accumulate( InputIt first, InputIt last, T init, BinaryOperator op)
{
for (; first != last; ++first)
init = op(opp::move(init), *first);
return init;
}
template<class ForwardIt, class T>
constexpr void iota(ForwardIt first, ForwardIt last, T value)
{
for (; first != last; ++first, ++value)
*first = value;
}
template<class InputIt1, class InputIt2, class T>
constexpr T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init)
{
while (first1 != last1)
{
init = opp::move(init) + (*first1) * (*first2);
++first1;
++first2;
}
return init;
}
template<class InputIt1, class InputIt2, class T, class BinaryOp1, class BinaryOp2>
constexpr T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init, BinaryOp1 op1, BinaryOp2 op2)
{
while (first1 != last1)
{
init = op1(opp::move(init), op2(*first1, *first2));
++first1;
++first2;
}
return init;
}
template< class InputIt, class OutputIt, class T >
OutputIt exclusive_scan( InputIt first, InputIt last, OutputIt d_first, T init )
{
while (first != last)
{
*d_first = init;
init = opp::move(init) + *first;
++d_first;
++first;
}
return d_first;
}
template< class InputIt, class OutputIt >
OutputIt inclusive_scan( InputIt first, InputIt last, OutputIt d_first )
{
if (first == last)
return d_first;
auto sum = *first;
*d_first = sum;
while (++first != last)
{
sum = opp::move(sum) + *first;
*++d_first = sum;
}
return ++d_first;
}
template< class InputIt, class OutputIt, class T, class BinaryOperator >
OutputIt exclusive_scan( InputIt first, InputIt last, OutputIt d_first, T init, BinaryOperator op )
{
while (first != last)
{
*d_first = init;
init = op(opp::move(init), *first);
++d_first;
++first;
}
return d_first;
}
template< class InputIt, class OutputIt, class BinaryOperator >
OutputIt inclusive_scan( InputIt first, InputIt last, OutputIt d_first, BinaryOperator op )
{
if (first == last)
return d_first;
auto sum = *first;
*d_first = sum;
while (++first != last)
{
sum = op(opp::move(sum), *first);
*++d_first = sum;
}
return ++d_first;
}
}
#endif
+32
View File
@@ -0,0 +1,32 @@
#include "ofstream.h"
#include <c64/kernalio.h>
namespace opp {
ofstream::ofstream(char fnum, char device, char channel, const string & name)
{
this->fnum = fnum;
krnio_setnam(name.tocstr());
krnio_open(fnum, device, channel);
mBufferFill = 0;
}
ofstream::~ofstream(void)
{
if (mBufferFill > 0)
krnio_write(fnum, mBuffer, mBufferFill);
krnio_close(fnum);
}
void ofstream::bput(char ch)
{
mBuffer[mBufferFill++] = ch;
if (mBufferFill == 32)
{
krnio_write(fnum, mBuffer, mBufferFill);
mBufferFill = 0;
}
}
}
+28
View File
@@ -0,0 +1,28 @@
#ifndef OPP_OFSTREAM_H
#define OPP_OFSTREAM_H
#include "iostream.h"
#include "string.h"
namespace opp {
class ofstream : public ostream
{
public:
ofstream(char fnum, char device, char channel, const string & name);
~ofstream(void);
protected:
virtual void bput(char ch);
char mBuffer[32];
char mBufferFill;
char fnum;
};
}
#pragma compile("ofstream.cpp")
#endif
+112
View File
@@ -0,0 +1,112 @@
#ifndef OPP_OPTIONAL_H
#define OPP_OPTIONAL_H
#include <opp/utility.h>
namespace opp {
template <class T>
class optional
{
protected:
char _data[sizeof(T)];
bool valid;
public:
optional(void) : valid(false) {}
optional(const T & data) : valid(true)
{
new (_data)T(data);
}
optional(T && data) : valid(true)
{
new (_data)T(opp::move(data));
}
optional(const optional<T> & o)
: valid(o.valid)
{
if (valid)
new (_data)T(*((T*)o._data));
}
optional(optional<T> && o)
: valid(o.valid)
{
if (valid)
new (_data)T(opp::move(*((T*)o._data)));
}
~optional(void)
{
if (valid)
((T*)_data)->~T();
}
optional<T> & operator=(const optional<T> & o)
{
if (this != &o)
{
if (valid)
((T*)_data)->~T();
valid = o.valid;
if (valid)
new (_data)T(*((T*)o._data));
}
return *this;
}
optional<T> & operator=(optional<T> && o)
{
if (this != &o)
{
if (valid)
((T*)_data)->~T();
valid = o.valid;
if (valid)
new (_data)T(opp::move(*((T*)o._data)));
}
return *this;
}
operator bool(void) const {return valid;}
T & operator *(void) const {return *(T*)_data;}
const T & operator *(void) const {return *(T*)_data;}
const T * operator->(void) const {return (T*)_data;}
T * begin(void)
{
return (T*)_data;
}
const T * begin(void) const
{
return (T*)_data;
}
const T * cbegin(void) const
{
return (T*)_data;
}
T * end(void)
{
return (T*)_data + (valid ? 1 : 0);
}
const T * end(void) const
{
return (T*)_data + (valid ? 1 : 0);
}
const T * cend(void) const
{
return (T*)_data + (valid ? 1 : 0);
}
};
}
#endif
+80
View File
@@ -0,0 +1,80 @@
#ifndef OPP_SLAB_H
#define OPP_SLAB_H
template<class T, int N>
class slabptr
{
public:
char index;
slabptr(void)
: index(N)
{}
slabptr(char i)
: index(i)
{}
slabptr(const slabptr & i)
: index(i.index)
{}
auto operator-> ();
auto & operator* ();
};
template <class T, int N>
class slab
{
protected:
static __striped T buffer[N];
static char head;
static char next[N];
public:
typedef slabptr<T, N> ptr;
static void init(void);
static auto alloc(void);
static void free(ptr p);
};
template<class T, int N>
inline auto slabptr<T, N>::operator-> ()
{
return slab<T, N>::buffer + index;
}
template<class T, int N>
inline auto & slabptr<T, N>::operator* ()
{
return slab<T, N>::buffer[index];
}
template <class T, int N>
void slab<T, N>::init(void)
{
head = 0;
for(char i=0; i<N; i++)
next[i] = i + 1;
}
template <class T, int N>
auto slab<T, N>::alloc(void)
{
char i = head;
head = next[head];
return slabptr<T, N>(i);
}
template <class T, int N>
void slab<T, N>::free(slabptr<T, N> p)
{
next[p.index] = head;
head = p.index;
}
#endif
+169
View File
@@ -0,0 +1,169 @@
#ifndef OPP_SPAN_H
#define OPP_SPAN_H
#include <stddef.h>
#include <stdlib.h>
#include <opp/utility.h>
namespace opp
{
static const size_t dynamic_extent = 0xffff;
template <class T, int N = dynamic_extent>
class span
{
protected:
T * _data;
size_t _size;
public:
span(void)
: _data(nullptr), _size(0)
{}
span(T * data, size_t size)
: _data(data), _size(size)
{}
span(T * data)
: _data(data), _size(N)
{}
span(opp::array<T, N> & arr)
: _data(arr.data()), _size(N)
{}
span(opp::vector<T> & vec)
: _data(vec.data()), _size(vec.size())
{}
span(const opp::array<T, N> & arr)
: _data(arr.data()), _size(N)
{}
span(const opp::vector<T> & vec)
: _data(vec.data()), _size(vec.size())
{}
constexpr size_t size(void) const
{
if constexpr (N == dynamic_extent)
return _size;
else
return N;
}
T & operator[](int i)
{return _data[i];}
const T & operator[](int i) const
{return _data[i];}
T * begin(void)
{
return _data;
}
const T * begin(void) const
{
return _data;
}
const T * cbegin(void) const
{
return _data;
}
T * end(void)
{
return _data + size();
}
const T * end(void) const
{
return _data + size();
}
const T * cend(void) const
{
return _data + size();
}
T & back(void)
{
return _data[size() - 1];
}
const T & back(void) const
{
return _data[size() - 1];
}
T & front(void)
{
return _data[0];
}
const T & front(void) const
{
return _data[0];
}
T * data(void)
{
return _data;
}
const T * data(void) const
{
return _data;
}
template< int Offset, int Count = dynamic_extent >
constexpr auto subspan() const
{
if constexpr (Count == dynamic_extent)
{
if constexpr (N == dynamic_extent)
return opp::span<T>(_data + Offset, _size - Offset);
else
return opp::span<T, (N - Offset)>(_data + Offset);
}
else
return opp::span<T, Count>(_data + Offset);
}
constexpr auto subspan(size_t offset, size_t count = dynamic_extent)
{
if (count == dynamic_extent)
return opp::span<T>(_data + offset, size() - offset);
else
return opp::span<T>(_data + offset, count);
}
template< int Count >
constexpr auto first() const
{
return opp::span<T, Count>(_data);
}
constexpr auto first( size_t count ) const
{
return opp::span<T>(_data, count);
}
template< int Count >
constexpr auto last() const
{
return opp::span<T, Count>(_data + size() - Count);
}
constexpr auto last( size_t count ) const
{
return opp::span<T>(_data + size() - count, count);
}
};
}
#endif
+86
View File
@@ -0,0 +1,86 @@
#include "sstream.h"
#include <stdlib.h>
namespace opp {
ostringstream::ostringstream(void)
{
mBuffer = nullptr;
mBFill = mBSize = 0;
}
ostringstream::~ostringstream(void)
{
free(mBuffer);
}
void ostringstream::bput(char ch)
{
if (!mBuffer)
{
mBSize = 15;
mBFill = 0;
mBuffer = (char *)malloc(15);
}
else if (mBFill == mBSize)
{
mBSize *= 2;
char * b = (char *)malloc(mBSize);
for(char i=0; i<mBFill; i++)
b[i] = mBuffer[i];
free(mBuffer);
mBuffer = b;
}
mBuffer[mBFill++] = ch;
}
string ostringstream::str(void) const
{
return string(mBuffer, mBFill);
}
void ostringstream::str(const string & str)
{
mBFill = str.size();
if (mBFill > mBSize)
{
free(mBuffer);
mBSize = mBFill;
mBuffer = (char *)malloc(mBSize);
}
str.copyseg(mBuffer, 0, mBFill);
}
istringstream::istringstream(const string & str)
: mString(str), mSPos(0)
{}
istringstream::~istringstream(void)
{}
string istringstream::str(void) const
{
return mString;
}
void istringstream::str(const string & str)
{
mState = goodbit;
mString = str;
mSPos = 0;
}
void istringstream::refill(void)
{
mBufferFill = 0;
mBufferPos = 0;
char ch;
while (mSPos < mString.size() && mBufferFill < 32)
{
mBuffer[mBufferFill++] = mString[mSPos++];
}
}
}
+42
View File
@@ -0,0 +1,42 @@
#ifndef OPP_SSTREAM_H
#define OPP_SSTREAM_H
#include "iostream.h"
namespace opp {
class ostringstream : public ostream
{
public:
ostringstream(void);
~ostringstream(void);
string str(void) const;
void str(const string & str);
protected:
void bput(char ch);
char * mBuffer;
char mBFill, mBSize;
};
class istringstream : public istream
{
public:
istringstream(const string & str);
~istringstream(void);
string str(void) const;
void str(const string & str);
protected:
virtual void refill(void);
string mString;
char mSPos;
};
}
#pragma compile("sstream.cpp")
#endif
+308
View File
@@ -0,0 +1,308 @@
#ifndef OPP_STATIC_VECTOR_H
#define OPP_STATIC_VECTOR_H
#include <new>
#include <stdlib.h>
#include <opp/utility.h>
#include <oscar.h>
namespace opp {
template <class T, int N>
class static_vector
{
protected:
enum { m = N } _size;
char _space[N * sizeof(T)];
public:
typedef T element_type;
static_vector(void) : _size(0) {}
static_vector(size_t n) : _size(n)
{
#ifdef CAPACITYCHECK
if (n > N) debugcrash();
#endif
T * data = (T*)_space;
for(size_t i=0; i<n; i++)
new (data + i) T();
}
static_vector(const static_vector & v)
: _size(v._size)
{
size_t n = _size;
T * data = (T*)_space, * vdata = (T*)(v._space);
for(size_t i=0; i<n; i++)
new (data + i)T(vdata[i]);
}
~static_vector(void)
{
T * data = (T*)_space;
size_t n = _size;
for(size_t i=0; i<n; i++)
data[i].~T();
}
static_vector & operator=(const static_vector & v)
{
if (this != &v)
{
T * data = (T*)_space, * vdata = (T*)(v._space);
size_t n = _size;
for(size_t i=0; i<n; i++)
data[i].~T();
_size = v._size;
n = _size;
for(size_t i=0; i<n; i++)
new (data + i)T(vdata[i]);
}
return *this;
}
size_t size(void) const
{
return _size;
}
size_t max_size(void) const
{
return N;
}
bool empty(void) const
{
return _size == 0;
}
bool full(void) const
{
return _size == N;
}
size_t capacity(void) const
{
return N;
}
void resize(size_t n);
void clear(void);
T & at(size_t at)
{
return ((T*)_space)[at];
}
const T & at(size_t at) const
{
return ((T*)_space)[at];
}
T & operator[](size_t at)
{
return ((T*)_space)[at];
}
const T & operator[](size_t at) const
{
return ((T*)_space)[at];
}
T * begin(void)
{
return (T*)_space;
}
const T * begin(void) const
{
return (T*)_space;
}
const T * cbegin(void) const
{
return (T*)_space;
}
T * end(void)
{
return (T*)_space + _size;
}
const T * end(void) const
{
return (T*)_space + _size;
}
const T * cend(void) const
{
return (T*)_space + _size;
}
T & front(void)
{
return ((T*)_space)[0];
}
const T & front(void) const
{
return ((T*)_space)[0];
}
T & back(void)
{
return ((T*)_space)[_size - 1];
}
const T & back(void) const
{
return ((T*)_space)[_size - 1];
}
T * data(void)
{
return (T*)_space;
}
const T * at(void) const
{
return (T*)_space;
}
void push_back(const T & t);
void push_back(T && t);
void pop_back(void)
{
_size--;
((T*)_space)[_size].~T();
}
void assign(size_t count, const T & t);
void insert(size_t at, const T & t);
void erase(size_t at, size_t n = 1);
T * insert(T * at, const T & t);
template <typename ...P>
void emplace_back(const P&... p);
};
template <class T, int N>
void static_vector<T, N>::clear(void)
{
T * data = (T*)_space;
for(size_t i=0; i<_size; i++)
data[i].~T();
_size = 0;
}
template <class T, int N>
void static_vector<T, N>::resize(size_t n)
{
#ifdef CAPACITYCHECK
if (n > N) debugcrash();
#endif
T * data = (T*)_space;
if (n < _size)
{
for(size_t i=n; i<_size; i++)
data[i].~T();
}
else if (n > 0)
{
for(size_t i=_size; i<n; i++)
new(data + i)T();
}
_size = n;
}
template <class T, int N>
void static_vector<T, N>::push_back(const T & t)
{
#ifdef CAPACITYCHECK
if (_size >= N) debugcrash();
#endif
new ((T*)_space + _size++)T(t);
}
template <class T, int N>
void static_vector<T, N>::push_back(T && t)
{
#ifdef CAPACITYCHECK
if (_size >= N) debugcrash();
#endif
new ((T*)_space + _size++)T(t);
}
template <class T, int N>
template <typename ...P>
void static_vector<T, N>::emplace_back(const P&... p)
{
#ifdef CAPACITYCHECK
if (_size >= N) debugcrash();
#endif
new ((T*)_space + _size++)T(p...);
}
template <class T, int N>
void static_vector<T, N>::assign(size_t count, const T & t)
{
T * data = (T*)_space;
for(size_t i=0; i<_size; i++)
data[i].~T();
for(size_t i=0; i<count; i++)
new (data + i)T(t);
_size = count;
}
template <class T, int N>
void static_vector<T, N>::insert(size_t at, const T & t)
{
T * data = (T*)_space;
new (data + _size)T();
for(size_t i=_size; i>at; i--)
data[i] = move(data[i - 1]);
data[at] = t;
_size++;
}
template <class T, int N>
void static_vector<T, N>::erase(size_t at, size_t n)
{
T * data = (T*)_space;
_size -= n;
for(size_t i=at; i<_size; i++)
data[i] = move(data[i + n]);
for(size_t i=0; i<n; i++)
data[_size + i].~T();
}
template <class T, int N>
T * static_vector<T, N>::insert(T * at, const T & t)
{
#ifdef CAPACITYCHECK
if (_size >= N) debugcrash();
#endif
T * data = (T*)_space;
T * dp = data + _size;
new (dp)T();
while (dp != at)
{
dp--;
dp[1] = move(dp[0]);
}
dp[0] = t;
_size++;
return dp + 1;
}
}
#endif
File diff suppressed because it is too large Load Diff
+110
View File
@@ -0,0 +1,110 @@
#ifndef OPP_STRING_H
#define OPP_STRING_H
namespace opp {
class string
{
private:
char * cstr;
friend void swap(string & u, string & v);
public:
string(void);
string(const string & s);
string(string && s);
string(const char * s);
string(const char * s, char size);
string(char c);
~string(void);
unsigned size(void) const;
void clear(void);
string & operator=(const string & s);
string & operator=(string && s);
string & operator=(const char * s);
string & operator+=(const string & s);
string & operator+=(const char * s);
string & operator+=(char c);
string operator+(const string & s) const;
string operator+(const char * s) const;
string operator+(char c) const;
string & operator<<=(char n);
string & operator>>=(char n);
string operator<<(char n) const;
string operator>>(char n) const;
bool operator==(const string & s) const;
bool operator==(const char * s) const;
bool operator!=(const string & s) const;
bool operator!=(const char * s) const;
bool operator<(const string & s) const;
bool operator<(const char * s) const;
bool operator<=(const string & s) const;
bool operator<=(const char * s) const;
bool operator>(const string & s) const;
bool operator>(const char * s) const;
bool operator>=(const string & s) const;
bool operator>=(const char * s) const;
char & operator[](char t);
char operator[](char t) const;
char * begin(void);
const char * begin(void) const;
const char * cbegin(void) const;
char * end(void);
const char * end(void) const;
const char * cend(void) const;
const char * c_str(void) const;
const char * tocstr(void) const;
string substr(char pos, char len) const;
int find(const string & s) const;
int find(const char * s) const;
int find(char c) const;
int find(const string & s, char pos) const;
int find(const char * s, char pos) const;
int find(char c, char pos) const;
void copyseg(char * p, char at, char num) const;
int to_int(char * idx = nullptr, char base = 10) const;
long to_long(char * idx = nullptr, char base = 10) const;
unsigned to_uint(char * idx = nullptr, char base = 10) const;
unsigned long to_ulong(char * idx = nullptr, char base = 10) const;
float to_float(char * idx = nullptr) const;
protected:
string(char l, char * b);
};
void swap(string & u, string & v);
string to_string(int val);
string to_string(long val);
string to_string(unsigned int val);
string to_string(unsigned long val);
string to_string(float val);
}
#pragma compile("string.cpp")
#endif
+40
View File
@@ -0,0 +1,40 @@
#ifndef OPP_UTILITY_H
#define OPP_UTILITY_H
namespace opp {
template <class T>
inline T && move(T && m)
{
return (T &&)m;
}
template <class T>
inline void swap(T & x, T & y)
{
T t(x); x = y; y = move(t);
}
template<class T1, class T2>
struct pair
{
T1 first;
T2 second;
pair(T1 && t1, T2 && t2)
: first(t1), second(t2)
{}
};
template<class T1, class T2>
constexpr pair<T1, T2> make_pair(T1 && t1, T2 && t2)
{
return pair<T1, T2>(t1, t2);
}
}
#endif
+364
View File
@@ -0,0 +1,364 @@
#ifndef OPP_VECTOR_H
#define OPP_VECTOR_H
#include <new>
#include <stdlib.h>
#include <opp/utility.h>
namespace opp {
template <class T>
class vector
{
protected:
T * _data;
size_t _size, _capacity;
public:
typedef T element_type;
vector(void) : _data(nullptr), _size(0), _capacity(0) {}
vector(size_t n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n)
{
for(size_t i=0; i<n; i++)
new (_data + i) T();
}
vector(const vector & v)
: _data((T*)malloc(v._size * sizeof(T))), _size(v._size), _capacity(v._size)
{
size_t n = _size;
for(size_t i=0; i<n; i++)
new (_data + i)T(v._data[i]);
}
vector(vector && v)
: _data(v._data), _size(v._size), _capacity(v._capacity)
{
v._data = nullptr;
v._size = 0;
v._capacity = 0;
}
~vector(void)
{
for(size_t i=0; i<_size; i++)
_data[i].~T();
free(_data);
}
vector & operator=(const vector & v)
{
if (this != &v)
{
size_t n = _size;
for(size_t i=0; i<n; i++)
_data[i].~T();
free(_data);
_data = (T*)malloc(v._size * sizeof(T));
_size = v._size;
_capacity = v._size;
n = _size;
for(size_t i=0; i<n; i++)
new (_data + i)T(v._data[i]);
}
return *this;
}
vector & operator=(vector && v)
{
if (this != &v)
{
swap(_data, v._data);
swap(_size, v._size);
swap(_capacity, v._capacity);
}
return *this;
}
size_t size(void) const
{
return _size;
}
size_t max_size(void) const
{
return 32767;
}
bool empty(void) const
{
return _size == 0;
}
size_t capacity(void) const
{
return _capacity;
}
void clear(void);
void resize(size_t n);
void reserve(size_t n);
void shrink_to_fit(void);
T & at(size_t at)
{
return _data[at];
}
const T & at(size_t at) const
{
return _data[at];
}
T & operator[](size_t at)
{
return _data[at];
}
const T & operator[](size_t at) const
{
return _data[at];
}
T * begin(void)
{
return _data;
}
const T * begin(void) const
{
return _data;
}
const T * cbegin(void) const
{
return _data;
}
T * end(void)
{
return _data + _size;
}
const T * end(void) const
{
return _data + _size;
}
const T * cend(void) const
{
return _data + _size;
}
T & front(void)
{
return _data[0];
}
const T & front(void) const
{
return _data[0];
}
T & back(void)
{
return _data[_size - 1];
}
const T & back(void) const
{
return _data[_size - 1];
}
T * data(void)
{
return _data;
}
const T * at(void) const
{
return _data;
}
void push_back(const T & t);
void push_back(T && t);
void pop_back(void)
{
_size--;
_data[_size].~T();
}
void assign(size_t count, const T & t);
void insert(size_t at, const T & t);
void erase(size_t at, size_t n = 1);
T * insert(T * at, const T & t);
template <typename ...P>
void emplace_back(const P&... p);
protected:
T * add_back(void);
};
template <class T>
__noinline void vector<T>::reserve(size_t n)
{
if (n > _capacity)
{
_capacity = n;
T * d = (T *)malloc(_capacity * sizeof(T));
size_t s = _size;
for(size_t i=0; i<s; i++)
{
new (d + i)T(move(_data[i]));
_data[i].~T();
}
free(_data);
_data = d;
}
}
template <class T>
void vector<T>::clear(void)
{
for(size_t i=0; i<_size; i++)
_data[i].~T();
_size = 0;
}
template <class T>
__noinline void vector<T>::resize(size_t n)
{
if (n < _size)
{
for(size_t i=n; i<_size; i++)
_data[i].~T();
_size = n;
}
else if (n < _capacity)
{
for(size_t i=_size; i<n; i++)
new(_data + i)T();
_size = n;
}
else
{
reserve(n);
_size = n;
}
}
template <class T>
void vector<T>::shrink_to_fit(void)
{
if (_size < _capacity)
{
_capacity = _size;
T * d = (T *)malloc(_capacity * sizeof(T));
for(size_t i=0; i<_size; i++)
{
new (d + i)T(move(_data[i]));
_data[i].~T();
}
free(_data);
_data = d;
}
}
template <class T>
T * vector<T>::add_back(void)
{
if (_size == _capacity)
reserve(_size + 1 + (_size >> 1));
return _data + _size++;
}
template <class T>
void vector<T>::push_back(const T & t)
{
new (add_back())T(t);
}
template <class T>
void vector<T>::push_back(T && t)
{
new (add_back())T(t);
}
template <class T>
template <typename ...P>
void vector<T>::emplace_back(const P&... p)
{
new (add_back())T(p...);
}
template <class T>
void vector<T>::assign(size_t count, const T & t)
{
for(size_t i=0; i<_size; i++)
_data[i].~T();
if (count > _capacity)
{
_size = 0;
reserve(count);
}
for(size_t i=0; i<count; i++)
new (_data + i)T(t);
_size = count;
}
template <class T>
void vector<T>::insert(size_t at, const T & t)
{
if (_size == _capacity)
reserve(_size + 1 + (_size >> 1));
new (_data + _size)T();
for(size_t i=_size; i>at; i--)
_data[i] = move(_data[i - 1]);
_data[at] = t;
_size++;
}
template <class T>
void vector<T>::erase(size_t at, size_t n)
{
_size -= n;
for(size_t i=at; i<_size; i++)
_data[i] = move(_data[i + n]);
for(size_t i=0; i<n; i++)
_data[_size + i].~T();
}
template <class T>
T * vector<T>::insert(T * at, const T & t)
{
if (_size == _capacity)
{
unsigned f = unsigned(at) - unsigned(_data);
reserve(_size + 1 + (_size >> 1));
at = (T *)(f + unsigned(_data));
}
T * dp = _data + _size;
new (dp)T();
while (dp != at)
{
dp--;
dp[1] = move(dp[0]);
}
dp[0] = t;
_size++;
return dp + 1;
}
}
#endif