use unique_ptr

This commit is contained in:
q66 2017-01-29 15:16:13 +01:00
parent 71515c5383
commit a41299505c
2 changed files with 4 additions and 335 deletions

View file

@ -551,7 +551,7 @@ public:
using AA = AllocatorRebind<A, FuncCore>; using AA = AllocatorRebind<A, FuncCore>;
AA a(f_stor.second()); AA a(f_stor.second());
using D = AllocatorDestructor<AA>; using D = AllocatorDestructor<AA>;
Box<FuncCore, D> hold(a.allocate(1), D(a, 1)); std::unique_ptr<FuncCore, D> hold(a.allocate(1), D(a, 1));
::new(hold.get()) FuncCore(f_stor.first(), A(a)); ::new(hold.get()) FuncCore(f_stor.first(), A(a));
return hold.release(); return hold.release();
} }
@ -739,7 +739,7 @@ Function<R(Args...)>::Function(F f): p_f(nullptr) {
using AA = Allocator<FF>; using AA = Allocator<FF>;
AA a; AA a;
using D = detail::AllocatorDestructor<AA>; using D = detail::AllocatorDestructor<AA>;
Box<FF, D> hold(a.allocate(1), D(a, 1)); std::unique_ptr<FF, D> hold(a.allocate(1), D(a, 1));
::new(hold.get()) FF(std::move(f), Allocator<F>(a)); ::new(hold.get()) FF(std::move(f), Allocator<F>(a));
p_f = hold.release(); p_f = hold.release();
} }
@ -763,7 +763,7 @@ Function<R(Args...)>::Function(AllocatorArg, A const &a, F f):
return; return;
} }
using D = detail::AllocatorDestructor<AA>; using D = detail::AllocatorDestructor<AA>;
Box<FF, D> hold(aa.allocate(1), D(aa, 1)); std::unique_ptr<FF, D> hold(aa.allocate(1), D(aa, 1));
::new(hold.get()) FF(std::move(f), A(aa)); ::new(hold.get()) FF(std::move(f), A(aa));
p_f = hold.release(); p_f = hold.release();
} }

View file

@ -8,6 +8,7 @@
#include <stddef.h> #include <stddef.h>
#include <new> #include <new>
#include <memory>
#include "ostd/utility.hh" #include "ostd/utility.hh"
#include "ostd/type_traits.hh" #include "ostd/type_traits.hh"
@ -189,36 +190,6 @@ static T pointer_to(
return detail::PointerTo<T>::pointer_to(r); return detail::PointerTo<T>::pointer_to(r);
} }
/* default deleter */
template<typename T>
struct DefaultDelete {
constexpr DefaultDelete() = default;
template<typename U>
DefaultDelete(DefaultDelete<U> const &) noexcept {};
void operator()(T *p) const {
delete p;
}
};
template<typename T>
struct DefaultDelete<T[]> {
constexpr DefaultDelete() = default;
template<typename U>
DefaultDelete(DefaultDelete<U[]> const &) noexcept {};
void operator()(T *p) const {
delete[] p;
}
template<typename U>
void operator()(U *) const = delete;
};
/* box */
namespace detail { namespace detail {
template<typename T> template<typename T>
static int ptr_test(...); static int ptr_test(...);
@ -244,308 +215,6 @@ namespace detail {
}; };
} /* namespace detail */ } /* namespace detail */
template<typename T, typename D = DefaultDelete<T>>
struct Box {
using Element = T;
using Deleter = D;
using Pointer = typename detail::PointerType<T, D>::Type;
private:
struct Nat { int x; };
using Dref = RemoveReference<D> &;
using Dcref = RemoveReference<D> const &;
public:
constexpr Box() noexcept: p_stor(nullptr, D()) {
static_assert(!IsPointer<D>, "Box constructed with null fptr deleter");
}
constexpr Box(Nullptr) noexcept: p_stor(nullptr, D()) {
static_assert(!IsPointer<D>, "Box constructed with null fptr deleter");
}
explicit Box(Pointer p) noexcept: p_stor(p, D()) {
static_assert(!IsPointer<D>, "Box constructed with null fptr deleter");
}
Box(
Pointer p, Conditional<IsReference<D>, D, AddLvalueReference<D const>> d
) noexcept:
p_stor(p, d)
{}
Box(Pointer p, RemoveReference<D> &&d) noexcept:
p_stor(p, std::move(d))
{
static_assert(!IsReference<D>, "rvalue deleter cannot be a ref");
}
Box(Box &&u) noexcept:
p_stor(u.release(), std::forward<D>(u.get_deleter()))
{}
template<typename TT, typename DD>
Box(
Box<TT, DD> &&u, EnableIf<
!IsArray<TT> &&
IsConvertible<typename Box<TT, DD>::Pointer, Pointer> &&
IsConvertible<DD, D> && (!IsReference<D> || IsSame<D, DD>),
Nat
> = Nat()
) noexcept: p_stor(u.release(), std::forward<DD>(u.get_deleter())) {}
Box &operator=(Box &&u) noexcept {
reset(u.release());
p_stor.second() = std::forward<D>(u.get_deleter());
return *this;
}
template<typename TT, typename DD>
EnableIf<
!IsArray<TT> &&
IsConvertible<typename Box<TT, DD>::Pointer, Pointer> &&
IsAssignable<D &, DD &&>,
Box &
> operator=(Box<TT, DD> &&u) noexcept {
reset(u.release());
p_stor.second() = std::forward<DD>(u.get_deleter());
return *this;
}
Box &operator=(Nullptr) noexcept {
reset();
return *this;
}
~Box() { reset(); }
AddLvalueReference<T> operator*() const { return *p_stor.first(); }
Pointer operator->() const noexcept { return p_stor.first(); }
explicit operator bool() const noexcept {
return p_stor.first() != nullptr;
}
Pointer get() const noexcept { return p_stor.first(); }
Dref get_deleter() noexcept { return p_stor.second(); }
Dcref get_deleter() const noexcept { return p_stor.second(); }
Pointer release() noexcept {
Pointer p = p_stor.first();
p_stor.first() = nullptr;
return p;
}
void reset(Pointer p = nullptr) noexcept {
Pointer tmp = p_stor.first();
p_stor.first() = p;
if (tmp) {
p_stor.second()(tmp);
}
}
void swap(Box &u) noexcept {
p_stor.swap(u.p_stor);
}
private:
detail::CompressedPair<T *, D> p_stor;
};
namespace detail {
template<typename T, typename U, bool = IsSame<
RemoveCv<PointerElement<T>>,
RemoveCv<PointerElement<U>>
>>
constexpr bool SameOrLessCvQualifiedBase = IsConvertible<T, U>;
template<typename T, typename U>
constexpr bool SameOrLessCvQualifiedBase<T, U, false> = false;
template<typename T, typename U, bool =
IsPointer<T> || IsSame<T, U> || detail::HasElement<T>::value
>
constexpr bool SameOrLessCvQualified = SameOrLessCvQualifiedBase<T, U>;
template<typename T, typename U>
constexpr bool SameOrLessCvQualified<T, U, false> = false;
} /* namespace detail */
template<typename T, typename D>
struct Box<T[], D> {
using Element = T;
using Deleter = D;
using Pointer = typename detail::PointerType<T, D>::Type;
private:
struct Nat { int x; };
using Dref = RemoveReference<D> &;
using Dcref = RemoveReference<D> const &;
public:
constexpr Box() noexcept: p_stor(nullptr, D()) {
static_assert(!IsPointer<D>, "Box constructed with null fptr deleter");
}
constexpr Box(Nullptr) noexcept: p_stor(nullptr, D()) {
static_assert(!IsPointer<D>, "Box constructed with null fptr deleter");
}
template<typename U> explicit Box(U p, EnableIf<
detail::SameOrLessCvQualified<U, Pointer>, Nat
> = Nat()) noexcept: p_stor(p, D()) {
static_assert(!IsPointer<D>, "Box constructed with null fptr deleter");
}
template<typename U> Box(U p, Conditional<
IsReference<D>, D, AddLvalueReference<D const>
> d, EnableIf<
detail::SameOrLessCvQualified<U, Pointer>, Nat
> = Nat()) noexcept:
p_stor(p, d)
{}
Box(
Nullptr, Conditional<IsReference<D>, D, AddLvalueReference<D const>> d
) noexcept:
p_stor(nullptr, d)
{}
template<typename U> Box(U p, RemoveReference<D> &&d,
EnableIf<detail::SameOrLessCvQualified<U, Pointer>, Nat> = Nat()) noexcept:
p_stor(p, std::move(d))
{
static_assert(!IsReference<D>, "rvalue deleter cannot be a ref");
}
Box(Nullptr, RemoveReference<D> &&d) noexcept:
p_stor(nullptr, std::move(d))
{
static_assert(!IsReference<D>, "rvalue deleter cannot be a ref");
}
Box(Box &&u) noexcept:
p_stor(u.release(), std::forward<D>(u.get_deleter()))
{}
template<typename TT, typename DD>
Box(
Box<TT, DD> &&u, EnableIf<
IsArray<TT> &&
detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer,Pointer> &&
IsConvertible<DD, D> && (!IsReference<D> || IsSame<D, DD>),
Nat
> = Nat()
) noexcept:
p_stor(u.release(), std::forward<DD>(u.get_deleter()))
{}
Box &operator=(Box &&u) noexcept {
reset(u.release());
p_stor.second() = std::forward<D>(u.get_deleter());
return *this;
}
template<typename TT, typename DD>
EnableIf<
IsArray<TT> &&
detail::SameOrLessCvQualified<typename Box<TT, DD>::Pointer, Pointer> &&
IsAssignable<D &, DD &&>,
Box &
> operator=(Box<TT, DD> &&u) noexcept {
reset(u.release());
p_stor.second() = std::forward<DD>(u.get_deleter());
return *this;
}
Box &operator=(Nullptr) noexcept {
reset();
return *this;
}
~Box() { reset(); }
AddLvalueReference<T> operator[](Size idx) const {
return p_stor.first()[idx];
}
explicit operator bool() const noexcept {
return p_stor.first() != nullptr;
}
Pointer get() const noexcept { return p_stor.first(); }
Dref get_deleter() noexcept { return p_stor.second(); }
Dcref get_deleter() const noexcept { return p_stor.second(); }
Pointer release() noexcept {
Pointer p = p_stor.first();
p_stor.first() = nullptr;
return p;
}
template<typename U>
EnableIf<
detail::SameOrLessCvQualified<U, Pointer>, void
> reset(U p) noexcept {
Pointer tmp = p_stor.first();
p_stor.first() = p;
if (tmp) {
p_stor.second()(tmp);
}
}
void reset(Nullptr) noexcept {
Pointer tmp = p_stor.first();
p_stor.first() = nullptr;
if (tmp) {
p_stor.second()(tmp);
}
}
void reset() noexcept {
reset(nullptr);
}
void swap(Box &u) noexcept {
p_stor.swap(u.p_stor);
}
private:
detail::CompressedPair<T *, D> p_stor;
};
namespace detail {
template<typename T>
struct BoxIf {
using BoxType = Box<T>;
};
template<typename T>
struct BoxIf<T[]> {
using BoxUnknownSize = Box<T[]>;
};
template<typename T, Size N>
struct BoxIf<T[N]> {
using BoxKnownSize = void;
};
}
template<typename T, typename ...A>
typename detail::BoxIf<T>::BoxType make_box(A &&...args) {
return Box<T>(new T(std::forward<A>(args)...));
}
template<typename T>
typename detail::BoxIf<T>::BoxUnknownSize make_box(Size n) {
return Box<T>(new RemoveExtent<T>[n]());
}
template<typename T, typename ...A>
typename detail::BoxIf<T>::BoxKnownSize make_box(A &&...args) = delete;
/* allocator */ /* allocator */
template<typename T> template<typename T>