implement a basic CompressedPair for internal container usage (removes code dups)

master
Daniel Kolesa 2015-06-13 16:32:03 +01:00
parent 4d97aa7ac2
commit e4738e0368
4 changed files with 237 additions and 193 deletions

View File

@ -207,43 +207,6 @@ struct DefaultDelete<T[]> {
/* box */
namespace detail {
template<typename T, typename U, bool = octa::IsEmpty<U>::value>
struct BoxPair;
template<typename T, typename U>
struct BoxPair<T, U, false> { /* non-empty deleter */
T *p_ptr;
private:
U p_del;
public:
template<typename D>
BoxPair(T *ptr, D &&dltr): p_ptr(ptr), p_del(octa::forward<D>(dltr)) {}
U &get_deleter() { return p_del; }
const U &get_deleter() const { return p_del; }
void swap(BoxPair &v) {
octa::swap(p_ptr, v.p_ptr);
octa::swap(p_del, v.p_del);
}
};
template<typename T, typename U>
struct BoxPair<T, U, true>: U { /* empty deleter */
T *p_ptr;
template<typename D>
BoxPair(T *ptr, D &&dltr): U(octa::forward<D>(dltr)), p_ptr(ptr) {}
U &get_deleter() { return *this; }
const U &get_deleter() const { return *this; }
void swap(BoxPair &v) {
octa::swap(p_ptr, v.p_ptr);
}
};
template<typename T>
static int ptr_test(...);
template<typename T>
@ -315,7 +278,7 @@ public:
Box &operator=(Box &&u) {
reset(u.release());
p_stor.get_deleter() = octa::forward<D>(u.get_deleter());
p_stor.second() = octa::forward<D>(u.get_deleter());
return *this;
}
@ -326,7 +289,7 @@ public:
Box &
> operator=(Box<TT, DD> &&u) {
reset(u.release());
p_stor.get_deleter() = octa::forward<DD>(u.get_deleter());
p_stor.second() = octa::forward<DD>(u.get_deleter());
return *this;
}
@ -337,28 +300,28 @@ public:
~Box() { reset(); }
octa::AddLvalueReference<T> operator*() const { return *p_stor.p_ptr; }
Pointer operator->() const { return p_stor.p_ptr; }
octa::AddLvalueReference<T> operator*() const { return *p_stor.first(); }
Pointer operator->() const { return p_stor.first(); }
explicit operator bool() const {
return p_stor.p_ptr != nullptr;
return p_stor.first() != nullptr;
}
Pointer get() const { return p_stor.p_ptr; }
Pointer get() const { return p_stor.first(); }
Dref get_deleter() { return p_stor.get_deleter(); }
Dcref get_deleter() const { return p_stor.get_deleter(); }
Dref get_deleter() { return p_stor.second(); }
Dcref get_deleter() const { return p_stor.second(); }
Pointer release() {
Pointer p = p_stor.p_ptr;
p_stor.p_ptr = nullptr;
Pointer p = p_stor.first();
p_stor.first() = nullptr;
return p;
}
void reset(Pointer p = nullptr) {
Pointer tmp = p_stor.p_ptr;
p_stor.p_ptr = p;
if (tmp) p_stor.get_deleter()(tmp);
Pointer tmp = p_stor.first();
p_stor.first() = p;
if (tmp) p_stor.second()(tmp);
}
void swap(Box &u) {
@ -366,7 +329,7 @@ public:
}
private:
octa::detail::BoxPair<T, D> p_stor;
octa::detail::CompressedPair<T *, D> p_stor;
};
namespace detail {
@ -452,7 +415,7 @@ public:
Box &operator=(Box &&u) {
reset(u.release());
p_stor.get_deleter() = octa::forward<D>(u.get_deleter());
p_stor.second() = octa::forward<D>(u.get_deleter());
return *this;
}
@ -464,7 +427,7 @@ public:
Box &
> operator=(Box<TT, DD> &&u) {
reset(u.release());
p_stor.get_deleter() = octa::forward<DD>(u.get_deleter());
p_stor.second() = octa::forward<DD>(u.get_deleter());
return *this;
}
@ -476,36 +439,36 @@ public:
~Box() { reset(); }
octa::AddLvalueReference<T> operator[](octa::Size idx) const {
return p_stor.p_ptr[idx];
return p_stor.first()[idx];
}
explicit operator bool() const {
return p_stor.p_ptr != nullptr;
return p_stor.first() != nullptr;
}
Pointer get() const { return p_stor.p_ptr; }
Pointer get() const { return p_stor.first(); }
Dref get_deleter() { return p_stor.get_deleter(); }
Dcref get_deleter() const { return p_stor.get_deleter(); }
Dref get_deleter() { return p_stor.second(); }
Dcref get_deleter() const { return p_stor.second(); }
Pointer release() {
Pointer p = p_stor.p_ptr;
p_stor.p_ptr = nullptr;
Pointer p = p_stor.first();
p_stor.first() = nullptr;
return p;
}
template<typename U> EnableIf<
octa::detail::SameOrLessCvQualified<U, Pointer>::value, void
> reset(U p) {
Pointer tmp = p_stor.p_ptr;
p_stor.p_ptr = p;
if (tmp) p_stor.get_deleter()(tmp);
Pointer tmp = p_stor.first();
p_stor.first() = p;
if (tmp) p_stor.second()(tmp);
}
void reset(octa::Nullptr) {
Pointer tmp = p_stor.p_ptr;
p_stor.p_ptr = nullptr;
if (tmp) p_stor.get_deleter()(tmp);
Pointer tmp = p_stor.first();
p_stor.first() = nullptr;
if (tmp) p_stor.second()(tmp);
}
void reset() {
@ -517,7 +480,7 @@ public:
}
private:
octa::detail::BoxPair<T, D> p_stor;
octa::detail::CompressedPair<T *, D> p_stor;
};
namespace detail {

View File

@ -133,7 +133,7 @@ private:
template<typename T, typename A>
class StringBase {
octa::Vector<T> p_buf;
octa::Vector<T, A> p_buf;
void terminate() {
if (p_buf.empty() || (p_buf.back() != '\0')) p_buf.push('\0');
@ -417,7 +417,7 @@ namespace detail {
n = 0;
*(s->data()) = '\0';
}
*(((octa::Size *)s) + 1) = n + 1;
*((octa::Size *)s) = n + 1;
}
}

View File

@ -166,6 +166,125 @@ Pair<typename octa::detail::MakePairRet<T>::Type,
>(forward<T>(a), forward<U>(b));;
}
namespace detail {
template<typename T, typename U,
bool = octa::IsSame<octa::RemoveCv<T>, octa::RemoveCv<U>>::value,
bool = octa::IsEmpty<T>::value,
bool = octa::IsEmpty<U>::value
> struct CompressedPairSwitch;
/* neither empty */
template<typename T, typename U, bool Same>
struct CompressedPairSwitch<T, U, Same, false, false> { enum { value = 0 }; };
/* first empty */
template<typename T, typename U, bool Same>
struct CompressedPairSwitch<T, U, Same, true, false> { enum { value = 1 }; };
/* second empty */
template<typename T, typename U, bool Same>
struct CompressedPairSwitch<T, U, Same, false, true> { enum { value = 2 }; };
/* both empty, not the same */
template<typename T, typename U>
struct CompressedPairSwitch<T, U, false, true, true> { enum { value = 3 }; };
/* both empty and same */
template<typename T, typename U>
struct CompressedPairSwitch<T, U, true, true, true> { enum { value = 1 }; };
template<typename T, typename U, octa::Size = CompressedPairSwitch<T, U>::value>
struct CompressedPairBase;
template<typename T, typename U>
struct CompressedPairBase<T, U, 0> {
T p_first;
U p_second;
CompressedPairBase(T a, U b): p_first(octa::forward<T>(a)),
p_second(octa::forward<U>(b)) {}
T &first() { return p_first; }
const T &first() const { return p_first; }
U &second() { return p_second; }
const U &second() const { return p_second; }
void swap(CompressedPairBase &v) {
octa::swap(p_first, v.p_first);
octa::swap(p_second, v.p_second);
}
};
template<typename T, typename U>
struct CompressedPairBase<T, U, 1>: T {
U p_second;
CompressedPairBase(T a, U b): T(octa::forward<T>(a)),
p_second(octa::forward<U>(b)) {}
T &first() { return *this; }
const T &first() const { return *this; }
U &second() { return p_second; }
const U &second() const { return p_second; }
void swap(CompressedPairBase &v) {
octa::swap(p_second, v.p_second);
}
};
template<typename T, typename U>
struct CompressedPairBase<T, U, 2>: U {
T p_first;
CompressedPairBase(T a, U b): U(octa::forward<U>(b)),
p_first(octa::forward<T>(a)) {}
T &first() { return p_first; }
const T &first() const { return p_first; }
U &second() { return *this; }
const U &second() const { return *this; }
void swap(CompressedPairBase &v) {
octa::swap(p_first, v.p_first);
}
};
template<typename T, typename U>
struct CompressedPairBase<T, U, 3>: T, U {
CompressedPairBase(T a, U b): T(octa::forward<T>(a)),
U(octa::forward<U>(b)) {}
T &first() { return *this; }
const T &first() const { return *this; }
U &second() { return *this; }
const U &second() const { return *this; }
void swap(CompressedPairBase &) {}
};
template<typename T, typename U>
struct CompressedPair: CompressedPairBase<T, U> {
typedef CompressedPairBase<T, U> Base;
CompressedPair(T a, U b): Base(octa::forward<T>(a),
octa::forward<U>(b)) {}
T &first() { return Base::first(); }
const T &first() const { return Base::first(); }
U &second() { return Base::second(); }
const U &second() const { return Base::second(); }
void swap(CompressedPair &v) {
Base::swap(v);
}
};
} /* namespace detail */
} /* namespace octa */
#endif

View File

@ -19,56 +19,20 @@
namespace octa {
namespace detail {
template<typename A, bool = octa::IsEmpty<A>::value>
struct VectorPair;
template<typename A>
struct VectorPair<A, false> { /* non-empty allocator */
octa::AllocatorPointer<A> p_ptr;
A p_a;
template<typename U>
VectorPair(octa::AllocatorPointer<A> ptr, U &&a): p_ptr(ptr),
p_a(octa::forward<U>(a)) {}
A &get_alloc() { return p_a; }
const A &get_alloc() const { return p_a; }
void swap(VectorPair &v) {
octa::swap(p_ptr, v.p_ptr);
octa::swap(p_a , v.p_a );
}
};
template<typename A>
struct VectorPair<A, true>: A { /* empty allocator */
octa::AllocatorPointer<A> p_ptr;
template<typename U>
VectorPair(octa::AllocatorPointer<A> ptr, U &&a):
A(octa::forward<U>(a)), p_ptr(ptr) {}
A &get_alloc() { return *this; }
const A &get_alloc() const { return *this; }
void swap(VectorPair &v) {
octa::swap(p_ptr, v.p_ptr);
}
};
} /* namespace detail */
template<typename T, typename A = octa::Allocator<T>>
class Vector {
using VecPair = octa::detail::VectorPair<A>;
using VecPair = octa::detail::CompressedPair<octa::AllocatorPointer<A>, A>;
VecPair p_buf;
octa::Size p_len, p_cap;
VecPair p_buf;
void insert_base(octa::Size idx, octa::Size n) {
if (p_len + n > p_cap) reserve(p_len + n);
p_len += n;
for (octa::Size i = p_len - 1; i > idx + n - 1; --i) {
p_buf.p_ptr[i] = octa::move(p_buf.p_ptr[i - n]);
p_buf.first()[i] = octa::move(p_buf.first()[i - n]);
}
}
@ -80,12 +44,12 @@ class Vector {
reserve(l);
p_len = l;
if (octa::IsPod<T>() && octa::IsSame<T, octa::RangeValue<R>>()) {
memcpy(p_buf.p_ptr, &range.front(), range.size());
memcpy(p_buf.first(), &range.front(), range.size());
return;
}
for (octa::Size i = 0; !range.empty(); range.pop_front()) {
octa::allocator_construct(p_buf.get_alloc(),
&p_buf.p_ptr[i], range.front());
octa::allocator_construct(p_buf.second(),
&p_buf.first()[i], range.front());
++i;
}
}
@ -97,8 +61,8 @@ class Vector {
octa::Size i = 0;
for (; !range.empty(); range.pop_front()) {
reserve(i + 1);
octa::allocator_construct(p_buf.get_alloc(),
&p_buf.p_ptr[i], range.front());
octa::allocator_construct(p_buf.second(),
&p_buf.first()[i], range.front());
++i;
p_len = i;
}
@ -106,12 +70,12 @@ class Vector {
void copy_contents(const Vector &v) {
if (octa::IsPod<T>()) {
memcpy(p_buf.p_ptr, v.p_buf.p_ptr, p_len * sizeof(T));
memcpy(p_buf.first(), v.p_buf.first(), p_len * sizeof(T));
} else {
Pointer cur = p_buf.p_ptr, last = p_buf.p_ptr + p_len;
Pointer vbuf = v.p_buf.p_ptr;
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
Pointer vbuf = v.p_buf.first();
while (cur != last) {
octa::allocator_construct(p_buf.get_alloc(),
octa::allocator_construct(p_buf.second(),
cur++, *vbuf++);
}
}
@ -133,71 +97,69 @@ public:
>;
using Allocator = A;
Vector(const A &a = A()): p_buf(nullptr, a), p_len(0), p_cap(0) {}
Vector(const A &a = A()): p_len(0), p_cap(0), p_buf(nullptr, a) {}
explicit Vector(Size n, const T &val = T(),
const A &al = A()): Vector(al) {
p_buf.p_ptr = octa::allocator_allocate(p_buf.get_alloc(), n);
p_buf.first() = octa::allocator_allocate(p_buf.second(), n);
p_len = p_cap = n;
Pointer cur = p_buf.p_ptr, last = p_buf.p_ptr + n;
Pointer cur = p_buf.first(), last = p_buf.first() + n;
while (cur != last)
octa::allocator_construct(p_buf.get_alloc(), cur++, val);
octa::allocator_construct(p_buf.second(), cur++, val);
}
Vector(const Vector &v): p_buf(nullptr,
octa::allocator_container_copy(v.p_buf.get_alloc())), p_len(0),
p_cap(0) {
Vector(const Vector &v): p_len(0), p_cap(0), p_buf(nullptr,
octa::allocator_container_copy(v.p_buf.second())) {
reserve(v.p_cap);
p_len = v.p_len;
copy_contents(v);
}
Vector(const Vector &v, const A &a): p_buf(nullptr, a),
p_len(0), p_cap(0) {
Vector(const Vector &v, const A &a): p_len(0), p_cap(0), p_buf(nullptr, a) {
reserve(v.p_cap);
p_len = v.p_len;
copy_contents(v);
}
Vector(Vector &&v): p_buf(v.p_buf.p_ptr,
octa::move(v.p_buf.get_alloc())), p_len(v.p_len), p_cap(v.p_cap) {
v.p_buf.p_ptr = nullptr;
Vector(Vector &&v): p_len(v.p_len), p_cap(v.p_cap), p_buf(v.p_buf.first(),
octa::move(v.p_buf.second())) {
v.p_buf.first() = nullptr;
v.p_len = v.p_cap = 0;
}
Vector(Vector &&v, const A &a) {
if (a != v.a) {
p_buf.get_alloc() = a;
p_buf.second() = a;
reserve(v.p_cap);
p_len = v.p_len;
if (octa::IsPod<T>()) {
memcpy(p_buf.p_ptr, v.p_buf.p_ptr, p_len * sizeof(T));
memcpy(p_buf.first(), v.p_buf.first(), p_len * sizeof(T));
} else {
Pointer cur = p_buf.p_ptr, last = p_buf.p_ptr + p_len;
Pointer vbuf = v.p_buf.p_ptr;
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
Pointer vbuf = v.p_buf.first();
while (cur != last) {
octa::allocator_construct(p_buf.get_alloc(), cur++,
octa::allocator_construct(p_buf.second(), cur++,
octa::move(*vbuf++));
}
}
return;
}
new (&p_buf) VecPair(v.p_buf.p_ptr,
octa::move(v.p_buf.get_alloc()));
new (&p_buf) VecPair(v.p_buf.first(),
octa::move(v.p_buf.second()));
p_len = v.p_len;
p_cap = v.p_cap;
v.p_buf.p_ptr = nullptr;
v.p_buf.first() = nullptr;
v.p_len = v.p_cap = 0;
}
Vector(ConstPointer buf, Size n, const A &a = A()): Vector(a) {
reserve(n);
if (octa::IsPod<T>()) {
memcpy(p_buf.p_ptr, buf, n * sizeof(T));
memcpy(p_buf.first(), buf, n * sizeof(T));
} else {
for (Size i = 0; i < n; ++i)
octa::allocator_construct(p_buf.get_alloc(),
&p_buf.p_ptr[i], buf[i]);
octa::allocator_construct(p_buf.second(),
&p_buf.first()[i], buf[i]);
}
p_len = n;
}
@ -212,14 +174,14 @@ public:
~Vector() {
clear();
octa::allocator_deallocate(p_buf.get_alloc(), p_buf.p_ptr, p_cap);
octa::allocator_deallocate(p_buf.second(), p_buf.first(), p_cap);
}
void clear() {
if (p_len > 0 && !octa::IsPod<T>()) {
Pointer cur = p_buf.p_ptr, last = p_buf.p_ptr + p_len;
Pointer cur = p_buf.first(), last = p_buf.first() + p_len;
while (cur != last)
octa::allocator_destroy(p_buf.get_alloc(), cur++);
octa::allocator_destroy(p_buf.second(), cur++);
}
p_len = 0;
}
@ -235,11 +197,11 @@ public:
Vector &operator=(Vector &&v) {
clear();
octa::allocator_deallocate(p_buf.get_alloc(), p_buf.p_ptr, p_cap);
octa::allocator_deallocate(p_buf.second(), p_buf.first(), p_cap);
p_len = v.p_len;
p_cap = v.p_cap;
p_buf.~VecPair();
new (&p_buf) VecPair(v.disown(), octa::move(v.p_buf.get_alloc()));
new (&p_buf) VecPair(v.disown(), octa::move(v.p_buf.second()));
return *this;
}
@ -248,12 +210,12 @@ public:
Size ilen = il.end() - il.begin();
reserve(ilen);
if (octa::IsPod<T>()) {
memcpy(p_buf.p_ptr, il.begin(), ilen);
memcpy(p_buf.first(), il.begin(), ilen);
} else {
Pointer tbuf = p_buf.p_ptr, ibuf = il.begin(),
Pointer tbuf = p_buf.first(), ibuf = il.begin(),
last = il.end();
while (ibuf != last) {
octa::allocator_construct(p_buf.get_alloc(),
octa::allocator_construct(p_buf.second(),
tbuf++, *ibuf++);
}
}
@ -274,13 +236,13 @@ public:
p_len = n;
if (octa::IsPod<T>()) {
for (Size i = l; i < p_len; ++i) {
p_buf.p_ptr[i] = T(v);
p_buf.first()[i] = T(v);
}
} else {
Pointer first = p_buf.p_ptr + l;
Pointer last = p_buf.p_ptr + p_len;
Pointer first = p_buf.first() + l;
Pointer last = p_buf.first() + p_len;
while (first != last)
octa::allocator_construct(p_buf.get_alloc(), first++, v);
octa::allocator_construct(p_buf.second(), first++, v);
}
}
@ -292,69 +254,69 @@ public:
} else {
while (p_cap < n) p_cap *= 2;
}
Pointer tmp = octa::allocator_allocate(p_buf.get_alloc(), p_cap);
Pointer tmp = octa::allocator_allocate(p_buf.second(), p_cap);
if (oc > 0) {
if (octa::IsPod<T>()) {
memcpy(tmp, p_buf.p_ptr, p_len * sizeof(T));
memcpy(tmp, p_buf.first(), p_len * sizeof(T));
} else {
Pointer cur = p_buf.p_ptr, tcur = tmp,
Pointer cur = p_buf.first(), tcur = tmp,
last = tmp + p_len;
while (tcur != last) {
octa::allocator_construct(p_buf.get_alloc(), tcur++,
octa::allocator_construct(p_buf.second(), tcur++,
octa::move(*cur));
octa::allocator_destroy(p_buf.get_alloc(), cur);
octa::allocator_destroy(p_buf.second(), cur);
++cur;
}
}
octa::allocator_deallocate(p_buf.get_alloc(), p_buf.p_ptr, oc);
octa::allocator_deallocate(p_buf.second(), p_buf.first(), oc);
}
p_buf.p_ptr = tmp;
p_buf.first() = tmp;
}
T &operator[](Size i) { return p_buf.p_ptr[i]; }
const T &operator[](Size i) const { return p_buf.p_ptr[i]; }
T &operator[](Size i) { return p_buf.first()[i]; }
const T &operator[](Size i) const { return p_buf.first()[i]; }
T &at(Size i) { return p_buf.p_ptr[i]; }
const T &at(Size i) const { return p_buf.p_ptr[i]; }
T &at(Size i) { return p_buf.first()[i]; }
const T &at(Size i) const { return p_buf.first()[i]; }
T &push(const T &v) {
if (p_len == p_cap) reserve(p_len + 1);
octa::allocator_construct(p_buf.get_alloc(),
&p_buf.p_ptr[p_len], v);
return p_buf.p_ptr[p_len++];
octa::allocator_construct(p_buf.second(),
&p_buf.first()[p_len], v);
return p_buf.first()[p_len++];
}
T &push() {
if (p_len == p_cap) reserve(p_len + 1);
octa::allocator_construct(p_buf.get_alloc(), &p_buf.p_ptr[p_len]);
return p_buf.p_ptr[p_len++];
octa::allocator_construct(p_buf.second(), &p_buf.first()[p_len]);
return p_buf.first()[p_len++];
}
template<typename ...U>
T &emplace_back(U &&...args) {
if (p_len == p_cap) reserve(p_len + 1);
octa::allocator_construct(p_buf.get_alloc(), &p_buf.p_ptr[p_len],
octa::allocator_construct(p_buf.second(), &p_buf.first()[p_len],
octa::forward<U>(args)...);
return p_buf.p_ptr[p_len++];
return p_buf.first()[p_len++];
}
void pop() {
if (!octa::IsPod<T>()) {
octa::allocator_destroy(p_buf.get_alloc(),
&p_buf.p_ptr[--p_len]);
octa::allocator_destroy(p_buf.second(),
&p_buf.first()[--p_len]);
} else {
--p_len;
}
}
T &front() { return p_buf.p_ptr[0]; }
const T &front() const { return p_buf.p_ptr[0]; }
T &front() { return p_buf.first()[0]; }
const T &front() const { return p_buf.first()[0]; }
T &back() { return p_buf.p_ptr[p_len - 1]; }
const T &back() const { return p_buf.p_ptr[p_len - 1]; }
T &back() { return p_buf.first()[p_len - 1]; }
const T &back() const { return p_buf.first()[p_len - 1]; }
Pointer data() { return p_buf.p_ptr; }
ConstPointer data() const { return p_buf.p_ptr; }
Pointer data() { return p_buf.first(); }
ConstPointer data() const { return p_buf.first(); }
Size size() const { return p_len; }
Size capacity() const { return p_cap; }
@ -364,34 +326,34 @@ public:
bool in_range(Size idx) { return idx < p_len; }
bool in_range(int idx) { return idx >= 0 && Size(idx) < p_len; }
bool in_range(ConstPointer ptr) {
return ptr >= p_buf.p_ptr && ptr < &p_buf.p_ptr[p_len];
return ptr >= p_buf.first() && ptr < &p_buf.first()[p_len];
}
Pointer disown() {
Pointer r = p_buf.p_ptr;
p_buf.p_ptr = nullptr;
Pointer r = p_buf.first();
p_buf.first() = nullptr;
p_len = p_cap = 0;
return r;
}
Range insert(Size idx, T &&v) {
insert_base(idx, 1);
p_buf.p_ptr[idx] = octa::move(v);
return Range(&p_buf.p_ptr[idx], &p_buf.p_ptr[p_len]);
p_buf.first()[idx] = octa::move(v);
return Range(&p_buf.first()[idx], &p_buf.first()[p_len]);
}
Range insert(Size idx, const T &v) {
insert_base(idx, 1);
p_buf.p_ptr[idx] = v;
return Range(&p_buf.p_ptr[idx], &p_buf.p_ptr[p_len]);
p_buf.first()[idx] = v;
return Range(&p_buf.first()[idx], &p_buf.first()[p_len]);
}
Range insert(Size idx, Size n, const T &v) {
insert_base(idx, n);
for (Size i = 0; i < n; ++i) {
p_buf.p_ptr[idx + i] = v;
p_buf.first()[idx + i] = v;
}
return Range(&p_buf.p_ptr[idx], &p_buf.p_ptr[p_len]);
return Range(&p_buf.first()[idx], &p_buf.first()[p_len]);
}
template<typename U>
@ -399,10 +361,10 @@ public:
Size l = range.size();
insert_base(idx, l);
for (Size i = 0; i < l; ++i) {
p_buf.p_ptr[idx + i] = range.front();
p_buf.first()[idx + i] = range.front();
range.pop_front();
}
return Range(&p_buf.p_ptr[idx], &p_buf.p_ptr[p_len]);
return Range(&p_buf.first()[idx], &p_buf.first()[p_len]);
}
Range insert(Size idx, InitializerList<T> il) {
@ -410,13 +372,13 @@ public:
}
Range each() {
return Range(p_buf.p_ptr, p_buf.p_ptr + p_len);
return Range(p_buf.first(), p_buf.first() + p_len);
}
ConstRange each() const {
return ConstRange(p_buf.p_ptr, p_buf.p_ptr + p_len);
return ConstRange(p_buf.first(), p_buf.first() + p_len);
}
ConstRange ceach() const {
return ConstRange(p_buf.p_ptr, p_buf.p_ptr + p_len);
return ConstRange(p_buf.first(), p_buf.first() + p_len);
}
void swap(Vector &v) {
@ -426,7 +388,7 @@ public:
}
A get_allocator() const {
return p_buf.get_alloc();
return p_buf.second();
}
};