| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 | 
							- #ifndef __GBLIBCPP_MEMORY__
 
- #define __GBLIBCPP_MEMORY__
 
- #include <cstddef>
 
- #include <type_traits>
 
- #include <utility>
 
- namespace std {
 
- template <typename T>
 
- constexpr T* addressof(T& arg) noexcept
 
- {
 
-     return __builtin_addressof(arg);
 
- }
 
- // template <typename T>
 
- // constexpr enable_if_t<is_function_v<remove_reference_t<T>>, T*>
 
- // addressof(T& arg) noexcept
 
- // {
 
- //     return &arg;
 
- // }
 
- // template <typename T>
 
- // constexpr enable_if_t<!is_function_v<remove_reference_t<T>>, T*>
 
- // addressof(T& arg) noexcept
 
- // {
 
- //     return reinterpret_cast<T*>(
 
- //         &const_cast<char&>(
 
- //             reinterpret_cast<const volatile char&>(arg)
 
- //         )
 
- //     );
 
- // }
 
- template <typename T>
 
- const T* addressof(const T&&) = delete;
 
- namespace __helpers {
 
- template <typename Ptr, typename = void>
 
- struct pointer_difference_type
 
- { using type = std::ptrdiff_t; };
 
- template <typename Ptr>
 
- struct pointer_difference_type<Ptr,
 
-     std::void_t<typename Ptr::difference_type>>
 
- { using type = typename Ptr::difference_type; };
 
- template <typename Ptr>
 
- using pointer_difference_type_t =
 
-     typename pointer_difference_type<Ptr>::type;
 
- template <typename Base, typename T>
 
- struct rebind;
 
- template <template <typename, typename...> typename Template,
 
-     typename NewType, typename OldType, typename... Args>
 
- struct rebind<Template<OldType, Args...>, NewType> {
 
-     using type = Template<NewType, Args...>;
 
- };
 
- template <typename Ptr, typename T, typename = void>
 
- struct try_rebind { using type = typename rebind<Ptr, T>::type; };
 
- template <typename Ptr, typename T>
 
- struct try_rebind<Ptr, T,
 
-     std::void_t<typename Ptr::template rebind<T>>> {
 
-     using type = typename Ptr::template rebind<T>;
 
- };
 
- template <typename Ptr, typename = void>
 
- struct pointer_element {};
 
- template <typename Ptr>
 
- struct pointer_element<Ptr, std::enable_if_t<
 
-     std::is_same_v<void, std::void_t<typename Ptr::element_type>>
 
- >> { using type = typename Ptr::element_type; };
 
- template <template <typename, typename...> typename Template,
 
-     typename T, typename... Args>
 
- struct pointer_element<Template<T, Args...>, void>
 
- { using type = T; };
 
- template <typename Ptr, typename = void>
 
- struct pointer_traits_impl {};
 
- template <typename Ptr>
 
- struct pointer_traits_impl<Ptr,
 
-     std::void_t<typename pointer_element<Ptr>::type>> {
 
-     using pointer = Ptr;
 
-     using element_type = typename pointer_element<Ptr>::type;
 
-     using difference_type = pointer_difference_type_t<Ptr>;
 
-     template <typename U>
 
-     using rebind = typename try_rebind<Ptr, U>::type;
 
-     static pointer pointer_to(element_type& ref)
 
-     { return Ptr::pointer_to(ref); }
 
- };
 
- template <typename T>
 
- struct pointer_traits_impl<T*, void> {
 
-     using pointer = T*;
 
-     using element_type = T;
 
-     using difference_type = std::ptrdiff_t;
 
-     template <typename U>
 
-     using rebind = U*;
 
-     static pointer pointer_to(element_type& ref)
 
-     { return std::addressof(ref); }
 
- };
 
- } // namespace __helpers
 
- template <typename Ptr>
 
- struct pointer_traits : public __helpers::pointer_traits_impl<Ptr> {};
 
- namespace __helpers {
 
- template <typename Alloc, typename = void>
 
- struct allocator_pointer
 
- { using type = typename Alloc::value_type*; };
 
- template <typename Alloc>
 
- struct allocator_pointer<Alloc,
 
-     std::void_t<typename Alloc::pointer>>
 
- { using type = typename Alloc::pointer; };
 
- template <typename Alloc>
 
- using allocator_pointer_t =
 
-     typename allocator_pointer<Alloc>::type;
 
- template <typename Alloc, typename Pointer, typename = void>
 
- struct allocator_const_pointer {
 
-     using type = typename std::pointer_traits<Pointer>::template
 
-         rebind<const typename Alloc::value_type>;
 
- };
 
- template <typename Alloc, typename Pointer>
 
- struct allocator_const_pointer<Alloc, Pointer,
 
-     std::void_t<typename Alloc::const_pointer>>
 
- { using type = typename Alloc::const_pointer; };
 
- template <typename Alloc, typename Pointer>
 
- using allocator_const_pointer_t =
 
-     typename allocator_const_pointer<Alloc, Pointer>::type;
 
- template <typename Alloc, typename Pointer, typename = void>
 
- struct allocator_void_pointer {
 
-     using type = typename std::pointer_traits<Pointer>::template
 
-         rebind<void>;
 
- };
 
- template <typename Alloc, typename Pointer>
 
- struct allocator_void_pointer<Alloc, Pointer,
 
-     std::void_t<typename Alloc::void_pointer>>
 
- { using type = typename Alloc::void_pointer; };
 
- template <typename Alloc, typename Pointer>
 
- using allocator_void_pointer_t =
 
-     typename allocator_void_pointer<Alloc, Pointer>::type;
 
- template <typename Alloc, typename Pointer, typename = void>
 
- struct allocator_const_void_pointer {
 
-     using type = typename std::pointer_traits<Pointer>::template
 
-         rebind<const void>;
 
- };
 
- template <typename Alloc, typename Pointer>
 
- struct allocator_const_void_pointer<Alloc, Pointer,
 
-     std::void_t<typename Alloc::const_void_pointer>>
 
- { using type = typename Alloc::const_void_pointer; };
 
- template <typename Alloc, typename Pointer>
 
- using allocator_const_void_pointer_t =
 
-     typename allocator_const_void_pointer<Alloc, Pointer>::type;
 
- template <typename Alloc, typename = void>
 
- struct allocator_difference_type
 
- { using type = std::ptrdiff_t; };
 
- template <typename Alloc>
 
- struct allocator_difference_type<Alloc,
 
-     std::void_t<typename Alloc::difference_type>>
 
- { using type = typename Alloc::difference_type; };
 
- template <typename Alloc>
 
- using allocator_difference_type_t =
 
-     typename allocator_difference_type<Alloc>::type;
 
- template <typename Alloc, typename = void>
 
- struct allocator_size_type
 
- { using type = std::size_t; };
 
- template <typename Alloc>
 
- struct allocator_size_type<Alloc,
 
-     std::void_t<typename Alloc::size_type>>
 
- { using type = typename Alloc::size_type; };
 
- template <typename Alloc>
 
- using allocator_size_type_t =
 
-     typename allocator_size_type<Alloc>::type;
 
- template <typename Alloc, typename = void>
 
- struct allocator_prop_copy
 
- { using type = std::false_type; };
 
- template <typename Alloc>
 
- struct allocator_prop_copy<Alloc,
 
-     std::void_t<typename Alloc::propagate_on_container_copy_assignment>>
 
- { using type = typename Alloc::propagate_on_container_copy_assignment; };
 
- template <typename Alloc>
 
- using allocator_prop_copy_t =
 
-     typename allocator_prop_copy<Alloc>::type;
 
- template <typename Alloc, typename = void>
 
- struct allocator_prop_move
 
- { using type = std::false_type; };
 
- template <typename Alloc>
 
- struct allocator_prop_move<Alloc,
 
-     std::void_t<typename Alloc::propagate_on_container_move_assignment>>
 
- { using type = typename Alloc::propagate_on_container_move_assignment; };
 
- template <typename Alloc>
 
- using allocator_prop_move_t =
 
-     typename allocator_prop_move<Alloc>::type;
 
- template <typename Alloc, typename = void>
 
- struct allocator_prop_swap
 
- { using type = std::false_type; };
 
- template <typename Alloc>
 
- struct allocator_prop_swap<Alloc,
 
-     std::void_t<typename Alloc::propagate_on_container_swap>>
 
- { using type = typename Alloc::propagate_on_container_swap; };
 
- template <typename Alloc>
 
- using allocator_prop_swap_t =
 
-     typename allocator_prop_swap<Alloc>::type;
 
- template <typename Alloc, typename = void>
 
- struct is_always_equal
 
- { using type = std::false_type; };
 
- template <typename Alloc>
 
- struct is_always_equal<Alloc,
 
-     std::void_t<typename Alloc::is_always_equal>>
 
- { using type = typename Alloc::is_always_equal; };
 
- template <typename Alloc>
 
- using is_always_equal_t =
 
-     typename is_always_equal<Alloc>::type;
 
- template <typename Alloc, typename = void>
 
- struct allocator_select_on_copy {
 
-     static constexpr Alloc get(const Alloc& alloc)
 
-     { return alloc; }
 
- };
 
- template <typename Alloc>
 
- struct allocator_select_on_copy<Alloc, std::enable_if_t<
 
-     std::is_same_v<void, std::void_t<decltype(
 
-         std::declval<Alloc>().select_on_container_copy_construction()
 
-     )>> >> {
 
-     static constexpr Alloc get(const Alloc& alloc)
 
-     { return alloc.select_on_container_copy_construction(); }
 
- };
 
- template <typename Allocator, typename T, typename = void>
 
- struct allocator_rebind_type {
 
-     using type = typename rebind<Allocator, T>::type;
 
- };
 
- template <typename Allocator, typename T>
 
- struct allocator_rebind_type<Allocator, T, std::void_t<
 
-     typename Allocator::template rebind<T>::other
 
- >> {
 
-     using type = typename Allocator::template rebind<T>::other;
 
- };
 
- } // namespace __helpers
 
- template <typename T>
 
- struct allocator {
 
-     using value_type = T;
 
-     using propagate_on_container_move_assignment = std::true_type;
 
-     constexpr allocator() noexcept = default;
 
-     constexpr allocator(const allocator& other) noexcept = default;
 
-     template <typename U>
 
-     constexpr allocator(const allocator<U>&) noexcept {}
 
-     constexpr ~allocator() = default;
 
-     // throws std::bad_alloc
 
-     [[nodiscard]] constexpr T* allocate(std::size_t n)
 
-     { return static_cast<T*>(::operator new(n * sizeof(T))); }
 
-     // TODO: check allocated size
 
-     constexpr void deallocate(T* ptr, std::size_t)
 
-     { ::operator delete(ptr); }
 
- };
 
- template <typename T1, typename T2>
 
- constexpr bool operator==(const allocator<T1>&, const allocator<T2>&) noexcept
 
- { return true; }
 
- template <typename T, typename... Args>
 
- constexpr std::enable_if_t<std::is_same_v<T*,
 
-     decltype(::new(std::declval<void*>()) T(std::declval<Args>()...))> , T*>
 
- construct_at(T* p, Args&&... args)
 
- {
 
-     return ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
 
- }
 
- template <typename T>
 
- constexpr void destroy_at(T* p)
 
- {
 
-     // TODO: destroy array
 
-     p->~T();
 
- }
 
- template <typename Allocator>
 
- struct allocator_traits {
 
-     using allocator_type = Allocator;
 
-     using value_type = typename Allocator::value_type;
 
-     using pointer =
 
-         __helpers::allocator_pointer_t<Allocator>;
 
-     using const_pointer =
 
-         __helpers::allocator_const_pointer_t<Allocator, pointer>;
 
-     using void_pointer =
 
-         __helpers::allocator_void_pointer_t<Allocator, pointer>;
 
-     using const_void_pointer =
 
-         __helpers::allocator_const_void_pointer_t<Allocator, pointer>;
 
-     using difference_type =
 
-         __helpers::allocator_difference_type_t<Allocator>;
 
-     using size_type =
 
-         __helpers::allocator_size_type_t<Allocator>;
 
-     using propagate_on_container_copy_assignment =
 
-         __helpers::allocator_prop_copy_t<Allocator>;
 
-     using propagate_on_container_move_assignment =
 
-         __helpers::allocator_prop_move_t<Allocator>;
 
-     using propagate_on_container_swap =
 
-         __helpers::allocator_prop_swap_t<Allocator>;
 
-     using is_always_equal =
 
-         __helpers::is_always_equal_t<Allocator>;
 
-     template <typename T>
 
-     using rebind_alloc =
 
-         typename __helpers::allocator_rebind_type<Allocator, T>::type;
 
-     [[nodiscard]] static constexpr pointer allocate(Allocator& alloc, size_type n)
 
-     { return alloc.allocate(n); }
 
-     static constexpr void deallocate(Allocator& alloc, pointer p, size_type n)
 
-     { return alloc.deallocate(p, n); }
 
-     template <typename T, typename... Args>
 
-     static constexpr void construct(Allocator&, T* p, Args&&... args)
 
-     { std::construct_at(p, std::forward<Args>(args)...); }
 
-     template <typename T>
 
-     static constexpr void destroy(Allocator&, T* p)
 
-     { std::destroy_at(p); }
 
-     static constexpr Allocator
 
-         select_on_container_copy_construction(const Allocator& alloc)
 
-     { return __helpers::allocator_select_on_copy<Allocator>::get(alloc); }
 
- };
 
- } // namespace std
 
- #endif
 
 
  |