diff --git a/ostd/functional.hh b/ostd/functional.hh index 86a07f8..2a1925f 100644 --- a/ostd/functional.hh +++ b/ostd/functional.hh @@ -13,7 +13,6 @@ #include #include "ostd/platform.hh" -#include "ostd/memory.hh" #include "ostd/utility.hh" #include "ostd/type_traits.hh" diff --git a/ostd/memory.hh b/ostd/memory.hh deleted file mode 100644 index ff16d18..0000000 --- a/ostd/memory.hh +++ /dev/null @@ -1,768 +0,0 @@ -/* Memory utilities for OctaSTD. - * - * This file is part of OctaSTD. See COPYING.md for futher information. - */ - -#ifndef OSTD_MEMORY_HH -#define OSTD_MEMORY_HH - -#include -#include -#include - -#include "ostd/utility.hh" -#include "ostd/type_traits.hh" - -namespace ostd { -/* address of */ - -template constexpr T *address_of(T &v) noexcept { - return reinterpret_cast( - &const_cast(reinterpret_cast(v)) - ); -} - -/* pointer traits */ - -namespace detail { - template - struct HasElement { - template - static int test(...); - template - static char test(typename U::Element * = 0); - - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value> - struct PointerElementBase; - - template - struct PointerElementBase { - using Type = typename T::Element; - }; - - template class T, typename U, typename ...A> - struct PointerElementBase, true> { - using Type = typename T::Element; - }; - - template class T, typename U, typename ...A> - struct PointerElementBase, false> { - using Type = U; - }; - - template - struct PointerElementType { - using Type = typename PointerElementBase::Type; - }; - - template - struct PointerElementType { - using Type = T; - }; - - template - struct HasDifference { - template - static int test(...); - template - static char test(typename U::Difference * = 0); - - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value> - struct PointerDifferenceBase { - using Type = ptrdiff_t; - }; - - template - struct PointerDifferenceBase { - using Type = typename T::Difference; - }; - - template - struct PointerDifferenceType { - using Type = typename PointerDifferenceBase::Type; - }; - - template - struct PointerDifferenceType { - using Type = ptrdiff_t; - }; - - template - struct HasRebind { - template - static int test(...); - template - static char test(typename V::template Rebind * = 0); - - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value> - struct PointerRebindBase { - using Type = typename T::template Rebind; - }; - - template< - template class T, typename U, - typename ...A, typename V - > - struct PointerRebindBase, V, true> { - using Type = typename T::template Rebind; - }; - - template< - template class T, typename U, - typename ...A, typename V - > - struct PointerRebindBase, V, false> { - using Type = T; - }; - - template - struct PointerRebindType { - using Type = typename PointerRebindBase::Type; - }; - - template - struct PointerRebindType { - using Type = U *; - }; - - template - struct PointerPointer { - using Type = T; - }; - - template - struct PointerPointer { - using Type = T *; - }; -} /*namespace detail */ - -template -using Pointer = typename detail::PointerPointer::Type; - -template -using PointerElement = typename detail::PointerElementType::Type; - -template -using PointerDifference = typename detail::PointerDifferenceType::Type; - -template -using PointerRebind = typename detail::PointerRebindType::Type; - -/* pointer to */ - -namespace detail { - struct PointerToNat {}; - - template - struct PointerTo { - static T pointer_to( - Conditional< - IsVoid>, PointerToNat, PointerElement - > &r - ) { - return T::pointer_to(r); - } - }; - - template - struct PointerTo { - static T pointer_to(Conditional, PointerToNat, T> &r) { - return address_of(r); - } - }; -} - -template -static T pointer_to( - Conditional< - IsVoid>, detail::PointerToNat, PointerElement - > &r -) { - return detail::PointerTo::pointer_to(r); -} - -namespace detail { - template - static int ptr_test(...); - template - static char ptr_test(typename T::Pointer * = 0); - - template - constexpr bool HasPtr = sizeof(ptr_test(0)) == 1; - - template> - struct PointerBase { - using Type = typename D::Pointer; - }; - - template - struct PointerBase { - using Type = T *; - }; - - template - struct PointerType { - using Type = typename PointerBase>::Type; - }; -} /* namespace detail */ - -/* allocator */ - -template -struct Allocator { - using Value = T; - - Allocator() noexcept {} - template - Allocator(Allocator const &) noexcept {} - - Value *allocate(size_t n) { - return reinterpret_cast(::new byte[n * sizeof(T)]); - } - - void deallocate(Value *p, size_t) noexcept { - ::delete[] reinterpret_cast(p); - } -}; - -template -bool operator==(Allocator const &, Allocator const &) noexcept { - return true; -} - -template -bool operator!=(Allocator const &, Allocator const &) noexcept { - return false; -} - -/* allocator traits - modeled after libc++ */ - -namespace detail { - template - struct ConstPtrTest { - template - static char test(typename U::ConstPointer * = 0); - template - static int test(...); - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value> - struct ConstPointer { - using Type = typename A::ConstPointer; - }; - - template - struct ConstPointer { - using Type = PointerRebind; - }; - - template - struct VoidPtrTest { - template - static char test(typename U::VoidPointer * = 0); - template - static int test(...); - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value> - struct VoidPointer { - using Type = typename A::VoidPointer; - }; - - template - struct VoidPointer { - using Type = PointerRebind; - }; - - template - struct ConstVoidPtrTest { - template static char test( - typename U::ConstVoidPointer * = 0); - template static int test(...); - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value> - struct ConstVoidPointer { - using Type = typename A::ConstVoidPointer; - }; - - template - struct ConstVoidPointer { - using Type = PointerRebind; - }; - - template - struct SizeTest { - template - static char test(typename U::Size * = 0); - template - static int test(...); - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value> - struct SizeBase { - using Type = MakeUnsigned; - }; - - template - struct SizeBase { - using Type = typename A::Size; - }; -} /* namespace detail */ - -/* allocator type traits */ - -template -using AllocatorType = A; - -template -using AllocatorValue = typename AllocatorType::Value; - -template -using AllocatorPointer = typename detail::PointerType< - AllocatorValue, AllocatorType ->::Type; - -template -using AllocatorConstPointer = typename detail::ConstPointer< - AllocatorValue, AllocatorPointer, AllocatorType ->::Type; - -template -using AllocatorVoidPointer = typename detail::VoidPointer< - AllocatorPointer, AllocatorType ->::Type; - -template -using AllocatorConstVoidPointer = typename detail::ConstVoidPointer< - AllocatorPointer, AllocatorType ->::Type; - -/* allocator difference */ - -namespace detail { - template - struct DiffTest { - template - static char test(typename U::Difference * = 0); - template - static int test(...); - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value> - struct AllocDifference { - using Type = PointerDifference

; - }; - - template - struct AllocDifference { - using Type = typename A::Difference; - }; -} - -template -using AllocatorDifference = typename detail::AllocDifference< - A, AllocatorPointer ->::Type; - -/* allocator size */ - -template -using AllocatorSize = typename detail::SizeBase< - A, AllocatorDifference ->::Type; - -/* allocator rebind */ - -namespace detail { - template::value> - struct AllocTraitsRebindType { - using Type = typename T::template Rebind; - }; - - template< - template class A, typename T, - typename ...Args, typename U - > - struct AllocTraitsRebindType, U, true> { - using Type = typename A::template Rebind; - }; - - template< - template class A, typename T, - typename ...Args, typename U - > - struct AllocTraitsRebindType, U, false> { - using Type = A; - }; -} /* namespace detail */ - -template -using AllocatorRebind = typename detail::AllocTraitsRebindType< - AllocatorType, T ->::Type; - -/* allocator propagate on container copy assignment */ - -namespace detail { - template - struct PropagateOnContainerCopyAssignmentTest { - template - static char test(decltype(U::PropagateOnContainerCopyAssignment) * = 0); - template - static int test(...); - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value - > - constexpr bool PropagateOnContainerCopyAssignmentBase = false; - - template - constexpr bool PropagateOnContainerCopyAssignmentBase = - A::PropagateOnContainerCopyAssignment; -} /* namespace detail */ - -template -constexpr bool AllocatorPropagateOnContainerCopyAssignment = - detail::PropagateOnContainerCopyAssignmentBase; - -/* allocator propagate on container move assignment */ - -namespace detail { - template - struct PropagateOnContainerMoveAssignmentTest { - template - static char test(decltype(U::PropagateOnContainerMoveAssignment) * = 0); - template - static int test(...); - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value - > - constexpr bool PropagateOnContainerMoveAssignmentBase = false; - - template - constexpr bool PropagateOnContainerMoveAssignmentBase = - A::PropagateOnContainerMoveAssignment; -} /* namespace detail */ - -template -constexpr bool AllocatorPropagateOnContainerMoveAssignment = - detail::PropagateOnContainerMoveAssignmentBase; - -/* allocator propagate on container swap */ - -namespace detail { - template - struct PropagateOnContainerSwapTest { - template - static char test(decltype(U::PropagateOnContainerSwap) * = 0); - template - static int test(...); - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value> - constexpr bool PropagateOnContainerSwapBase = false; - - template - constexpr bool PropagateOnContainerSwapBase = - A::PropagateOnContainerSwap; -} /* namespace detail */ - -template -constexpr bool AllocatorPropagateOnContainerSwap = - detail::PropagateOnContainerSwapBase; - -/* allocator is always equal */ - -namespace detail { - template - struct IsAlwaysEqualTest { - template - static char test(decltype(U::IsAlwaysEqual) * = 0); - template - static int test(...); - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value> - constexpr bool IsAlwaysEqualBase = IsEmpty; - - template - constexpr bool IsAlwaysEqualBase = A::IsAlwaysEqual; -} /* namespace detail */ - -template -constexpr bool AllocatorIsAlwaysEqual = detail::IsAlwaysEqualBase; - -/* allocator allocate */ - -template -inline AllocatorPointer allocator_allocate(A &a, AllocatorSize n) { - return a.allocate(n); -} - -namespace detail { - template - auto allocate_hint_test(A &&a, S &&sz, CVP &&p) -> - decltype(a.allocate(sz, p), True()); - - template - auto allocate_hint_test(A const &, S &&, CVP &&) -> False; - - template - constexpr bool AllocateHintTest = - IsSame< - decltype(allocate_hint_test( - std::declval(), std::declval(), std::declval() - )), True - >; - - template - inline AllocatorPointer allocate( - A &a, AllocatorSize n, AllocatorConstVoidPointer h, True - ) { - return a.allocate(n, h); - } - - template - inline AllocatorPointer allocate( - A &a, AllocatorSize n, AllocatorConstVoidPointer, False - ) { - return a.allocate(n); - } -} /* namespace detail */ - -template -inline AllocatorPointer allocator_allocate( - A &a, AllocatorSize n, AllocatorConstVoidPointer h -) { - return detail::allocate( - a, n, h, BoolConstant, AllocatorConstVoidPointer - >>() - ); -} - -/* allocator deallocate */ - -template -inline void allocator_deallocate( - A &a, AllocatorPointer p, AllocatorSize n -) noexcept { - a.deallocate(p, n); -} - -/* allocator construct */ - -namespace detail { - template - auto construct_test(A &&a, T *p, Args &&...args) -> - decltype(a.construct(p, std::forward(args)...), True()); - - template - auto construct_test(A const &, T *, Args &&...) -> False; - - template - constexpr bool ConstructTest = - IsSame< - decltype(construct_test( - std::declval(), std::declval(), std::declval()... - )), True - >; - - template - inline void construct(True, A &a, T *p, Args &&...args) { - a.construct(p, std::forward(args)...); - } - - template - inline void construct(False, A &, T *p, Args &&...args) { - ::new (p) T(std::forward(args)...); - } -} /* namespace detail */ - -template -inline void allocator_construct(A &a, T *p, Args &&...args) { - detail::construct( - BoolConstant>(), - a, p, std::forward(args)... - ); -} - -/* allocator destroy */ - -namespace detail { - template - auto destroy_test(A &&a, P &&p) -> decltype(a.destroy(p), True()); - - template - auto destroy_test(A const &, P &&) -> False; - - template - constexpr bool DestroyTest = IsSame< - decltype(destroy_test(std::declval(), std::declval

())), True - >; - - template - inline void destroy(True, A &a, T *p) { - a.destroy(p); - } - - template - inline void destroy(False, A &, T *p) { - p->~T(); - } -} /* namespace detail */ - -template -inline void allocator_destroy(A &a, T *p) noexcept { - detail::destroy(BoolConstant>(), a, p); -} - -/* allocator max size */ - -namespace detail { - template - auto alloc_max_size_test(A &&a) -> decltype(a.max_size(), True()); - - template - auto alloc_max_size_test(A const &) -> False; - - template - constexpr bool AllocMaxSizeTest = - IsSame())), True>; - - template - inline AllocatorSize alloc_max_size(True, A const &a) { - return a.max_size(); - } - - template - inline AllocatorSize alloc_max_size(False, A const &) { - return AllocatorSize(~0); - } -} /* namespace detail */ - -template -inline AllocatorSize allocator_max_size(A const &a) noexcept { - return detail::alloc_max_size( - BoolConstant>(), a - ); -} - -/* allocator container copy */ - -namespace detail { - template - auto alloc_copy_test(A &&a) -> decltype(a.container_copy(), True()); - - template - auto alloc_copy_test(A const &) -> False; - - template - constexpr bool AllocCopyTest = - IsSame())), True>; - - template - inline AllocatorType alloc_container_copy(True, A const &a) { - return a.container_copy(); - } - - template - inline AllocatorType alloc_container_copy(False, A const &a) { - return a; - } -} /* namespace detail */ - -template -inline AllocatorType allocator_container_copy(A const &a) { - return detail::alloc_container_copy( - BoolConstant>(), a - ); -} - -/* allocator arg */ - -struct AllocatorArg {}; - -constexpr AllocatorArg allocator_arg = AllocatorArg(); - -/* uses allocator */ - -namespace detail { - template - struct HasAllocatorType { - template - static char test(typename U::Allocator *); - template - static int test(...); - static constexpr bool value = (sizeof(test(0)) == 1); - }; - - template::value> - constexpr bool UsesAllocatorBase = IsConvertible; - - template - constexpr bool UsesAllocatorBase = false; -} - -template -constexpr bool UsesAllocator = detail::UsesAllocatorBase; - -/* uses allocator ctor */ - -namespace detail { - template - struct UsesAllocCtor { - static constexpr bool ua = UsesAllocator; - static constexpr bool ic = IsConstructible< - T, AllocatorArg, A, Args... - >; - static constexpr int value = ua ? (2 - ic) : 0; - }; -} - -template -constexpr int UsesAllocatorConstructor = - detail::UsesAllocCtor::value; - -/* util for other classes */ - -namespace detail { - template - struct AllocatorDestructor { - using Pointer = AllocatorPointer; - using Size = size_t; - AllocatorDestructor(A &a, Size s) noexcept: p_alloc(a), p_size(s) {} - void operator()(Pointer p) noexcept { - allocator_deallocate(p_alloc, p, p_size); - } - private: - A &p_alloc; - Size p_size; - }; -} - -} /* namespace ostd */ - -#endif