initial commit
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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++];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user