| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740 | #ifndef __GBLIBCPP_MEMORY__#define __GBLIBCPP_MEMORY__#include <bits/compressed_pair>#include <cstddef>#include <new>#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 __helperstemplate <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 __helperstemplate <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);    }};template <typename T>struct default_delete {    __GBLIBCPP_CONSTEXPR default_delete() noexcept = default;    template <typename U,              std::enable_if_t<std::is_convertible_v<U*, T*>, bool> = true>    __GBLIBCPP_CONSTEXPR default_delete(const default_delete<U>&) noexcept {}    __GBLIBCPP_CONSTEXPR void operator()(T* p) const { delete p; }};// TODO: weak_ptrtemplate <typename T>class shared_ptr {   public:    using element_type = std::remove_extent_t<T>;    using pointer = element_type*; // TODO: pointer_traits    using const_pointer = const element_type*;    using reference = element_type&;    using const_reference = const element_type&;   private:    struct control_block_base {        std::size_t ref_count;        std::size_t weak_count;        pointer ptr;        constexpr control_block_base(std::size_t ref_count,                                     std::size_t weak_count, pointer ptr)            : ref_count(ref_count), weak_count(weak_count), ptr(ptr) {}        virtual constexpr ~control_block_base() = default;        virtual constexpr void do_delete() = 0;        // template <typename U, std::enable_if_t<std::is_convertible_v<T*, U*>,        // bool> = true> constexpr operator typename        // shared_ptr<U>::control_block_base*() const        // {        //     return this;        // }    };    template <typename Deleter>    struct control_block : public virtual control_block_base, private Deleter {        using Base = control_block_base;        virtual constexpr ~control_block() = default;        constexpr control_block(std::size_t ref_count, std::size_t weak_count,                                pointer ptr)            : control_block_base{ref_count, weak_count, ptr}, Deleter{} {}        template <typename UDeleter>        constexpr control_block(std::size_t ref_count, std::size_t weak_count,                                pointer ptr, UDeleter&& deleter)            : control_block_base{ref_count, weak_count, ptr}            , Deleter(std::forward<UDeleter>(deleter)) {}        virtual constexpr void do_delete() override {            if (this->Base::ptr)                this->Deleter::operator()(this->Base::ptr);            this->Base::ptr = nullptr;        }    };    control_block_base* cb{};    pointer ptr{};    void inc_ref() {        if (cb)            ++cb->ref_count; // TODO: lock and atomic    }    void dec_ref() {        if (cb && --cb->ref_count == 0) {            cb->do_delete();            if (cb->weak_count == 0)                delete cb;        }    }   private:    template <typename Allocator, typename Deleter>    using rebound_allocator = typename std::allocator_traits<        Allocator>::template rebind_alloc<control_block<Deleter>>;    template <typename Allocator, typename Deleter>    using rebound_traits =        typename std::allocator_traits<rebound_allocator<Allocator, Deleter>>;    template <typename U>    friend class shared_ptr;   public:    __GBLIBCPP_CONSTEXPR shared_ptr() noexcept = default;    __GBLIBCPP_CONSTEXPR shared_ptr(std::nullptr_t) noexcept : shared_ptr{} {}    template <typename U, enable_if_t<is_convertible_v<U*, T*>, bool> = true>    __GBLIBCPP_CONSTEXPR explicit shared_ptr(U* p) // TODO: array type        : cb(new control_block<default_delete<T>>{1, 0, p}), ptr(p) {}    template <typename U, typename Deleter,              enable_if_t<is_convertible_v<U*, T*>, bool> = true>    __GBLIBCPP_CONSTEXPR explicit shared_ptr(U* p, Deleter d)        : cb(new control_block<Deleter>{1, 0, p, d}), ptr(p) {}    template <typename Deleter>    __GBLIBCPP_CONSTEXPR explicit shared_ptr(std::nullptr_t, Deleter d)        : cb(new control_block<Deleter>{1, 0, nullptr, d}) {}    template <typename U, typename Deleter, typename Alloc,              enable_if_t<is_convertible_v<U*, T*>, bool> = true>    __GBLIBCPP_CONSTEXPR explicit shared_ptr(U* p, Deleter d, Alloc alloc) {        cb = rebound_traits<Alloc, Deleter>::allocate(alloc, 1);        rebound_traits<Alloc, Deleter>::construct(alloc, cb, 1, 0, p, d);        ptr = p;    }    template <typename Deleter, typename Alloc>    __GBLIBCPP_CONSTEXPR explicit shared_ptr(std::nullptr_t, Deleter d,                                             Alloc alloc) {        cb = rebound_traits<Alloc, Deleter>::allocate(alloc, 1);        rebound_traits<Alloc, Deleter>::construct(alloc, cb, 1, 0, nullptr, d);    }    __GBLIBCPP_CONSTEXPR    shared_ptr(const shared_ptr& other) noexcept        : cb(other.cb), ptr(other.ptr) {        inc_ref();    }    __GBLIBCPP_CONSTEXPR    shared_ptr(shared_ptr&& other) noexcept        : cb(std::exchange(other.cb, nullptr))        , ptr(std::exchange(other.ptr, nullptr)) {}    template <typename U, enable_if_t<is_convertible_v<U*, T*>, bool> = true>    __GBLIBCPP_CONSTEXPR shared_ptr(const shared_ptr<U>& other) noexcept        : cb((control_block_base*)other.cb), ptr((T*)other.ptr) {        inc_ref();    }    template <typename U, enable_if_t<is_convertible_v<U*, T*>, bool> = true>    __GBLIBCPP_CONSTEXPR shared_ptr(shared_ptr<U>&& other) noexcept        : cb((control_block_base*)std::exchange(other.cb, nullptr))        , ptr((T*)std::exchange(other.ptr, nullptr)) {}    // TODO: weak_ptr and unique_ptr    __GBLIBCPP_CONSTEXPR    ~shared_ptr() {        dec_ref();        cb = nullptr;        ptr = nullptr;    }    __GBLIBCPP_CONSTEXPR    shared_ptr& operator=(const shared_ptr& other) noexcept {        shared_ptr{other}.swap(*this);        return *this;    }    template <typename U, enable_if_t<is_convertible_v<U*, T*>, bool> = true>    __GBLIBCPP_CONSTEXPR shared_ptr& operator=(        const shared_ptr<U>& other) noexcept {        shared_ptr{other}.swap(*this);        return *this;    }    __GBLIBCPP_CONSTEXPR    shared_ptr& operator=(shared_ptr&& other) noexcept {        shared_ptr{move(other)}.swap(*this);        return *this;    }    template <typename U, enable_if_t<is_convertible_v<U*, T*>, bool> = true>    __GBLIBCPP_CONSTEXPR shared_ptr& operator=(shared_ptr<U>&& other) noexcept {        shared_ptr{move(other)}.swap(*this);        return *this;    }    __GBLIBCPP_CONSTEXPR    element_type* get() const noexcept { return cb ? ptr : nullptr; }    __GBLIBCPP_CONSTEXPR    explicit operator bool() const noexcept { return get(); }    __GBLIBCPP_CONSTEXPR    T& operator*() const noexcept { return *get(); }    __GBLIBCPP_CONSTEXPR    T* operator->() const noexcept { return get(); }    __GBLIBCPP_CONSTEXPR    element_type& operator[](std::size_t i) const noexcept { return get()[i]; }    __GBLIBCPP_CONSTEXPR    long use_count() const noexcept { return cb ? cb->ref_count : 0; }    __GBLIBCPP_CONSTEXPR    bool owner_before(const shared_ptr& other) const noexcept {        return cb < other.cb;    }    __GBLIBCPP_CONSTEXPR    void swap(shared_ptr& other) noexcept {        std::swap(cb, other.cb);        std::swap(ptr, other.ptr);    }    __GBLIBCPP_CONSTEXPR    void reset() noexcept { shared_ptr{}.swap(*this); }    template <typename U, enable_if_t<is_convertible_v<U*, T*>, bool> = true>    __GBLIBCPP_CONSTEXPR void reset(U* p) noexcept {        shared_ptr{p}.swap(*this);    }    template <typename U, typename Deleter,              enable_if_t<is_convertible_v<U*, T*>, bool> = true>    __GBLIBCPP_CONSTEXPR void reset(U* p, Deleter d) noexcept {        shared_ptr{p, d}.swap(*this);    }    template <typename U, typename Deleter, typename Allocator,              enable_if_t<is_convertible_v<U*, T*>, bool> = true>    __GBLIBCPP_CONSTEXPR void reset(U* p, Deleter d, Allocator alloc) {        shared_ptr{p, d, alloc}.swap(*this);    }};template <typename T, typename Deleter = std::default_delete<T>>class unique_ptr {   public:    using element_type = T;    using deleter_type = Deleter;    using pointer = element_type*;    template <typename U, typename UDeleter>    friend class unique_ptr;   private:    impl::compressed_pair<pointer, deleter_type> data;   public:    __GBLIBCPP_CONSTEXPR unique_ptr() noexcept        : data{impl::default_construct_t{}} {}    __GBLIBCPP_CONSTEXPR unique_ptr(std::nullptr_t) noexcept : unique_ptr{} {}    __GBLIBCPP_CONSTEXPR unique_ptr(pointer p) noexcept        : data{p, deleter_type{}} {}    __GBLIBCPP_CONSTEXPR unique_ptr(pointer p, const deleter_type& d) noexcept        : data{p, d} {}    __GBLIBCPP_CONSTEXPR unique_ptr(pointer p, deleter_type&& d) noexcept        : data{p, std::move(d)} {}    __GBLIBCPP_CONSTEXPR unique_ptr(const unique_ptr&) = delete;    __GBLIBCPP_CONSTEXPR unique_ptr(unique_ptr&& other) noexcept        : data{std::exchange(other.data.first(), nullptr),               std::move(other.data.second())} {}    template <        typename U, typename E,        std::enable_if_t<!std::is_array_v<U> && std::is_convertible_v<U*, T*> &&                             std::is_convertible_v<E, Deleter>,                         bool> = true>    __GBLIBCPP_CONSTEXPR unique_ptr(unique_ptr<U, E>&& other) noexcept        : data{std::exchange(other.data.first(), nullptr),               std::move(other.data.second())} {}    __GBLIBCPP_CONSTEXPR ~unique_ptr() { reset(); }    __GBLIBCPP_CONSTEXPR unique_ptr& operator=(const unique_ptr&) = delete;    __GBLIBCPP_CONSTEXPR unique_ptr& operator=(std::nullptr_t) noexcept {        reset();        return *this;    }    __GBLIBCPP_CONSTEXPR unique_ptr& operator=(unique_ptr&& other) noexcept {        reset(other.release());        get_deleter() = std::move(other.get_deleter());        return *this;    }    template <        typename U, typename E,        std::enable_if_t<!std::is_array_v<U> && std::is_convertible_v<U*, T*> &&                             std::is_assignable_v<Deleter&, E&&>,                         bool> = true>    __GBLIBCPP_CONSTEXPR unique_ptr& operator=(        unique_ptr<U, E>&& other) noexcept {        reset(other.release());        get_deleter() = std::move(other.get_deleter());        return *this;    }    __GBLIBCPP_CONSTEXPR void swap(unique_ptr& other) noexcept {        std::swap(data, other.data);    }    __GBLIBCPP_CONSTEXPR pointer get() const noexcept { return data.first(); }    __GBLIBCPP_CONSTEXPR deleter_type& get_deleter() noexcept {        return data.second();    }    __GBLIBCPP_CONSTEXPR const deleter_type& get_deleter() const noexcept {        return data.second();    }    __GBLIBCPP_CONSTEXPR pointer release() noexcept {        pointer ret = get();        data.first() = nullptr;        return ret;    }    __GBLIBCPP_CONSTEXPR void reset(pointer p = pointer{}) noexcept {        pointer old = release();        data.first() = p;        if (old)            get_deleter()(old);    }    __GBLIBCPP_CONSTEXPR explicit operator bool() const noexcept {        return get();    }    __GBLIBCPP_CONSTEXPR pointer operator->() const noexcept { return get(); }    __GBLIBCPP_CONSTEXPR std::add_lvalue_reference_t<T> operator*() const        noexcept(noexcept(*std::declval<pointer>())) {        return *get();    }};// TODO: use only one allocationtemplate <typename T, typename... Args>std::shared_ptr<T> make_shared(Args&&... args) {    return std::shared_ptr<T>(new T(std::forward<Args>(args)...));}template <typename T, typename... Args>__GBLIBCPP_CONSTEXPR std::unique_ptr<T> make_unique(Args&&... args) {    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));}template <typename T>__GBLIBCPP_CONSTEXPR void swap(std::shared_ptr<T>& lhs,                               std::shared_ptr<T>& rhs) noexcept {    lhs.swap(rhs);}template <typename T, typename D>__GBLIBCPP_CONSTEXPR void swap(std::unique_ptr<T, D>& lhs,                               std::unique_ptr<T, D>& rhs) noexcept {    lhs.swap(rhs);}} // namespace std#endif
 |