make allocator based containers more predictable + simplified PointerRange
This commit is contained in:
parent
ec44dbbfbd
commit
dc58d09388
42
octa/range.h
42
octa/range.h
|
@ -742,20 +742,14 @@ NumberRange<T> range(T v) {
|
||||||
return NumberRange<T>(v);
|
return NumberRange<T>(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T,
|
template<typename T>
|
||||||
typename R = T &, typename P = T *,
|
struct PointerRange: InputRange<PointerRange<T>, FiniteRandomAccessRangeTag, T> {
|
||||||
typename S = octa::Size, typename D = octa::Ptrdiff
|
|
||||||
>
|
|
||||||
struct PointerRange: InputRange<
|
|
||||||
PointerRange<T, R, P, S, D>, FiniteRandomAccessRangeTag, T, R, S, D
|
|
||||||
> {
|
|
||||||
using Pointer = P;
|
|
||||||
|
|
||||||
PointerRange(): p_beg(nullptr), p_end(nullptr) {}
|
PointerRange(): p_beg(nullptr), p_end(nullptr) {}
|
||||||
PointerRange(const PointerRange &v): p_beg(v.p_beg),
|
PointerRange(const PointerRange &v): p_beg(v.p_beg),
|
||||||
p_end(v.p_end) {}
|
p_end(v.p_end) {}
|
||||||
PointerRange(Pointer beg, Pointer end): p_beg(beg), p_end(end) {}
|
PointerRange(T *beg, T *end): p_beg(beg), p_end(end) {}
|
||||||
PointerRange(Pointer beg, octa::Size n): p_beg(beg), p_end(beg + n) {}
|
PointerRange(T *beg, octa::Size n): p_beg(beg), p_end(beg + n) {}
|
||||||
|
|
||||||
PointerRange &operator=(const PointerRange &v) {
|
PointerRange &operator=(const PointerRange &v) {
|
||||||
p_beg = v.p_beg;
|
p_beg = v.p_beg;
|
||||||
|
@ -775,8 +769,8 @@ struct PointerRange: InputRange<
|
||||||
--p_beg; return true;
|
--p_beg; return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
S pop_front_n(S n) {
|
octa::Size pop_front_n(octa::Size n) {
|
||||||
S olen = p_end - p_beg;
|
octa::Size olen = p_end - p_beg;
|
||||||
p_beg += n;
|
p_beg += n;
|
||||||
if (p_beg > p_end) {
|
if (p_beg > p_end) {
|
||||||
p_beg = p_end;
|
p_beg = p_end;
|
||||||
|
@ -785,17 +779,17 @@ struct PointerRange: InputRange<
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
S push_front_n(S n) {
|
octa::Size push_front_n(octa::Size n) {
|
||||||
p_beg -= n; return true;
|
p_beg -= n; return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
R front() const { return *p_beg; }
|
T &front() const { return *p_beg; }
|
||||||
|
|
||||||
bool equals_front(const PointerRange &range) const {
|
bool equals_front(const PointerRange &range) const {
|
||||||
return p_beg == range.p_beg;
|
return p_beg == range.p_beg;
|
||||||
}
|
}
|
||||||
|
|
||||||
D distance_front(const PointerRange &range) const {
|
octa::Ptrdiff distance_front(const PointerRange &range) const {
|
||||||
return range.p_beg - p_beg;
|
return range.p_beg - p_beg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -809,8 +803,8 @@ struct PointerRange: InputRange<
|
||||||
++p_end; return true;
|
++p_end; return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
S pop_back_n(S n) {
|
octa::Size pop_back_n(octa::Size n) {
|
||||||
S olen = p_end - p_beg;
|
octa::Size olen = p_end - p_beg;
|
||||||
p_end -= n;
|
p_end -= n;
|
||||||
if (p_end < p_beg) {
|
if (p_end < p_beg) {
|
||||||
p_end = p_beg;
|
p_end = p_beg;
|
||||||
|
@ -819,28 +813,28 @@ struct PointerRange: InputRange<
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
S push_back_n(S n) {
|
octa::Size push_back_n(octa::Size n) {
|
||||||
p_end += n; return true;
|
p_end += n; return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
R back() const { return *(p_end - 1); }
|
T &back() const { return *(p_end - 1); }
|
||||||
|
|
||||||
bool equals_back(const PointerRange &range) const {
|
bool equals_back(const PointerRange &range) const {
|
||||||
return p_end == range.p_end;
|
return p_end == range.p_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
D distance_back(const PointerRange &range) const {
|
octa::Ptrdiff distance_back(const PointerRange &range) const {
|
||||||
return range.p_end - p_end;
|
return range.p_end - p_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* satisfy FiniteRandomAccessRange */
|
/* satisfy FiniteRandomAccessRange */
|
||||||
S size() const { return p_end - p_beg; }
|
octa::Size size() const { return p_end - p_beg; }
|
||||||
|
|
||||||
PointerRange slice(S start, S end) const {
|
PointerRange slice(octa::Size start, octa::Size end) const {
|
||||||
return PointerRange(p_beg + start, p_beg + end);
|
return PointerRange(p_beg + start, p_beg + end);
|
||||||
}
|
}
|
||||||
|
|
||||||
R operator[](S i) const { return p_beg[i]; }
|
T &operator[](octa::Size i) const { return p_beg[i]; }
|
||||||
|
|
||||||
/* satisfy OutputRange */
|
/* satisfy OutputRange */
|
||||||
void put(const T &v) {
|
void put(const T &v) {
|
||||||
|
@ -851,7 +845,7 @@ struct PointerRange: InputRange<
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
P p_beg, p_end;
|
T *p_beg, *p_end;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, octa::Size N>
|
template<typename T, octa::Size N>
|
||||||
|
|
|
@ -168,10 +168,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: traits for utf-16/utf-32 string lengths, for now assume char */
|
/* TODO: traits for utf-16/utf-32 string lengths, for now assume char */
|
||||||
StringBase(ConstPointer v, const A &a = A()):
|
StringBase(const Value *v, const A &a = A()):
|
||||||
p_buf(ConstRange(v, strlen(v) + 1), a) {}
|
p_buf(ConstRange(v, strlen(v) + 1), a) {}
|
||||||
|
|
||||||
StringBase(ConstPointer v, Size n, const A &a = A()):
|
StringBase(const Value *v, Size n, const A &a = A()):
|
||||||
p_buf(ConstRange(v, n), a) {}
|
p_buf(ConstRange(v, n), a) {}
|
||||||
|
|
||||||
template<typename R> StringBase(R range, const A &a = A(),
|
template<typename R> StringBase(R range, const A &a = A(),
|
||||||
|
@ -194,7 +194,7 @@ public:
|
||||||
p_buf.operator=(octa::move(v));
|
p_buf.operator=(octa::move(v));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
StringBase &operator=(ConstPointer v) {
|
StringBase &operator=(const Value *v) {
|
||||||
p_buf = ConstRange(v, strlen(v) + 1);
|
p_buf = ConstRange(v, strlen(v) + 1);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -231,8 +231,8 @@ public:
|
||||||
T &back() { return p_buf[size() - 1]; }
|
T &back() { return p_buf[size() - 1]; }
|
||||||
const T &back() const { return p_buf[size() - 1]; }
|
const T &back() const { return p_buf[size() - 1]; }
|
||||||
|
|
||||||
Pointer data() { return p_buf.data(); }
|
Value *data() { return p_buf.data(); }
|
||||||
ConstPointer data() const { return p_buf.data(); }
|
const Value *data() const { return p_buf.data(); }
|
||||||
|
|
||||||
octa::Size size() const {
|
octa::Size size() const {
|
||||||
return p_buf.size() - 1;
|
return p_buf.size() - 1;
|
||||||
|
@ -263,7 +263,7 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBase &append(ConstPointer s) {
|
StringBase &append(const Value *s) {
|
||||||
p_buf.pop();
|
p_buf.pop();
|
||||||
p_buf.insert_range(p_buf.size(), ConstRange(s,
|
p_buf.insert_range(p_buf.size(), ConstRange(s,
|
||||||
strlen(s) + 1));
|
strlen(s) + 1));
|
||||||
|
@ -288,7 +288,7 @@ public:
|
||||||
StringBase &operator+=(const StringBase &s) {
|
StringBase &operator+=(const StringBase &s) {
|
||||||
return append(s);
|
return append(s);
|
||||||
}
|
}
|
||||||
StringBase &operator+=(ConstPointer s) {
|
StringBase &operator+=(const Value *s) {
|
||||||
return append(s);
|
return append(s);
|
||||||
}
|
}
|
||||||
StringBase &operator+=(T c) {
|
StringBase &operator+=(T c) {
|
||||||
|
@ -302,7 +302,7 @@ public:
|
||||||
return strcmp(p_buf.data(), s.data());
|
return strcmp(p_buf.data(), s.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
int compare(ConstPointer p) const {
|
int compare(const Value *p) const {
|
||||||
return strcmp(p_buf.data(), p);
|
return strcmp(p_buf.data(), p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,12 +89,8 @@ public:
|
||||||
using ConstReference = const T &;
|
using ConstReference = const T &;
|
||||||
using Pointer = octa::AllocatorPointer<A>;
|
using Pointer = octa::AllocatorPointer<A>;
|
||||||
using ConstPointer = octa::AllocatorConstPointer<A>;
|
using ConstPointer = octa::AllocatorConstPointer<A>;
|
||||||
using Range = octa::PointerRange<Value, Reference, Pointer, Size,
|
using Range = octa::PointerRange<T>;
|
||||||
Difference
|
using ConstRange = octa::PointerRange<const T>;
|
||||||
>;
|
|
||||||
using ConstRange = octa::PointerRange<const Value, ConstReference,
|
|
||||||
ConstPointer, Size, Difference
|
|
||||||
>;
|
|
||||||
using Allocator = A;
|
using Allocator = A;
|
||||||
|
|
||||||
Vector(const A &a = A()): p_len(0), p_cap(0), p_buf(nullptr, a) {}
|
Vector(const A &a = A()): p_len(0), p_cap(0), p_buf(nullptr, a) {}
|
||||||
|
@ -150,7 +146,7 @@ public:
|
||||||
v.p_len = v.p_cap = 0;
|
v.p_len = v.p_cap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector(ConstPointer buf, Size n, const A &a = A()): Vector(a) {
|
Vector(const Value *buf, Size n, const A &a = A()): Vector(a) {
|
||||||
reserve(n);
|
reserve(n);
|
||||||
if (octa::IsPod<T>()) {
|
if (octa::IsPod<T>()) {
|
||||||
memcpy(p_buf.first(), buf, n * sizeof(T));
|
memcpy(p_buf.first(), buf, n * sizeof(T));
|
||||||
|
@ -331,8 +327,8 @@ public:
|
||||||
T &back() { return p_buf.first()[p_len - 1]; }
|
T &back() { return p_buf.first()[p_len - 1]; }
|
||||||
const T &back() const { return p_buf.first()[p_len - 1]; }
|
const T &back() const { return p_buf.first()[p_len - 1]; }
|
||||||
|
|
||||||
Pointer data() { return p_buf.first(); }
|
Value *data() { return (Value *)p_buf.first(); }
|
||||||
ConstPointer data() const { return p_buf.first(); }
|
const Value *data() const { return (const Value *)p_buf.first(); }
|
||||||
|
|
||||||
Size size() const { return p_len; }
|
Size size() const { return p_len; }
|
||||||
Size capacity() const { return p_cap; }
|
Size capacity() const { return p_cap; }
|
||||||
|
@ -343,15 +339,15 @@ public:
|
||||||
|
|
||||||
bool in_range(Size idx) { return idx < p_len; }
|
bool in_range(Size idx) { return idx < p_len; }
|
||||||
bool in_range(int idx) { return idx >= 0 && Size(idx) < p_len; }
|
bool in_range(int idx) { return idx >= 0 && Size(idx) < p_len; }
|
||||||
bool in_range(ConstPointer ptr) {
|
bool in_range(const Value *ptr) {
|
||||||
return ptr >= p_buf.first() && ptr < &p_buf.first()[p_len];
|
return ptr >= p_buf.first() && ptr < &p_buf.first()[p_len];
|
||||||
}
|
}
|
||||||
|
|
||||||
Pointer disown() {
|
Value *disown() {
|
||||||
Pointer r = p_buf.first();
|
Pointer r = p_buf.first();
|
||||||
p_buf.first() = nullptr;
|
p_buf.first() = nullptr;
|
||||||
p_len = p_cap = 0;
|
p_len = p_cap = 0;
|
||||||
return r;
|
return (Value *)r;
|
||||||
}
|
}
|
||||||
|
|
||||||
Range insert(Size idx, T &&v) {
|
Range insert(Size idx, T &&v) {
|
||||||
|
|
Loading…
Reference in a new issue