#ifndef __GBLIBCPP_MEMORY__ #define __GBLIBCPP_MEMORY__ #include #include #include namespace std { template constexpr T* addressof(T& arg) noexcept { return __builtin_addressof(arg); } // template // constexpr enable_if_t>, T*> // addressof(T& arg) noexcept // { // return &arg; // } // template // constexpr enable_if_t>, T*> // addressof(T& arg) noexcept // { // return reinterpret_cast( // &const_cast( // reinterpret_cast(arg) // ) // ); // } template const T* addressof(const T&&) = delete; template struct allocator { using value_type = T; using size_type = std::size_t; using difference_type = std::ptrdiff_t; constexpr allocator() noexcept = default; constexpr allocator(const allocator& other) noexcept = default; template constexpr allocator(const allocator&) noexcept {} constexpr ~allocator() = default; // throws std::bad_alloc [[nodiscard]] constexpr T* allocate(std::size_t n) { return static_cast(::operator new(n * sizeof(T))); } // TODO: check allocated size constexpr void deallocate(T* ptr, std::size_t) { ::operator delete(ptr); } }; template constexpr bool operator==(const allocator&, const allocator&) noexcept { return true; } template constexpr std::enable_if_t()) T(std::declval()...))> , T*> construct_at(T* p, Args&&... args) { return ::new (static_cast(p)) T(std::forward(args)...); } template constexpr void destroy_at(T* p) { // TODO: destroy array p->~T(); } namespace __helpers { template struct rebind; template