forked from OctaForge/libostd
fully cleaned up memory.h
parent
bc2e3575b2
commit
d9366475b5
250
octa/memory.h
250
octa/memory.h
|
@ -13,198 +13,198 @@
|
||||||
#include "octa/type_traits.h"
|
#include "octa/type_traits.h"
|
||||||
|
|
||||||
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 */
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
template<typename _T>
|
template<typename _T>
|
||||||
struct __OctaHasElement {
|
struct HasElement {
|
||||||
template<typename _U>
|
template<typename _U> static int test(...);
|
||||||
static int __test(...);
|
template<typename _U> static char test(typename _U::Element * = 0);
|
||||||
template<typename _U>
|
|
||||||
static char __test(typename _U::Element * = 0);
|
|
||||||
|
|
||||||
static constexpr bool value = (sizeof(__test<_T>(0)) == 1);
|
static constexpr bool value = (sizeof(test<_T>(0)) == 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _T, bool = __OctaHasElement<_T>::value>
|
template<typename _T, bool = HasElement<_T>::value>
|
||||||
struct __OctaPtrTraitsElementType;
|
struct PointerElementBase;
|
||||||
|
|
||||||
template<typename _T> struct __OctaPtrTraitsElementType<_T, true> {
|
template<typename _T> struct PointerElementBase<_T, true> {
|
||||||
typedef typename _T::Element Type;
|
typedef typename _T::Element Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<template<typename, typename...> class _T, typename _U, typename ..._A>
|
template<template<typename, typename...> class _T, typename _U, typename ..._A>
|
||||||
struct __OctaPtrTraitsElementType<_T<_U, _A...>, true> {
|
struct PointerElementBase<_T<_U, _A...>, true> {
|
||||||
typedef typename _T<_U, _A...>::Element Type;
|
typedef typename _T<_U, _A...>::Element Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<template<typename, typename...> class _T, typename _U, typename ..._A>
|
template<template<typename, typename...> class _T, typename _U, typename ..._A>
|
||||||
struct __OctaPtrTraitsElementType<_T<_U, _A...>, false> {
|
struct PointerElementBase<_T<_U, _A...>, false> {
|
||||||
typedef _U Type;
|
typedef _U Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _T>
|
template<typename _T>
|
||||||
struct __OctaHasDifference {
|
struct PointerElementType {
|
||||||
template<typename _U>
|
typedef typename PointerElementBase<_T>::Type Type;
|
||||||
static int __test(...);
|
|
||||||
template<typename _U>
|
|
||||||
static char __test(typename _U::Difference * = 0);
|
|
||||||
|
|
||||||
static constexpr bool value = (sizeof(__test<_T>(0)) == 1);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _T, bool = __OctaHasDifference<_T>::value>
|
template<typename _T>
|
||||||
struct __OctaPtrTraitsDifferenceType {
|
struct PointerElementType<_T *> {
|
||||||
|
typedef _T Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _T>
|
||||||
|
struct HasDifference {
|
||||||
|
template<typename _U> static int test(...);
|
||||||
|
template<typename _U> static char test(typename _U::Difference * = 0);
|
||||||
|
|
||||||
|
static constexpr bool value = (sizeof(test<_T>(0)) == 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _T, bool = HasDifference<_T>::value>
|
||||||
|
struct PointerDifferenceBase {
|
||||||
typedef ptrdiff_t Type;
|
typedef ptrdiff_t Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _T> struct __OctaPtrTraitsDifferenceType<_T, true> {
|
template<typename _T> struct PointerDifferenceBase<_T, true> {
|
||||||
typedef typename _T::Difference Type;
|
typedef typename _T::Difference Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _T, typename _U>
|
template<typename _T>
|
||||||
struct __OctaHasRebind {
|
struct PointerDifferenceType {
|
||||||
template<typename _V>
|
typedef typename PointerDifferenceBase<_T>::Type Type;
|
||||||
static int __test(...);
|
|
||||||
template<typename _V>
|
|
||||||
static char __test(typename _V::template Rebind<_U> * = 0);
|
|
||||||
|
|
||||||
static constexpr bool value = (sizeof(__test<_T>(0)) == 1);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _T, typename _U, bool = __OctaHasRebind<_T, _U>::value>
|
template<typename _T>
|
||||||
struct __OctaPtrTraitsRebindType {
|
struct PointerDifferenceType<_T *> {
|
||||||
|
typedef ptrdiff_t Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _T, typename _U>
|
||||||
|
struct HasRebind {
|
||||||
|
template<typename _V> static int test(...);
|
||||||
|
template<typename _V> static char test(
|
||||||
|
typename _V::template Rebind<_U> * = 0);
|
||||||
|
|
||||||
|
static constexpr bool value = (sizeof(test<_T>(0)) == 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _T, typename _U, bool = HasRebind<_T, _U>::value>
|
||||||
|
struct PointerRebindBase {
|
||||||
typedef typename _T::template Rebind<_U> Type;
|
typedef typename _T::template Rebind<_U> Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<template<typename, typename...> class _T, typename _U,
|
template<template<typename, typename...> class _T, typename _U,
|
||||||
typename ..._A, typename _V
|
typename ..._A, typename _V
|
||||||
>
|
>
|
||||||
struct __OctaPtrTraitsRebindType<_T<_U, _A...>, _V, true> {
|
struct PointerRebindBase<_T<_U, _A...>, _V, true> {
|
||||||
typedef typename _T<_U, _A...>::template Rebind<_V> Type;
|
typedef typename _T<_U, _A...>::template Rebind<_V> Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<template<typename, typename...> class _T, typename _U,
|
template<template<typename, typename...> class _T, typename _U,
|
||||||
typename ..._A, typename _V
|
typename ..._A, typename _V
|
||||||
>
|
>
|
||||||
struct __OctaPtrTraitsRebindType<_T<_U, _A...>, _V, false> {
|
struct PointerRebindBase<_T<_U, _A...>, _V, false> {
|
||||||
typedef _T<_V, _A...> Type;
|
typedef _T<_V, _A...> Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _T>
|
|
||||||
struct __OctaPtrTraitsPointer {
|
|
||||||
typedef _T Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _T>
|
|
||||||
struct __OctaPtrTraitsPointer<_T *> {
|
|
||||||
typedef _T *Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _T>
|
|
||||||
using Pointer = typename __OctaPtrTraitsPointer<_T>::Type;
|
|
||||||
|
|
||||||
template<typename _T>
|
|
||||||
struct __OctaPtrTraitsElement {
|
|
||||||
typedef typename __OctaPtrTraitsElementType<_T>::Type Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _T>
|
|
||||||
struct __OctaPtrTraitsElement<_T *> {
|
|
||||||
typedef _T Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _T>
|
|
||||||
using PointerElement = typename __OctaPtrTraitsElement<_T>::Type;
|
|
||||||
|
|
||||||
template<typename _T>
|
|
||||||
struct __OctaPtrTraitsDifference {
|
|
||||||
typedef typename __OctaPtrTraitsDifferenceType<_T>::Type Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<typename _T>
|
|
||||||
struct __OctaPtrTraitsDifference<_T *> {
|
|
||||||
typedef ptrdiff_t Type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _T>
|
|
||||||
using PointerDifference = typename __OctaPtrTraitsDifference<_T>::Type;
|
|
||||||
|
|
||||||
template<typename _T, typename _U>
|
template<typename _T, typename _U>
|
||||||
struct __OctaPtrTraitsRebind {
|
struct PointerRebindType {
|
||||||
using type = typename __OctaPtrTraitsRebindType<_T, _U>::Type;
|
using type = typename PointerRebindBase<_T, _U>::Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _T, typename _U>
|
template<typename _T, typename _U>
|
||||||
struct __OctaPtrTraitsRebind<_T *, _U> {
|
struct PointerRebindType<_T *, _U> {
|
||||||
using type = _U *;
|
using type = _U *;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _T, typename _U>
|
template<typename _T>
|
||||||
using PointerRebind = typename __OctaPtrTraitsRebind<_T, _U>::Type;
|
struct PointerPointer {
|
||||||
|
typedef _T Type;
|
||||||
struct __OctaPtrTraitsNat {};
|
};
|
||||||
|
|
||||||
template<typename _T>
|
template<typename _T>
|
||||||
struct __OctaPtrTraitsPointerTo {
|
struct PointerPointer<_T *> {
|
||||||
|
typedef _T *Type;
|
||||||
|
};
|
||||||
|
} /*namespace detail */
|
||||||
|
|
||||||
|
template<typename _T>
|
||||||
|
using Pointer = typename octa::detail::PointerPointer<_T>::Type;
|
||||||
|
|
||||||
|
template<typename _T>
|
||||||
|
using PointerElement = typename octa::detail::PointerElementType<_T>::Type;
|
||||||
|
|
||||||
|
template<typename _T>
|
||||||
|
using PointerDifference = typename octa::detail::PointerDifferenceType<_T>::Type;
|
||||||
|
|
||||||
|
template<typename _T, typename _U>
|
||||||
|
using PointerRebind = typename octa::detail::PointerRebindType<_T, _U>::Type;
|
||||||
|
|
||||||
|
/* pointer to */
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
struct PointerToNat {};
|
||||||
|
|
||||||
|
template<typename _T>
|
||||||
|
struct PointerTo {
|
||||||
static _T pointer_to(octa::Conditional<
|
static _T pointer_to(octa::Conditional<
|
||||||
octa::IsVoid<PointerElement<_T>>::value,
|
octa::IsVoid<PointerElement<_T>>::value,
|
||||||
__OctaPtrTraitsNat, PointerElement<_T>
|
PointerToNat, PointerElement<_T>
|
||||||
> &__r) {
|
> &r) {
|
||||||
return _T::pointer_to(__r);
|
return _T::pointer_to(r);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _T>
|
template<typename _T>
|
||||||
struct __OctaPtrTraitsPointerTo<_T *> {
|
struct PointerTo<_T *> {
|
||||||
static _T pointer_to(octa::Conditional<
|
static _T pointer_to(octa::Conditional<
|
||||||
octa::IsVoid<_T>::value, __OctaPtrTraitsNat, _T
|
octa::IsVoid<_T>::value, PointerToNat, _T
|
||||||
> &__r) {
|
> &r) {
|
||||||
return octa::address_of(__r);
|
return octa::address_of(r);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
template<typename _T>
|
template<typename _T>
|
||||||
static _T pointer_to(octa::Conditional<
|
static _T pointer_to(octa::Conditional<
|
||||||
octa::IsVoid<PointerElement<_T>>::value,
|
octa::IsVoid<PointerElement<_T>>::value,
|
||||||
__OctaPtrTraitsNat, PointerElement<_T>
|
octa::detail::PointerToNat, PointerElement<_T>
|
||||||
> &__r) {
|
> &r) {
|
||||||
return __OctaPtrTraitsPointerTo<_T>::pointer_to(__r);
|
return octa::detail::PointerTo<_T>::pointer_to(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* default deleter */
|
||||||
|
|
||||||
|
template<typename _T>
|
||||||
|
struct DefaultDelete {
|
||||||
|
constexpr DefaultDelete() = default;
|
||||||
|
|
||||||
|
template<typename _U> DefaultDelete(const DefaultDelete<_U> &) {};
|
||||||
|
|
||||||
|
void operator()(_T *p) const {
|
||||||
|
delete p;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* default deleter */
|
template<typename _T>
|
||||||
|
struct DefaultDelete<_T[]> {
|
||||||
|
constexpr DefaultDelete() = default;
|
||||||
|
|
||||||
template<typename _T>
|
template<typename _U> DefaultDelete(const DefaultDelete<_U[]> &) {};
|
||||||
struct DefaultDelete {
|
|
||||||
constexpr DefaultDelete() = default;
|
|
||||||
|
|
||||||
template<typename _U> DefaultDelete(const DefaultDelete<_U> &) {};
|
void operator()(_T *p) const {
|
||||||
|
delete[] p;
|
||||||
|
}
|
||||||
|
template<typename _U> void operator()(_U *) const = delete;
|
||||||
|
};
|
||||||
|
|
||||||
void operator()(_T *p) const {
|
/* box */
|
||||||
delete p;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename _T>
|
|
||||||
struct DefaultDelete<_T[]> {
|
|
||||||
constexpr DefaultDelete() = default;
|
|
||||||
|
|
||||||
template<typename _U> DefaultDelete(const DefaultDelete<_U[]> &) {};
|
|
||||||
|
|
||||||
void operator()(_T *p) const {
|
|
||||||
delete[] p;
|
|
||||||
}
|
|
||||||
template<typename _U> void operator()(_U *) const = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* box */
|
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename _T, typename _U, bool = octa::IsEmpty<_U>::value>
|
template<typename _T, typename _U, bool = octa::IsEmpty<_U>::value>
|
||||||
|
@ -379,7 +379,7 @@ namespace detail {
|
||||||
struct SameOrLessCvQualifiedBase<_T, _U, false>: octa::False {};
|
struct SameOrLessCvQualifiedBase<_T, _U, false>: octa::False {};
|
||||||
|
|
||||||
template<typename _T, typename _U, bool = octa::IsPointer<_T>::value
|
template<typename _T, typename _U, bool = octa::IsPointer<_T>::value
|
||||||
|| octa::IsSame<_T, _U>::value || __OctaHasElement<_T>::value
|
|| octa::IsSame<_T, _U>::value || octa::detail::HasElement<_T>::value
|
||||||
> struct SameOrLessCvQualified: SameOrLessCvQualifiedBase<_T, _U> {};
|
> struct SameOrLessCvQualified: SameOrLessCvQualifiedBase<_T, _U> {};
|
||||||
|
|
||||||
template<typename _T, typename _U>
|
template<typename _T, typename _U>
|
||||||
|
@ -782,7 +782,7 @@ using AllocatorSize = typename octa::detail::SizeBase<
|
||||||
/* allocator rebind */
|
/* allocator rebind */
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename _T, typename _U, bool = __OctaHasRebind<_T, _U>::value>
|
template<typename _T, typename _U, bool = octa::detail::HasRebind<_T, _U>::value>
|
||||||
struct AllocTraitsRebindType {
|
struct AllocTraitsRebindType {
|
||||||
typedef typename _T::template Rebind<_U> Type;
|
typedef typename _T::template Rebind<_U> Type;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue