uglify the code by using unique identifiers only (prevent macro conflicts)

This commit is contained in:
q66 2015-06-02 00:57:34 +01:00
parent 8bfd38f2e6
commit bfc94e31d7
11 changed files with 3024 additions and 3309 deletions

View file

@ -17,545 +17,557 @@ namespace octa {
/* partitioning */ /* partitioning */
template<typename R, typename U> template<typename _R, typename _U>
R partition(R range, U pred) { _R partition(_R __range, _U __pred) {
R ret = range; _R __ret = __range;
for (; !range.empty(); range.pop_front()) { for (; !__range.empty(); __range.pop_front()) {
if (pred(range.front())) { if (__pred(__range.front())) {
swap(range.front(), ret.front()); octa::swap(__range.front(), __ret.front());
ret.pop_front(); __ret.pop_front();
} }
} }
return ret; return __ret;
} }
template<typename R, typename P> template<typename _R, typename _P>
bool is_partitioned(R range, P pred) { bool is_partitioned(_R __range, _P __pred) {
for (; !range.empty() && pred(range.front()); range.pop_front()); for (; !__range.empty() && __pred(__range.front()); __range.pop_front());
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (pred(range.front())) return false; if (__pred(__range.front())) return false;
return true; return true;
} }
/* sorting */ /* sorting */
template<typename R, typename C> template<typename _R, typename _C>
void __octa_insort(R range, C compare) { void __octa_insort(_R __range, _C __compare) {
RangeSize<R> rlen = range.size(); octa::RangeSize<_R> __rlen = __range.size();
for (RangeSize<R> i = 1; i < rlen; ++i) { for (octa::RangeSize<_R> __i = 1; __i < __rlen; ++__i) {
RangeSize<R> j = i; octa::RangeSize<_R> __j = __i;
RangeReference<R> v = range[i]; octa::RangeReference<_R> __v = __range[__i];
while (j > 0 && !compare(range[j - 1], v)) { while (__j > 0 && !__compare(__range[__j - 1], __v)) {
range[j] = range[j - 1]; __range[__j] = __range[__j - 1];
--j; --__j;
} }
range[j] = v; __range[__j] = __v;
} }
} }
template<typename T, typename U> template<typename _T, typename _U>
struct __OctaUnaryCompare { struct __OctaUnaryCompare {
const T &val; const _T &__val;
U comp; _U __comp;
bool operator()(const T &v) const { return comp(v, val); } bool operator()(const _T &__v) const { return __comp(__v, __val); }
}; };
template<typename R, typename C> template<typename _R, typename _C>
void __octa_hs_sift_down(R range, RangeSize<R> s, void __octa_hs_sift_down(_R __range, octa::RangeSize<_R> __s,
RangeSize<R> e, C compare) { octa::RangeSize<_R> __e, _C __compare) {
RangeSize<R> r = s; octa::RangeSize<_R> __r = __s;
while ((r * 2 + 1) <= e) { while ((__r * 2 + 1) <= __e) {
RangeSize<R> ch = r * 2 + 1; octa::RangeSize<_R> __ch = __r * 2 + 1;
RangeSize<R> sw = r; octa::RangeSize<_R> __sw = __r;
if (compare(range[sw], range[ch])) if (__compare(__range[__sw], __range[__ch]))
sw = ch; __sw = __ch;
if (((ch + 1) <= e) && compare(range[sw], range[ch + 1])) if (((__ch + 1) <= __e) && __compare(__range[__sw], __range[__ch + 1]))
sw = ch + 1; __sw = __ch + 1;
if (sw != r) { if (__sw != __r) {
swap(range[r], range[sw]); octa::swap(__range[__r], __range[__sw]);
r = sw; __r = __sw;
} else return; } else return;
} }
} }
template<typename R, typename C> template<typename _R, typename _C>
void __octa_heapsort(R range, C compare) { void __octa_heapsort(_R __range, _C __compare) {
RangeSize<R> len = range.size(); octa::RangeSize<_R> __len = __range.size();
RangeSize<R> st = (len - 2) / 2; octa::RangeSize<_R> __st = (__len - 2) / 2;
for (;;) { for (;;) {
__octa_hs_sift_down(range, st, len - 1, compare); __octa_hs_sift_down(__range, __st, __len - 1, __compare);
if (st-- == 0) break; if (__st-- == 0) break;
} }
RangeSize<R> e = len - 1; octa::RangeSize<_R> __e = __len - 1;
while (e > 0) { while (__e > 0) {
swap(range[e], range[0]); octa::swap(__range[__e], __range[0]);
--e; --__e;
__octa_hs_sift_down(range, 0, e, compare); __octa_hs_sift_down(__range, 0, __e, __compare);
} }
} }
template<typename R, typename C> template<typename _R, typename _C>
void __octa_introloop(R range, C compare, RangeSize<R> depth) { void __octa_introloop(_R __range, _C __compare, RangeSize<_R> __depth) {
if (range.size() <= 10) { if (__range.size() <= 10) {
__octa_insort(range, compare); __octa_insort(__range, __compare);
return; return;
} }
if (depth == 0) { if (__depth == 0) {
__octa_heapsort(range, compare); __octa_heapsort(__range, __compare);
return; return;
} }
RangeReference<R> p = range[range.size() / 2]; octa::RangeReference<_R> __p = __range[__range.size() / 2];
swap(p, range.back()); octa::swap(__p, __range.back());
R r = partition(range, __OctaUnaryCompare<decltype(p), C>{ p, compare }); _R __r = octa::partition(__range,
R l = range.slice(0, range.size() - r.size()); __OctaUnaryCompare<decltype(__p), _C>{ __p, __compare });
swap(r.front(), r.back()); _R __l = __range.slice(0, __range.size() - __r.size());
__octa_introloop(l, compare, depth - 1); octa::swap(__r.front(), __r.back());
__octa_introloop(r, compare, depth - 1); __octa_introloop(__l, __compare, __depth - 1);
__octa_introloop(__r, __compare, __depth - 1);
} }
template<typename R, typename C> template<typename _R, typename _C>
void __octa_introsort(R range, C compare) { void __octa_introsort(_R __range, _C __compare) {
__octa_introloop(range, compare, RangeSize<R>(2 __octa_introloop(__range, __compare, octa::RangeSize<_R>(2
* (log(range.size()) / log(2)))); * (log(__range.size()) / log(2))));
} }
template<typename R, typename C> template<typename _R, typename _C>
void sort(R range, C compare) { void sort(_R __range, _C __compare) {
__octa_introsort(range, compare); __octa_introsort(__range, __compare);
} }
template<typename R> template<typename _R>
void sort(R range) { void sort(_R __range) {
sort(range, Less<RangeValue<R>>()); sort(__range, octa::Less<RangeValue<_R>>());
} }
/* min/max(_element) */ /* min/max(_element) */
template<typename T> template<typename _T>
inline const T &min(const T &a, const T &b) { inline const _T &min(const _T &__a, const _T &__b) {
return (a < b) ? a : b; return (__a < __b) ? __a : __b;
} }
template<typename T, typename C> template<typename _T, typename _C>
inline const T &min(const T &a, const T &b, C compare) { inline const _T &min(const _T &__a, const _T &__b, _C __compare) {
return compare(a, b) ? a : b; return __compare(__a, __b) ? __a : __b;
} }
template<typename T> template<typename _T>
inline const T &max(const T &a, const T &b) { inline const _T &max(const _T &__a, const _T &__b) {
return (a < b) ? b : a; return (__a < __b) ? __b : __a;
} }
template<typename T, typename C> template<typename _T, typename _C>
inline const T &max(const T &a, const T &b, C compare) { inline const _T &max(const _T &__a, const _T &__b, _C __compare) {
return compare(a, b) ? b : a; return __compare(__a, __b) ? __b : __a;
} }
template<typename R> template<typename _R>
inline R min_element(R range) { inline _R min_element(_R __range) {
R r = range; _R __r = __range;
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (min(r.front(), range.front()) == range.front()) if (octa::min(__r.front(), __range.front()) == __range.front())
r = range; __r = __range;
return r; return __r;
} }
template<typename R, typename C> template<typename _R, typename _C>
inline R min_element(R range, C compare) { inline _R min_element(_R __range, _C __compare) {
R r = range; _R __r = __range;
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (min(r.front(), range.front(), compare) == range.front()) if (octa::min(__r.front(), __range.front(), __compare) == __range.front())
r = range; __r = __range;
return r; return __r;
} }
template<typename R> template<typename _R>
inline R max_element(R range) { inline _R max_element(_R __range) {
R r = range; _R __r = __range;
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (max(r.front(), range.front()) == range.front()) if (octa::max(__r.front(), __range.front()) == __range.front())
r = range; __r = __range;
return r; return __r;
} }
template<typename R, typename C> template<typename _R, typename _C>
inline R max_element(R range, C compare) { inline _R max_element(_R __range, _C __compare) {
R r = range; _R __r = __range;
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (max(r.front(), range.front(), compare) == range.front()) if (octa::max(__r.front(), __range.front(), __compare) == __range.front())
r = range; __r = __range;
return r; return __r;
} }
using std::initializer_list; template<typename _T>
inline _T min(std::initializer_list<_T> __il) {
template<typename T> return octa::min_element(octa::each(__il)).front();
inline T min(initializer_list<T> il) {
return min_element(each(il)).front();
} }
template<typename T, typename C> template<typename _T, typename _C>
inline T min(initializer_list<T> il, C compare) { inline _T min(std::initializer_list<_T> __il, _C __compare) {
return min_element(each(il), compare).front(); return octa::min_element(octa::each(__il), __compare).front();
} }
template<typename T> template<typename _T>
inline T max(initializer_list<T> il) { inline _T max(std::initializer_list<_T> __il) {
return max_element(each(il)).front(); return octa::max_element(octa::each(__il)).front();
} }
template<typename T, typename C> template<typename _T, typename _C>
inline T max(initializer_list<T> il, C compare) { inline _T max(std::initializer_list<_T> __il, _C __compare) {
return max_element(each(il), compare).front(); return octa::max_element(octa::each(__il), __compare).front();
} }
/* clamp */ /* clamp */
template<typename T, typename U> template<typename _T, typename _U>
inline T clamp(const T &v, const U &lo, const U &hi) { inline _T clamp(const _T &__v, const _U &__lo, const _U &__hi) {
return max(T(lo), min(v, T(hi))); return octa::max(_T(__lo), octa::min(__v, _T(__hi)));
} }
template<typename T, typename U, typename C> template<typename _T, typename _U, typename _C>
inline T clamp(const T &v, const U &lo, const U &hi, C compare) { inline _T clamp(const _T &__v, const _U &__lo, const _U &__hi, _C __compare) {
return max(T(lo), min(v, T(hi), compare), compare); return octa::max(_T(__lo), octa::min(__v, _T(__hi), __compare), __compare);
} }
/* algos that don't change the range */ /* algos that don't change the range */
template<typename R, typename F> template<typename _R, typename _F>
F for_each(R range, F func) { _F for_each(_R __range, _F __func) {
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
func(range.front()); __func(__range.front());
return move(func); return octa::move(__func);
} }
template<typename R, typename P> template<typename _R, typename _P>
bool all_of(R range, P pred) { bool all_of(_R __range, _P __pred) {
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (!pred(range.front())) return false; if (!__pred(__range.front())) return false;
return true; return true;
} }
template<typename R, typename P> template<typename _R, typename _P>
bool any_of(R range, P pred) { bool any_of(_R __range, _P __pred) {
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (pred(range.front())) return true; if (__pred(__range.front())) return true;
return false; return false;
} }
template<typename R, typename P> template<typename _R, typename _P>
bool none_of(R range, P pred) { bool none_of(_R __range, _P __pred) {
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (pred(range.front())) return false; if (__pred(__range.front())) return false;
return true; return true;
} }
template<typename R, typename T> template<typename _R, typename _T>
R find(R range, const T &v) { _R find(_R __range, const _T &__v) {
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (range.front() == v) if (__range.front() == __v)
break; break;
return range; return __range;
} }
template<typename R, typename P> template<typename _R, typename _P>
R find_if(R range, P pred) { _R find_if(_R __range, _P __pred) {
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (pred(range.front())) if (__pred(__range.front()))
break; break;
return range; return __range;
} }
template<typename R, typename P> template<typename _R, typename _P>
R find_if_not(R range, P pred) { _R find_if_not(_R __range, _P __pred) {
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (!pred(range.front())) if (!__pred(__range.front()))
break; break;
return range; return __range;
} }
template<typename R, typename T> template<typename _R, typename _T>
RangeSize<R> count(R range, const T &v) { RangeSize<_R> count(_R __range, const _T &__v) {
RangeSize<R> ret = 0; RangeSize<_R> __ret = 0;
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (range.front() == v) if (__range.front() == __v)
++ret; ++__ret;
return ret; return __ret;
} }
template<typename R, typename P> template<typename _R, typename _P>
RangeSize<R> count_if(R range, P pred) { RangeSize<_R> count_if(_R __range, _P __pred) {
RangeSize<R> ret = 0; RangeSize<_R> __ret = 0;
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (pred(range.front())) if (__pred(__range.front()))
++ret; ++__ret;
return ret; return __ret;
} }
template<typename R, typename P> template<typename _R, typename _P>
RangeSize<R> count_if_not(R range, P pred) { RangeSize<_R> count_if_not(_R __range, _P __pred) {
RangeSize<R> ret = 0; RangeSize<_R> __ret = 0;
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
if (!pred(range.front())) if (!__pred(__range.front()))
++ret; ++__ret;
return ret; return __ret;
} }
template<typename R> template<typename _R>
bool equal(R range1, R range2) { bool equal(_R __range1, _R __range2) {
for (; !range1.empty(); range1.pop_front()) { for (; !__range1.empty(); __range1.pop_front()) {
if (range2.empty() || (range1.front() != range2.front())) if (__range2.empty() || (__range1.front() != __range2.front()))
return false; return false;
range2.pop_front(); __range2.pop_front();
} }
return range2.empty(); return __range2.empty();
} }
/* algos that modify ranges or work with output ranges */ /* algos that modify ranges or work with output ranges */
template<typename R1, typename R2> template<typename _R1, typename _R2>
R2 copy(R1 irange, R2 orange) { _R2 copy(_R1 __irange, _R2 __orange) {
for (; !irange.empty(); irange.pop_front()) for (; !__irange.empty(); __irange.pop_front())
orange.put(irange.front()); __orange.put(__irange.front());
return orange; return __orange;
} }
template<typename R1, typename R2, typename P> template<typename _R1, typename _R2, typename _P>
R2 copy_if(R1 irange, R2 orange, P pred) { _R2 copy_if(_R1 __irange, _R2 __orange, _P __pred) {
for (; !irange.empty(); irange.pop_front()) for (; !__irange.empty(); __irange.pop_front())
if (pred(irange.front())) if (__pred(__irange.front()))
orange.put(irange.front()); __orange.put(__irange.front());
return orange; return __orange;
} }
template<typename R1, typename R2, typename P> template<typename _R1, typename _R2, typename _P>
R2 copy_if_not(R1 irange, R2 orange, P pred) { _R2 copy_if_not(_R1 __irange, _R2 __orange, _P __pred) {
for (; !irange.empty(); irange.pop_front()) for (; !__irange.empty(); __irange.pop_front())
if (!pred(irange.front())) if (!__pred(__irange.front()))
orange.put(irange.front()); __orange.put(__irange.front());
return orange; return __orange;
} }
template<typename R1, typename R2> template<typename _R1, typename _R2>
R2 move(R1 irange, R2 orange) { _R2 move(_R1 __irange, _R2 __orange) {
for (; !irange.empty(); irange.pop_front()) for (; !__irange.empty(); __irange.pop_front())
orange.put(move(irange.front())); __orange.put(octa::move(__irange.front()));
return orange; return __orange;
} }
template<typename R> template<typename _R>
void reverse(R range) { void reverse(_R __range) {
while (!range.empty()) { while (!__range.empty()) {
swap(range.front(), range.back()); octa::swap(__range.front(), __range.back());
range.pop_front(); __range.pop_front();
range.pop_back(); __range.pop_back();
} }
} }
template<typename R1, typename R2> template<typename _R1, typename _R2>
R2 reverse_copy(R1 irange, R2 orange) { _R2 reverse_copy(_R1 __irange, _R2 __orange) {
for (; !irange.empty(); irange.pop_back()) for (; !__irange.empty(); __irange.pop_back())
orange.put(irange.back()); __orange.put(__irange.back());
return orange; return __orange;
} }
template<typename R, typename T> template<typename _R, typename _T>
void fill(R range, const T &v) { void fill(_R __range, const _T &__v) {
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
range.front() = v; __range.front() = __v;
} }
template<typename R, typename F> template<typename _R, typename _F>
void generate(R range, F gen) { void generate(_R __range, _F __gen) {
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
range.front() = gen(); __range.front() = __gen();
} }
template<typename R1, typename R2> template<typename _R1, typename _R2>
Pair<R1, R2> swap_ranges(R1 range1, R2 range2) { octa::Pair<_R1, _R2> swap_ranges(_R1 __range1, _R2 __range2) {
while (!range1.empty() && !range2.empty()) { while (!__range1.empty() && !__range2.empty()) {
swap(range1.front(), range2.front()); octa::swap(__range1.front(), __range2.front());
range1.pop_front(); __range1.pop_front();
range2.pop_front(); __range2.pop_front();
} }
return Pair<R1, R2>(range1, range2); return octa::Pair<_R1, _R2>(__range1, __range2);
} }
template<typename R, typename T> template<typename _R, typename _T>
void iota(R range, T value) { void iota(_R __range, _T __value) {
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
range.front() = value++; __range.front() = __value++;
} }
template<typename R, typename T> template<typename _R, typename _T>
T foldl(R range, T init) { _T foldl(_R __range, _T __init) {
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
init = init + range.front(); __init = __init + __range.front();
return init; return __init;
} }
template<typename R, typename T, typename F> template<typename _R, typename _T, typename _F>
T foldl(R range, T init, F func) { _T foldl(_R __range, _T __init, _F __func) {
for (; !range.empty(); range.pop_front()) for (; !__range.empty(); __range.pop_front())
init = func(init, range.front()); __init = __func(__init, __range.front());
return init; return __init;
} }
template<typename R, typename T> template<typename _R, typename _T>
T foldr(R range, T init) { _T foldr(_R __range, _T __init) {
for (; !range.empty(); range.pop_back()) for (; !__range.empty(); __range.pop_back())
init = init + range.back(); __init = __init + __range.back();
return init; return __init;
} }
template<typename R, typename T, typename F> template<typename _R, typename _T, typename _F>
T foldr(R range, T init, F func) { _T foldr(_R __range, _T __init, _F __func) {
for (; !range.empty(); range.pop_back()) for (; !__range.empty(); __range.pop_back())
init = func(init, range.back()); __init = __func(__init, __range.back());
return init; return __init;
} }
template<typename T, typename R> template<typename _T, typename _R>
struct MapRange: InputRange< struct MapRange: InputRange<
MapRange<T, R>, RangeCategory<T>, R, R, RangeSize<T> MapRange<_T, _R>, octa::RangeCategory<_T>, _R, _R, octa::RangeSize<_T>
> { > {
private: private:
T p_range; _T __range;
Function<R(RangeReference<T>)> p_func; octa::Function<_R(octa::RangeReference<_T>)> __func;
public: public:
MapRange(): p_range(), p_func() {} MapRange(): __range(), __func() {}
template<typename F> template<typename _F>
MapRange(const T &range, const F &func): p_range(range), p_func(func) {} MapRange(const _T &__range, const _F &__func):
MapRange(const MapRange &it): p_range(it.p_range), p_func(it.p_func) {} __range(__range), __func(__func) {}
MapRange(MapRange &&it): p_range(move(it.p_range)), p_func(move(it.p_func)) {} MapRange(const MapRange &__it):
__range(__it.__range), __func(__it.__func) {}
MapRange(MapRange &&__it):
__range(move(__it.__range)), __func(move(__it.__func)) {}
MapRange &operator=(const MapRange &v) { MapRange &operator=(const MapRange &__v) {
p_range = v.p_range; __range = __v.__range;
p_func = v.p_func; __func = __v.__func;
return *this; return *this;
} }
MapRange &operator=(MapRange &&v) { MapRange &operator=(MapRange &&__v) {
p_range = move(v.p_range); __range = move(__v.__range);
p_func = move(v.p_func); __func = move(__v.__func);
return *this; return *this;
} }
bool empty() const { return p_range.empty(); } bool empty() const { return __range.empty(); }
RangeSize<T> size() const { return p_range.size(); } octa::RangeSize<_T> size() const { return __range.size(); }
bool equals_front(const MapRange &range) const { bool equals_front(const MapRange &__r) const {
return p_range.equals_front(range.p_range); return __range.equals_front(__r.__range);
} }
bool equals_back(const MapRange &range) const { bool equals_back(const MapRange &__r) const {
return p_range.equals_front(range.p_range); return __range.equals_front(__r.__range);
} }
RangeDifference<T> distance_front(const MapRange &range) const { octa::RangeDifference<_T> distance_front(const MapRange &__r) const {
return p_range.distance_front(range.p_range); return __range.distance_front(__r.__range);
} }
RangeDifference<T> distance_back(const MapRange &range) const { octa::RangeDifference<_T> distance_back(const MapRange &__r) const {
return p_range.distance_back(range.p_range); return __range.distance_back(__r.__range);
} }
bool pop_front() { return p_range.pop_front(); } bool pop_front() { return __range.pop_front(); }
bool pop_back() { return p_range.pop_back(); } bool pop_back() { return __range.pop_back(); }
bool push_front() { return p_range.pop_front(); } bool push_front() { return __range.pop_front(); }
bool push_back() { return p_range.push_back(); } bool push_back() { return __range.push_back(); }
RangeSize<T> pop_front_n(RangeSize<T> n) { p_range.pop_front_n(n); } octa::RangeSize<_T> pop_front_n(octa::RangeSize<_T> __n) {
RangeSize<T> pop_back_n(RangeSize<T> n) { p_range.pop_back_n(n); } __range.pop_front_n(__n);
}
RangeSize<T> push_front_n(RangeSize<T> n) { return p_range.push_front_n(n); } octa::RangeSize<_T> pop_back_n(octa::RangeSize<_T> __n) {
RangeSize<T> push_back_n(RangeSize<T> n) { return p_range.push_back_n(n); } __range.pop_back_n(__n);
R front() const { return p_func(p_range.front()); }
R back() const { return p_func(p_range.back()); }
R operator[](RangeSize<T> idx) const {
return p_func(p_range[idx]);
} }
MapRange<T, R> slice(RangeSize<T> start, RangeSize<T> end) { octa::RangeSize<_T> push_front_n(octa::RangeSize<_T> __n) {
return MapRange<T, R>(p_range.slice(start, end), p_func); return __range.push_front_n(__n);
}
octa::RangeSize<_T> push_back_n(octa::RangeSize<_T> __n) {
return __range.push_back_n(__n);
}
_R front() const { return __func(__range.front()); }
_R back() const { return __func(__range.back()); }
_R operator[](octa::RangeSize<_T> __idx) const {
return __func(__range[__idx]);
}
MapRange<_T, _R> slice(octa::RangeSize<_T> __start,
octa::RangeSize<_T> __end) {
return MapRange<_T, _R>(__range.slice(__start, __end), __func);
} }
}; };
template<typename R, typename F> template<typename _R, typename _F> using __OctaMapReturnType
using __OctaMapReturnType = decltype(declval<F>()(declval<RangeReference<R>>())); = decltype(declval<_F>()(octa::declval<octa::RangeReference<_R>>()));
template<typename R, typename F> template<typename _R, typename _F>
MapRange<R, __OctaMapReturnType<R, F>> map(R range, F func) { MapRange<_R, __OctaMapReturnType<_R, _F>> map(_R __range, _F __func) {
return MapRange<R, __OctaMapReturnType<R, F>>(range, func); return octa::MapRange<_R, __OctaMapReturnType<_R, _F>>(__range, __func);
} }
template<typename T> template<typename _T>
struct FilterRange: InputRange< struct FilterRange: InputRange<
FilterRange<T>, CommonType<RangeCategory<T>, ForwardRangeTag>, FilterRange<_T>, octa::CommonType<octa::RangeCategory<_T>,
RangeValue<T>, RangeReference<T>, RangeSize<T> octa::ForwardRangeTag>,
octa::RangeValue<_T>, octa::RangeReference<_T>, octa::RangeSize<_T>
> { > {
private: private:
T p_range; _T __range;
Function<bool(RangeReference<T>)> p_pred; octa::Function<bool(octa::RangeReference<_T>)> __pred;
void advance_valid() { void advance_valid() {
while (!p_range.empty() && !p_pred(front())) p_range.pop_front(); while (!__range.empty() && !__pred(front())) __range.pop_front();
} }
public: public:
FilterRange(): p_range(), p_pred() {} FilterRange(): __range(), __pred() {}
template<typename P> template<typename _P>
FilterRange(const T &range, const P &pred): p_range(range), FilterRange(const _T &__range, const _P &__pred): __range(__range),
p_pred(pred) { __pred(__pred) {
advance_valid(); advance_valid();
} }
FilterRange(const FilterRange &it): p_range(it.p_range), FilterRange(const FilterRange &__it): __range(__it.__range),
p_pred(it.p_pred) { __pred(__it.__pred) {
advance_valid(); advance_valid();
} }
FilterRange(FilterRange &&it): p_range(move(it.p_range)), FilterRange(FilterRange &&__it): __range(move(__it.__range)),
p_pred(move(it.p_pred)) { __pred(move(__it.__pred)) {
advance_valid(); advance_valid();
} }
FilterRange &operator=(const FilterRange &v) { FilterRange &operator=(const FilterRange &__v) {
p_range = v.p_range; __range = __v.__range;
p_pred = v.p_pred; __pred = __v.__pred;
advance_valid(); advance_valid();
return *this; return *this;
} }
FilterRange &operator=(FilterRange &&v) { FilterRange &operator=(FilterRange &&__v) {
p_range = move(v.p_range); __range = move(__v.__range);
p_pred = move(v.p_pred); __pred = move(__v.__pred);
advance_valid(); advance_valid();
return *this; return *this;
} }
bool empty() const { return p_range.empty(); } bool empty() const { return __range.empty(); }
bool equals_front(const FilterRange &range) const { bool equals_front(const FilterRange &__r) const {
return p_range.equals_front(range.p_range); return __range.equals_front(__r.__range);
} }
bool pop_front() { bool pop_front() {
bool ret = p_range.pop_front(); bool __ret = __range.pop_front();
advance_valid(); advance_valid();
return ret; return __ret;
} }
bool push_front() { bool push_front() {
T tmp = p_range; _T __tmp = __range;
if (!tmp.push_front()) return false; if (!__tmp.push_front()) return false;
while (!pred(tmp.front())) while (!pred(__tmp.front()))
if (!tmp.push_front()) if (!__tmp.push_front())
return false; return false;
p_range = tmp; __range = __tmp;
return true; return true;
} }
RangeReference<T> front() const { return p_range.front(); } octa::RangeReference<_T> front() const { return __range.front(); }
}; };
template<typename R, typename P> template<typename _R, typename _P>
FilterRange<R> filter(R range, P pred) { FilterRange<_R> filter(_R __range, _P __pred) {
return FilterRange<R>(range, pred); return octa::FilterRange<_R>(__range, __pred);
} }
} }

View file

@ -13,55 +13,55 @@
#include "octa/string.h" #include "octa/string.h"
namespace octa { namespace octa {
template<typename T, size_t N> template<typename _T, size_t _N>
struct Array { struct Array {
typedef size_t SizeType; typedef size_t SizeType;
typedef ptrdiff_t DiffType; typedef ptrdiff_t DiffType;
typedef T ValType; typedef _T ValType;
typedef T &RefType; typedef _T &RefType;
typedef const T &ConstRefType; typedef const _T &ConstRefType;
typedef T *PtrType; typedef _T *PtrType;
typedef const T *ConstPtrType; typedef const _T *ConstPtrType;
typedef PointerRange< T> RangeType; typedef PointerRange< _T> RangeType;
typedef PointerRange<const T> ConstRangeType; typedef PointerRange<const _T> ConstRangeType;
T &operator[](size_t i) { return p_buf[i]; } _T &operator[](size_t __i) { return __buf[__i]; }
const T &operator[](size_t i) const { return p_buf[i]; } const _T &operator[](size_t __i) const { return __buf[__i]; }
T &at(size_t i) { return p_buf[i]; } _T &at(size_t __i) { return __buf[__i]; }
const T &at(size_t i) const { return p_buf[i]; } const _T &at(size_t __i) const { return __buf[__i]; }
T &front() { return p_buf[0]; } _T &front() { return __buf[0]; }
const T &front() const { return p_buf[0]; } const _T &front() const { return __buf[0]; }
T &back() { return p_buf[(N > 0) ? (N - 1) : 0]; } _T &back() { return __buf[(_N > 0) ? (_N - 1) : 0]; }
const T &back() const { return p_buf[(N > 0) ? (N - 1) : 0]; } const _T &back() const { return __buf[(_N > 0) ? (_N - 1) : 0]; }
size_t size() const { return N; } size_t size() const { return _N; }
bool empty() const { return N == 0; } bool empty() const { return _N == 0; }
bool in_range(size_t idx) { return idx < N; } bool in_range(size_t __idx) { return __idx < _N; }
bool in_range(int idx) { return idx >= 0 && size_t(idx) < N; } bool in_range(int __idx) { return __idx >= 0 && size_t(__idx) < _N; }
bool in_range(const T *ptr) { bool in_range(const _T *__ptr) {
return ptr >= &p_buf[0] && ptr < &p_buf[N]; return __ptr >= &__buf[0] && __ptr < &__buf[_N];
} }
T *data() { return p_buf; } _T *data() { return __buf; }
const T *data() const { return p_buf; } const _T *data() const { return __buf; }
RangeType each() { RangeType each() {
return PointerRange<T>(p_buf, p_buf + N); return octa::PointerRange<_T>(__buf, __buf + _N);
} }
ConstRangeType each() const { ConstRangeType each() const {
return PointerRange<const T>(p_buf, p_buf + N); return octa::PointerRange<const _T>(__buf, __buf + _N);
} }
void swap(Array &v) { void swap(Array &__v) {
swap_ranges(each(), v.each()); octa::swap_ranges(each(), __v.each());
} }
T p_buf[(N > 0) ? N : 1]; _T __buf[(_N > 0) ? _N : 1];
}; };
} }

File diff suppressed because it is too large Load diff

View file

@ -14,12 +14,14 @@
namespace octa { namespace octa {
/* basic function objects */ /* basic function objects */
#define __OCTA_DEFINE_BINARY_OP(name, op, rettype) \ #define __OCTA_DEFINE_BINARY_OP(_name, _op, _rettype) \
template<typename T> struct name { \ template<typename _T> struct _name { \
rettype operator()(const T &x, const T &y) const { return x op y; } \ _rettype operator()(const _T &__x, const _T &__y) const { \
typedef T FirstArgType; \ return __x _op __y; \
typedef T SecondArgType; \ } \
typedef rettype ResultType; \ typedef _T FirstArgType; \
typedef _T SecondArgType; \
typedef _rettype ResultType; \
}; };
__OCTA_DEFINE_BINARY_OP(Less, <, bool) __OCTA_DEFINE_BINARY_OP(Less, <, bool)
@ -30,78 +32,78 @@ namespace octa {
__OCTA_DEFINE_BINARY_OP(NotEqual, !=, bool) __OCTA_DEFINE_BINARY_OP(NotEqual, !=, bool)
__OCTA_DEFINE_BINARY_OP(LogicalAnd, &&, bool) __OCTA_DEFINE_BINARY_OP(LogicalAnd, &&, bool)
__OCTA_DEFINE_BINARY_OP(LogicalOr, ||, bool) __OCTA_DEFINE_BINARY_OP(LogicalOr, ||, bool)
__OCTA_DEFINE_BINARY_OP(Modulus, %, T) __OCTA_DEFINE_BINARY_OP(Modulus, %, _T)
__OCTA_DEFINE_BINARY_OP(Multiplies, *, T) __OCTA_DEFINE_BINARY_OP(Multiplies, *, _T)
__OCTA_DEFINE_BINARY_OP(Divides, /, T) __OCTA_DEFINE_BINARY_OP(Divides, /, _T)
__OCTA_DEFINE_BINARY_OP(Plus, +, T) __OCTA_DEFINE_BINARY_OP(Plus, +, _T)
__OCTA_DEFINE_BINARY_OP(Minus, -, T) __OCTA_DEFINE_BINARY_OP(Minus, -, _T)
__OCTA_DEFINE_BINARY_OP(BitAnd, &, T) __OCTA_DEFINE_BINARY_OP(BitAnd, &, _T)
__OCTA_DEFINE_BINARY_OP(BitOr, |, T) __OCTA_DEFINE_BINARY_OP(BitOr, |, _T)
__OCTA_DEFINE_BINARY_OP(BitXor, ^, T) __OCTA_DEFINE_BINARY_OP(BitXor, ^, _T)
#undef __OCTA_DEFINE_BINARY_OP #undef __OCTA_DEFINE_BINARY_OP
template<typename T> struct LogicalNot { template<typename _T> struct LogicalNot {
bool operator()(const T &x) const { return !x; } bool operator()(const _T &__x) const { return !__x; }
typedef T ArgType; typedef _T ArgType;
typedef bool ResultType; typedef bool ResultType;
}; };
template<typename T> struct Negate { template<typename _T> struct Negate {
bool operator()(const T &x) const { return -x; } bool operator()(const _T &__x) const { return -__x; }
typedef T ArgType; typedef _T ArgType;
typedef T ResultType; typedef _T ResultType;
}; };
template<typename T> struct BinaryNegate { template<typename _T> struct BinaryNegate {
typedef typename T::FirstArgType FirstArgType; typedef typename _T::FirstArgType FirstArgType;
typedef typename T::SecondArgType SecondArgType; typedef typename _T::SecondArgType SecondArgType;
typedef bool ResultType; typedef bool ResultType;
explicit BinaryNegate(const T &f): p_fn(f) {} explicit BinaryNegate(const _T &__f): __fn(__f) {}
bool operator()(const FirstArgType &x, bool operator()(const FirstArgType &__x,
const SecondArgType &y) { const SecondArgType &__y) {
return !p_fn(x, y); return !__fn(__x, __y);
} }
private: private:
T p_fn; _T __fn;
}; };
template<typename T> struct UnaryNegate { template<typename _T> struct UnaryNegate {
typedef typename T::ArgType ArgType; typedef typename _T::ArgType ArgType;
typedef bool ResultType; typedef bool ResultType;
explicit UnaryNegate(const T &f): p_fn(f) {} explicit UnaryNegate(const _T &__f): __fn(__f) {}
bool operator()(const ArgType &x) { bool operator()(const ArgType &__x) {
return !p_fn(x); return !__fn(__x);
} }
private: private:
T p_fn; _T __fn;
}; };
template<typename T> UnaryNegate<T> not1(const T &fn) { template<typename _T> UnaryNegate<_T> not1(const _T &__fn) {
return UnaryNegate<T>(fn); return UnaryNegate<_T>(__fn);
} }
template<typename T> BinaryNegate<T> not2(const T &fn) { template<typename _T> BinaryNegate<_T> not2(const _T &__fn) {
return BinaryNegate<T>(fn); return BinaryNegate<_T>(__fn);
} }
/* hash */ /* hash */
template<typename T> struct Hash; template<typename _T> struct Hash;
template<typename T> struct __OctaHashBase { template<typename _T> struct __OctaHashBase {
typedef T ArgType; typedef _T ArgType;
typedef size_t ResultType; typedef size_t ResultType;
size_t operator()(T v) const { size_t operator()(_T __v) const {
return (size_t)v; return size_t(__v);
} }
}; };
#define __OCTA_HASH_BASIC(T) template<> struct Hash<T>: __OctaHashBase<T> {}; #define __OCTA_HASH_BASIC(_T) template<> struct Hash<_T>: __OctaHashBase<_T> {};
__OCTA_HASH_BASIC(bool) __OCTA_HASH_BASIC(bool)
__OCTA_HASH_BASIC(char) __OCTA_HASH_BASIC(char)
@ -119,69 +121,69 @@ namespace octa {
#undef __OCTA_HASH_BASIC #undef __OCTA_HASH_BASIC
static inline size_t __octa_mem_hash(const void *p, size_t l) { static inline size_t __octa_mem_hash(const void *__p, size_t __l) {
const uchar *d = (const uchar *)p; const uchar *__d = (const uchar *)__p;
size_t h = 5381; size_t __h = 5381;
for (size_t i = 0; i < l; ++i) h = ((h << 5) + h) ^ d[i]; for (size_t __i = 0; __i < __l; ++__i) __h = ((__h << 5) + __h) ^ __d[__i];
return h; return __h;
} }
template<typename T, size_t = sizeof(T) / sizeof(size_t)> template<typename _T, size_t = sizeof(_T) / sizeof(size_t)>
struct __OctaScalarHash; struct __OctaScalarHash;
template<typename T> struct __OctaScalarHash<T, 0> { template<typename _T> struct __OctaScalarHash<_T, 0> {
typedef T ArgType; typedef _T ArgType;
typedef size_t ResultType; typedef size_t ResultType;
size_t operator()(T v) const { size_t operator()(_T __v) const {
union { T v; size_t h; } u; union { _T __v; size_t __h; } __u;
u.h = 0; __u.__h = 0;
u.v = v; __u.__v = __v;
return u.h; return __u.__h;
} }
}; };
template<typename T> struct __OctaScalarHash<T, 1> { template<typename _T> struct __OctaScalarHash<_T, 1> {
typedef T ArgType; typedef _T ArgType;
typedef size_t ResultType; typedef size_t ResultType;
size_t operator()(T v) const { size_t operator()(_T __v) const {
union { T v; size_t h; } u; union { _T __v; size_t __h; } __u;
u.v = v; __u.__v = __v;
return u.h; return __u.__h;
} }
}; };
template<typename T> struct __OctaScalarHash<T, 2> { template<typename _T> struct __OctaScalarHash<_T, 2> {
typedef T ArgType; typedef _T ArgType;
typedef size_t ResultType; typedef size_t ResultType;
size_t operator()(T v) const { size_t operator()(_T __v) const {
union { T v; struct { size_t h1, h2; }; } u; union { _T __v; struct { size_t __h1, __h2; }; } __u;
u.v = v; __u.__v = __v;
return __octa_mem_hash((const void *)&u, sizeof(u)); return __octa_mem_hash((const void *)&__u, sizeof(__u));
} }
}; };
template<typename T> struct __OctaScalarHash<T, 3> { template<typename _T> struct __OctaScalarHash<_T, 3> {
typedef T ArgType; typedef _T ArgType;
typedef size_t ResultType; typedef size_t ResultType;
size_t operator()(T v) const { size_t operator()(_T __v) const {
union { T v; struct { size_t h1, h2, h3; }; } u; union { _T __v; struct { size_t __h1, __h2, __h3; }; } __u;
u.v = v; __u.__v = __v;
return __octa_mem_hash((const void *)&u, sizeof(u)); return __octa_mem_hash((const void *)&__u, sizeof(__u));
} }
}; };
template<typename T> struct __OctaScalarHash<T, 4> { template<typename _T> struct __OctaScalarHash<_T, 4> {
typedef T ArgType; typedef _T ArgType;
typedef size_t ResultType; typedef size_t ResultType;
size_t operator()(T v) const { size_t operator()(_T __v) const {
union { T v; struct { size_t h1, h2, h3, h4; }; } u; union { _T __v; struct { size_t __h1, __h2, __h3, __h4; }; } __u;
u.v = v; __u.__v = __v;
return __octa_mem_hash((const void *)&u, sizeof(u)); return __octa_mem_hash((const void *)&__u, sizeof(__u));
} }
}; };
@ -189,146 +191,146 @@ namespace octa {
template<> struct Hash<ullong>: __OctaScalarHash<ullong> {}; template<> struct Hash<ullong>: __OctaScalarHash<ullong> {};
template<> struct Hash<float>: __OctaScalarHash<float> { template<> struct Hash<float>: __OctaScalarHash<float> {
size_t operator()(float v) const { size_t operator()(float __v) const {
if (v == 0) return 0; if (__v == 0) return 0;
return __OctaScalarHash<float>::operator()(v); return __OctaScalarHash<float>::operator()(__v);
} }
}; };
template<> struct Hash<double>: __OctaScalarHash<double> { template<> struct Hash<double>: __OctaScalarHash<double> {
size_t operator()(double v) const { size_t operator()(double __v) const {
if (v == 0) return 0; if (__v == 0) return 0;
return __OctaScalarHash<double>::operator()(v); return __OctaScalarHash<double>::operator()(__v);
} }
}; };
template<> struct Hash<ldouble>: __OctaScalarHash<ldouble> { template<> struct Hash<ldouble>: __OctaScalarHash<ldouble> {
size_t operator()(ldouble v) const { size_t operator()(ldouble __v) const {
if (v == 0) return 0; if (__v == 0) return 0;
#ifdef __i386__ #ifdef __i386__
union { ldouble v; struct { size_t h1, h2, h3, h4; }; } u; union { ldouble __v; struct { size_t __h1, __h2, __h3, __h4; }; } __u;
u.h1 = u.h2 = u.h3 = u.h4 = 0; __u.__h1 = __u.__h2 = __u.__h3 = __u.__h4 = 0;
u.v = v; __u.__v = __v;
return (u.h1 ^ u.h2 ^ u.h3 ^ u.h4); return (__u.__h1 ^ __u.__h2 ^ __u.__h3 ^ __u.__h4);
#else #else
#ifdef __x86_64__ #ifdef __x86_64__
union { ldouble v; struct { size_t h1, h2; }; } u; union { ldouble __v; struct { size_t __h1, __h2; }; } __u;
u.h1 = u.h2 = 0; __u.__h1 = __u.__h2 = 0;
u.v = v; __u.__v = __v;
return (u.h1 ^ u.h2); return (__u.__h1 ^ __u.__h2);
#else #else
return __OctaScalarHash<ldouble>::operator()(v); return __OctaScalarHash<ldouble>::operator()(__v);
#endif #endif
#endif #endif
} }
}; };
template<typename T> struct Hash<T *> { template<typename _T> struct Hash<_T *> {
typedef T *ArgType; typedef _T *ArgType;
typedef size_t ResultType; typedef size_t ResultType;
size_t operator()(T *v) const { size_t operator()(_T *__v) const {
union { T *v; size_t h; } u; union { _T *__v; size_t __h; } __u;
u.v = v; __u.__v = __v;
return __octa_mem_hash((const void *)&u, sizeof(u)); return __octa_mem_hash((const void *)&__u, sizeof(__u));
} }
}; };
/* reference wrapper */ /* reference wrapper */
template<typename T> template<typename _T>
struct ReferenceWrapper { struct ReferenceWrapper {
typedef T type; typedef _T type;
ReferenceWrapper(T &v): p_ptr(address_of(v)) {} ReferenceWrapper(_T &__v): __ptr(address_of(__v)) {}
ReferenceWrapper(const ReferenceWrapper &) = default; ReferenceWrapper(const ReferenceWrapper &) = default;
ReferenceWrapper(T &&) = delete; ReferenceWrapper(_T &&) = delete;
ReferenceWrapper &operator=(const ReferenceWrapper &) = default; ReferenceWrapper &operator=(const ReferenceWrapper &) = default;
operator T &() const { return *p_ptr; } operator _T &() const { return *__ptr; }
T &get() const { return *p_ptr; } _T &get() const { return *__ptr; }
private: private:
T *p_ptr; _T *__ptr;
}; };
template<typename T> template<typename _T>
ReferenceWrapper<T> ref(T &v) { ReferenceWrapper<_T> ref(_T &__v) {
return ReferenceWrapper<T>(v); return ReferenceWrapper<_T>(__v);
} }
template<typename T> template<typename _T>
ReferenceWrapper<T> ref(ReferenceWrapper<T> v) { ReferenceWrapper<_T> ref(ReferenceWrapper<_T> __v) {
return ReferenceWrapper<T>(v); return ReferenceWrapper<_T>(__v);
} }
template<typename T> void ref(const T &&) = delete; template<typename _T> void ref(const _T &&) = delete;
template<typename T> template<typename _T>
ReferenceWrapper<const T> cref(const T &v) { ReferenceWrapper<const _T> cref(const _T &__v) {
return ReferenceWrapper<T>(v); return ReferenceWrapper<_T>(__v);
} }
template<typename T> template<typename _T>
ReferenceWrapper<const T> cref(ReferenceWrapper<T> v) { ReferenceWrapper<const _T> cref(ReferenceWrapper<_T> __v) {
return ReferenceWrapper<T>(v); return ReferenceWrapper<_T>(__v);
} }
template<typename T> void cref(const T &&) = delete; template<typename _T> void cref(const _T &&) = delete;
/* mem_fn */ /* mem_fn */
template<typename, typename> struct __OctaMemTypes; template<typename, typename> struct __OctaMemTypes;
template<typename T, typename R, typename ...A> template<typename _T, typename _R, typename ..._A>
struct __OctaMemTypes<T, R(A...)> { struct __OctaMemTypes<_T, _R(_A...)> {
typedef R ResultType; typedef _R ResultType;
typedef T ArgType; typedef _T ArgType;
}; };
template<typename T, typename R, typename A> template<typename _T, typename _R, typename _A>
struct __OctaMemTypes<T, R(A)> { struct __OctaMemTypes<_T, _R(_A)> {
typedef R ResultType; typedef _R ResultType;
typedef T FirstArgType; typedef _T FirstArgType;
typedef A SecondArgType; typedef _A SecondArgType;
}; };
template<typename T, typename R, typename ...A> template<typename _T, typename _R, typename ..._A>
struct __OctaMemTypes<T, R(A...) const> { struct __OctaMemTypes<_T, _R(_A...) const> {
typedef R ResultType; typedef _R ResultType;
typedef const T ArgType; typedef const _T ArgType;
}; };
template<typename T, typename R, typename A> template<typename _T, typename _R, typename _A>
struct __OctaMemTypes<T, R(A) const> { struct __OctaMemTypes<_T, _R(_A) const> {
typedef R ResultType; typedef _R ResultType;
typedef const T FirstArgType; typedef const _T FirstArgType;
typedef A SecondArgType; typedef _A SecondArgType;
}; };
template<typename R, typename T> template<typename _R, typename _T>
class __OctaMemFn: __OctaMemTypes<T, R> { class __OctaMemFn: __OctaMemTypes<_T, _R> {
R T::*p_ptr; _R _T::*__ptr;
public: public:
__OctaMemFn(R T::*ptr): p_ptr(ptr) {} __OctaMemFn(_R _T::*__ptr): __ptr(__ptr) {}
template<typename... A> template<typename... _A>
auto operator()(T &obj, A &&...args) -> auto operator()(_T &__obj, _A &&...__args) ->
decltype(((obj).*(p_ptr))(forward<A>(args)...)) { decltype(((__obj).*(__ptr))(forward<_A>(__args)...)) {
return ((obj).*(p_ptr))(forward<A>(args)...); return ((__obj).*(__ptr))(forward<_A>(__args)...);
} }
template<typename... A> template<typename... _A>
auto operator()(const T &obj, A &&...args) -> auto operator()(const _T &__obj, _A &&...__args) ->
decltype(((obj).*(p_ptr))(forward<A>(args)...)) const { decltype(((__obj).*(__ptr))(forward<_A>(__args)...)) const {
return ((obj).*(p_ptr))(forward<A>(args)...); return ((__obj).*(__ptr))(forward<_A>(__args)...);
} }
template<typename... A> template<typename... _A>
auto operator()(T *obj, A &&...args) -> auto operator()(_T *__obj, _A &&...__args) ->
decltype(((obj)->*(p_ptr))(forward<A>(args)...)) { decltype(((__obj)->*(__ptr))(forward<_A>(__args)...)) {
return ((obj)->*(p_ptr))(forward<A>(args)...); return ((__obj)->*(__ptr))(forward<_A>(__args)...);
} }
template<typename... A> template<typename... _A>
auto operator()(const T *obj, A &&...args) -> auto operator()(const _T *__obj, _A &&...__args) ->
decltype(((obj)->*(p_ptr))(forward<A>(args)...)) const { decltype(((__obj)->*(__ptr))(forward<_A>(__args)...)) const {
return ((obj)->*(p_ptr))(forward<A>(args)...); return ((__obj)->*(__ptr))(forward<_A>(__args)...);
} }
}; };
template<typename R, typename T> template<typename _R, typename _T>
__OctaMemFn<R, T> mem_fn(R T:: *ptr) { __OctaMemFn<_R, _T> mem_fn(_R _T:: *__ptr) {
return __OctaMemFn<R, T>(ptr); return __OctaMemFn<_R, _T>(__ptr);
} }
/* function impl /* function impl
@ -338,296 +340,303 @@ namespace octa {
template<typename> struct Function; template<typename> struct Function;
struct __OctaFunctorData { struct __OctaFunctorData {
void *p1, *p2; void *__p1, *__p2;
}; };
template<typename T> template<typename _T>
struct __OctaFunctorInPlace { struct __OctaFunctorInPlace {
static constexpr bool value = sizeof(T) <= sizeof(__OctaFunctorData) static constexpr bool value = sizeof(_T) <= sizeof(__OctaFunctorData)
&& (alignof(__OctaFunctorData) % alignof(T)) == 0 && (alignof(__OctaFunctorData) % alignof(_T)) == 0
&& octa::IsMoveConstructible<T>::value; && octa::IsMoveConstructible<_T>::value;
}; };
template<typename T, typename E = void> template<typename _T, typename _E = void>
struct __OctaFunctorDataManager { struct __OctaFunctorDataManager {
template<typename R, typename ...A> template<typename _R, typename ..._A>
static R call(const __OctaFunctorData &s, A ...args) { static _R __call(const __OctaFunctorData &__s, _A ...__args) {
return ((T &)s)(forward<A>(args)...); return ((_T &)__s)(octa::forward<_A>(__args)...);
} }
static void store_f(__OctaFunctorData &s, T v) { static void __store_f(__OctaFunctorData &__s, _T __v) {
new (&get_ref(s)) T(forward<T>(v)); new (&__get_ref(__s)) _T(octa::forward<_T>(__v));
} }
static void move_f(__OctaFunctorData &lhs, __OctaFunctorData &&rhs) { static void __move_f(__OctaFunctorData &__lhs, __OctaFunctorData &&__rhs) {
new (&get_ref(lhs)) T(move(get_ref(rhs))); new (&__get_ref(__lhs)) _T(octa::move(__get_ref(__rhs)));
} }
static void destroy_f(__OctaFunctorData &s) { static void __destroy_f(__OctaFunctorData &__s) {
get_ref(s).~T(); __get_ref(__s).~_T();
} }
static T &get_ref(const __OctaFunctorData &s) { static _T &__get_ref(const __OctaFunctorData &__s) {
return (T &)s; return (_T &)__s;
} }
}; };
template<typename T> template<typename _T>
struct __OctaFunctorDataManager<T, EnableIf<!__OctaFunctorInPlace<T>::value>> { struct __OctaFunctorDataManager<_T, EnableIf<!__OctaFunctorInPlace<_T>::value>> {
template<typename R, typename ...A> template<typename _R, typename ..._A>
static R call(const __OctaFunctorData &s, A ...args) { static _R __call(const __OctaFunctorData &__s, _A ...__args) {
return (*(T *&)s)(forward<A>(args)...); return (*(_T *&)__s)(octa::forward<_A>(__args)...);
} }
static void store_f(__OctaFunctorData &s, T v) { static void __store_f(__OctaFunctorData &__s, _T __v) {
new (&get_ptr_ref(s)) T *(new T(forward<T>(v))); new (&__get_ptr_ref(__s)) _T *(new _T(octa::forward<_T>(__v)));
} }
static void move_f(__OctaFunctorData &lhs, __OctaFunctorData &&rhs) { static void __move_f(__OctaFunctorData &__lhs, __OctaFunctorData &&__rhs) {
new (&get_ptr_ref(lhs)) T *(get_ptr_ref(rhs)); new (&__get_ptr_ref(__lhs)) _T *(__get_ptr_ref(__rhs));
get_ptr_ref(rhs) = nullptr; __get_ptr_ref(__rhs) = nullptr;
} }
static void destroy_f(__OctaFunctorData &s) { static void __destroy_f(__OctaFunctorData &__s) {
T *&ptr = get_ptr_ref(s); _T *&__ptr = __get_ptr_ref(__s);
if (!ptr) return; if (!__ptr) return;
delete ptr; delete __ptr;
ptr = nullptr; __ptr = nullptr;
} }
static T &get_ref(const __OctaFunctorData &s) { static _T &__get_ref(const __OctaFunctorData &__s) {
return *get_ptr_ref(s); return *__get_ptr_ref(__s);
} }
static T *&get_ptr_ref(__OctaFunctorData &s) { static _T *&__get_ptr_ref(__OctaFunctorData &__s) {
return (T *&)s; return (_T *&)__s;
} }
static T *&get_ptr_ref(const __OctaFunctorData &s) { static _T *&__get_ptr_ref(const __OctaFunctorData &__s) {
return (T *&)s; return (_T *&)__s;
} }
}; };
struct __OctaFunctionManager; struct __OctaFunctionManager;
struct __OctaFmStorage { struct __OctaFmStorage {
__OctaFunctorData data; __OctaFunctorData __data;
const __OctaFunctionManager *manager; const __OctaFunctionManager *__manager;
}; };
template<typename T> template<typename _T>
static const __OctaFunctionManager &__octa_get_default_fm(); static const __OctaFunctionManager &__octa_get_default_fm();
struct __OctaFunctionManager { struct __OctaFunctionManager {
template<typename T> template<typename _T>
inline static const __OctaFunctionManager create_default_manager() { inline static const __OctaFunctionManager __create_default_manager() {
return __OctaFunctionManager { return __OctaFunctionManager {
&t_call_move_and_destroy<T>, &__call_move_and_destroy<_T>,
&t_call_copy<T>, &__call_copy<_T>,
&t_call_destroy<T> &__call_destroy<_T>
}; };
} }
void (* const call_move_and_destroy)(__OctaFmStorage &lhs, void (* const __call_move_and_destroyf)(__OctaFmStorage &__lhs,
__OctaFmStorage &&rhs); __OctaFmStorage &&__rhs);
void (* const call_copy)(__OctaFmStorage &lhs, void (* const __call_copyf)(__OctaFmStorage &__lhs,
const __OctaFmStorage &rhs); const __OctaFmStorage &__rhs);
void (* const call_destroy)(__OctaFmStorage &s); void (* const __call_destroyf)(__OctaFmStorage &__s);
template<typename T> template<typename _T>
static void t_call_move_and_destroy(__OctaFmStorage &lhs, static void __call_move_and_destroy(__OctaFmStorage &__lhs,
__OctaFmStorage &&rhs) { __OctaFmStorage &&__rhs) {
typedef __OctaFunctorDataManager<T> spec; typedef __OctaFunctorDataManager<_T> _spec;
spec::move_f(lhs.data, move(rhs.data)); _spec::__move_f(__lhs.__data, octa::move(__rhs.__data));
spec::destroy_f(rhs.data); _spec::__destroy_f(__rhs.__data);
lhs.manager = &__octa_get_default_fm<T>(); __lhs.__manager = &__octa_get_default_fm<_T>();
} }
template<typename T> template<typename _T>
static void t_call_copy(__OctaFmStorage &lhs, static void __call_copy(__OctaFmStorage &__lhs,
const __OctaFmStorage &rhs) { const __OctaFmStorage &__rhs) {
typedef __OctaFunctorDataManager<T> spec; typedef __OctaFunctorDataManager<_T> _spec;
lhs.manager = &__octa_get_default_fm<T>(); __lhs.__manager = &__octa_get_default_fm<_T>();
spec::store_f(lhs.data, spec::get_ref(rhs.data)); _spec::__store_f(__lhs.__data, _spec::__get_ref(__rhs.__data));
} }
template<typename T> template<typename _T>
static void t_call_destroy(__OctaFmStorage &s) { static void __call_destroy(__OctaFmStorage &__s) {
typedef __OctaFunctorDataManager<T> spec; typedef __OctaFunctorDataManager<_T> _spec;
spec::destroy_f(s.data); _spec::__destroy_f(__s.__data);
} }
}; };
template<typename T> template<typename _T>
inline static const __OctaFunctionManager &__octa_get_default_fm() { inline static const __OctaFunctionManager &__octa_get_default_fm() {
static const __OctaFunctionManager def_manager static const __OctaFunctionManager __def_manager
= __OctaFunctionManager::create_default_manager<T>(); = __OctaFunctionManager::__create_default_manager<_T>();
return def_manager; return __def_manager;
} }
template<typename R, typename...> template<typename _R, typename...>
struct __OctaFunction { struct __OctaFunction {
typedef R ResultType; typedef _R ResultType;
}; };
template<typename R, typename T> template<typename _R, typename _T>
struct __OctaFunction<R, T> { struct __OctaFunction<_R, _T> {
typedef R ResultType; typedef _R ResultType;
typedef T ArgType; typedef _T ArgType;
}; };
template<typename R, typename T, typename U> template<typename _R, typename _T, typename _U>
struct __OctaFunction<R, T, U> { struct __OctaFunction<_R, _T, _U> {
typedef R ResultType; typedef _R ResultType;
typedef T FirstArgType; typedef _T FirstArgType;
typedef U SecondArgType; typedef _U SecondArgType;
}; };
template<typename, typename> template<typename, typename>
struct IsValidFunctor { struct __OctaIsValidFunctor {
static constexpr bool value = false; static constexpr bool value = false;
}; };
template<typename R, typename ...A> template<typename _R, typename ..._A>
struct IsValidFunctor<Function<R(A...)>, R(A...)> { struct __OctaIsValidFunctor<Function<_R(_A...)>, _R(_A...)> {
static constexpr bool value = false; static constexpr bool value = false;
}; };
struct __OctaEmpty { struct __OctaEmpty {
}; };
template<typename T> template<typename _T>
T func_to_functor(T &&f) { _T __octa_func_to_functor(_T &&__f) {
return forward<T>(f); return octa::forward<_T>(__f);
} }
template<typename RR, typename T, typename ...AA> template<typename _RR, typename _T, typename ..._AA>
auto func_to_functor(RR (T::*f)(AA...)) -> decltype(mem_fn(f)) { auto __octa_func_to_functor(_RR (_T::*__f)(_AA...))
return mem_fn(f); -> decltype(mem_fn(__f)) {
return mem_fn(__f);
} }
template<typename RR, typename T, typename ...AA> template<typename _RR, typename _T, typename ..._AA>
auto func_to_functor(RR (T::*f)(AA...) const) -> decltype(mem_fn(f)) { auto __octa_func_to_functor(_RR (_T::*__f)(_AA...) const)
return mem_fn(f); -> decltype(mem_fn(__f)) {
return mem_fn(__f);
} }
template<typename T, typename R, typename ...A> template<typename _T, typename _R, typename ..._A>
struct IsValidFunctor<T, R(A...)> { struct __OctaIsValidFunctor<_T, _R(_A...)> {
template<typename U> template<typename _U>
static decltype(func_to_functor(declval<U>())(declval<A>()...)) __octa_test(U *); static decltype(__octa_func_to_functor(octa::declval<_U>())
(octa::declval<_A>()...)) __test(_U *);
template<typename> template<typename>
static __OctaEmpty __octa_test(...); static __OctaEmpty __test(...);
static constexpr bool value = IsConvertible< static constexpr bool value = octa::IsConvertible<
decltype(__octa_test<T>(nullptr)), R decltype(__test<_T>(nullptr)), _R
>::value; >::value;
}; };
template<typename R, typename ...A> template<typename _R, typename ..._A>
struct Function<R(A...)>: __OctaFunction<R, A...> { struct Function<_R(_A...)>: __OctaFunction<_R, _A...> {
Function( ) { initialize_empty(); } Function( ) { __init_empty(); }
Function(nullptr_t) { initialize_empty(); } Function(nullptr_t) { __init_empty(); }
Function(Function &&f) { Function(Function &&__f) {
initialize_empty(); __init_empty();
swap(f); swap(__f);
} }
Function(const Function &f): p_call(f.p_call) { Function(const Function &__f): __call(__f.__call) {
f.p_stor.manager->call_copy(p_stor, f.p_stor); __f.__stor.__manager->__call_copyf(__stor, __f.__stor);
} }
template<typename T> template<typename _T>
Function(T f, EnableIf<IsValidFunctor<T, R(A...)>::value, __OctaEmpty> Function(_T __f, EnableIf<__OctaIsValidFunctor<_T, _R(_A...)>::value, __OctaEmpty>
= __OctaEmpty()) { = __OctaEmpty()) {
if (func_is_null(f)) { if (__func_is_null(__f)) {
initialize_empty(); __init_empty();
return; return;
} }
initialize(func_to_functor(forward<T>(f))); __initialize(__octa_func_to_functor(octa::forward<_T>(__f)));
} }
~Function() { ~Function() {
p_stor.manager->call_destroy(p_stor); __stor.__manager->__call_destroyf(__stor);
} }
Function &operator=(Function &&f) { Function &operator=(Function &&__f) {
p_stor.manager->call_destroy(p_stor); __stor.__manager->__call_destroyf(__stor);
swap(f); swap(__f);
return *this; return *this;
} }
Function &operator=(const Function &f) { Function &operator=(const Function &__f) {
p_stor.manager->call_destroy(p_stor); __stor.__manager->__call_destroyf(__stor);
f.p_stor.manager->call_copy(p_stor, f.p_stor); __f.__stor.__manager->__call_copyf(__stor, __f.__stor);
return *this; return *this;
}; };
R operator()(A ...args) const { _R operator()(_A ...__args) const {
return p_call(p_stor.data, forward<A>(args)...); return __call(__stor.__data, octa::forward<_A>(__args)...);
} }
template<typename F> void assign(F &&f) { template<typename _F> void assign(_F &&__f) {
Function(forward<F>(f)).swap(*this); Function(octa::forward<_F>(__f)).swap(*this);
} }
void swap(Function &f) { void swap(Function &__f) {
__OctaFmStorage tmp; __OctaFmStorage __tmp;
f.p_stor.manager->call_move_and_destroy(tmp, move(f.p_stor)); __f.__stor.__manager->__call_move_and_destroyf(__tmp,
p_stor.manager->call_move_and_destroy(f.p_stor, move(p_stor)); octa::move(__f.__stor));
tmp.manager->call_move_and_destroy(p_stor, move(tmp)); __stor.__manager->__call_move_and_destroyf(__f.__stor,
octa::swap(p_call, f.p_call); octa::move(__stor));
__tmp.__manager->__call_move_and_destroyf(__stor,
octa::move(__tmp));
octa::swap(__call, __f.__call);
} }
operator bool() const { return p_call != nullptr; } operator bool() const { return __call != nullptr; }
private: private:
__OctaFmStorage p_stor; __OctaFmStorage __stor;
R (*p_call)(const __OctaFunctorData &, A...); _R (*__call)(const __OctaFunctorData &, _A...);
template<typename T> template<typename _T>
void initialize(T f) { void __initialize(_T __f) {
p_call = &__OctaFunctorDataManager<T>::template call<R, A...>; __call = &__OctaFunctorDataManager<_T>::template __call<_R, _A...>;
p_stor.manager = &__octa_get_default_fm<T>(); __stor.__manager = &__octa_get_default_fm<_T>();
__OctaFunctorDataManager<T>::store_f(p_stor.data, forward<T>(f)); __OctaFunctorDataManager<_T>::__store_f(__stor.__data,
octa::forward<_T>(__f));
} }
void initialize_empty() { void __init_empty() {
typedef R(*emptyf)(A...); typedef _R(*__emptyf)(_A...);
p_call = nullptr; __call = nullptr;
p_stor.manager = &__octa_get_default_fm<emptyf>(); __stor.__manager = &__octa_get_default_fm<__emptyf>();
__OctaFunctorDataManager<emptyf>::store_f(p_stor.data, nullptr); __OctaFunctorDataManager<__emptyf>::__store_f(__stor.__data, nullptr);
} }
template<typename T> template<typename _T>
static bool func_is_null(const T &) { return false; } static bool __func_is_null(const _T &) { return false; }
static bool func_is_null(R (* const &fptr)(A...)) { static bool __func_is_null(_R (* const &__fptr)(_A...)) {
return fptr == nullptr; return __fptr == nullptr;
} }
template<typename RR, typename T, typename ...AA> template<typename _RR, typename _T, typename ..._AA>
static bool func_is_null(RR (T::* const &fptr)(AA...)) { static bool __func_is_null(_RR (_T::* const &__fptr)(_AA...)) {
return fptr == nullptr; return __fptr == nullptr;
} }
template<typename RR, typename T, typename ...AA> template<typename _RR, typename _T, typename ..._AA>
static bool func_is_null(RR (T::* const &fptr)(AA...) const) { static bool __func_is_null(_RR (_T::* const &__fptr)(_AA...) const) {
return fptr == nullptr; return __fptr == nullptr;
} }
}; };
template<typename T> template<typename _T>
bool operator==(nullptr_t, const Function<T> &rhs) { return !rhs; } bool operator==(nullptr_t, const Function<_T> &__rhs) { return !__rhs; }
template<typename T> template<typename _T>
bool operator==(const Function<T> &lhs, nullptr_t) { return !lhs; } bool operator==(const Function<_T> &__lhs, nullptr_t) { return !__lhs; }
template<typename T> template<typename _T>
bool operator!=(nullptr_t, const Function<T> &rhs) { return rhs; } bool operator!=(nullptr_t, const Function<_T> &__rhs) { return __rhs; }
template<typename T> template<typename _T>
bool operator!=(const Function<T> &lhs, nullptr_t) { return lhs; } bool operator!=(const Function<_T> &__lhs, nullptr_t) { return __lhs; }
} }
#endif #endif

View file

@ -13,19 +13,19 @@
#ifndef OCTA_ALLOW_CXXSTD #ifndef OCTA_ALLOW_CXXSTD
/* must be in std namespace otherwise the compiler won't know about it */ /* must be in std namespace otherwise the compiler won't know about it */
namespace std { namespace std {
template<typename T> template<typename _T>
class initializer_list { class initializer_list {
const T *p_buf; const _T *__buf;
size_t p_len; size_t __len;
initializer_list(const T *v, size_t n): p_buf(v), p_len(n) {} initializer_list(const _T *__v, size_t __n): __buf(__v), __len(__n) {}
public: public:
initializer_list(): p_buf(nullptr), p_len(0) {} initializer_list(): __buf(nullptr), __len(0) {}
size_t size() const { return p_len; } size_t size() const { return __len; }
const T *begin() const { return p_buf; } const _T *begin() const { return __buf; }
const T *end() const { return p_buf + p_len; } const _T *end() const { return __buf + __len; }
}; };
} }
#else #else
@ -33,13 +33,11 @@ namespace std {
#endif #endif
namespace octa { namespace octa {
using std::initializer_list; template<typename _T> using InitializerList = std::initializer_list<_T>;
template<typename T> using InitializerList = std::initializer_list<T>; template<typename _T>
octa::PointerRange<const _T> each(std::initializer_list<_T> __init) {
template<typename T> return octa::PointerRange<const _T>(__init.begin(), __init.end());
octa::PointerRange<const T> each(initializer_list<T> init) {
return octa::PointerRange<const T>(init.begin(), init.end());
} }
} }

View file

@ -15,312 +15,319 @@
namespace octa { namespace octa {
/* address of */ /* address of */
template<typename T> constexpr T *address_of(T &v) { template<typename _T> constexpr _T *address_of(_T &__v) {
return reinterpret_cast<T *>(&const_cast<char &> return reinterpret_cast<_T *>(&const_cast<char &>
(reinterpret_cast<const volatile char &>(v))); (reinterpret_cast<const volatile char &>(__v)));
} }
/* pointer traits */ /* pointer traits */
template<typename T> template<typename _T>
struct __OctaHasElementType { struct __OctaHasElementType {
template<typename U> template<typename _U>
static int __octa_test(...); static int __test(...);
template<typename U> template<typename _U>
static char __octa_test(typename U::ElementType * = 0); static char __test(typename _U::ElementType * = 0);
static constexpr bool value = (sizeof(__octa_test<T>(0)) == 1); static constexpr bool value = (sizeof(__test<_T>(0)) == 1);
}; };
template<typename T, bool = __OctaHasElementType<T>::value> template<typename _T, bool = __OctaHasElementType<_T>::value>
struct __OctaPtrTraitsElementType; struct __OctaPtrTraitsElementType;
template<typename T> struct __OctaPtrTraitsElementType<T, true> { template<typename _T> struct __OctaPtrTraitsElementType<_T, true> {
typedef typename T::ElementType Type; typedef typename _T::ElementType Type;
}; };
template<template<typename, typename...> class T, typename U, typename ...A> template<template<typename, typename...> class _T, typename _U, typename ..._A>
struct __OctaPtrTraitsElementType<T<U, A...>, true> { struct __OctaPtrTraitsElementType<_T<_U, _A...>, true> {
typedef typename T<U, A...>::ElementType Type; typedef typename _T<_U, _A...>::ElementType Type;
}; };
template<template<typename, typename...> class T, typename U, typename ...A> template<template<typename, typename...> class _T, typename _U, typename ..._A>
struct __OctaPtrTraitsElementType<T<U, A...>, false> { struct __OctaPtrTraitsElementType<_T<_U, _A...>, false> {
typedef U Type; typedef _U Type;
}; };
template<typename T> template<typename _T>
struct __OctaHasDiffType { struct __OctaHasDiffType {
template<typename U> template<typename _U>
static int __octa_test(...); static int __test(...);
template<typename U> template<typename _U>
static char __octa_test(typename U::DiffType * = 0); static char __test(typename _U::DiffType * = 0);
static constexpr bool value = (sizeof(__octa_test<T>(0)) == 1); static constexpr bool value = (sizeof(__test<_T>(0)) == 1);
}; };
template<typename T, bool = __OctaHasDiffType<T>::value> template<typename _T, bool = __OctaHasDiffType<_T>::value>
struct __OctaPtrTraitsDiffType { struct __OctaPtrTraitsDiffType {
typedef ptrdiff_t Type; typedef ptrdiff_t Type;
}; };
template<typename T> struct __OctaPtrTraitsDiffType<T, true> { template<typename _T> struct __OctaPtrTraitsDiffType<_T, true> {
typedef typename T::DiffType Type; typedef typename _T::DiffType Type;
}; };
template<typename T, typename U> template<typename _T, typename _U>
struct __OctaHasRebind { struct __OctaHasRebind {
template<typename V> template<typename _V>
static int __octa_test(...); static int __test(...);
template<typename V> template<typename _V>
static char __octa_test(typename V::template rebind<U> * = 0); static char __test(typename _V::template rebind<_U> * = 0);
static constexpr bool value = (sizeof(__octa_test<T>(0)) == 1); static constexpr bool value = (sizeof(__test<_T>(0)) == 1);
}; };
template<typename T, typename U, bool = __OctaHasRebind<T, U>::value> template<typename _T, typename _U, bool = __OctaHasRebind<_T, _U>::value>
struct __OctaPtrTraitsRebindType { struct __OctaPtrTraitsRebindType {
typedef typename T::template rebind<U> Type; typedef typename _T::template rebind<_U> Type;
}; };
template<template<typename, typename...> class T, typename U, template<template<typename, typename...> class _T, typename _U,
typename ...A, typename V typename ..._A, typename _V
> >
struct __OctaPtrTraitsRebindType<T<U, A...>, V, true> { struct __OctaPtrTraitsRebindType<_T<_U, _A...>, _V, true> {
typedef typename T<U, A...>::template rebind<V> Type; typedef typename _T<_U, _A...>::template rebind<_V> Type;
}; };
template<template<typename, typename...> class T, typename U, template<template<typename, typename...> class _T, typename _U,
typename ...A, typename V typename ..._A, typename _V
> >
struct __OctaPtrTraitsRebindType<T<U, A...>, V, false> { struct __OctaPtrTraitsRebindType<_T<_U, _A...>, _V, false> {
typedef T<V, A...> Type; typedef _T<_V, _A...> Type;
}; };
template<typename T> template<typename _T>
struct __OctaPtrTraitsPointer { struct __OctaPtrTraitsPointer {
typedef T Type; typedef _T Type;
}; };
template<typename T> template<typename _T>
struct __OctaPtrTraitsPointer<T *> { struct __OctaPtrTraitsPointer<_T *> {
typedef T *Type; typedef _T *Type;
}; };
template<typename T> template<typename _T>
using PtrType = typename __OctaPtrTraitsPointer<T>::Type; using PtrType = typename __OctaPtrTraitsPointer<_T>::Type;
template<typename T> template<typename _T>
struct __OctaPtrTraitsElement { struct __OctaPtrTraitsElement {
typedef typename __OctaPtrTraitsElementType<T>::Type Type; typedef typename __OctaPtrTraitsElementType<_T>::Type Type;
}; };
template<typename T> template<typename _T>
struct __OctaPtrTraitsElement<T *> { struct __OctaPtrTraitsElement<_T *> {
typedef T Type; typedef _T Type;
}; };
template<typename T> template<typename _T>
using PointerElement = typename __OctaPtrTraitsElement<T>::Type; using PointerElement = typename __OctaPtrTraitsElement<_T>::Type;
template<typename T> template<typename _T>
struct __OctaPtrTraitsDifference { struct __OctaPtrTraitsDifference {
typedef typename __OctaPtrTraitsDiffType<T>::Type Type; typedef typename __OctaPtrTraitsDiffType<_T>::Type Type;
}; };
template<typename T> template<typename _T>
struct __OctaPtrTraitsDifference<T *> { struct __OctaPtrTraitsDifference<_T *> {
typedef ptrdiff_t DiffType; typedef ptrdiff_t DiffType;
}; };
template<typename T> template<typename _T>
using PointerDifference = typename __OctaPtrTraitsDifference<T>::Type; using PointerDifference = typename __OctaPtrTraitsDifference<_T>::Type;
template<typename T, typename U> template<typename _T, typename _U>
struct __OctaPtrTraitsRebind { struct __OctaPtrTraitsRebind {
using type = typename __OctaPtrTraitsRebindType<T, U>::Type; using type = typename __OctaPtrTraitsRebindType<_T, _U>::Type;
}; };
template<typename T, typename U> template<typename _T, typename _U>
struct __OctaPtrTraitsRebind<T *, U> { struct __OctaPtrTraitsRebind<_T *, _U> {
using type = U *; using type = _U *;
}; };
template<typename T, typename U> template<typename _T, typename _U>
using PointerRebind = typename __OctaPtrTraitsRebind<T, U>::Type; using PointerRebind = typename __OctaPtrTraitsRebind<_T, _U>::Type;
struct __OctaPtrTraitsNat {}; struct __OctaPtrTraitsNat {};
template<typename T> template<typename _T>
struct __OctaPtrTraitsPointerTo { struct __OctaPtrTraitsPointerTo {
static T pointer_to(Conditional<IsVoid<PointerElement<T>>::value, static _T pointer_to(octa::Conditional<
__OctaPtrTraitsNat, PointerElement<T> octa::IsVoid<PointerElement<_T>>::value,
> &r) { __OctaPtrTraitsNat, PointerElement<_T>
return T::pointer_to(r); > &__r) {
return _T::pointer_to(__r);
} }
}; };
template<typename T> template<typename _T>
struct __OctaPtrTraitsPointerTo<T *> { struct __OctaPtrTraitsPointerTo<_T *> {
static T pointer_to(Conditional<IsVoid<T>::value, __OctaPtrTraitsNat, T static _T pointer_to(octa::Conditional<
> &r) { octa::IsVoid<_T>::value, __OctaPtrTraitsNat, _T
return octa::address_of(r); > &__r) {
return octa::address_of(__r);
} }
}; };
template<typename T> template<typename _T>
static T pointer_to(Conditional<IsVoid<PointerElement<T>>::value, static _T pointer_to(octa::Conditional<
__OctaPtrTraitsNat, PointerElement<T> octa::IsVoid<PointerElement<_T>>::value,
> &r) { __OctaPtrTraitsNat, PointerElement<_T>
return __OctaPtrTraitsPointerTo<T>::pointer_to(r); > &__r) {
return __OctaPtrTraitsPointerTo<_T>::pointer_to(__r);
} }
/* default deleter */ /* default deleter */
template<typename T> template<typename _T>
struct DefaultDelete { struct DefaultDelete {
constexpr DefaultDelete() = default; constexpr DefaultDelete() = default;
template<typename U> DefaultDelete(const DefaultDelete<U> &) {}; template<typename _U> DefaultDelete(const DefaultDelete<_U> &) {};
void operator()(T *p) const { void operator()(_T *__p) const {
delete p; delete __p;
} }
}; };
template<typename T> template<typename _T>
struct DefaultDelete<T[]> { struct DefaultDelete<_T[]> {
constexpr DefaultDelete() = default; constexpr DefaultDelete() = default;
template<typename U> DefaultDelete(const DefaultDelete<U[]> &) {}; template<typename _U> DefaultDelete(const DefaultDelete<_U[]> &) {};
void operator()(T *p) const { void operator()(_T *__p) const {
delete[] p; delete[] __p;
} }
template<typename U> void operator()(U *) const = delete; template<typename _U> void operator()(_U *) const = delete;
}; };
/* box */ /* box */
template<typename T, typename U, bool = IsEmpty<U>::value> template<typename _T, typename _U, bool = octa::IsEmpty<_U>::value>
struct __OctaBoxPair; struct __OctaBoxPair;
template<typename T, typename U> template<typename _T, typename _U>
struct __OctaBoxPair<T, U, false> { /* non-empty deleter */ struct __OctaBoxPair<_T, _U, false> { /* non-empty deleter */
T *i_ptr; _T *__ptr;
private: private:
U p_del; _U __del;
public: public:
template<typename D> template<typename _D>
__OctaBoxPair(T *ptr, D &&dltr): i_ptr(ptr), p_del(forward<D>(dltr)) {} __OctaBoxPair(_T *__ptr, _D &&__dltr): __ptr(__ptr),
__del(octa::forward<_D>(__dltr)) {}
U &get_deleter() { return p_del; } _U &get_deleter() { return __del; }
const U &get_deleter() const { return p_del; } const _U &get_deleter() const { return __del; }
void swap(__OctaBoxPair &v) { void swap(__OctaBoxPair &__v) {
octa::swap(i_ptr, v.i_ptr); octa::swap(__ptr, __v.__ptr);
octa::swap(p_del, v.p_del); octa::swap(__del, __v.__del);
} }
}; };
template<typename T, typename U> template<typename _T, typename _U>
struct __OctaBoxPair<T, U, true>: U { /* empty deleter */ struct __OctaBoxPair<_T, _U, true>: _U { /* empty deleter */
T *i_ptr; _T *__ptr;
template<typename D> template<typename _D>
__OctaBoxPair(T *ptr, D &&dltr): U(forward<D>(dltr)), i_ptr(ptr) {} __OctaBoxPair(_T *__ptr, _D &&__dltr):
_U(octa::forward<_D>(__dltr)), __ptr(__ptr) {}
U &get_deleter() { return *this; } _U &get_deleter() { return *this; }
const U &get_deleter() const { return *this; } const _U &get_deleter() const { return *this; }
void swap(__OctaBoxPair &v) { void swap(__OctaBoxPair &__v) {
octa::swap(i_ptr, v.i_ptr); octa::swap(__ptr, __v.__ptr);
} }
}; };
template<typename T> template<typename _T>
static int __octa_ptr_test(...); static int __octa_ptr_test(...);
template<typename T> template<typename _T>
static char __octa_ptr_test(typename T::PtrType * = 0); static char __octa_ptr_test(typename _T::PtrType * = 0);
template<typename T> struct __OctaHasPtr: IntegralConstant<bool, template<typename _T> struct __OctaHasPtr: octa::IntegralConstant<bool,
(sizeof(__octa_ptr_test<T>(0)) == 1) (sizeof(__octa_ptr_test<_T>(0)) == 1)
> {}; > {};
template<typename T, typename D, bool = __OctaHasPtr<D>::value> template<typename _T, typename _D, bool = __OctaHasPtr<_D>::value>
struct __OctaPtrTypeBase { struct __OctaPtrTypeBase {
typedef typename D::PtrType Type; typedef typename _D::PtrType Type;
}; };
template<typename T, typename D> struct __OctaPtrTypeBase<T, D, false> { template<typename _T, typename _D> struct __OctaPtrTypeBase<_T, _D, false> {
typedef T *Type; typedef _T *Type;
}; };
template<typename T, typename D> struct __OctaPtrType { template<typename _T, typename _D> struct __OctaPtrType {
typedef typename __OctaPtrTypeBase<T, RemoveReference<D>>::Type Type; typedef typename __OctaPtrTypeBase<_T, octa::RemoveReference<_D>>::Type Type;
}; };
template<typename T, typename D = DefaultDelete<T>> template<typename _T, typename _D = DefaultDelete<_T>>
struct Box { struct Box {
typedef T ElementType; typedef _T ElementType;
typedef D DeleterType; typedef _D DeleterType;
typedef typename __OctaPtrType<T, D>::Type PtrType; typedef typename __OctaPtrType<_T, _D>::Type PtrType;
private: private:
struct __OctaNat { int x; }; struct __OctaNat { int __x; };
typedef RemoveReference<D> &D_ref; typedef RemoveReference<_D> &_D_ref;
typedef const RemoveReference<D> &D_cref; typedef const RemoveReference<_D> &_D_cref;
public: public:
constexpr Box(): p_stor(nullptr, D()) { constexpr Box(): __stor(nullptr, _D()) {
static_assert(!IsPointer<D>::value, static_assert(!octa::IsPointer<_D>::value,
"Box constructed with null fptr deleter"); "Box constructed with null fptr deleter");
} }
constexpr Box(nullptr_t): p_stor(nullptr, D()) { constexpr Box(nullptr_t): __stor(nullptr, _D()) {
static_assert(!IsPointer<D>::value, static_assert(!octa::IsPointer<_D>::value,
"Box constructed with null fptr deleter"); "Box constructed with null fptr deleter");
} }
explicit Box(PtrType p): p_stor(p, D()) { explicit Box(PtrType __p): __stor(__p, _D()) {
static_assert(!IsPointer<D>::value, static_assert(!octa::IsPointer<_D>::value,
"Box constructed with null fptr deleter"); "Box constructed with null fptr deleter");
} }
Box(PtrType p, Conditional<IsReference<D>::value, Box(PtrType __p, octa::Conditional<octa::IsReference<_D>::value,
D, AddLvalueReference<const D> _D, octa::AddLvalueReference<const _D>
> d): p_stor(p, d) {} > __d): __stor(__p, __d) {}
Box(PtrType p, RemoveReference<D> &&d): p_stor(p, move(d)) { Box(PtrType __p, octa::RemoveReference<_D> &&__d):
static_assert(!IsReference<D>::value, __stor(__p, octa::move(__d)) {
static_assert(!octa::IsReference<_D>::value,
"rvalue deleter cannot be a ref"); "rvalue deleter cannot be a ref");
} }
Box(Box &&u): p_stor(u.release(), forward<D>(u.get_deleter())) {} Box(Box &&__u): __stor(__u.release(),
octa::forward<_D>(__u.get_deleter())) {}
template<typename TT, typename DD> template<typename _TT, typename _DD>
Box(Box<TT, DD> &&u, EnableIf<!IsArray<TT>::value Box(Box<_TT, _DD> &&__u, octa::EnableIf<!octa::IsArray<_TT>::value
&& IsConvertible<typename Box<TT, DD>::PtrType, PtrType>::value && octa::IsConvertible<typename Box<_TT, _DD>::PtrType, PtrType>::value
&& IsConvertible<DD, D>::value && octa::IsConvertible<_DD, _D>::value
&& (!IsReference<D>::value || IsSame<D, DD>::value) && (!octa::IsReference<_D>::value || octa::IsSame<_D, _DD>::value)
> = __OctaNat()): p_stor(u.release(), forward<DD>(u.get_deleter())) {} > = __OctaNat()): __stor(__u.release(), octa::forward<_DD>(__u.get_deleter())) {}
Box &operator=(Box &&u) { Box &operator=(Box &&__u) {
reset(u.release()); reset(__u.release());
p_stor.get_deleter() = forward<D>(u.get_deleter()); __stor.get_deleter() = octa::forward<_D>(__u.get_deleter());
return *this; return *this;
} }
template<typename TT, typename DD> template<typename _TT, typename _DD>
EnableIf<!IsArray<TT>::value EnableIf<!octa::IsArray<_TT>::value
&& IsConvertible<typename Box<TT, DD>::PtrType, PtrType>::value && octa::IsConvertible<typename Box<_TT, _DD>::PtrType, PtrType>::value
&& IsAssignable<D &, DD &&>::value, && octa::IsAssignable<_D &, _DD &&>::value,
Box & Box &
> operator=(Box<TT, DD> &&u) { > operator=(Box<_TT, _DD> &&__u) {
reset(u.release()); reset(__u.release());
p_stor.get_deleter() = forward<DD>(u.get_deleter()); __stor.get_deleter() = octa::forward<_DD>(__u.get_deleter());
return *this; return *this;
} }
@ -331,128 +338,133 @@ namespace octa {
~Box() { reset(); } ~Box() { reset(); }
AddLvalueReference<T> operator*() const { return *p_stor.i_ptr; } octa::AddLvalueReference<_T> operator*() const { return *__stor.__ptr; }
PtrType operator->() const { return p_stor.i_ptr; } PtrType operator->() const { return __stor.__ptr; }
explicit operator bool() const { explicit operator bool() const {
return p_stor.i_ptr != nullptr; return __stor.__ptr != nullptr;
} }
PtrType get() const { return p_stor.i_ptr; } PtrType get() const { return __stor.__ptr; }
D_ref get_deleter() { return p_stor.get_deleter(); } _D_ref get_deleter() { return __stor.get_deleter(); }
D_cref get_deleter() const { return p_stor.get_deleter(); } _D_cref get_deleter() const { return __stor.get_deleter(); }
PtrType release() { PtrType release() {
PtrType p = p_stor.i_ptr; PtrType __p = __stor.__ptr;
p_stor.i_ptr = nullptr; __stor.__ptr = nullptr;
return p; return __p;
} }
void reset(PtrType p = nullptr) { void reset(PtrType __p = nullptr) {
PtrType tmp = p_stor.i_ptr; PtrType __tmp = __stor.__ptr;
p_stor.i_ptr = p; __stor.__ptr = __p;
if (tmp) p_stor.get_deleter()(tmp); if (__tmp) __stor.get_deleter()(__tmp);
} }
void swap(Box &u) { void swap(Box &__u) {
p_stor.swap(u.p_stor); __stor.swap(__u.__stor);
} }
private: private:
__OctaBoxPair<T, D> p_stor; __OctaBoxPair<_T, _D> __stor;
}; };
template<typename T, typename U, bool = IsSame< template<typename _T, typename _U, bool = octa::IsSame<
RemoveCv<PointerElement<T>>, octa::RemoveCv<PointerElement<_T>>,
RemoveCv<PointerElement<U>> octa::RemoveCv<PointerElement<_U>>
>::value> struct __OctaSameOrLessCvQualifiedBase: IsConvertible<T, U> {}; >::value> struct __OctaSameOrLessCvQualifiedBase: octa::IsConvertible<_T, _U> {};
template<typename T, typename U> template<typename _T, typename _U>
struct __OctaSameOrLessCvQualifiedBase<T, U, false>: False {}; struct __OctaSameOrLessCvQualifiedBase<_T, _U, false>: octa::False {};
template<typename T, typename U, bool = IsPointer<T>::value template<typename _T, typename _U, bool = octa::IsPointer<_T>::value
|| IsSame<T, U>::value || __OctaHasElementType<T>::value || octa::IsSame<_T, _U>::value || __OctaHasElementType<_T>::value
> struct __OctaSameOrLessCvQualified: __OctaSameOrLessCvQualifiedBase<T, U> {}; > struct __OctaSameOrLessCvQualified: __OctaSameOrLessCvQualifiedBase<_T, _U> {};
template<typename T, typename U> template<typename _T, typename _U>
struct __OctaSameOrLessCvQualified<T, U, false>: False {}; struct __OctaSameOrLessCvQualified<_T, _U, false>: octa::False {};
template<typename T, typename D> template<typename _T, typename _D>
struct Box<T[], D> { struct Box<_T[], _D> {
typedef T ElementType; typedef _T ElementType;
typedef D DeleterType; typedef _D DeleterType;
typedef typename __OctaPtrType<T, D>::Type PtrType; typedef typename __OctaPtrType<_T, _D>::Type PtrType;
private: private:
struct __OctaNat { int x; }; struct __OctaNat { int __x; };
typedef RemoveReference<D> &D_ref; typedef RemoveReference<_D> &_D_ref;
typedef const RemoveReference<D> &D_cref; typedef const RemoveReference<_D> &_D_cref;
public: public:
constexpr Box(): p_stor(nullptr, D()) { constexpr Box(): __stor(nullptr, _D()) {
static_assert(!IsPointer<D>::value, static_assert(!octa::IsPointer<_D>::value,
"Box constructed with null fptr deleter"); "Box constructed with null fptr deleter");
} }
constexpr Box(nullptr_t): p_stor(nullptr, D()) { constexpr Box(nullptr_t): __stor(nullptr, _D()) {
static_assert(!IsPointer<D>::value, static_assert(!octa::IsPointer<_D>::value,
"Box constructed with null fptr deleter"); "Box constructed with null fptr deleter");
} }
template<typename U> explicit Box(U p, EnableIf< template<typename _U> explicit Box(_U __p, octa::EnableIf<
__OctaSameOrLessCvQualified<U, PtrType>::value, __OctaNat __OctaSameOrLessCvQualified<_U, PtrType>::value, __OctaNat
> = __OctaNat()): p_stor(p, D()) { > = __OctaNat()): __stor(__p, _D()) {
static_assert(!IsPointer<D>::value, static_assert(!octa::IsPointer<_D>::value,
"Box constructed with null fptr deleter"); "Box constructed with null fptr deleter");
} }
template<typename U> Box(U p, Conditional<IsReference<D>::value, template<typename _U> Box(_U __p, octa::Conditional<
D, AddLvalueReference<const D> octa::IsReference<_D>::value,
> d, EnableIf<__OctaSameOrLessCvQualified<U, PtrType>::value, __OctaNat _D, AddLvalueReference<const _D>
> = __OctaNat()): p_stor(p, d) {} > __d, octa::EnableIf<__OctaSameOrLessCvQualified<_U, PtrType>::value,
__OctaNat> = __OctaNat()): __stor(__p, __d) {}
Box(nullptr_t, Conditional<IsReference<D>::value, Box(nullptr_t, octa::Conditional<octa::IsReference<_D>::value,
D, AddLvalueReference<const D> _D, AddLvalueReference<const _D>
> d): p_stor(nullptr, d) {} > __d): __stor(nullptr, __d) {}
template<typename U> Box(U p, RemoveReference<D> &&d, EnableIf< template<typename _U> Box(_U __p, octa::RemoveReference<_D> &&__d,
__OctaSameOrLessCvQualified<U, PtrType>::value, __OctaNat octa::EnableIf<
> = __OctaNat()): p_stor(p, move(d)) { __OctaSameOrLessCvQualified<_U, PtrType>::value, __OctaNat
static_assert(!IsReference<D>::value, > = __OctaNat()): __stor(__p, octa::move(__d)) {
static_assert(!octa::IsReference<_D>::value,
"rvalue deleter cannot be a ref"); "rvalue deleter cannot be a ref");
} }
Box(nullptr_t, RemoveReference<D> &&d): p_stor(nullptr, move(d)) { Box(nullptr_t, octa::RemoveReference<_D> &&__d):
static_assert(!IsReference<D>::value, __stor(nullptr, octa::move(__d)) {
static_assert(!octa::IsReference<_D>::value,
"rvalue deleter cannot be a ref"); "rvalue deleter cannot be a ref");
} }
Box(Box &&u): p_stor(u.release(), forward<D>(u.get_deleter())) {} Box(Box &&__u): __stor(__u.release(),
octa::forward<_D>(__u.get_deleter())) {}
template<typename TT, typename DD> template<typename _TT, typename _DD>
Box(Box<TT, DD> &&u, EnableIf<IsArray<TT>::value Box(Box<_TT, _DD> &&__u, EnableIf<IsArray<_TT>::value
&& __OctaSameOrLessCvQualified<typename Box<TT, DD>::PtrType, && __OctaSameOrLessCvQualified<typename Box<_TT, _DD>::PtrType,
PtrType>::value PtrType>::value
&& IsConvertible<DD, D>::value && octa::IsConvertible<_DD, _D>::value
&& (!IsReference<D>::value || IsSame<D, DD>::value)> = __OctaNat() && (!octa::IsReference<_D>::value ||
): p_stor(u.release(), forward<DD>(u.get_deleter())) {} octa::IsSame<_D, _DD>::value)> = __OctaNat()
): __stor(__u.release(), octa::forward<_DD>(__u.get_deleter())) {}
Box &operator=(Box &&u) { Box &operator=(Box &&__u) {
reset(u.release()); reset(__u.release());
p_stor.get_deleter() = forward<D>(u.get_deleter()); __stor.get_deleter() = octa::forward<_D>(__u.get_deleter());
return *this; return *this;
} }
template<typename TT, typename DD> template<typename _TT, typename _DD>
EnableIf<IsArray<TT>::value EnableIf<octa::IsArray<_TT>::value
&& __OctaSameOrLessCvQualified<typename Box<TT, DD>::PtrType, && __OctaSameOrLessCvQualified<typename Box<_TT, _DD>::PtrType,
PtrType>::value PtrType>::value
&& IsAssignable<D &, DD &&>::value, && IsAssignable<_D &, _DD &&>::value,
Box & Box &
> operator=(Box<TT, DD> &&u) { > operator=(Box<_TT, _DD> &&__u) {
reset(u.release()); reset(__u.release());
p_stor.get_deleter() = forward<DD>(u.get_deleter()); __stor.get_deleter() = octa::forward<_DD>(__u.get_deleter());
return *this; return *this;
} }
@ -463,75 +475,75 @@ namespace octa {
~Box() { reset(); } ~Box() { reset(); }
AddLvalueReference<T> operator[](size_t idx) const { octa::AddLvalueReference<_T> operator[](size_t __idx) const {
return p_stor.i_ptr[idx]; return __stor.__ptr[__idx];
} }
explicit operator bool() const { explicit operator bool() const {
return p_stor.i_ptr != nullptr; return __stor.__ptr != nullptr;
} }
PtrType get() const { return p_stor.i_ptr; } PtrType get() const { return __stor.__ptr; }
D_ref get_deleter() { return p_stor.get_deleter(); } _D_ref get_deleter() { return __stor.get_deleter(); }
D_cref get_deleter() const { return p_stor.get_deleter(); } _D_cref get_deleter() const { return __stor.get_deleter(); }
PtrType release() { PtrType release() {
PtrType p = p_stor.i_ptr; PtrType __p = __stor.__ptr;
p_stor.i_ptr = nullptr; __stor.__ptr = nullptr;
return p; return __p;
} }
template<typename U> EnableIf< template<typename _U> EnableIf<
__OctaSameOrLessCvQualified<U, PtrType>::value, void __OctaSameOrLessCvQualified<_U, PtrType>::value, void
> reset(U p) { > reset(_U __p) {
PtrType tmp = p_stor.i_ptr; PtrType __tmp = __stor.__ptr;
p_stor.i_ptr = p; __stor.__ptr = __p;
if (tmp) p_stor.get_deleter()(tmp); if (__tmp) __stor.get_deleter()(__tmp);
} }
void reset(nullptr_t) { void reset(nullptr_t) {
PtrType tmp = p_stor.i_ptr; PtrType __tmp = __stor.__ptr;
p_stor.i_ptr = nullptr; __stor.__ptr = nullptr;
if (tmp) p_stor.get_deleter()(tmp); if (__tmp) __stor.get_deleter()(__tmp);
} }
void reset() { void reset() {
reset(nullptr); reset(nullptr);
} }
void swap(Box &u) { void swap(Box &__u) {
p_stor.swap(u.p_stor); __stor.swap(__u.__stor);
} }
private: private:
__OctaBoxPair<T, D> p_stor; __OctaBoxPair<_T, _D> __stor;
}; };
template<typename T> struct __OctaBoxIf { template<typename _T> struct __OctaBoxIf {
typedef Box<T> __OctaBox; typedef Box<_T> __OctaBox;
}; };
template<typename T> struct __OctaBoxIf<T[]> { template<typename _T> struct __OctaBoxIf<_T[]> {
typedef Box<T[]> __OctaBoxUnknownSize; typedef Box<_T[]> __OctaBoxUnknownSize;
}; };
template<typename T, size_t N> struct __OctaBoxIf<T[N]> { template<typename _T, size_t _N> struct __OctaBoxIf<_T[_N]> {
typedef void __OctaBoxKnownSize; typedef void __OctaBoxKnownSize;
}; };
template<typename T, typename ...A> template<typename _T, typename ..._A>
typename __OctaBoxIf<T>::__OctaBox make_box(A &&...args) { typename __OctaBoxIf<_T>::__OctaBox make_box(_A &&...__args) {
return Box<T>(new T(forward<A>(args)...)); return Box<_T>(new _T(octa::forward<_A>(__args)...));
} }
template<typename T> template<typename _T>
typename __OctaBoxIf<T>::__OctaBoxUnknownSize make_box(size_t n) { typename __OctaBoxIf<_T>::__OctaBoxUnknownSize make_box(size_t __n) {
return Box<T>(new RemoveExtent<T>[n]()); return Box<_T>(new octa::RemoveExtent<_T>[__n]());
} }
template<typename T, typename ...A> template<typename _T, typename ..._A>
typename __OctaBoxIf<T>::__OctaBoxKnownSize make_box(A &&...args) = delete; typename __OctaBoxIf<_T>::__OctaBoxKnownSize make_box(_A &&...__args) = delete;
/* allocator */ /* allocator */
@ -542,7 +554,7 @@ namespace octa {
typedef void *PtrType; typedef void *PtrType;
typedef const void *ConstPtrType; typedef const void *ConstPtrType;
template<typename U> using Rebind = Allocator<U>; template<typename _U> using Rebind = Allocator<_U>;
}; };
template<> struct Allocator<const void> { template<> struct Allocator<const void> {
@ -550,81 +562,81 @@ namespace octa {
typedef const void *PtrType; typedef const void *PtrType;
typedef const void *ConstPtrType; typedef const void *ConstPtrType;
template<typename U> using Rebind = Allocator<U>; template<typename _U> using Rebind = Allocator<_U>;
}; };
template<typename T> struct Allocator { template<typename _T> struct Allocator {
typedef size_t SizeType; typedef size_t SizeType;
typedef ptrdiff_t DiffType; typedef ptrdiff_t DiffType;
typedef T ValType; typedef _T ValType;
typedef T &RefType; typedef _T &RefType;
typedef const T &ConstRefType; typedef const _T &ConstRefType;
typedef T *PtrType; typedef _T *PtrType;
typedef const T *ConstPtrType; typedef const _T *ConstPtrType;
template<typename U> using Rebind = Allocator<U>; template<typename _U> using Rebind = Allocator<_U>;
PtrType address(RefType v) const { PtrType address(RefType __v) const {
return address_of(v); return address_of(__v);
}; };
ConstPtrType address(ConstRefType v) const { ConstPtrType address(ConstRefType __v) const {
return address_of(v); return address_of(__v);
}; };
SizeType max_size() const { return SizeType(~0) / sizeof(T); } SizeType max_size() const { return SizeType(~0) / sizeof(_T); }
PtrType allocate(SizeType n, Allocator<void>::ConstPtrType = nullptr) { PtrType allocate(SizeType __n, Allocator<void>::ConstPtrType = nullptr) {
return (PtrType) ::new uchar[n * sizeof(T)]; return (PtrType) ::new uchar[__n * sizeof(_T)];
} }
void deallocate(PtrType p, SizeType) { ::delete[] (uchar *) p; } void deallocate(PtrType __p, SizeType) { ::delete[] (uchar *) __p; }
template<typename U, typename ...A> template<typename _U, typename ..._A>
void construct(U *p, A &&...args) { void construct(_U *__p, _A &&...__args) {
::new((void *)p) U(forward<A>(args)...); ::new((void *)__p) _U(octa::forward<_A>(__args)...);
} }
void destroy(PtrType p) { p->~T(); } void destroy(PtrType __p) { __p->~_T(); }
}; };
template<typename T> struct Allocator<const T> { template<typename _T> struct Allocator<const _T> {
typedef size_t SizeType; typedef size_t SizeType;
typedef ptrdiff_t DiffType; typedef ptrdiff_t DiffType;
typedef const T ValType; typedef const _T ValType;
typedef const T &RefType; typedef const _T &RefType;
typedef const T &ConstRefType; typedef const _T &ConstRefType;
typedef const T *PtrType; typedef const _T *PtrType;
typedef const T *ConstPtrType; typedef const _T *ConstPtrType;
template<typename U> using Rebind = Allocator<U>; template<typename _U> using Rebind = Allocator<_U>;
ConstPtrType address(ConstRefType v) const { ConstPtrType address(ConstRefType __v) const {
return address_of(v); return address_of(__v);
}; };
SizeType max_size() const { return SizeType(~0) / sizeof(T); } SizeType max_size() const { return SizeType(~0) / sizeof(_T); }
PtrType allocate(SizeType n, Allocator<void>::ConstPtrType = nullptr) { PtrType allocate(SizeType __n, Allocator<void>::ConstPtrType = nullptr) {
return (PtrType) ::new uchar[n * sizeof(T)]; return (PtrType) ::new uchar[__n * sizeof(_T)];
} }
void deallocate(PtrType p, SizeType) { ::delete[] (uchar *) p; } void deallocate(PtrType __p, SizeType) { ::delete[] (uchar *) __p; }
template<typename U, typename ...A> template<typename _U, typename ..._A>
void construct(U *p, A &&...args) { void construct(_U *__p, _A &&...__args) {
::new((void *)p) U(forward<A>(args)...); ::new((void *)__p) _U(octa::forward<_A>(__args)...);
} }
void destroy(PtrType p) { p->~T(); } void destroy(PtrType __p) { __p->~_T(); }
}; };
template<typename T, typename U> template<typename _T, typename _U>
bool operator==(const Allocator<T> &, const Allocator<U> &) { bool operator==(const Allocator<_T> &, const Allocator<_U> &) {
return true; return true;
} }
template<typename T, typename U> template<typename _T, typename _U>
bool operator!=(const Allocator<T> &, const Allocator<U> &) { bool operator!=(const Allocator<_T> &, const Allocator<_U> &) {
return false; return false;
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -14,298 +14,298 @@
#include "octa/vector.h" #include "octa/vector.h"
namespace octa { namespace octa {
using std::initializer_list;
static constexpr size_t npos = -1; static constexpr size_t npos = -1;
template<typename T> template<typename _T>
class StringBase { class StringBase {
Vector<T> p_buf; octa::Vector<_T> __buf;
void terminate() { void __terminate() {
if (p_buf.empty() || (p_buf.back() != '\0')) p_buf.push('\0'); if (__buf.empty() || (__buf.back() != '\0')) __buf.push('\0');
} }
public: public:
typedef size_t SizeType; typedef size_t SizeType;
typedef ptrdiff_t DiffType; typedef ptrdiff_t DiffType;
typedef T ValType; typedef _T ValType;
typedef T &RefType; typedef _T &RefType;
typedef const T &ConstRefType; typedef const _T &ConstRefType;
typedef T *PtrType; typedef _T *PtrType;
typedef const T *ConstPtrType; typedef const _T *ConstPtrType;
typedef PointerRange< T> RangeType; typedef PointerRange< _T> RangeType;
typedef PointerRange<const T> ConstRangeType; typedef PointerRange<const _T> ConstRangeType;
StringBase(): p_buf(1, '\0') {} StringBase(): __buf(1, '\0') {}
StringBase(const StringBase &s): p_buf(s.p_buf) {} StringBase(const StringBase &__s): __buf(__s.__buf) {}
StringBase(StringBase &&s): p_buf(move(s.p_buf)) {} StringBase(StringBase &&__s): __buf(octa::move(__s.__buf)) {}
StringBase(const StringBase &s, size_t pos, size_t len = npos): StringBase(const StringBase &__s, size_t __pos, size_t __len = npos):
p_buf(s.p_buf.each().slice(pos, __buf(__s.__buf.each().slice(__pos,
(len == npos) ? s.p_buf.size() : (pos + len))) { (__len == npos) ? __s.__buf.size() : (__pos + __len))) {
terminate(); __terminate();
} }
/* TODO: traits for utf-16/utf-32 string lengths, for now assume char */ /* TODO: traits for utf-16/utf-32 string lengths, for now assume char */
StringBase(const T *v): p_buf(PointerRange<const T>(v, strlen(v) + 1)) {} StringBase(const _T *__v): __buf(ConstRangeType(__v, strlen(__v) + 1)) {}
template<typename R> StringBase(R range): p_buf(range) { template<typename _R> StringBase(_R __range): __buf(__range) {
terminate(); __terminate();
} }
void clear() { p_buf.clear(); } void clear() { __buf.clear(); }
StringBase<T> &operator=(const StringBase &v) { StringBase<_T> &operator=(const StringBase &__v) {
p_buf.operator=(v); __buf.operator=(__v);
return *this; return *this;
} }
StringBase<T> &operator=(StringBase &&v) { StringBase<_T> &operator=(StringBase &&__v) {
p_buf.operator=(move(v)); __buf.operator=(octa::move(__v));
return *this; return *this;
} }
StringBase<T> &operator=(const T *v) { StringBase<_T> &operator=(const _T *__v) {
p_buf = PointerRange<const T>(v, strlen(v) + 1); __buf = ConstRangeType(__v, strlen(__v) + 1);
return *this; return *this;
} }
void resize(size_t n, T v = T()) { void resize(size_t __n, _T __v = _T()) {
p_buf.pop(); __buf.pop();
p_buf.resize(n, v); __buf.resize(__n, __v);
terminate(); __terminate();
} }
void reserve(size_t n) { void reserve(size_t __n) {
p_buf.reserve(n + 1); __buf.reserve(__n + 1);
} }
T &operator[](size_t i) { return p_buf[i]; } _T &operator[](size_t __i) { return __buf[__i]; }
const T &operator[](size_t i) const { return p_buf[i]; } const _T &operator[](size_t __i) const { return __buf[__i]; }
T &at(size_t i) { return p_buf[i]; } _T &at(size_t __i) { return __buf[__i]; }
const T &at(size_t i) const { return p_buf[i]; } const _T &at(size_t __i) const { return __buf[__i]; }
T &front() { return p_buf[0]; } _T &front() { return __buf[0]; }
const T &front() const { return p_buf[0]; }; const _T &front() const { return __buf[0]; };
T &back() { return p_buf[size() - 1]; } _T &back() { return __buf[size() - 1]; }
const T &back() const { return p_buf[size() - 1]; } const _T &back() const { return __buf[size() - 1]; }
T *data() { return p_buf.data(); } _T *data() { return __buf.data(); }
const T *data() const { return p_buf.data(); } const _T *data() const { return __buf.data(); }
size_t size() const { size_t size() const {
return p_buf.size() - 1; return __buf.size() - 1;
} }
size_t capacity() const { size_t capacity() const {
return p_buf.capacity() - 1; return __buf.capacity() - 1;
} }
bool empty() const { return (size() == 0); } bool empty() const { return (size() == 0); }
void push(T v) { void push(_T __v) {
p_buf.back() = v; __buf.back() = __v;
p_buf.push('\0'); __buf.push('\0');
} }
StringBase<T> &append(const StringBase &s) { StringBase<_T> &append(const StringBase &__s) {
p_buf.pop(); __buf.pop();
p_buf.insert_range(p_buf.size(), s.p_buf.each()); __buf.insert_range(__buf.size(), __s.__buf.each());
return *this; return *this;
} }
StringBase<T> &append(const StringBase &s, size_t idx, size_t len) { StringBase<_T> &append(const StringBase &__s, size_t __idx, size_t __len) {
p_buf.pop(); __buf.pop();
p_buf.insert_range(p_buf.size(), PointerRange<T>(&s[idx], __buf.insert_range(__buf.size(), octa::PointerRange<_T>(&__s[__idx],
(len == npos) ? (s.size() - idx) : len)); (__len == npos) ? (__s.size() - __idx) : __len));
terminate(); __terminate();
return *this; return *this;
} }
StringBase<T> &append(const T *s) { StringBase<_T> &append(const _T *__s) {
p_buf.pop(); __buf.pop();
p_buf.insert_range(p_buf.size(), PointerRange<const T>(s, __buf.insert_range(__buf.size(), ConstRangeType(__s,
strlen(s) + 1)); strlen(__s) + 1));
return *this; return *this;
} }
StringBase<T> &append(size_t n, T c) { StringBase<_T> &append(size_t __n, _T __c) {
p_buf.pop(); __buf.pop();
for (size_t i = 0; i < n; ++i) p_buf.push(c); for (size_t __i = 0; __i < __n; ++__i) __buf.push(__c);
p_buf.push('\0'); __buf.push('\0');
return *this; return *this;
} }
template<typename R> template<typename _R>
StringBase<T> &append_range(R range) { StringBase<_T> &append_range(_R __range) {
p_buf.pop(); __buf.pop();
p_buf.insert_range(p_buf.size(), range); __buf.insert_range(__buf.size(), __range);
terminate(); __terminate();
return *this; return *this;
} }
StringBase<T> &operator+=(const StringBase &s) { StringBase<_T> &operator+=(const StringBase &__s) {
return append(s); return append(__s);
} }
StringBase<T> &operator+=(const T *s) { StringBase<_T> &operator+=(const _T *__s) {
return append(s); return append(__s);
} }
StringBase<T> &operator+=(T c) { StringBase<_T> &operator+=(_T __c) {
p_buf.pop(); __buf.pop();
p_buf.push(c); __buf.push(__c);
p_buf.push('\0'); __buf.push('\0');
return *this; return *this;
} }
RangeType each() { RangeType each() {
return PointerRange<T>(p_buf.data(), size()); return RangeType(__buf.data(), size());
} }
ConstRangeType each() const { ConstRangeType each() const {
return PointerRange<const T>(p_buf.data(), size()); return ConstRangeType(__buf.data(), size());
} }
void swap(StringBase &v) { void swap(StringBase &__v) {
p_buf.swap(v); __buf.swap(__v);
} }
}; };
typedef StringBase<char> String; typedef StringBase<char> String;
template<typename T> template<typename _T>
struct __OctaIsRangeTest { struct __OctaIsRangeTest {
template<typename U> static char __octa_test(typename U::Category *); template<typename _U> static char __test(typename _U::Category *);
template<typename U> static int __octa_test(...); template<typename _U> static int __test(...);
static constexpr bool value = (sizeof(__octa_test<T>(0)) == sizeof(char)); static constexpr bool value = (sizeof(__test<_T>(0)) == sizeof(char));
}; };
template<typename T, typename F> template<typename _T, typename _F>
String concat(const T &v, const String &sep, F func) { String concat(const _T &__v, const String &__sep, _F __func) {
String ret; String __ret;
auto range = each(v); auto __range = octa::each(__v);
if (range.empty()) return move(ret); if (__range.empty()) return octa::move(__ret);
for (;;) { for (;;) {
ret += func(range.front()); __ret += __func(__range.front());
range.pop_front(); __range.pop_front();
if (range.empty()) break; if (__range.empty()) break;
ret += sep; __ret += __sep;
} }
return move(ret); return octa::move(__ret);
} }
template<typename T> template<typename _T>
String concat(const T &v, const String &sep = " ") { String concat(const _T &__v, const String &__sep = " ") {
String ret; String __ret;
auto range = each(v); auto __range = octa::each(__v);
if (range.empty()) return move(ret); if (__range.empty()) return octa::move(__ret);
for (;;) { for (;;) {
ret += range.front(); __ret += __range.front();
range.pop_front(); __range.pop_front();
if (range.empty()) break; if (__range.empty()) break;
ret += sep; __ret += __sep;
} }
return move(ret); return octa::move(__ret);
} }
template<typename T, typename F> template<typename _T, typename _F>
String concat(initializer_list<T> v, const String &sep, F func) { String concat(std::initializer_list<_T> __v, const String &__sep, _F __func) {
return concat(each(v), sep, func); return concat(octa::each(__v), __sep, __func);
} }
template<typename T> template<typename _T>
String concat(initializer_list<T> v, const String &sep = " ") { String concat(std::initializer_list<_T> __v, const String &__sep = " ") {
return concat(each(v), sep); return concat(octa::each(__v), __sep);
} }
template<typename T> template<typename _T>
struct __OctaToStringTest { struct __OctaToStringTest {
template<typename U, String (U::*)() const> struct __OctaTest {}; template<typename _U, String (_U::*)() const> struct __Test {};
template<typename U> static char __octa_test(__OctaTest<U, &U::to_string> *); template<typename _U> static char __test(__Test<_U, &_U::to_string> *);
template<typename U> static int __octa_test(...); template<typename _U> static int __test(...);
static constexpr bool value = (sizeof(__octa_test<T>(0)) == sizeof(char)); static constexpr bool value = (sizeof(__test<_T>(0)) == sizeof(char));
}; };
template<typename T> struct ToString { template<typename _T> struct ToString {
typedef T ArgType; typedef _T ArgType;
typedef String ResultType; typedef String ResultType;
template<typename U> template<typename _U>
static String __octa_to_str(const U &v, static String __octa_to_str(const _U &__v,
EnableIf<__OctaToStringTest<U>::value, bool> = true octa::EnableIf<__OctaToStringTest<_U>::value, bool> = true
) { ) {
return v.to_string(); return __v.to_string();
} }
template<typename U> template<typename _U>
static String __octa_to_str(const U &v, static String __octa_to_str(const _U &__v,
EnableIf<!__OctaToStringTest<U>::value && !IsScalar<U>::value, octa::EnableIf<!__OctaToStringTest<_U>::value &&
bool> = true !octa::IsScalar<_U>::value, bool> = true
) { ) {
String ret("{"); String __ret("{");
ret += concat(each(v), ", ", ToString<RangeReference< __ret += concat(octa::each(__v), ", ", ToString<octa::RangeReference<
decltype(each(v)) decltype(octa::each(__v))
>>()); >>());
ret += "}"; __ret += "}";
return move(ret); return octa::move(__ret);
} }
template<typename U> template<typename _U>
static String __octa_to_str(const U &v, static String __octa_to_str(const _U &__v,
EnableIf<!__OctaToStringTest<U>::value && IsScalar<U>::value, octa::EnableIf<!__OctaToStringTest<_U>::value &&
bool> = true octa::IsScalar<_U>::value, bool> = true
) { ) {
return ToString<U>()(v); return ToString<_U>()(__v);
} }
String operator()(const T &v) { String operator()(const _T &__v) {
return move(__octa_to_str<RemoveCv<RemoveReference<T>>>(v)); return octa::move(__octa_to_str<octa::RemoveCv<
octa::RemoveReference<_T>
>>(__v));
} }
}; };
template<typename T> template<typename _T>
void __octa_str_printf(Vector<char> *s, const char *fmt, T v) { void __octa_str_printf(octa::Vector<char> *__s, const char *__fmt, _T __v) {
char buf[256]; char __buf[256];
int n = snprintf(buf, sizeof(buf), fmt, v); int __n = snprintf(__buf, sizeof(__buf), __fmt, __v);
s->clear(); __s->clear();
s->reserve(n + 1); __s->reserve(__n + 1);
if (n >= (int)sizeof(buf)) if (__n >= (int)sizeof(__buf))
snprintf(s->data(), n + 1, fmt, v); snprintf(__s->data(), __n + 1, __fmt, __v);
else if (n > 0) else if (__n > 0)
memcpy(s->data(), buf, n + 1); memcpy(__s->data(), __buf, __n + 1);
else { else {
n = 0; __n = 0;
*(s->data()) = '\0'; *(__s->data()) = '\0';
} }
*(((size_t *)s) + 1) = n + 1; *(((size_t *)__s) + 1) = __n + 1;
} }
template<> struct ToString<bool> { template<> struct ToString<bool> {
typedef bool ArgType; typedef bool ArgType;
typedef String ResultType; typedef String ResultType;
String operator()(bool b) { String operator()(bool __b) {
return b ? "true" : "false"; return __b ? "true" : "false";
} }
}; };
template<> struct ToString<char> { template<> struct ToString<char> {
typedef char ArgType; typedef char ArgType;
typedef String ResultType; typedef String ResultType;
String operator()(char c) { String operator()(char __c) {
String ret; String __ret;
ret.push(c); __ret.push(__c);
return move(ret); return octa::move(__ret);
} }
}; };
#define __OCTA_TOSTR_NUM(T, fmt) \ #define __OCTA_TOSTR_NUM(_T, __fmt) \
template<> struct ToString<T> { \ template<> struct ToString<_T> { \
typedef T ArgType; \ typedef _T ArgType; \
typedef String ResultType; \ typedef String ResultType; \
String operator()(T v) { \ String operator()(_T __v) { \
String ret; \ String __ret; \
__octa_str_printf((Vector<char> *)&ret, fmt, v); \ __octa_str_printf((octa::Vector<char> *)&__ret, __fmt, __v); \
return move(ret); \ return octa::move(__ret); \
} \ } \
}; };
@ -322,45 +322,48 @@ namespace octa {
#undef __OCTA_TOSTR_NUM #undef __OCTA_TOSTR_NUM
template<typename T> struct ToString<T *> { template<typename _T> struct ToString<_T *> {
typedef T *ArgType; typedef _T *ArgType;
typedef String ResultType; typedef String ResultType;
String operator()(ArgType v) { String operator()(ArgType __v) {
String ret; String __ret;
__octa_str_printf((Vector<char> *)&ret, "%p", v); __octa_str_printf((octa::Vector<char> *)&__ret, "%p", __v);
return move(ret); return octa::move(__ret);
} }
}; };
template<> struct ToString<String> { template<> struct ToString<String> {
typedef const String &ArgType; typedef const String &ArgType;
typedef String ResultType; typedef String ResultType;
String operator()(ArgType s) { String operator()(ArgType __s) {
return s; return __s;
} }
}; };
template<typename T, typename U> struct ToString<Pair<T, U>> { template<typename _T, typename _U> struct ToString<octa::Pair<_T, _U>> {
typedef const Pair<T, U> &ArgType; typedef const octa::Pair<_T, _U> &ArgType;
typedef String ResultType; typedef String ResultType;
String operator()(ArgType v) { String operator()(ArgType __v) {
String ret("{"); String __ret("{");
ret += ToString<RemoveCv<RemoveReference<T>>>()(v.first); __ret += ToString<octa::RemoveCv<octa::RemoveReference<_T>>>()
ret += ", "; (__v.first);
ret += ToString<RemoveCv<RemoveReference<U>>>()(v.second); __ret += ", ";
ret += "}"; __ret += ToString<octa::RemoveCv<octa::RemoveReference<_U>>>()
return move(ret); (__v.second);
__ret += "}";
return octa::move(__ret);
} }
}; };
template<typename T> template<typename _T>
String to_string(const T &v) { String to_string(const _T &__v) {
return move(ToString<RemoveCv<RemoveReference<T>>>()(v)); return octa::move(ToString<octa::RemoveCv<octa::RemoveReference<_T>>>
()(__v));
} }
template<typename T> template<typename _T>
String to_string(initializer_list<T> init) { String to_string(std::initializer_list<_T> __init) {
return move(ToString<initializer_list<T>>()(init)); return octa::move(ToString<std::initializer_list<_T>>()(__init));
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -13,67 +13,67 @@
namespace octa { namespace octa {
/* move */ /* move */
template<typename T> template<typename _T>
static inline constexpr RemoveReference<T> &&move(T &&v) { static inline constexpr RemoveReference<_T> &&move(_T &&__v) {
return static_cast<RemoveReference<T> &&>(v); return static_cast<RemoveReference<_T> &&>(__v);
} }
/* forward */ /* forward */
template<typename T> template<typename _T>
static inline constexpr T &&forward(RemoveReference<T> &v) { static inline constexpr _T &&forward(RemoveReference<_T> &__v) {
return static_cast<T &&>(v); return static_cast<_T &&>(__v);
} }
template<typename T> template<typename _T>
static inline constexpr T &&forward(RemoveReference<T> &&v) { static inline constexpr _T &&forward(RemoveReference<_T> &&__v) {
return static_cast<T &&>(v); return static_cast<_T &&>(__v);
} }
/* declval */ /* declval */
template<typename T> AddRvalueReference<T> declval(); template<typename _T> AddRvalueReference<_T> declval();
/* swap */ /* swap */
template<typename T> template<typename _T>
struct __OctaSwapTest { struct __OctaSwapTest {
template<typename U, void (U::*)(U &)> struct __OctaTest {}; template<typename _U, void (_U::*)(_U &)> struct __Test {};
template<typename U> static char __octa_test(__OctaTest<U, &U::swap> *); template<typename _U> static char __test(__Test<_U, &_U::swap> *);
template<typename U> static int __octa_test(...); template<typename _U> static int __test(...);
static constexpr bool value = (sizeof(__octa_test<T>(0)) == sizeof(char)); static constexpr bool value = (sizeof(__test<_T>(0)) == sizeof(char));
}; };
template<typename T> inline void __octa_swap(T &a, T &b, EnableIf< template<typename _T> inline void __octa_swap(_T &__a, _T &__b, EnableIf<
__OctaSwapTest<T>::value, bool __OctaSwapTest<_T>::value, bool
> = true) { > = true) {
a.swap(b); __a.swap(__b);
} }
template<typename T> inline void __octa_swap(T &a, T &b, EnableIf< template<typename _T> inline void __octa_swap(_T &__a, _T &__b, EnableIf<
!__OctaSwapTest<T>::value, bool !__OctaSwapTest<_T>::value, bool
> = true) { > = true) {
T c(move(a)); _T __c(octa::move(__a));
a = move(b); __a = octa::move(__b);
b = move(c); __b = octa::move(__c);
} }
template<typename T> void swap(T &a, T &b) { template<typename _T> void swap(_T &__a, _T &__b) {
__octa_swap(a, b); __octa_swap(__a, __b);
} }
template<typename T, size_t N> void swap(T (&a)[N], T (&b)[N]) { template<typename _T, size_t _N> void swap(_T (&__a)[_N], _T (&__b)[_N]) {
for (size_t i = 0; i < N; ++i) { for (size_t __i = 0; __i < _N; ++__i) {
swap(a[i], b[i]); octa::swap(__a[__i], __b[__i]);
} }
} }
/* pair */ /* pair */
template<typename T, typename U> template<typename _T, typename _U>
struct Pair { struct Pair {
T first; _T first;
U second; _U second;
Pair() = default; Pair() = default;
~Pair() = default; ~Pair() = default;
@ -81,46 +81,48 @@ namespace octa {
Pair(const Pair &) = default; Pair(const Pair &) = default;
Pair(Pair &&) = default; Pair(Pair &&) = default;
Pair(const T &x, const U &y): first(x), second(y) {} Pair(const _T &__x, const _U &__y): first(__x), second(__y) {}
template<typename TT, typename UU> template<typename _TT, typename _UU>
Pair(TT &&x, UU &&y): first(forward<TT>(x)), second(forward<UU>(y)) {} Pair(_TT &&__x, _UU &&__y):
first(octa::forward<_TT>(__x)), second(octa::forward<_UU>(__y)) {}
template<typename TT, typename UU> template<typename _TT, typename _UU>
Pair(const Pair<TT, UU> &v): first(v.first), second(v.second) {} Pair(const Pair<_TT, _UU> &__v): first(__v.first), second(__v.second) {}
template<typename TT, typename UU> template<typename _TT, typename _UU>
Pair(Pair<TT, UU> &&v): first(move(v.first)), second(move(v.second)) {} Pair(Pair<_TT, _UU> &&__v):
first(octa::move(__v.first)), second(octa::move(__v.second)) {}
Pair &operator=(const Pair &v) { Pair &operator=(const Pair &__v) {
first = v.first; first = __v.first;
second = v.second; second = __v.second;
return *this; return *this;
} }
template<typename TT, typename UU> template<typename _TT, typename _UU>
Pair &operator=(const Pair<TT, UU> &v) { Pair &operator=(const Pair<_TT, _UU> &__v) {
first = v.first; first = __v.first;
second = v.second; second = __v.second;
return *this; return *this;
} }
Pair &operator=(Pair &&v) { Pair &operator=(Pair &&__v) {
first = move(v.first); first = octa::move(__v.first);
second = move(v.second); second = octa::move(__v.second);
return *this; return *this;
} }
template<typename TT, typename UU> template<typename _TT, typename _UU>
Pair &operator=(Pair<TT, UU> &&v) { Pair &operator=(Pair<_TT, _UU> &&__v) {
first = forward<TT>(v.first); first = octa::forward<_TT>(__v.first);
second = forward<UU>(v.second); second = octa::forward<_UU>(__v.second);
return *this; return *this;
} }
void swap(Pair &v) { void swap(Pair &__v) {
octa::swap(first, v.first); octa::swap(first, __v.first);
octa::swap(second, v.second); octa::swap(second, __v.second);
} }
}; };
} }

View file

@ -17,298 +17,297 @@
#include "octa/initializer_list.h" #include "octa/initializer_list.h"
namespace octa { namespace octa {
template<typename T> template<typename _T>
class Vector { class Vector {
T *p_buf; _T *__buf;
size_t p_len, p_cap; size_t __len, __cap;
void insert_base(size_t idx, size_t n) { void __insert_base(size_t __idx, size_t __n) {
if (p_len + n > p_cap) reserve(p_len + n); if (__len + __n > __cap) reserve(__len + __n);
p_len += n; __len += __n;
for (size_t i = p_len - 1; i > idx + n - 1; --i) { for (size_t __i = __len - 1; __i > __idx + __n - 1; --__i) {
p_buf[i] = move(p_buf[i - n]); __buf[__i] = octa::move(__buf[__i - __n]);
} }
} }
template<typename R> template<typename _R>
void ctor_from_range(R &range, EnableIf<IsFiniteRandomAccessRange<R> void __ctor_from_range(_R &__range, octa::EnableIf<
::value, bool octa::IsFiniteRandomAccessRange<_R>::value, bool
> = true) { > = true) {
RangeSize<R> len = range.size(); octa::RangeSize<_R> __l = __range.size();
reserve(len); reserve(__l);
p_len = len; __len = __l;
for (size_t i = 0; !range.empty(); range.pop_front()) { for (size_t __i = 0; !__range.empty(); __range.pop_front()) {
new (&p_buf[i]) T(range.front()); new (&__buf[__i]) _T(__range.front());
++i; ++__i;
} }
} }
template<typename R> template<typename _R>
void ctor_from_range(R &range, EnableIf<!IsFiniteRandomAccessRange<R> void __ctor_from_range(_R &__range, EnableIf<
::value, bool !octa::IsFiniteRandomAccessRange<_R>::value, bool
> = true) { > = true) {
size_t i = 0; size_t __i = 0;
for (; !range.empty(); range.pop_front()) { for (; !__range.empty(); __range.pop_front()) {
reserve(i + 1); reserve(__i + 1);
new (&p_buf[i]) T(range.front()); new (&__buf[__i]) _T(__range.front());
++i; ++__i;
p_len = i; __len = __i;
} }
} }
public: public:
enum { MIN_SIZE = 8 }; enum { MIN_SIZE = 8 };
typedef size_t SizeType; typedef size_t SizeType;
typedef ptrdiff_t DiffType; typedef ptrdiff_t DiffType;
typedef T ValType; typedef _T ValType;
typedef T &RefType; typedef _T &RefType;
typedef const T &ConstRefType; typedef const _T &ConstRefType;
typedef T *PtrType; typedef _T *PtrType;
typedef const T *ConstPtrType; typedef const _T *ConstPtrType;
typedef PointerRange< T> RangeType; typedef PointerRange< _T> RangeType;
typedef PointerRange<const T> ConstRangeType; typedef PointerRange<const _T> ConstRangeType;
Vector(): p_buf(nullptr), p_len(0), p_cap(0) {} Vector(): __buf(nullptr), __len(0), __cap(0) {}
explicit Vector(size_t n, const T &val = T()): Vector() { explicit Vector(size_t __n, const _T &__val = _T()): Vector() {
p_buf = (T *)new uchar[n * sizeof(T)]; __buf = (_T *)new uchar[__n * sizeof(_T)];
p_len = p_cap = n; __len = __cap = __n;
T *cur = p_buf, *last = p_buf + n; _T *__cur = __buf, *__last = __buf + __n;
while (cur != last) new (cur++) T(val); while (__cur != __last) new (__cur++) _T(__val);
} }
Vector(const Vector &v): Vector() { Vector(const Vector &__v): Vector() {
*this = v; *this = __v;
} }
Vector(Vector &&v): p_buf(v.p_buf), p_len(v.p_len), p_cap(v.p_cap) { Vector(Vector &&__v): __buf(__v.__buf), __len(__v.__len),
v.p_buf = nullptr; __cap(__v.__cap) {
v.p_len = v.p_cap = 0; __v.__buf = nullptr;
__v.__len = __v.__cap = 0;
} }
Vector(InitializerList<T> v): Vector() { Vector(InitializerList<_T> __v): Vector() {
size_t len = v.end() - v.begin(); size_t __l = __v.end() - __v.begin();
const T *ptr = v.begin(); const _T *__ptr = __v.begin();
reserve(len); reserve(__l);
for (size_t i = 0; i < len; ++i) for (size_t __i = 0; __i < __l; ++__i)
new (&p_buf[i]) T(ptr[i]); new (&__buf[__i]) _T(__ptr[__i]);
p_len = len; __len = __l;
} }
template<typename R> Vector(R range): Vector() { template<typename _R> Vector(_R __range): Vector() {
ctor_from_range(range); __ctor_from_range(__range);
} }
~Vector() { ~Vector() {
clear(); clear();
delete[] (uchar *)p_buf; delete[] (uchar *)__buf;
p_buf = nullptr;
p_cap = 0;
} }
void clear() { void clear() {
if (p_len > 0 && !octa::IsPod<T>()) { if (__len > 0 && !octa::IsPod<_T>()) {
T *cur = p_buf, *last = p_buf + p_len; _T *__cur = __buf, *__last = __buf + __len;
while (cur != last) (*cur++).~T(); while (__cur != __last) (*__cur++).~_T();
} }
p_len = 0; __len = 0;
} }
Vector<T> &operator=(const Vector<T> &v) { Vector<_T> &operator=(const Vector<_T> &__v) {
if (this == &v) return *this; if (this == &__v) return *this;
clear(); clear();
reserve(v.p_cap); reserve(__v.__cap);
p_len = v.p_len; __len = __v.__len;
if (octa::IsPod<T>()) { if (octa::IsPod<_T>()) {
memcpy(p_buf, v.p_buf, p_len * sizeof(T)); memcpy(__buf, __v.__buf, __len * sizeof(_T));
} else { } else {
T *cur = p_buf, *last = p_buf + p_len; _T *__cur = __buf, *__last = __buf + __len;
T *vbuf = v.p_buf; _T *__vbuf = __v.__buf;
while (cur != last) { while (__cur != __last) {
new (cur++) T(*vbuf++); new (__cur++) _T(*__vbuf++);
} }
} }
return *this; return *this;
} }
Vector<T> &operator=(Vector<T> &&v) { Vector<_T> &operator=(Vector<_T> &&__v) {
clear(); clear();
delete[] (uchar *)p_buf; delete[] (uchar *)__buf;
p_len = v.p_len; __len = __v.__len;
p_cap = v.p_cap; __cap = __v.__cap;
p_buf = v.disown(); __buf = __v.disown();
return *this; return *this;
} }
Vector<T> &operator=(InitializerList<T> il) { Vector<_T> &operator=(InitializerList<_T> __il) {
clear(); clear();
size_t ilen = il.end() - il.begin(); size_t __ilen = __il.end() - __il.begin();
reserve(ilen); reserve(__ilen);
if (octa::IsPod<T>()) { if (octa::IsPod<_T>()) {
memcpy(p_buf, il.begin(), ilen); memcpy(__buf, __il.begin(), __ilen);
} else { } else {
T *buf = p_buf, *ibuf = il.begin(), *last = il.end(); _T *__tbuf = __buf, *__ibuf = __il.begin(), *__last = __il.end();
while (ibuf != last) { while (__ibuf != __last) {
new (buf++) T(*ibuf++); new (__tbuf++) _T(*__ibuf++);
} }
} }
p_len = ilen; __len = __ilen;
return *this; return *this;
} }
template<typename R> template<typename _R>
Vector<T> &operator=(R range) { Vector<_T> &operator=(_R __range) {
clear(); clear();
ctor_from_range(range); __ctor_from_range(__range);
} }
void resize(size_t n, const T &v = T()) { void resize(size_t __n, const _T &__v = _T()) {
size_t len = p_len; size_t __l = __len;
reserve(n); reserve(__n);
p_len = n; __len = __n;
if (octa::IsPod<T>()) { if (octa::IsPod<_T>()) {
for (size_t i = len; i < p_len; ++i) { for (size_t __i = __l; __i < __len; ++__i) {
p_buf[i] = T(v); __buf[__i] = _T(__v);
} }
} else { } else {
T *first = p_buf + len; _T *__first = __buf + __l;
T *last = p_buf + p_len; _T *__last = __buf + __len;
while (first != last) new (first++) T(v); while (__first != __last) new (__first++) _T(__v);
} }
} }
void reserve(size_t n) { void reserve(size_t __n) {
if (n <= p_cap) return; if (__n <= __cap) return;
size_t oc = p_cap; size_t __oc = __cap;
if (!oc) { if (!__oc) {
p_cap = max(n, size_t(MIN_SIZE)); __cap = octa::max(__n, size_t(MIN_SIZE));
} else { } else {
while (p_cap < n) p_cap *= 2; while (__cap < __n) __cap *= 2;
} }
T *tmp = (T *)new uchar[p_cap * sizeof(T)]; _T *__tmp = (_T *)new uchar[__cap * sizeof(_T)];
if (oc > 0) { if (__oc > 0) {
if (octa::IsPod<T>()) { if (octa::IsPod<_T>()) {
memcpy(tmp, p_buf, p_len * sizeof(T)); memcpy(__tmp, __buf, __len * sizeof(_T));
} else { } else {
T *cur = p_buf, *tcur = tmp, *last = tmp + p_len; _T *__cur = __buf, *__tcur = __tmp, *__last = __tmp + __len;
while (tcur != last) { while (__tcur != __last) {
new (tcur++) T(move(*cur)); new (__tcur++) _T(octa::move(*__cur));
(*cur).~T(); (*__cur).~_T();
++cur; ++__cur;
} }
} }
delete[] (uchar *)p_buf; delete[] (uchar *)__buf;
} }
p_buf = tmp; __buf = __tmp;
} }
T &operator[](size_t i) { return p_buf[i]; } _T &operator[](size_t __i) { return __buf[__i]; }
const T &operator[](size_t i) const { return p_buf[i]; } const _T &operator[](size_t __i) const { return __buf[__i]; }
T &at(size_t i) { return p_buf[i]; } _T &at(size_t __i) { return __buf[__i]; }
const T &at(size_t i) const { return p_buf[i]; } const _T &at(size_t __i) const { return __buf[__i]; }
T &push(const T &v) { _T &push(const _T &__v) {
if (p_len == p_cap) reserve(p_len + 1); if (__len == __cap) reserve(__len + 1);
new (&p_buf[p_len]) T(v); new (&__buf[__len]) _T(__v);
return p_buf[p_len++]; return __buf[__len++];
} }
T &push() { _T &push() {
if (p_len == p_cap) reserve(p_len + 1); if (__len == __cap) reserve(__len + 1);
new (&p_buf[p_len]) T; new (&__buf[__len]) _T;
return p_buf[p_len++]; return __buf[__len++];
} }
template<typename ...U> template<typename ..._U>
T &emplace_back(U &&...args) { _T &emplace_back(_U &&...__args) {
if (p_len == p_cap) reserve(p_len + 1); if (__len == __cap) reserve(__len + 1);
new (&p_buf[p_len]) T(forward<U>(args)...); new (&__buf[__len]) _T(octa::forward<_U>(__args)...);
return p_buf[p_len++]; return __buf[__len++];
} }
void pop() { void pop() {
if (!octa::IsPod<T>()) { if (!octa::IsPod<_T>()) {
p_buf[--p_len].~T(); __buf[--__len].~_T();
} else { } else {
--p_len; --__len;
} }
} }
T &front() { return p_buf[0]; } _T &front() { return __buf[0]; }
const T &front() const { return p_buf[0]; }; const _T &front() const { return __buf[0]; };
T &back() { return p_buf[p_len - 1]; } _T &back() { return __buf[__len - 1]; }
const T &back() const { return p_buf[p_len - 1]; } const _T &back() const { return __buf[__len - 1]; }
T *data() { return p_buf; } _T *data() { return __buf; }
const T *data() const { return p_buf; } const _T *data() const { return __buf; }
size_t size() const { return p_len; } size_t size() const { return __len; }
size_t capacity() const { return p_cap; } size_t capacity() const { return __cap; }
bool empty() const { return (p_len == 0); } bool empty() const { return (__len == 0); }
bool in_range(size_t idx) { return idx < p_len; } bool in_range(size_t __idx) { return __idx < __len; }
bool in_range(int idx) { return idx >= 0 && size_t(idx) < p_len; } bool in_range(int __idx) { return __idx >= 0 && size_t(__idx) < __len; }
bool in_range(const T *ptr) { bool in_range(const _T *__ptr) {
return ptr >= p_buf && ptr < &p_buf[p_len]; return __ptr >= __buf && __ptr < &__buf[__len];
} }
T *disown() { _T *disown() {
T *r = p_buf; _T *__r = __buf;
p_buf = nullptr; __buf = nullptr;
p_len = p_cap = 0; __len = __cap = 0;
return r; return __r;
} }
T *insert(size_t idx, T &&v) { _T *insert(size_t __idx, _T &&__v) {
insert_base(idx, 1); __insert_base(__idx, 1);
p_buf[idx] = move(v); __buf[__idx] = octa::move(__v);
return &p_buf[idx]; return &__buf[__idx];
} }
T *insert(size_t idx, const T &v) { _T *insert(size_t __idx, const _T &__v) {
insert_base(idx, 1); __insert_base(__idx, 1);
p_buf[idx] = v; __buf[__idx] = __v;
return &p_buf[idx]; return &__buf[__idx];
} }
T *insert(size_t idx, size_t n, const T &v) { _T *insert(size_t __idx, size_t __n, const _T &__v) {
insert_base(idx, n); __insert_base(__idx, __n);
for (size_t i = 0; i < n; ++i) { for (size_t __i = 0; __i < __n; ++__i) {
p_buf[idx + i] = v; __buf[__idx + __i] = __v;
} }
return &p_buf[idx]; return &__buf[__idx];
} }
template<typename U> template<typename _U>
T *insert_range(size_t idx, U range) { _T *insert_range(size_t __idx, _U __range) {
size_t len = range.size(); size_t __l = __range.size();
insert_base(idx, len); __insert_base(__idx, __l);
for (size_t i = 0; i < len; ++i) { for (size_t __i = 0; __i < __l; ++__i) {
p_buf[idx + i] = range.front(); __buf[__idx + __i] = __range.front();
range.pop_front(); __range.pop_front();
} }
return &p_buf[idx]; return &__buf[__idx];
} }
T *insert(size_t idx, InitializerList<T> il) { _T *insert(size_t __idx, InitializerList<_T> __il) {
return insert_range(idx, octa::each(il)); return insert_range(__idx, octa::each(__il));
} }
RangeType each() { RangeType each() {
return PointerRange<T>(p_buf, p_buf + p_len); return RangeType(__buf, __buf + __len);
} }
ConstRangeType each() const { ConstRangeType each() const {
return PointerRange<const T>(p_buf, p_buf + p_len); return ConstRangeType(__buf, __buf + __len);
} }
void swap(Vector &v) { void swap(Vector &__v) {
octa::swap(p_len, v.p_len); octa::swap(__len, __v.__len);
octa::swap(p_cap, v.p_cap); octa::swap(__cap, __v.__cap);
octa::swap(p_buf, v.p_buf); octa::swap(__buf, __v.__buf);
} }
}; };
} }