memory.h partial cleanup

master
Daniel Kolesa 2015-06-04 01:45:30 +01:00
parent 62b8bee6c3
commit 1b038b0de8
1 changed files with 120 additions and 114 deletions

View File

@ -15,9 +15,9 @@
namespace octa { namespace octa {
/* address of */ /* address of */
template<typename _T> constexpr _T *address_of(_T &__v) { template<typename _T> constexpr _T *address_of(_T &v) {
return reinterpret_cast<_T *>(&const_cast<char &> return reinterpret_cast<_T *>(&const_cast<char &>
(reinterpret_cast<const volatile char &>(__v))); (reinterpret_cast<const volatile char &>(v)));
} }
/* pointer traits */ /* pointer traits */
@ -187,8 +187,8 @@ namespace octa {
template<typename _U> DefaultDelete(const DefaultDelete<_U> &) {}; template<typename _U> DefaultDelete(const DefaultDelete<_U> &) {};
void operator()(_T *__p) const { void operator()(_T *p) const {
delete __p; delete p;
} }
}; };
@ -198,8 +198,8 @@ namespace octa {
template<typename _U> DefaultDelete(const DefaultDelete<_U[]> &) {}; template<typename _U> DefaultDelete(const DefaultDelete<_U[]> &) {};
void operator()(_T *__p) const { void operator()(_T *p) const {
delete[] __p; delete[] p;
} }
template<typename _U> void operator()(_U *) const = delete; template<typename _U> void operator()(_U *) const = delete;
}; };
@ -896,201 +896,207 @@ namespace octa {
template<typename _A> template<typename _A>
using IsAlwaysEqual = typename __OctaIsAlwaysEqual<_A>::Type; using IsAlwaysEqual = typename __OctaIsAlwaysEqual<_A>::Type;
/* allocator allocate */ /* allocator allocate */
template<typename _A> template<typename _A>
inline AllocatorPointer<_A> inline AllocatorPointer<_A>
allocator_allocate(_A &__a, AllocatorSize<_A> __n) { allocator_allocate(_A &a, AllocatorSize<_A> n) {
return __a.allocate(__n); return a.allocate(n);
} }
namespace detail {
template<typename _A, typename _S, typename _CVP>
auto allocate_hint_test(_A &&a, _S &&sz, _CVP &&p)
-> decltype(a.allocate(sz, p), octa::True());
template<typename _A, typename _S, typename _CVP> template<typename _A, typename _S, typename _CVP>
auto __octa_allocate_hint_test(_A &&__a, _S &&__sz, _CVP &&__p) auto allocate_hint_test(const _A &, _S &&, _CVP &&)
-> decltype(__a.allocate(__sz, __p), octa::True());
template<typename _A, typename _S, typename _CVP>
auto __octa_allocate_hint_test(const _A &__a, _S &&__sz, _CVP &&__p)
-> octa::False; -> octa::False;
template<typename _A, typename _S, typename _CVP> template<typename _A, typename _S, typename _CVP>
struct __OctaAllocateHintTest: octa::IntegralConstant<bool, struct AllocateHintTest: octa::IntegralConstant<bool,
octa::IsSame< octa::IsSame<
decltype(__octa_allocate_hint_test(octa::declval<_A>(), decltype(allocate_hint_test(octa::declval<_A>(),
octa::declval<_S>(), octa::declval<_S>(),
octa::declval<_CVP>())), octa::declval<_CVP>())),
octa::True octa::True
>::value >::value
> {}; > {};
template<typename _A> template<typename _A>
inline AllocatorPointer<_A> inline AllocatorPointer<_A> allocate(_A &a, AllocatorSize<_A> n,
__octa_allocate(_A &__a, AllocatorSize<_A> __n, AllocatorConstVoidPointer<_A> h,
AllocatorConstVoidPointer<_A> __h, octa::True) { octa::True) {
return __a.allocate(__n, __h); return a.allocate(n, h);
} }
template<typename _A> template<typename _A>
inline AllocatorPointer<_A> inline AllocatorPointer<_A> allocate(_A &a, AllocatorSize<_A> n,
__octa_allocate(_A &__a, AllocatorSize<_A> __n, AllocatorConstVoidPointer<_A>,
AllocatorConstVoidPointer<_A>, octa::False) { octa::False) {
return __a.allocate(__n); return a.allocate(n);
} }
} /* namespace detail */
template<typename _A> template<typename _A>
inline AllocatorPointer<_A> inline AllocatorPointer<_A>
allocator_allocate(_A &__a, AllocatorSize<_A> __n, allocator_allocate(_A &a, AllocatorSize<_A> n,
AllocatorConstVoidPointer<_A> __h) { AllocatorConstVoidPointer<_A> h) {
return __octa_allocate(__a, __n, __h, __OctaAllocateHintTest< return octa::detail::allocate(a, n, h,
octa::detail::AllocateHintTest<
_A, AllocatorSize<_A>, AllocatorConstVoidPointer<_A> _A, AllocatorSize<_A>, AllocatorConstVoidPointer<_A>
>()); >());
} }
/* allocator deallocate */ /* allocator deallocate */
template<typename _A> template<typename _A>
inline void allocator_deallocate(_A &__a, AllocatorPointer<_A> __p, inline void allocator_deallocate(_A &a, AllocatorPointer<_A> p,
AllocatorSize<_A> __n) { AllocatorSize<_A> n) {
__a.deallocate(__p, __n); a.deallocate(p, n);
} }
/* allocator construct */ /* allocator construct */
namespace detail {
template<typename _A, typename _T, typename ..._Args> template<typename _A, typename _T, typename ..._Args>
auto __octa_construct_test(_A &&__a, _T *__p, _Args &&...__args) auto construct_test(_A &&a, _T *p, _Args &&...args)
-> decltype(__a.construct(__p, octa::forward<_Args>(__args)...), -> decltype(a.construct(p, octa::forward<_Args>(args)...),
octa::True()); octa::True());
template<typename _A, typename _T, typename ..._Args> template<typename _A, typename _T, typename ..._Args>
auto __octa_construct_test(const _A &__a, _T *__p, _Args &&...__args) auto construct_test(const _A &, _T *, _Args &&...)
-> octa::False; -> octa::False;
template<typename _A, typename _T, typename ..._Args> template<typename _A, typename _T, typename ..._Args>
struct __OctaConstructTest: octa::IntegralConstant<bool, struct ConstructTest: octa::IntegralConstant<bool,
octa::IsSame< octa::IsSame<
decltype(__octa_construct_test(octa::declval<_A>(), decltype(construct_test(octa::declval<_A>(),
octa::declval<_T>(), octa::declval<_T>(),
octa::declval<_Args>()...)), octa::declval<_Args>()...)),
octa::True octa::True
>::value >::value
> {}; > {};
template<typename _A, typename _T, typename ..._Args> template<typename _A, typename _T, typename ..._Args>
inline void inline void construct(octa::True, _A &a, _T *p, _Args &&...args) {
__octa_construct(octa::True, _A &__a, _T *__p, _Args &&...__args) { a.construct(p, octa::forward<_Args>(args)...);
__a.construct(__p, octa::forward<_Args>(__args)...);
} }
template<typename _A, typename _T, typename ..._Args> template<typename _A, typename _T, typename ..._Args>
inline void inline void construct(octa::False, _A &, _T *p, _Args &&...args) {
__octa_construct(octa::False, _A &, _T *__p, _Args &&...__args) { ::new ((void *)p) _T(octa::forward<_Args>(args)...);
::new ((void *)__p) _T(octa::forward<_Args>(__args)...);
} }
} /* namespace detail */
template<typename _A, typename _T, typename ..._Args> template<typename _A, typename _T, typename ..._Args>
inline void allocator_construct(_A &__a, _T *__p, _Args &&...__args) { inline void allocator_construct(_A &a, _T *p, _Args &&...args) {
__octa_construct(__OctaConstructTest<_A, _T *, _Args...>(), octa::detail::construct(octa::detail::ConstructTest<
__a, __p, octa::forward<_Args>(__args)...); _A, _T *, _Args...
} >(), a, p, octa::forward<_Args>(args)...);
}
/* allocator destroy */ /* allocator destroy */
namespace detail {
template<typename _A, typename _P>
auto destroy_test(_A &&a, _P &&p) -> decltype(a.destroy(p), octa::True());
template<typename _A, typename _P> template<typename _A, typename _P>
auto __octa_destroy_test(_A &&__a, _P &&__p) auto destroy_test(const _A &, _P &&) -> octa::False;
-> decltype(__a.destroy(__p), octa::True());
template<typename _A, typename _P> template<typename _A, typename _P>
auto __octa_destroy_test(const _A &__a, _P &&__p) -> octa::False; struct DestroyTest: octa::IntegralConstant<bool,
template<typename _A, typename _P>
struct __OctaDestroyTest: octa::IntegralConstant<bool,
octa::IsSame< octa::IsSame<
decltype(__octa_destroy_test(octa::declval<_A>(), decltype(destroy_test(octa::declval<_A>(), octa::declval<_P>())),
octa::declval<_P>())),
octa::True octa::True
>::value >::value
> {}; > {};
template<typename _A, typename _T> template<typename _A, typename _T>
inline void __octa_destroy(octa::True, _A &__a, _T *__p) { inline void destroy(octa::True, _A &a, _T *p) {
__a.destroy(__p); a.destroy(p);
} }
template<typename _A, typename _T> template<typename _A, typename _T>
inline void __octa_destroy(octa::False, _A &, _T *__p) { inline void destroy(octa::False, _A &, _T *p) {
__p->~_T(); p->~_T();
} }
} /* namespace detail */
template<typename _A, typename _T> template<typename _A, typename _T>
inline void allocator_destroy(_A &__a, _T *__p) { inline void allocator_destroy(_A &a, _T *p) {
__octa_destroy(__OctaDestroyTest<_A, _T *>(), __a, __p); octa::detail::destroy(octa::detail::DestroyTest<_A, _T *>(), a, p);
} }
/* allocator max size */ /* allocator max size */
namespace detail {
template<typename _A>
auto alloc_max_size_test(_A &&a) -> decltype(a.max_size(), octa::True());
template<typename _A> template<typename _A>
auto __octa_alloc_max_size_test(_A &&__a) auto alloc_max_size_test(const _A &) -> octa::False;
-> decltype(__a.max_size(), octa::True());
template<typename _A> template<typename _A>
auto __octa_alloc_max_size_test(const _A &__a) -> octa::False; struct AllocMaxSizeTest: octa::IntegralConstant<bool,
template<typename _A>
struct __OctaAllocMaxSizeTest: octa::IntegralConstant<bool,
octa::IsSame< octa::IsSame<
decltype(__octa_alloc_max_size_test(octa::declval<_A &>())), decltype(alloc_max_size_test(octa::declval<_A &>())),
octa::True octa::True
>::value >::value
> {}; > {};
template<typename _A> template<typename _A>
inline AllocatorSize<_A> __octa_alloc_max_size(octa::True, const _A &__a) { inline AllocatorSize<_A> alloc_max_size(octa::True, const _A &a) {
return __a.max_size(); return a.max_size();
} }
template<typename _A> template<typename _A>
inline AllocatorSize<_A> __octa_alloc_max_size(octa::False, const _A &) { inline AllocatorSize<_A> alloc_max_size(octa::False, const _A &) {
return AllocatorSize<_A>(~0); return AllocatorSize<_A>(~0);
} }
} /* namespace detail */
template<typename _A>
inline AllocatorSize<_A> allocator_max_size(const _A &a) {
return octa::detail::alloc_max_size(octa::detail::AllocMaxSizeTest<
const _A
>(), a);
}
/* allocator container copy */
namespace detail {
template<typename _A>
auto alloc_copy_test(_A &&a) -> decltype(a.container_copy(), octa::True());
template<typename _A> template<typename _A>
inline AllocatorSize<_A> allocator_max_size(const _A &__a) { auto alloc_copy_test(const _A &) -> octa::False;
return __octa_alloc_max_size(__OctaAllocMaxSizeTest<const _A>(), __a);
}
/* allocator container copy */
template<typename _A> template<typename _A>
auto __octa_alloc_copy_test(_A &&__a) struct AllocCopyTest: octa::IntegralConstant<bool,
-> decltype(__a.container_copy(), octa::True());
template<typename _A>
auto __octa_alloc_copy_test(const _A &__a) -> octa::False;
template<typename _A>
struct __OctaAllocCopyTest: octa::IntegralConstant<bool,
octa::IsSame< octa::IsSame<
decltype(__octa_alloc_copy_test(octa::declval<_A &>())), decltype(alloc_copy_test(octa::declval<_A &>())), octa::True
octa::True
>::value >::value
> {}; > {};
template<typename _A> template<typename _A>
inline AllocatorType<_A> inline AllocatorType<_A> alloc_container_copy(octa::True, const _A &a) {
__octa_alloc_container_copy(octa::True, const _A &__a) { return a.container_copy();
return __a.container_copy();
} }
template<typename _A> template<typename _A>
inline AllocatorType<_A> inline AllocatorType<_A> alloc_container_copy(octa::False, const _A &a) {
__octa_alloc_container_copy(octa::False, const _A &__a) { return a;
return __a;
} }
} /* namespace detail */
template<typename _A> template<typename _A>
inline AllocatorType<_A> allocator_container_copy(const _A &__a) { inline AllocatorType<_A> allocator_container_copy(const _A &a) {
return __octa_alloc_container_copy(__OctaAllocCopyTest<const _A>(), return octa::detail::alloc_container_copy(octa::detail::AllocCopyTest<
__a); const _A
} >(), a);
}
} }
#endif #endif