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

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

View File

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

View File

@ -13,19 +13,19 @@
#ifndef OCTA_ALLOW_CXXSTD
/* must be in std namespace otherwise the compiler won't know about it */
namespace std {
template<typename T>
template<typename _T>
class initializer_list {
const T *p_buf;
size_t p_len;
const _T *__buf;
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:
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 *end() const { return p_buf + p_len; }
const _T *begin() const { return __buf; }
const _T *end() const { return __buf + __len; }
};
}
#else
@ -33,13 +33,11 @@ namespace std {
#endif
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(initializer_list<T> init) {
return octa::PointerRange<const T>(init.begin(), init.end());
template<typename _T>
octa::PointerRange<const _T> each(std::initializer_list<_T> __init) {
return octa::PointerRange<const _T>(__init.begin(), __init.end());
}
}

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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