Topic: Inferring stateless deleter from allocators


Author: Gareth Lloyd <gareth@ignition-web.co.uk>
Date: Wed, 17 Oct 2018 14:52:18 +0100
Raw View
--00000000000048004b05786cfb06
Content-Type: text/plain; charset="UTF-8"

tl;dr; Currently a deleter is a facade over an allocator which currently
doesn't hide how big the allocator is.

Allocators provides a customization point for a generic data structure
which may allocate internal structures.

An allocator controls allocation, construction, destruction and
deallocation. In the standard we have some opinionated allocators
std::allocator, std::scoped_allocator_adaptor and
std::pmr::polymorphic_allocator.

With current allocators, if any one of those customization points require
state then the entire allocator is stateful. This is fine if you are using
the allocator as an allocator, you are going to be using those methods that
require state so the state is not an overhead. But there are situations,
like deleter, where you are only using a subset of those methods.

For a concrete example, allocate_shared needs the allocator to do the
allocate and construct. But the returned shared_ptr only requires a
specialized deleter based on the provided allocator. This deleter is a
facade of the allocator, simplifying the interface and only using destroy
and deallocate methods of the allocator. If those methods are stateless in
nature then the shared_ptr should not have to carry unnecessarily state
that the deleter doesn't use.

In GCC, clang and MSVC, allocate_shared doesn't even optimize for
completely stateless allocators, this is an oversight and could/should be
fixed

auto ptr = std::allocate_shared<char>(std::allocator<char>{}, 'a');
static_assert(sizeof(ptr) > sizeof(void *));

But for allocators which are partially stateful there is currently no
facility to make an allocate_shared or allocate_unique implementation which
can sense if the deleter methods (destroy and deallocate) are stateless.
Without that sense the deleter has to be as stateful as the allocator it
was derived from.

In my experimental codebase I have a policy_based_allocator which uses a
policy to builds the right allocator and I have facilities to sense which
parts of the allocator are stateful. Consider the following code:

#include <memory>
#include <experimental/type_traits>
#include <type_traits>
#include <vector>

template<class> struct dependent_false : std::false_type {};

// Common policy fragments (all stateless)
struct allocate_as_default
{
    template<class T>
    [[nodiscard]] static T * allocate(std::size_t n)
    {
        auto constexpr alignment = static_cast<std::align_val_t>(alignof(T));
        auto const bytes = sizeof(T) * n;
        return static_cast<T *>(::operator new(bytes, alignment));
    }
};

struct construct_as_default
{
    template<class T, class... Args>
    static void construct(T * p, Args && ... args)
    {
        ::new((void *) p) T(std::forward<Args>(args)...);
    }
};

struct destroy_as_default
{
    template<typename T>
    static void destroy(T * p)
    {
        p->~T();
    }
};

struct deallocate_as_default
{
    template<typename T>
    static void deallocate(T * p, std::size_t n) noexcept
    {
        ::operator delete(p, alignof(T));
    }
};

struct deallocate_as_noop
{
    template<typename T>
    static void deallocate(T * p, std::size_t n) noexcept
    {
    }
};

template<class Policy>
struct allocator_policy_traits
{
private:
    template<class U> using detect_stateful_allocate =
decltype(U::template allocate<char>(
            std::declval<typename U::resource *>(),
std::declval<std::size_t>()));
    template<class U> using detect_stateless_allocate =
decltype(U::template allocate<char>(
            std::declval<std::size_t>()));

    template<class U> using detect_stateful_construct =
decltype(U::template construct<char>(
            std::declval<typename U::resource *>(), std::declval<char *>()));
    template<class U> using detect_stateless_construct =
decltype(U::template construct<char>(
            std::declval<char *>()));

    template<class U> using detect_stateful_destroy =
decltype(U::template destroy<char>(
            std::declval<typename U::resource *>(), std::declval<char *>()));
    template<class U> using detect_stateless_destroy =
decltype(U::template destroy<char>(
            std::declval<char *>()));

    template<class U> using detect_stateful_deallocate =
decltype(U::template deallocate<char>(
            std::declval<typename U::resource *>(), nullptr, 1));
    template<class U> using detect_stateless_deallocate =
decltype(U::template deallocate<char>(
            nullptr, 1));

    template<class U> using detect_allocate_method = typename
U::allocate_method;
    template<class U> using detect_construct_method = typename
U::construct_method;
    template<class U> using detect_destroy_method = typename U::destroy_method;
    template<class U> using detect_deallocate_method = typename
U::deallocate_method;

public:

    using has_explicit_stateful_allocate =
std::experimental::is_detected<detect_stateful_allocate, Policy>;
    using has_explicit_stateless_allocate =
std::experimental::is_detected<detect_stateless_allocate, Policy>;

    using has_explicit_stateful_construct =
std::experimental::is_detected<detect_stateful_construct, Policy>;
    using has_explicit_stateless_construct =
std::experimental::is_detected<detect_stateless_construct, Policy>;

    using has_explicit_stateful_destroy =
std::experimental::is_detected<detect_stateful_destroy, Policy>;
    using has_explicit_stateless_destroy =
std::experimental::is_detected<detect_stateless_destroy, Policy>;

    using has_explicit_stateful_deallocate =
std::experimental::is_detected<detect_stateful_deallocate, Policy>;
    using has_explicit_stateless_deallocate =
std::experimental::is_detected<detect_stateless_deallocate, Policy>;

    using requires_stateful_allocator = std::disjunction<
            has_explicit_stateful_allocate,
            has_explicit_stateful_construct,
            has_explicit_stateful_destroy,
            has_explicit_stateful_deallocate
    >;

    using requires_stateful_deleter = std::disjunction<
            has_explicit_stateful_destroy,
            has_explicit_stateful_deallocate
    >;

    using allocate_method = std::conditional_t<
            has_explicit_stateless_allocate::value,
            Policy,
            std::experimental::detected_or_t<allocate_as_default,
detect_allocate_method, Policy>
    >;
    using construct_method = std::conditional_t<
            has_explicit_stateless_construct::value,
            Policy,
            std::experimental::detected_or_t<construct_as_default,
detect_construct_method, Policy>
    >;
    using destroy_method = std::conditional_t<
            has_explicit_stateless_destroy::value,
            Policy,
            std::experimental::detected_or_t<destroy_as_default,
detect_destroy_method, Policy>
    >;
    using deallocate_method = std::conditional_t<
            has_explicit_stateless_deallocate::value,
            Policy,
            std::experimental::detected_or_t<deallocate_as_default,
detect_deallocate_method, Policy>
    >;
};


template<typename Policy, typename Enable = void>
struct policy_based_allocator_base // state-less
{
    using is_always_equal = std::true_type;
};

template<typename Policy>
struct policy_based_allocator_base<Policy,
std::enable_if_t<allocator_policy_traits<Policy>::requires_stateful_allocator::value>>
// state-full
{
    using resource_t = typename Policy::resource;
    using is_always_equal = std::false_type;

    policy_based_allocator_base() = delete;

    policy_based_allocator_base(resource_t * resource) :
m_resource{resource} {} // NOLINT

    policy_based_allocator_base(policy_based_allocator_base const &
other) : m_resource{other.m_resource} {}

    resource_t * m_resource;
};

template<typename T, typename Policy>
struct policy_based_allocator : policy_based_allocator_base<Policy>
{
    using policy = Policy;
    using base = policy_based_allocator_base<Policy>;
    using trait = allocator_policy_traits<Policy>;

    using value_type = std::remove_cv_t<T>;

    template<class U> struct rebind { typedef
policy_based_allocator<U, Policy> other; };

    //inherit base constructors
    using base::policy_based_allocator_base;

    template<typename U>
    policy_based_allocator(policy_based_allocator<U, Policy> const &
other) : base(other) {} // NOLINT

    [[nodiscard]] value_type * allocate(std::size_t n)
    {
        if constexpr(trait::has_explicit_stateful_allocate::value)
        {
            // Stateful allocate
            return Policy::template allocate<value_type>(base::m_resource, n);
        }
        else
        {
            return trait::allocate_method::template allocate<value_type>(n);
        }
    }

    template<class U, class... Args>
    void construct(U * p, Args && ... args)
    {
        constexpr bool uses_allocator = std::uses_allocator<U,
policy_based_allocator>::value;

        constexpr bool ctr_1 = std::is_constructible<U, Args...>::value;
        constexpr bool ctr_2 = std::is_constructible<U,
std::allocator_arg_t, policy_based_allocator<U, Policy>,
Args...>::value;
        constexpr bool ctr_3 = std::is_constructible<U, Args...,
policy_based_allocator<U, Policy>>::value;

        if constexpr (!uses_allocator && ctr_1)
        {
            construct_impl(p, std::forward<Args>(args)...);
        }
        else if constexpr (uses_allocator && ctr_2)
        {
            construct_impl(p, std::allocator_arg, *this,
std::forward<Args>(args)...);
        }
        else if constexpr (uses_allocator && ctr_3)
        {
            construct_impl(p, std::forward<Args>(args)..., *this);
        }
        else
        {
            static_assert(dependent_false<U>::value, "No valid constructor");
        }
    }

    template<typename U>
    void destroy(U * p)
    {
        if constexpr(trait::has_explicit_stateful_destroy::value)
        {
            // Stateful destroy
            Policy::destroy(base::m_resource, p);
        }
        else
        {
            trait::destroy_method::destroy(p);
        }
    }

    void deallocate(T * p, std::size_t n)
    {
        if constexpr(trait::has_explicit_stateful_deallocate::value)
        {
            // Stateful deallocate
            Policy::deallocate(base::m_resource, p, n);
        }
        else
        {
            trait::deallocate_method::deallocate(p, n);
        }
    }


private:

    template<class U, class... Args>
    void construct_impl(U * p, Args && ... args)
    {
        if constexpr(trait::has_explicit_stateful_construct::value)
        {
            // Stateful construct
            Policy::construct(base::m_resource, p, std::forward<Args>(args)...);
        }
        else
        {
            trait::construct_method::construct(p, std::forward<Args>(args)...);
        }
    }
};

template<class T, class U, typename Policy>
bool operator==(const policy_based_allocator<T, Policy> & lhs, const
policy_based_allocator<U, Policy> & rhs)
{
    if constexpr (policy_based_allocator<T, Policy>::is_always_equal::value)
    {
        return true;
    }
    else
    {
        return lhs.m_resource == rhs.m_resource;
    }
}

template<class T, class U, typename Policy>
bool operator!=(const policy_based_allocator<T, Policy> & lhs, const
policy_based_allocator<U, Policy> & rhs)
{
    return !(lhs == rhs);
}


template<class Alloc>
struct allocator_traits_demo
{
private:
    template<class U>
    using detect_policy = typename U::policy;

public:
    using has_policy = std::experimental::is_detected<detect_policy, Alloc>;
};


//default
template<typename Alloc, typename Enable = void>
struct allocator_delete : Alloc
{
    using alloc_traits = std::allocator_traits<Alloc>;
    using pointer = typename alloc_traits::pointer;

    template<class OtherAlloc>
    explicit allocator_delete(OtherAlloc && alloc)
            : Alloc{std::forward<OtherAlloc>(alloc)} {}

    void operator()(pointer p)
    {
        //Use allocator
        alloc_traits::destroy(*this, p);
        alloc_traits::deallocate(*this, p, 1);
    };
};

template<class U>
using detect_policy_requires_stateful_deleter = std::negation<typename
allocator_policy_traits<typename
U::policy>::requires_stateful_deleter>;

template<typename Alloc>
using stateless_deleter_due_to_policy =
std::experimental::detected_or_t<std::false_type,
detect_policy_requires_stateful_deleter, Alloc>;

template<typename Alloc>
using stateless_deleter_due_to_stateless = std::is_empty<Alloc>;

template<typename Alloc>
using stateless_deleter = std::disjunction<
        stateless_deleter_due_to_stateless<Alloc>,
        stateless_deleter_due_to_policy<Alloc>
>;

template<typename Alloc>
static constexpr bool stateless_deleter_v = stateless_deleter<Alloc>::value;


//Stateless specialization
template<typename Alloc>
struct allocator_delete<
        Alloc,
        std::enable_if_t<stateless_deleter_v<Alloc>>
> /*No Alloc storage*/
{
    using alloc_traits = std::allocator_traits<Alloc>;
    using pointer = typename alloc_traits::pointer;
    using value_type = typename alloc_traits::value_type;

    template<class OtherAlloc>
    explicit allocator_delete(OtherAlloc &&) noexcept {}

    void operator()(pointer p)
    {
        if constexpr (allocator_traits_demo<Alloc>::has_policy::value)
        {
            using policy = typename Alloc::policy;
            using policy_trait = allocator_policy_traits<policy>;
            policy_trait::destroy_method::destroy(p);
            policy_trait::deallocate_method::deallocate(p, 1);
        }
        else if constexpr (std::is_empty_v<Alloc>)
        {
            auto a = Alloc{};
            a.destroy(p);
            a.deallocate(p, 1);
        }

    };
};


template<typename T, typename Alloc, typename ... Args>
auto allocate_unique(Alloc const & allocator, Args && ... args)
{
    using value_type = std::remove_cv_t<T>; // Clean the type
    using alloc_traits = typename std::allocator_traits<Alloc>::
    template rebind_traits<value_type>; // Get actual allocator needed
    using pointer = typename alloc_traits::pointer;
    using allocator_type = typename alloc_traits::allocator_type;
    using deleter_T = allocator_delete<allocator_type>; // type of
custom delete we will use

    auto allocator_T = allocator_type{allocator};

    auto mem = alloc_traits::allocate(allocator_T, 1); // will throw
is can not allocate
    auto hold_deleter = [&](pointer p) {
alloc_traits::deallocate(allocator_T, p, 1); }; // Custom deleter
    auto holder = std::unique_ptr<value_type,
decltype(hold_deleter)>(mem, hold_deleter); // RAII protect mem
    auto deleter = deleter_T{allocator_T}; // Make actual custom
deleter (may throw) do this before construction
    alloc_traits::construct(allocator_T, holder.get(),
std::forward<Args>(args)...); // Construct in mem (may throw)
    return std::unique_ptr<value_type, deleter_T>(holder.release(),
                                                  std::move(deleter));
// repackage with new deleter
}

//*********************USER CODE BELLOW

// allocator resource that owns a slab of memory and allocated from that slab
struct slab_allocator_resource
{
    explicit slab_allocator_resource(std::size_t spaceNeeded) :
            m_buffer(std::malloc(spaceNeeded)),
            m_freeBegin(m_buffer),
            m_freeSpace(spaceNeeded)
    {
        if (!m_buffer) throw std::bad_alloc();
    }

    ~slab_allocator_resource() { std::free(m_buffer); }

    template<typename T>
    [[nodiscard]] T * allocate(std::size_t n)
    {
        return static_cast<T *>(allocate_bytes(alignof(T), sizeof(T) * n));
    }

private:
    void * allocate_bytes(std::size_t align, std::size_t bytes)
    {
        auto mem = std::align(align, bytes, m_freeBegin, m_freeSpace);
        if (!mem) throw std::bad_alloc();
        m_freeBegin = static_cast<char *>(m_freeBegin) + bytes;
        m_freeSpace -= bytes;
        return mem;
    }

    void * m_buffer;
    void * m_freeBegin;
    std::size_t m_freeSpace;
};

// Cooperative allocator policy for the slab_allocator_resource
// static methods are important (needed for detection)
struct slab_allocator_resource_policy
{
    using resource = slab_allocator_resource;

    // explicit stateful allocate
    template<typename T>
    static T * allocate(resource * s, std::size_t n)
    {
        return s->allocate<T>(n);
    }

    // use a common policy method
    using deallocate_method = deallocate_as_noop;
};


struct slab_allocator_resource_policy_not_stateless
{
    using resource = slab_allocator_resource;

    // explicit stateful allocate
    template<typename T>
    static T * allocate(resource * s, std::size_t n)
    {
        return s->allocate<T>(n);
    }

    template<typename T>
    static void deallocate(resource * s, T * p, std::size_t n) noexcept
    {
        //using stateful method signature for illustration purposes only
    }
};


template<typename T>
using slab_allocator = policy_based_allocator<T,
slab_allocator_resource_policy>;

template<typename T>
using slab_allocator_not_stateless = policy_based_allocator<T,
slab_allocator_resource_policy_not_stateless>;

int main()
{
    auto res = slab_allocator_resource{1024};
    {
        auto vec = std::vector<char, slab_allocator<char>>{&res};
        vec.reserve(10); //10 bytes used

        auto a = vec.get_allocator();

        //stateless deleter from policy
        auto ptr1 = allocate_unique<char>(a, 'a');
        static_assert(sizeof(ptr1) == sizeof(void *));

        //stateless deleter from std::allocator
        auto ptr2 = allocate_unique<char>(std::allocator<char>{}, 'a');
        static_assert(sizeof(ptr2) == sizeof(void *));

        //existing allocate_shared (unaware of policy)
        auto ptr3 = std::allocate_shared<char>(a, 'a');
        static_assert(sizeof(ptr3) > sizeof(void *));

        //existing allocate_shared (doesn't optimize for stateless allocators)
        auto ptr4 = std::allocate_shared<char>(std::allocator<char>{}, 'a');
        static_assert(sizeof(ptr4) > sizeof(void *));
    }
    {
        auto a = slab_allocator_not_stateless<char>{&res};

        //stateful deleter from policy
        auto ptr5 = allocate_unique<char>(a, 'a');
        static_assert(sizeof(ptr5) > sizeof(void *));
    }

}

Things to note:

   - Each method signature dictates if it is stateful or not
   - Mechanism to refer to common implementations
   - Policy has no state
   - Allocator conditionally has state
   - Deleter conditionally has state
   - Tried to make a policy which is simple to write and an easy facility
   to make a good quality allocator (I may have missed stuff in pursuit of
   making a "simple" policy)
   - allocate_unique can takes a stateful allocator and make a unique_ptr
   that has a stateless deleter

I propose:

   - allocate_unique and allocate_shared should optimize for stateless
   allocators
   - something like policy_based_allocator which exposes what parts are
   stateful or stateless
   - OR another way to do this ....

Requesting thoughts on:

   - Everything. I hacked this together a few months ago and cleaned it up
   to post here.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANgTfEgpE%3Dm-rnYRGfRgRWv6r_82Zn4f%3DXkup%3DuohpHmm3_PFA%40mail.gmail.com.

--00000000000048004b05786cfb06
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div di=
r=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"lt=
r">tl;dr; Currently a deleter is a facade over an allocator which currently=
 doesn&#39;t hide how big the allocator is.</div><div dir=3D"ltr"><br></div=
><div dir=3D"ltr">Allocators provides a customization point for a generic d=
ata structure which may allocate internal structures. <br></div><div dir=3D=
"ltr"><br></div><div dir=3D"ltr">An allocator controls allocation, construc=
tion, destruction and deallocation. In the standard we have some opinionate=
d allocators std::allocator, std::scoped_allocator_adaptor and std::pmr::po=
lymorphic_allocator.</div><div dir=3D"ltr"><br></div><div>With current allo=
cators, if any one of those customization points require state then the ent=
ire allocator is stateful. This is fine if you are using the allocator as a=
n allocator, you are going to be using those methods that require state so =
the state is not an overhead. But there are situations, like deleter, where=
 you are only using a subset of those methods.</div><div><br></div><div>For=
 a concrete example, allocate_shared needs the allocator to do the allocate=
 and construct. But the returned shared_ptr only requires a specialized del=
eter based on the provided allocator. This deleter is a facade of the alloc=
ator, simplifying the interface and only using destroy and deallocate metho=
ds of the allocator. If those methods are stateless in nature then the shar=
ed_ptr should not have to carry unnecessarily state that the deleter doesn&=
#39;t use. <br></div><div><br></div><div>In GCC, clang and MSVC, allocate_s=
hared doesn&#39;t even optimize for completely stateless allocators, this i=
s an oversight and could/should be fixed<br></div><div><pre style=3D"backgr=
ound-color:rgb(43,43,43);color:rgb(169,183,198);font-family:&quot;DejaVu Sa=
ns Mono&quot;"><font size=3D"2"><span style=3D"color:rgb(204,120,50);font-w=
eight:bold">auto </span>ptr =3D <span style=3D"color:rgb(181,182,227)">std<=
/span>::allocate_shared&lt;<span style=3D"color:rgb(204,120,50);font-weight=
:bold">char</span>&gt;(<span style=3D"color:rgb(181,182,227)">std</span>::a=
llocator&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">char</sp=
an>&gt;{}<span style=3D"color:rgb(204,120,50)">, </span><span style=3D"colo=
r:rgb(106,135,89)">&#39;a&#39;</span>)<span style=3D"color:rgb(204,120,50)"=
>;<br></span><span style=3D"color:rgb(204,120,50);font-weight:bold">static_=
assert</span>(<span style=3D"color:rgb(204,120,50);font-weight:bold">sizeof=
</span>(ptr) &gt; <span style=3D"color:rgb(204,120,50);font-weight:bold">si=
zeof</span>(<span style=3D"color:rgb(204,120,50);font-weight:bold">void </s=
pan>*))<span style=3D"color:rgb(204,120,50)">;</span></font></pre></div><di=
v>But for allocators which are partially stateful there is currently no fac=
ility to make an allocate_shared or allocate_unique implementation which ca=
n sense if the deleter methods (destroy and deallocate) are stateless. With=
out that sense the deleter has to be as stateful as the allocator it was de=
rived from.</div><div><br></div><div>In my experimental codebase I have a p=
olicy_based_allocator which uses a policy to builds the right allocator and=
 I have facilities to sense which parts of the allocator are stateful. Cons=
ider the following code:</div><div><pre style=3D"background-color:rgb(43,43=
,43);color:rgb(169,183,198);font-family:&quot;DejaVu Sans Mono&quot;"><font=
 size=3D"2"><span style=3D"color:rgb(187,181,41)">#include </span><span sty=
le=3D"color:rgb(106,135,89)">&lt;memory&gt;<br></span><span style=3D"color:=
rgb(187,181,41)">#include </span><span style=3D"color:rgb(106,135,89)">&lt;=
experimental/type_traits&gt;<br></span><span style=3D"color:rgb(187,181,41)=
">#include </span><span style=3D"color:rgb(106,135,89)">&lt;type_traits&gt;=
<br></span><span style=3D"color:rgb(187,181,41)">#include </span><span styl=
e=3D"color:rgb(106,135,89)">&lt;vector&gt;<br></span><span style=3D"color:r=
gb(106,135,89)"><br></span><span style=3D"color:rgb(204,120,50);font-weight=
:bold">template</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:=
bold">class</span>&gt; <span style=3D"color:rgb(204,120,50);font-weight:bol=
d">struct </span><span style=3D"color:rgb(181,182,227)">dependent_false </s=
pan>: <span style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"col=
or:rgb(185,188,209)">false_type </span>{}<span style=3D"color:rgb(204,120,5=
0)">;<br></span><span style=3D"color:rgb(204,120,50)"><br></span><span styl=
e=3D"color:rgb(128,128,128)">// Common policy fragments (all stateless)<br>=
</span><span style=3D"color:rgb(204,120,50);font-weight:bold">struct </span=
><span style=3D"color:rgb(181,182,227)">allocate_as_default<br></span>{<br>=
    <span style=3D"color:rgb(204,120,50);font-weight:bold">template</span>&=
lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">class </span><spa=
n style=3D"color:rgb(185,188,209)">T</span>&gt;<br>    [[nodiscard]] <span =
style=3D"color:rgb(204,120,50);font-weight:bold">static </span><span style=
=3D"color:rgb(185,188,209)">T </span>* <span style=3D"color:rgb(255,198,109=
)">allocate</span>(<span style=3D"color:rgb(181,182,227)">std</span>::<span=
 style=3D"color:rgb(185,188,209)">size_t </span>n)<br>    {<br>        <spa=
n style=3D"color:rgb(204,120,50);font-weight:bold">auto constexpr </span>al=
ignment =3D <span style=3D"color:rgb(204,120,50);font-weight:bold">static_c=
ast</span>&lt;<span style=3D"color:rgb(181,182,227)">std</span>::<span styl=
e=3D"color:rgb(181,182,227)">align_val_t</span>&gt;(<span style=3D"color:rg=
b(204,120,50);font-weight:bold">alignof</span>(<span style=3D"color:rgb(185=
,188,209)">T</span>))<span style=3D"color:rgb(204,120,50)">;<br></span><spa=
n style=3D"color:rgb(204,120,50)">        </span><span style=3D"color:rgb(2=
04,120,50);font-weight:bold">auto const </span>bytes =3D <span style=3D"col=
or:rgb(204,120,50);font-weight:bold">sizeof</span>(<span style=3D"color:rgb=
(185,188,209)">T</span>) * n<span style=3D"color:rgb(204,120,50)">;<br></sp=
an><span style=3D"color:rgb(204,120,50)">        </span><span style=3D"colo=
r:rgb(204,120,50);font-weight:bold">return static_cast</span>&lt;<span styl=
e=3D"color:rgb(185,188,209)">T </span>*&gt;(::<span style=3D"color:rgb(204,=
120,50);font-weight:bold">operator </span><span style=3D"color:rgb(95,140,1=
38);font-weight:bold">new</span>(bytes<span style=3D"color:rgb(204,120,50)"=
>, </span>alignment))<span style=3D"color:rgb(204,120,50)">;<br></span><spa=
n style=3D"color:rgb(204,120,50)">    </span>}<br>}<span style=3D"color:rgb=
(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)"><br></span>=
<span style=3D"color:rgb(204,120,50);font-weight:bold">struct </span><span =
style=3D"color:rgb(181,182,227)">construct_as_default<br></span>{<br>    <s=
pan style=3D"color:rgb(204,120,50);font-weight:bold">template</span>&lt;<sp=
an style=3D"color:rgb(204,120,50);font-weight:bold">class </span><span styl=
e=3D"color:rgb(185,188,209)">T</span><span style=3D"color:rgb(204,120,50)">=
, </span><span style=3D"color:rgb(204,120,50);font-weight:bold">class</span=
>... <span style=3D"color:rgb(185,188,209)">Args</span>&gt;<br>    <span st=
yle=3D"color:rgb(204,120,50);font-weight:bold">static void </span><span sty=
le=3D"color:rgb(255,198,109)">construct</span>(<span style=3D"color:rgb(185=
,188,209)">T </span>* p<span style=3D"color:rgb(204,120,50)">, </span><span=
 style=3D"color:rgb(185,188,209)">Args </span>&amp;&amp; ... args)<br>    {=
<br>        ::<span style=3D"color:rgb(204,120,50);font-weight:bold">new</s=
pan>((<span style=3D"color:rgb(204,120,50);font-weight:bold">void </span>*)=
 p) <span style=3D"color:rgb(185,188,209)">T</span>(<span style=3D"color:rg=
b(181,182,227)">std</span>::forward&lt;<span style=3D"color:rgb(185,188,209=
)">Args</span>&gt;(args)...)<span style=3D"color:rgb(204,120,50)">;<br></sp=
an><span style=3D"color:rgb(204,120,50)">    </span>}<br>}<span style=3D"co=
lor:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)"><br>=
</span><span style=3D"color:rgb(204,120,50);font-weight:bold">struct </span=
><span style=3D"color:rgb(181,182,227)">destroy_as_default<br></span>{<br> =
   <span style=3D"color:rgb(204,120,50);font-weight:bold">template</span>&l=
t;<span style=3D"color:rgb(204,120,50);font-weight:bold">typename </span><s=
pan style=3D"color:rgb(185,188,209)">T</span>&gt;<br>    <span style=3D"col=
or:rgb(204,120,50);font-weight:bold">static void </span><span style=3D"colo=
r:rgb(255,198,109)">destroy</span>(<span style=3D"color:rgb(185,188,209)">T=
 </span>* p)<br>    {<br>        p-&gt;<span style=3D"color:rgb(152,118,170=
);font-style:italic">~T</span>()<span style=3D"color:rgb(204,120,50)">;<br>=
</span><span style=3D"color:rgb(204,120,50)">    </span>}<br>}<span style=
=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)=
"><br></span><span style=3D"color:rgb(204,120,50);font-weight:bold">struct =
</span><span style=3D"color:rgb(181,182,227)">deallocate_as_default<br></sp=
an>{<br>    <span style=3D"color:rgb(204,120,50);font-weight:bold">template=
</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">typename =
</span><span style=3D"color:rgb(185,188,209)">T</span>&gt;<br>    <span sty=
le=3D"color:rgb(204,120,50);font-weight:bold">static void </span><span styl=
e=3D"color:rgb(255,198,109)">deallocate</span>(<span style=3D"color:rgb(185=
,188,209)">T </span>* p<span style=3D"color:rgb(204,120,50)">, </span><span=
 style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(185,=
188,209)">size_t </span>n) <span style=3D"color:rgb(204,120,50);font-weight=
:bold">noexcept<br></span><span style=3D"color:rgb(204,120,50);font-weight:=
bold">    </span>{<br>        ::<span style=3D"color:rgb(204,120,50);font-w=
eight:bold">operator </span><span style=3D"color:rgb(95,140,138);font-weigh=
t:bold">delete</span>(p<span style=3D"color:rgb(204,120,50)">, </span><span=
 style=3D"color:rgb(204,120,50);font-weight:bold">alignof</span>(<span styl=
e=3D"color:rgb(185,188,209)">T</span>))<span style=3D"color:rgb(204,120,50)=
">;<br></span><span style=3D"color:rgb(204,120,50)">    </span>}<br>}<span =
style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,12=
0,50)"><br></span><span style=3D"color:rgb(204,120,50);font-weight:bold">st=
ruct </span><span style=3D"color:rgb(181,182,227)">deallocate_as_noop<br></=
span>{<br>    <span style=3D"color:rgb(204,120,50);font-weight:bold">templa=
te</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">typenam=
e </span><span style=3D"color:rgb(185,188,209)">T</span>&gt;<br>    <span s=
tyle=3D"color:rgb(204,120,50);font-weight:bold">static void </span><span st=
yle=3D"color:rgb(255,198,109)">deallocate</span>(<span style=3D"color:rgb(1=
85,188,209)">T </span>* p<span style=3D"color:rgb(204,120,50)">, </span><sp=
an style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(18=
5,188,209)">size_t </span>n) <span style=3D"color:rgb(204,120,50);font-weig=
ht:bold">noexcept<br></span><span style=3D"color:rgb(204,120,50);font-weigh=
t:bold">    </span>{<br>    }<br>}<span style=3D"color:rgb(204,120,50)">;<b=
r></span><span style=3D"color:rgb(204,120,50)"><br></span><span style=3D"co=
lor:rgb(204,120,50);font-weight:bold">template</span>&lt;<span style=3D"col=
or:rgb(204,120,50);font-weight:bold">class </span><span style=3D"color:rgb(=
185,188,209)">Policy</span>&gt;<br><span style=3D"color:rgb(204,120,50);fon=
t-weight:bold">struct </span><span style=3D"color:rgb(181,182,227)">allocat=
or_policy_traits<br></span>{<br><span style=3D"color:rgb(204,120,50);font-w=
eight:bold">private</span>:<br>    <span style=3D"color:rgb(204,120,50);fon=
t-weight:bold">template</span>&lt;<span style=3D"color:rgb(204,120,50);font=
-weight:bold">class </span><span style=3D"color:rgb(185,188,209)">U</span>&=
gt; <span style=3D"color:rgb(204,120,50);font-weight:bold">using </span><sp=
an style=3D"color:rgb(185,188,209)">detect_stateful_allocate </span>=3D <sp=
an style=3D"color:rgb(204,120,50);font-weight:bold">decltype</span>(<span s=
tyle=3D"color:rgb(185,188,209)">U</span>::<span style=3D"color:rgb(204,120,=
50);font-weight:bold">template </span><span style=3D"color:rgb(185,188,209)=
">allocate</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold"=
>char</span>&gt;(<br>            <span style=3D"color:rgb(181,182,227)">std=
</span>::declval&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">=
typename </span><span style=3D"color:rgb(185,188,209)">U</span>::<span styl=
e=3D"color:rgb(185,188,209)">resource </span>*&gt;()<span style=3D"color:rg=
b(204,120,50)">, </span><span style=3D"color:rgb(181,182,227)">std</span>::=
declval&lt;<span style=3D"color:rgb(181,182,227)">std</span>::<span style=
=3D"color:rgb(185,188,209)">size_t</span>&gt;()))<span style=3D"color:rgb(2=
04,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">    </span><s=
pan style=3D"color:rgb(204,120,50);font-weight:bold">template</span>&lt;<sp=
an style=3D"color:rgb(204,120,50);font-weight:bold">class </span><span styl=
e=3D"color:rgb(185,188,209)">U</span>&gt; <span style=3D"color:rgb(204,120,=
50);font-weight:bold">using </span><span style=3D"color:rgb(185,188,209)">d=
etect_stateless_allocate </span>=3D <span style=3D"color:rgb(204,120,50);fo=
nt-weight:bold">decltype</span>(<span style=3D"color:rgb(185,188,209)">U</s=
pan>::<span style=3D"color:rgb(204,120,50);font-weight:bold">template </spa=
n><span style=3D"color:rgb(185,188,209)">allocate</span>&lt;<span style=3D"=
color:rgb(204,120,50);font-weight:bold">char</span>&gt;(<br>            <sp=
an style=3D"color:rgb(181,182,227)">std</span>::declval&lt;<span style=3D"c=
olor:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(185,188,209)">s=
ize_t</span>&gt;()))<span style=3D"color:rgb(204,120,50)">;<br></span><span=
 style=3D"color:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,12=
0,50)">    </span><span style=3D"color:rgb(204,120,50);font-weight:bold">te=
mplate</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">cla=
ss </span><span style=3D"color:rgb(185,188,209)">U</span>&gt; <span style=
=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"col=
or:rgb(185,188,209)">detect_stateful_construct </span>=3D <span style=3D"co=
lor:rgb(204,120,50);font-weight:bold">decltype</span>(<span style=3D"color:=
rgb(185,188,209)">U</span>::<span style=3D"color:rgb(204,120,50);font-weigh=
t:bold">template </span><span style=3D"color:rgb(185,188,209)">construct</s=
pan>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">char</span>&=
gt;(<br>            <span style=3D"color:rgb(181,182,227)">std</span>::decl=
val&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">typename </sp=
an><span style=3D"color:rgb(185,188,209)">U</span>::<span style=3D"color:rg=
b(185,188,209)">resource </span>*&gt;()<span style=3D"color:rgb(204,120,50)=
">, </span><span style=3D"color:rgb(181,182,227)">std</span>::declval&lt;<s=
pan style=3D"color:rgb(204,120,50);font-weight:bold">char </span>*&gt;()))<=
span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(2=
04,120,50)">    </span><span style=3D"color:rgb(204,120,50);font-weight:bol=
d">template</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold=
">class </span><span style=3D"color:rgb(185,188,209)">U</span>&gt; <span st=
yle=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"=
color:rgb(185,188,209)">detect_stateless_construct </span>=3D <span style=
=3D"color:rgb(204,120,50);font-weight:bold">decltype</span>(<span style=3D"=
color:rgb(185,188,209)">U</span>::<span style=3D"color:rgb(204,120,50);font=
-weight:bold">template </span><span style=3D"color:rgb(185,188,209)">constr=
uct</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">char</=
span>&gt;(<br>            <span style=3D"color:rgb(181,182,227)">std</span>=
::declval&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">char </=
span>*&gt;()))<span style=3D"color:rgb(204,120,50)">;<br></span><span style=
=3D"color:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50)"=
>    </span><span style=3D"color:rgb(204,120,50);font-weight:bold">template=
</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">class </s=
pan><span style=3D"color:rgb(185,188,209)">U</span>&gt; <span style=3D"colo=
r:rgb(204,120,50);font-weight:bold">using </span><span style=3D"color:rgb(1=
85,188,209)">detect_stateful_destroy </span>=3D <span style=3D"color:rgb(20=
4,120,50);font-weight:bold">decltype</span>(<span style=3D"color:rgb(185,18=
8,209)">U</span>::<span style=3D"color:rgb(204,120,50);font-weight:bold">te=
mplate </span><span style=3D"color:rgb(185,188,209)">destroy</span>&lt;<spa=
n style=3D"color:rgb(204,120,50);font-weight:bold">char</span>&gt;(<br>    =
        <span style=3D"color:rgb(181,182,227)">std</span>::declval&lt;<span=
 style=3D"color:rgb(204,120,50);font-weight:bold">typename </span><span sty=
le=3D"color:rgb(185,188,209)">U</span>::<span style=3D"color:rgb(185,188,20=
9)">resource </span>*&gt;()<span style=3D"color:rgb(204,120,50)">, </span><=
span style=3D"color:rgb(181,182,227)">std</span>::declval&lt;<span style=3D=
"color:rgb(204,120,50);font-weight:bold">char </span>*&gt;()))<span style=
=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)=
">    </span><span style=3D"color:rgb(204,120,50);font-weight:bold">templat=
e</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">class </=
span><span style=3D"color:rgb(185,188,209)">U</span>&gt; <span style=3D"col=
or:rgb(204,120,50);font-weight:bold">using </span><span style=3D"color:rgb(=
185,188,209)">detect_stateless_destroy </span>=3D <span style=3D"color:rgb(=
204,120,50);font-weight:bold">decltype</span>(<span style=3D"color:rgb(185,=
188,209)">U</span>::<span style=3D"color:rgb(204,120,50);font-weight:bold">=
template </span><span style=3D"color:rgb(185,188,209)">destroy</span>&lt;<s=
pan style=3D"color:rgb(204,120,50);font-weight:bold">char</span>&gt;(<br>  =
          <span style=3D"color:rgb(181,182,227)">std</span>::declval&lt;<sp=
an style=3D"color:rgb(204,120,50);font-weight:bold">char </span>*&gt;()))<s=
pan style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(20=
4,120,50)"><br></span><span style=3D"color:rgb(204,120,50)">    </span><spa=
n style=3D"color:rgb(204,120,50);font-weight:bold">template</span>&lt;<span=
 style=3D"color:rgb(204,120,50);font-weight:bold">class </span><span style=
=3D"color:rgb(185,188,209)">U</span>&gt; <span style=3D"color:rgb(204,120,5=
0);font-weight:bold">using </span><span style=3D"color:rgb(185,188,209)">de=
tect_stateful_deallocate </span>=3D <span style=3D"color:rgb(204,120,50);fo=
nt-weight:bold">decltype</span>(<span style=3D"color:rgb(185,188,209)">U</s=
pan>::<span style=3D"color:rgb(204,120,50);font-weight:bold">template </spa=
n><span style=3D"color:rgb(185,188,209)">deallocate</span>&lt;<span style=
=3D"color:rgb(204,120,50);font-weight:bold">char</span>&gt;(<br>           =
 <span style=3D"color:rgb(181,182,227)">std</span>::declval&lt;<span style=
=3D"color:rgb(204,120,50);font-weight:bold">typename </span><span style=3D"=
color:rgb(185,188,209)">U</span>::<span style=3D"color:rgb(185,188,209)">re=
source </span>*&gt;()<span style=3D"color:rgb(204,120,50)">, </span><span s=
tyle=3D"color:rgb(204,120,50);font-weight:bold">nullptr</span><span style=
=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(104,151,187)">=
1</span>))<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"=
color:rgb(204,120,50)">    </span><span style=3D"color:rgb(204,120,50);font=
-weight:bold">template</span>&lt;<span style=3D"color:rgb(204,120,50);font-=
weight:bold">class </span><span style=3D"color:rgb(185,188,209)">U</span>&g=
t; <span style=3D"color:rgb(204,120,50);font-weight:bold">using </span><spa=
n style=3D"color:rgb(185,188,209)">detect_stateless_deallocate </span>=3D <=
span style=3D"color:rgb(204,120,50);font-weight:bold">decltype</span>(<span=
 style=3D"color:rgb(185,188,209)">U</span>::<span style=3D"color:rgb(204,12=
0,50);font-weight:bold">template </span><span style=3D"color:rgb(185,188,20=
9)">deallocate</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:b=
old">char</span>&gt;(<br>            <span style=3D"color:rgb(204,120,50);f=
ont-weight:bold">nullptr</span><span style=3D"color:rgb(204,120,50)">, </sp=
an><span style=3D"color:rgb(104,151,187)">1</span>))<span style=3D"color:rg=
b(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)"><br></span=
><span style=3D"color:rgb(204,120,50)">    </span><span style=3D"color:rgb(=
204,120,50);font-weight:bold">template</span>&lt;<span style=3D"color:rgb(2=
04,120,50);font-weight:bold">class </span><span style=3D"color:rgb(185,188,=
209)">U</span>&gt; <span style=3D"color:rgb(204,120,50);font-weight:bold">u=
sing </span><span style=3D"color:rgb(185,188,209)">detect_allocate_method <=
/span>=3D <span style=3D"color:rgb(204,120,50);font-weight:bold">typename <=
/span><span style=3D"color:rgb(185,188,209)">U</span>::<span style=3D"color=
:rgb(185,188,209)">allocate_method</span><span style=3D"color:rgb(204,120,5=
0)">;<br></span><span style=3D"color:rgb(204,120,50)">    </span><span styl=
e=3D"color:rgb(204,120,50);font-weight:bold">template</span>&lt;<span style=
=3D"color:rgb(204,120,50);font-weight:bold">class </span><span style=3D"col=
or:rgb(185,188,209)">U</span>&gt; <span style=3D"color:rgb(204,120,50);font=
-weight:bold">using </span><span style=3D"color:rgb(185,188,209)">detect_co=
nstruct_method </span>=3D <span style=3D"color:rgb(204,120,50);font-weight:=
bold">typename </span><span style=3D"color:rgb(185,188,209)">U</span>::<spa=
n style=3D"color:rgb(185,188,209)">construct_method</span><span style=3D"co=
lor:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">    =
</span><span style=3D"color:rgb(204,120,50);font-weight:bold">template</spa=
n>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">class </span><=
span style=3D"color:rgb(185,188,209)">U</span>&gt; <span style=3D"color:rgb=
(204,120,50);font-weight:bold">using </span><span style=3D"color:rgb(185,18=
8,209)">detect_destroy_method </span>=3D <span style=3D"color:rgb(204,120,5=
0);font-weight:bold">typename </span><span style=3D"color:rgb(185,188,209)"=
>U</span>::<span style=3D"color:rgb(185,188,209)">destroy_method</span><spa=
n style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,=
120,50)">    </span><span style=3D"color:rgb(204,120,50);font-weight:bold">=
template</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">c=
lass </span><span style=3D"color:rgb(185,188,209)">U</span>&gt; <span style=
=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"col=
or:rgb(185,188,209)">detect_deallocate_method </span>=3D <span style=3D"col=
or:rgb(204,120,50);font-weight:bold">typename </span><span style=3D"color:r=
gb(185,188,209)">U</span>::<span style=3D"color:rgb(185,188,209)">deallocat=
e_method</span><span style=3D"color:rgb(204,120,50)">;<br></span><span styl=
e=3D"color:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50)=
;font-weight:bold">public</span>:<br><br>    <span style=3D"color:rgb(204,1=
20,50);font-weight:bold">using </span><span style=3D"color:rgb(185,188,209)=
">has_explicit_stateful_allocate </span>=3D <span style=3D"color:rgb(181,18=
2,227)">std</span>::<span style=3D"color:rgb(181,182,227)">experimental</sp=
an>::<span style=3D"color:rgb(185,188,209)">is_detected</span>&lt;<span sty=
le=3D"color:rgb(185,188,209)">detect_stateful_allocate</span><span style=3D=
"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(185,188,209)">Pol=
icy</span>&gt;<span style=3D"color:rgb(204,120,50)">;<br></span><span style=
=3D"color:rgb(204,120,50)">    </span><span style=3D"color:rgb(204,120,50);=
font-weight:bold">using </span><span style=3D"color:rgb(185,188,209)">has_e=
xplicit_stateless_allocate </span>=3D <span style=3D"color:rgb(181,182,227)=
">std</span>::<span style=3D"color:rgb(181,182,227)">experimental</span>::<=
span style=3D"color:rgb(185,188,209)">is_detected</span>&lt;<span style=3D"=
color:rgb(185,188,209)">detect_stateless_allocate</span><span style=3D"colo=
r:rgb(204,120,50)">, </span><span style=3D"color:rgb(185,188,209)">Policy</=
span>&gt;<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"c=
olor:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50)">    =
</span><span style=3D"color:rgb(204,120,50);font-weight:bold">using </span>=
<span style=3D"color:rgb(185,188,209)">has_explicit_stateful_construct </sp=
an>=3D <span style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"co=
lor:rgb(181,182,227)">experimental</span>::<span style=3D"color:rgb(185,188=
,209)">is_detected</span>&lt;<span style=3D"color:rgb(185,188,209)">detect_=
stateful_construct</span><span style=3D"color:rgb(204,120,50)">, </span><sp=
an style=3D"color:rgb(185,188,209)">Policy</span>&gt;<span style=3D"color:r=
gb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">    </spa=
n><span style=3D"color:rgb(204,120,50);font-weight:bold">using </span><span=
 style=3D"color:rgb(185,188,209)">has_explicit_stateless_construct </span>=
=3D <span style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color=
:rgb(181,182,227)">experimental</span>::<span style=3D"color:rgb(185,188,20=
9)">is_detected</span>&lt;<span style=3D"color:rgb(185,188,209)">detect_sta=
teless_construct</span><span style=3D"color:rgb(204,120,50)">, </span><span=
 style=3D"color:rgb(185,188,209)">Policy</span>&gt;<span style=3D"color:rgb=
(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)"><br></span>=
<span style=3D"color:rgb(204,120,50)">    </span><span style=3D"color:rgb(2=
04,120,50);font-weight:bold">using </span><span style=3D"color:rgb(185,188,=
209)">has_explicit_stateful_destroy </span>=3D <span style=3D"color:rgb(181=
,182,227)">std</span>::<span style=3D"color:rgb(181,182,227)">experimental<=
/span>::<span style=3D"color:rgb(185,188,209)">is_detected</span>&lt;<span =
style=3D"color:rgb(185,188,209)">detect_stateful_destroy</span><span style=
=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(185,188,209)">=
Policy</span>&gt;<span style=3D"color:rgb(204,120,50)">;<br></span><span st=
yle=3D"color:rgb(204,120,50)">    </span><span style=3D"color:rgb(204,120,5=
0);font-weight:bold">using </span><span style=3D"color:rgb(185,188,209)">ha=
s_explicit_stateless_destroy </span>=3D <span style=3D"color:rgb(181,182,22=
7)">std</span>::<span style=3D"color:rgb(181,182,227)">experimental</span>:=
:<span style=3D"color:rgb(185,188,209)">is_detected</span>&lt;<span style=
=3D"color:rgb(185,188,209)">detect_stateless_destroy</span><span style=3D"c=
olor:rgb(204,120,50)">, </span><span style=3D"color:rgb(185,188,209)">Polic=
y</span>&gt;<span style=3D"color:rgb(204,120,50)">;<br></span><span style=
=3D"color:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50)"=
>    </span><span style=3D"color:rgb(204,120,50);font-weight:bold">using </=
span><span style=3D"color:rgb(185,188,209)">has_explicit_stateful_deallocat=
e </span>=3D <span style=3D"color:rgb(181,182,227)">std</span>::<span style=
=3D"color:rgb(181,182,227)">experimental</span>::<span style=3D"color:rgb(1=
85,188,209)">is_detected</span>&lt;<span style=3D"color:rgb(185,188,209)">d=
etect_stateful_deallocate</span><span style=3D"color:rgb(204,120,50)">, </s=
pan><span style=3D"color:rgb(185,188,209)">Policy</span>&gt;<span style=3D"=
color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">  =
  </span><span style=3D"color:rgb(204,120,50);font-weight:bold">using </spa=
n><span style=3D"color:rgb(185,188,209)">has_explicit_stateless_deallocate =
</span>=3D <span style=3D"color:rgb(181,182,227)">std</span>::<span style=
=3D"color:rgb(181,182,227)">experimental</span>::<span style=3D"color:rgb(1=
85,188,209)">is_detected</span>&lt;<span style=3D"color:rgb(185,188,209)">d=
etect_stateless_deallocate</span><span style=3D"color:rgb(204,120,50)">, </=
span><span style=3D"color:rgb(185,188,209)">Policy</span>&gt;<span style=3D=
"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)"><=
br></span><span style=3D"color:rgb(204,120,50)">    </span><span style=3D"c=
olor:rgb(204,120,50);font-weight:bold">using </span><span style=3D"color:rg=
b(185,188,209)">requires_stateful_allocator </span>=3D <span style=3D"color=
:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(181,182,227)">disju=
nction</span>&lt;<br>            <span style=3D"color:rgb(185,188,209)">has=
_explicit_stateful_allocate</span><span style=3D"color:rgb(204,120,50)">,<b=
r></span><span style=3D"color:rgb(204,120,50)">            </span><span sty=
le=3D"color:rgb(185,188,209)">has_explicit_stateful_construct</span><span s=
tyle=3D"color:rgb(204,120,50)">,<br></span><span style=3D"color:rgb(204,120=
,50)">            </span><span style=3D"color:rgb(185,188,209)">has_explici=
t_stateful_destroy</span><span style=3D"color:rgb(204,120,50)">,<br></span>=
<span style=3D"color:rgb(204,120,50)">            </span><span style=3D"col=
or:rgb(185,188,209)">has_explicit_stateful_deallocate<br></span><span style=
=3D"color:rgb(185,188,209)">    </span>&gt;<span style=3D"color:rgb(204,120=
,50)">;<br></span><span style=3D"color:rgb(204,120,50)"><br></span><span st=
yle=3D"color:rgb(204,120,50)">    </span><span style=3D"color:rgb(204,120,5=
0);font-weight:bold">using </span><span style=3D"color:rgb(185,188,209)">re=
quires_stateful_deleter </span>=3D <span style=3D"color:rgb(181,182,227)">s=
td</span>::<span style=3D"color:rgb(181,182,227)">disjunction</span>&lt;<br=
>            <span style=3D"color:rgb(185,188,209)">has_explicit_stateful_d=
estroy</span><span style=3D"color:rgb(204,120,50)">,<br></span><span style=
=3D"color:rgb(204,120,50)">            </span><span style=3D"color:rgb(185,=
188,209)">has_explicit_stateful_deallocate<br></span><span style=3D"color:r=
gb(185,188,209)">    </span>&gt;<span style=3D"color:rgb(204,120,50)">;<br>=
</span><span style=3D"color:rgb(204,120,50)"><br></span><span style=3D"colo=
r:rgb(204,120,50)">    </span><span style=3D"color:rgb(204,120,50);font-wei=
ght:bold">using </span><span style=3D"color:rgb(185,188,209)">allocate_meth=
od </span>=3D <span style=3D"color:rgb(181,182,227)">std</span>::<span styl=
e=3D"color:rgb(185,188,209)">conditional_t</span>&lt;<br>            <span =
style=3D"color:rgb(185,188,209)">has_explicit_stateless_allocate</span>::<s=
pan style=3D"color:rgb(147,115,165)">value</span><span style=3D"color:rgb(2=
04,120,50)">,<br></span><span style=3D"color:rgb(204,120,50)">            <=
/span><span style=3D"color:rgb(185,188,209)">Policy</span><span style=3D"co=
lor:rgb(204,120,50)">,<br></span><span style=3D"color:rgb(204,120,50)">    =
        </span><span style=3D"color:rgb(181,182,227)">std</span>::<span sty=
le=3D"color:rgb(181,182,227)">experimental</span>::<span style=3D"color:rgb=
(185,188,209)">detected_or_t</span>&lt;<span style=3D"color:rgb(181,182,227=
)">allocate_as_default</span><span style=3D"color:rgb(204,120,50)">, </span=
><span style=3D"color:rgb(185,188,209)">detect_allocate_method</span><span =
style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(185,188,2=
09)">Policy</span>&gt;<br>    &gt;<span style=3D"color:rgb(204,120,50)">;<b=
r></span><span style=3D"color:rgb(204,120,50)">    </span><span style=3D"co=
lor:rgb(204,120,50);font-weight:bold">using </span><span style=3D"color:rgb=
(185,188,209)">construct_method </span>=3D <span style=3D"color:rgb(181,182=
,227)">std</span>::<span style=3D"color:rgb(185,188,209)">conditional_t</sp=
an>&lt;<br>            <span style=3D"color:rgb(185,188,209)">has_explicit_=
stateless_construct</span>::<span style=3D"color:rgb(147,115,165)">value</s=
pan><span style=3D"color:rgb(204,120,50)">,<br></span><span style=3D"color:=
rgb(204,120,50)">            </span><span style=3D"color:rgb(185,188,209)">=
Policy</span><span style=3D"color:rgb(204,120,50)">,<br></span><span style=
=3D"color:rgb(204,120,50)">            </span><span style=3D"color:rgb(181,=
182,227)">std</span>::<span style=3D"color:rgb(181,182,227)">experimental</=
span>::<span style=3D"color:rgb(185,188,209)">detected_or_t</span>&lt;<span=
 style=3D"color:rgb(181,182,227)">construct_as_default</span><span style=3D=
"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(185,188,209)">det=
ect_construct_method</span><span style=3D"color:rgb(204,120,50)">, </span><=
span style=3D"color:rgb(185,188,209)">Policy</span>&gt;<br>    &gt;<span st=
yle=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,=
50)">    </span><span style=3D"color:rgb(204,120,50);font-weight:bold">usin=
g </span><span style=3D"color:rgb(185,188,209)">destroy_method </span>=3D <=
span style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(=
185,188,209)">conditional_t</span>&lt;<br>            <span style=3D"color:=
rgb(185,188,209)">has_explicit_stateless_destroy</span>::<span style=3D"col=
or:rgb(147,115,165)">value</span><span style=3D"color:rgb(204,120,50)">,<br=
></span><span style=3D"color:rgb(204,120,50)">            </span><span styl=
e=3D"color:rgb(185,188,209)">Policy</span><span style=3D"color:rgb(204,120,=
50)">,<br></span><span style=3D"color:rgb(204,120,50)">            </span><=
span style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(=
181,182,227)">experimental</span>::<span style=3D"color:rgb(185,188,209)">d=
etected_or_t</span>&lt;<span style=3D"color:rgb(181,182,227)">destroy_as_de=
fault</span><span style=3D"color:rgb(204,120,50)">, </span><span style=3D"c=
olor:rgb(185,188,209)">detect_destroy_method</span><span style=3D"color:rgb=
(204,120,50)">, </span><span style=3D"color:rgb(185,188,209)">Policy</span>=
&gt;<br>    &gt;<span style=3D"color:rgb(204,120,50)">;<br></span><span sty=
le=3D"color:rgb(204,120,50)">    </span><span style=3D"color:rgb(204,120,50=
);font-weight:bold">using </span><span style=3D"color:rgb(185,188,209)">dea=
llocate_method </span>=3D <span style=3D"color:rgb(181,182,227)">std</span>=
::<span style=3D"color:rgb(185,188,209)">conditional_t</span>&lt;<br>      =
      <span style=3D"color:rgb(185,188,209)">has_explicit_stateless_dealloc=
ate</span>::<span style=3D"color:rgb(147,115,165)">value</span><span style=
=3D"color:rgb(204,120,50)">,<br></span><span style=3D"color:rgb(204,120,50)=
">            </span><span style=3D"color:rgb(185,188,209)">Policy</span><s=
pan style=3D"color:rgb(204,120,50)">,<br></span><span style=3D"color:rgb(20=
4,120,50)">            </span><span style=3D"color:rgb(181,182,227)">std</s=
pan>::<span style=3D"color:rgb(181,182,227)">experimental</span>::<span sty=
le=3D"color:rgb(185,188,209)">detected_or_t</span>&lt;<span style=3D"color:=
rgb(181,182,227)">deallocate_as_default</span><span style=3D"color:rgb(204,=
120,50)">, </span><span style=3D"color:rgb(185,188,209)">detect_deallocate_=
method</span><span style=3D"color:rgb(204,120,50)">, </span><span style=3D"=
color:rgb(185,188,209)">Policy</span>&gt;<br>    &gt;<span style=3D"color:r=
gb(204,120,50)">;<br></span>}<span style=3D"color:rgb(204,120,50)">;<br></s=
pan><span style=3D"color:rgb(204,120,50)"><br></span><span style=3D"color:r=
gb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50);font-weight=
:bold">template</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:=
bold">typename </span><span style=3D"color:rgb(185,188,209)">Policy</span><=
span style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(204,=
120,50);font-weight:bold">typename </span><span style=3D"color:rgb(185,188,=
209)">Enable </span>=3D <span style=3D"color:rgb(204,120,50);font-weight:bo=
ld">void</span>&gt;<br><span style=3D"color:rgb(204,120,50);font-weight:bol=
d">struct </span><span style=3D"color:rgb(181,182,227)">policy_based_alloca=
tor_base </span><span style=3D"color:rgb(128,128,128)">// state-less<br></s=
pan>{<br>    <span style=3D"color:rgb(204,120,50);font-weight:bold">using <=
/span><span style=3D"color:rgb(185,188,209)">is_always_equal </span>=3D <sp=
an style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(18=
5,188,209)">true_type</span><span style=3D"color:rgb(204,120,50)">;<br></sp=
an>}<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:=
rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50);font-weigh=
t:bold">template</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight=
:bold">typename </span><span style=3D"color:rgb(185,188,209)">Policy</span>=
&gt;<br><span style=3D"color:rgb(204,120,50);font-weight:bold">struct </spa=
n><span style=3D"color:rgb(181,182,227)">policy_based_allocator_base</span>=
&lt;<span style=3D"color:rgb(185,188,209)">Policy</span><span style=3D"colo=
r:rgb(204,120,50)">, </span><span style=3D"color:rgb(181,182,227)">std</spa=
n>::<span style=3D"color:rgb(185,188,209)">enable_if_t</span>&lt;<span styl=
e=3D"color:rgb(181,182,227)">allocator_policy_traits</span>&lt;<span style=
=3D"color:rgb(185,188,209)">Policy</span>&gt;::<span style=3D"color:rgb(185=
,188,209)">requires_stateful_allocator</span>::<span style=3D"color:rgb(185=
,188,209)">value</span>&gt;&gt; <span style=3D"color:rgb(128,128,128)">// s=
tate-full<br></span>{<br>    <span style=3D"color:rgb(204,120,50);font-weig=
ht:bold">using </span><span style=3D"color:rgb(185,188,209)">resource_t </s=
pan>=3D <span style=3D"color:rgb(204,120,50);font-weight:bold">typename </s=
pan><span style=3D"color:rgb(185,188,209)">Policy</span>::<span style=3D"co=
lor:rgb(185,188,209)">resource</span><span style=3D"color:rgb(204,120,50)">=
;<br></span><span style=3D"color:rgb(204,120,50)">    </span><span style=3D=
"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"color:=
rgb(185,188,209)">is_always_equal </span>=3D <span style=3D"color:rgb(181,1=
82,227)">std</span>::<span style=3D"color:rgb(185,188,209)">false_type</spa=
n><span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rg=
b(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50)">    </span>=
<span style=3D"color:rgb(255,198,109)">policy_based_allocator_base</span>()=
 =3D <span style=3D"color:rgb(204,120,50);font-weight:bold">delete</span><s=
pan style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(20=
4,120,50)"><br></span><span style=3D"color:rgb(204,120,50)">    </span><spa=
n style=3D"color:rgb(255,198,109)">policy_based_allocator_base</span>(<span=
 style=3D"color:rgb(185,188,209)">resource_t </span>* resource) : <span sty=
le=3D"color:rgb(147,115,165)">m_resource</span>{resource} {} <span style=3D=
"color:rgb(128,128,128)">// NOLINT<br></span><span style=3D"color:rgb(128,1=
28,128)"><br></span><span style=3D"color:rgb(128,128,128)">    </span><span=
 style=3D"color:rgb(255,198,109)">policy_based_allocator_base</span>(<span =
style=3D"color:rgb(181,182,227)">policy_based_allocator_base </span><span s=
tyle=3D"color:rgb(204,120,50);font-weight:bold">const </span>&amp; other) :=
 <span style=3D"color:rgb(147,115,165)">m_resource</span>{other.<span style=
=3D"color:rgb(147,115,165)">m_resource</span>} {}<br><br>    <span style=3D=
"color:rgb(185,188,209)">resource_t </span>* <span style=3D"color:rgb(147,1=
15,165)">m_resource</span><span style=3D"color:rgb(204,120,50)">;<br></span=
>}<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rg=
b(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50);font-weight:=
bold">template</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:b=
old">typename </span><span style=3D"color:rgb(185,188,209)">T</span><span s=
tyle=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(204,120,50=
);font-weight:bold">typename </span><span style=3D"color:rgb(185,188,209)">=
Policy</span>&gt;<br><span style=3D"color:rgb(204,120,50);font-weight:bold"=
>struct </span><span style=3D"color:rgb(181,182,227)">policy_based_allocato=
r </span>: <span style=3D"color:rgb(181,182,227)">policy_based_allocator_ba=
se</span>&lt;<span style=3D"color:rgb(185,188,209)">Policy</span>&gt;<br>{<=
br>    <span style=3D"color:rgb(204,120,50);font-weight:bold">using </span>=
<span style=3D"color:rgb(185,188,209)">policy </span>=3D <span style=3D"col=
or:rgb(185,188,209)">Policy</span><span style=3D"color:rgb(204,120,50)">;<b=
r></span><span style=3D"color:rgb(204,120,50)">    </span><span style=3D"co=
lor:rgb(204,120,50);font-weight:bold">using </span><span style=3D"color:rgb=
(185,188,209)">base </span>=3D <span style=3D"color:rgb(181,182,227)">polic=
y_based_allocator_base</span>&lt;<span style=3D"color:rgb(185,188,209)">Pol=
icy</span>&gt;<span style=3D"color:rgb(204,120,50)">;<br></span><span style=
=3D"color:rgb(204,120,50)">    </span><span style=3D"color:rgb(204,120,50);=
font-weight:bold">using </span><span style=3D"color:rgb(185,188,209)">trait=
 </span>=3D <span style=3D"color:rgb(181,182,227)">allocator_policy_traits<=
/span>&lt;<span style=3D"color:rgb(185,188,209)">Policy</span>&gt;<span sty=
le=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,5=
0)"><br></span><span style=3D"color:rgb(204,120,50)">    </span><span style=
=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"col=
or:rgb(185,188,209)">value_type </span>=3D <span style=3D"color:rgb(181,182=
,227)">std</span>::<span style=3D"color:rgb(185,188,209)">remove_cv_t</span=
>&lt;<span style=3D"color:rgb(185,188,209)">T</span>&gt;<span style=3D"colo=
r:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)"><br></=
span><span style=3D"color:rgb(204,120,50)">    </span><span style=3D"color:=
rgb(204,120,50);font-weight:bold">template</span>&lt;<span style=3D"color:r=
gb(204,120,50);font-weight:bold">class </span><span style=3D"color:rgb(185,=
188,209)">U</span>&gt; <span style=3D"color:rgb(204,120,50);font-weight:bol=
d">struct </span><span style=3D"color:rgb(181,182,227)">rebind </span>{ <sp=
an style=3D"color:rgb(204,120,50);font-weight:bold">typedef </span><span st=
yle=3D"color:rgb(181,182,227)">policy_based_allocator</span>&lt;<span style=
=3D"color:rgb(185,188,209)">U</span><span style=3D"color:rgb(204,120,50)">,=
 </span><span style=3D"color:rgb(185,188,209)">Policy</span>&gt; <span styl=
e=3D"color:rgb(185,188,209)">other</span><span style=3D"color:rgb(204,120,5=
0)">; </span>}<span style=3D"color:rgb(204,120,50)">;<br></span><span style=
=3D"color:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50)"=
>    </span><span style=3D"color:rgb(128,128,128)">//inherit base construct=
ors<br></span><span style=3D"color:rgb(128,128,128)">    </span><span style=
=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"col=
or:rgb(185,188,209)">base</span>::<span style=3D"color:rgb(181,182,227)">po=
licy_based_allocator_base</span><span style=3D"color:rgb(204,120,50)">;<br>=
</span><span style=3D"color:rgb(204,120,50)"><br></span><span style=3D"colo=
r:rgb(204,120,50)">    </span><span style=3D"color:rgb(204,120,50);font-wei=
ght:bold">template</span>&lt;<span style=3D"color:rgb(204,120,50);font-weig=
ht:bold">typename </span><span style=3D"color:rgb(185,188,209)">U</span>&gt=
;<br>    <span style=3D"color:rgb(255,198,109)">policy_based_allocator</spa=
n>(<span style=3D"color:rgb(181,182,227)">policy_based_allocator</span>&lt;=
<span style=3D"color:rgb(185,188,209)">U</span><span style=3D"color:rgb(204=
,120,50)">, </span><span style=3D"color:rgb(185,188,209)">Policy</span>&gt;=
 <span style=3D"color:rgb(204,120,50);font-weight:bold">const </span>&amp; =
other) : <span style=3D"color:rgb(185,188,209)">base</span>(other) {} <span=
 style=3D"color:rgb(128,128,128)">// NOLINT<br></span><span style=3D"color:=
rgb(128,128,128)"><br></span><span style=3D"color:rgb(128,128,128)">    </s=
pan>[[nodiscard]] <span style=3D"color:rgb(185,188,209)">value_type </span>=
* <span style=3D"color:rgb(255,198,109)">allocate</span>(<span style=3D"col=
or:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(185,188,209)">siz=
e_t </span>n)<br>    {<br>        <span style=3D"color:rgb(204,120,50);font=
-weight:bold">if constexpr</span>(<span style=3D"color:rgb(185,188,209)">tr=
ait</span>::<span style=3D"color:rgb(185,188,209)">has_explicit_stateful_al=
locate</span>::<span style=3D"color:rgb(147,115,165)">value</span>)<br>    =
    {<br>            <span style=3D"color:rgb(128,128,128)">// Stateful all=
ocate<br></span><span style=3D"color:rgb(128,128,128)">            </span><=
span style=3D"color:rgb(204,120,50);font-weight:bold">return </span><span s=
tyle=3D"color:rgb(185,188,209)">Policy</span>::<span style=3D"color:rgb(204=
,120,50);font-weight:bold">template </span><span style=3D"color:rgb(185,188=
,209)">allocate</span>&lt;<span style=3D"color:rgb(185,188,209)">value_type=
</span>&gt;(<span style=3D"color:rgb(185,188,209)">base</span>::<span style=
=3D"color:rgb(147,115,165)">m_resource</span><span style=3D"color:rgb(204,1=
20,50)">, </span>n)<span style=3D"color:rgb(204,120,50)">;<br></span><span =
style=3D"color:rgb(204,120,50)">        </span>}<br>        <span style=3D"=
color:rgb(204,120,50);font-weight:bold">else<br></span><span style=3D"color=
:rgb(204,120,50);font-weight:bold">        </span>{<br>            <span st=
yle=3D"color:rgb(204,120,50);font-weight:bold">return </span><span style=3D=
"color:rgb(185,188,209)">trait</span>::<span style=3D"color:rgb(185,188,209=
)">allocate_method</span>::<span style=3D"color:rgb(204,120,50);font-weight=
:bold">template </span><span style=3D"color:rgb(185,188,209)">allocate</spa=
n>&lt;<span style=3D"color:rgb(185,188,209)">value_type</span>&gt;(n)<span =
style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,12=
0,50)">        </span>}<br>    }<br><br>    <span style=3D"color:rgb(204,12=
0,50);font-weight:bold">template</span>&lt;<span style=3D"color:rgb(204,120=
,50);font-weight:bold">class </span><span style=3D"color:rgb(185,188,209)">=
U</span><span style=3D"color:rgb(204,120,50)">, </span><span style=3D"color=
:rgb(204,120,50);font-weight:bold">class</span>... <span style=3D"color:rgb=
(185,188,209)">Args</span>&gt;<br>    <span style=3D"color:rgb(204,120,50);=
font-weight:bold">void </span><span style=3D"color:rgb(255,198,109)">constr=
uct</span>(<span style=3D"color:rgb(185,188,209)">U </span>* p<span style=
=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(185,188,209)">=
Args </span>&amp;&amp; ... args)<br>    {<br>        <span style=3D"color:r=
gb(204,120,50);font-weight:bold">constexpr bool </span>uses_allocator =3D <=
span style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(=
181,182,227)">uses_allocator</span>&lt;<span style=3D"color:rgb(185,188,209=
)">U</span><span style=3D"color:rgb(204,120,50)">, </span><span style=3D"co=
lor:rgb(181,182,227)">policy_based_allocator</span>&gt;::<span style=3D"col=
or:rgb(147,115,165)">value</span><span style=3D"color:rgb(204,120,50)">;<br=
></span><span style=3D"color:rgb(204,120,50)"><br></span><span style=3D"col=
or:rgb(204,120,50)">        </span><span style=3D"color:rgb(204,120,50);fon=
t-weight:bold">constexpr bool </span>ctr_1 =3D <span style=3D"color:rgb(181=
,182,227)">std</span>::<span style=3D"color:rgb(181,182,227)">is_constructi=
ble</span>&lt;<span style=3D"color:rgb(185,188,209)">U</span><span style=3D=
"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(185,188,209)">Arg=
s</span>...&gt;::<span style=3D"color:rgb(147,115,165)">value</span><span s=
tyle=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120=
,50)">        </span><span style=3D"color:rgb(204,120,50);font-weight:bold"=
>constexpr bool </span>ctr_2 =3D <span style=3D"color:rgb(181,182,227)">std=
</span>::<span style=3D"color:rgb(181,182,227)">is_constructible</span>&lt;=
<span style=3D"color:rgb(185,188,209)">U</span><span style=3D"color:rgb(204=
,120,50)">, </span><span style=3D"color:rgb(181,182,227)">std</span>::<span=
 style=3D"color:rgb(181,182,227)">allocator_arg_t</span><span style=3D"colo=
r:rgb(204,120,50)">, </span><span style=3D"color:rgb(181,182,227)">policy_b=
ased_allocator</span>&lt;<span style=3D"color:rgb(185,188,209)">U</span><sp=
an style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(185,18=
8,209)">Policy</span>&gt;<span style=3D"color:rgb(204,120,50)">, </span><sp=
an style=3D"color:rgb(185,188,209)">Args</span>...&gt;::<span style=3D"colo=
r:rgb(147,115,165)">value</span><span style=3D"color:rgb(204,120,50)">;<br>=
</span><span style=3D"color:rgb(204,120,50)">        </span><span style=3D"=
color:rgb(204,120,50);font-weight:bold">constexpr bool </span>ctr_3 =3D <sp=
an style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(18=
1,182,227)">is_constructible</span>&lt;<span style=3D"color:rgb(185,188,209=
)">U</span><span style=3D"color:rgb(204,120,50)">, </span><span style=3D"co=
lor:rgb(185,188,209)">Args</span>...<span style=3D"color:rgb(204,120,50)">,=
 </span><span style=3D"color:rgb(181,182,227)">policy_based_allocator</span=
>&lt;<span style=3D"color:rgb(185,188,209)">U</span><span style=3D"color:rg=
b(204,120,50)">, </span><span style=3D"color:rgb(185,188,209)">Policy</span=
>&gt;&gt;::<span style=3D"color:rgb(147,115,165)">value</span><span style=
=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)=
"><br></span><span style=3D"color:rgb(204,120,50)">        </span><span sty=
le=3D"color:rgb(204,120,50);font-weight:bold">if constexpr </span>(!uses_al=
locator &amp;&amp; ctr_1)<br>        {<br>            construct_impl(p<span=
 style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(181,182,=
227)">std</span>::forward&lt;<span style=3D"color:rgb(185,188,209)">Args</s=
pan>&gt;(args)...)<span style=3D"color:rgb(204,120,50)">;<br></span><span s=
tyle=3D"color:rgb(204,120,50)">        </span>}<br>        <span style=3D"c=
olor:rgb(204,120,50);font-weight:bold">else if constexpr </span>(uses_alloc=
ator &amp;&amp; ctr_2)<br>        {<br>            construct_impl(p<span st=
yle=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(181,182,227=
)">std</span>::allocator_arg<span style=3D"color:rgb(204,120,50)">, </span>=
*<span style=3D"color:rgb(204,120,50);font-weight:bold">this</span><span st=
yle=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(181,182,227=
)">std</span>::forward&lt;<span style=3D"color:rgb(185,188,209)">Args</span=
>&gt;(args)...)<span style=3D"color:rgb(204,120,50)">;<br></span><span styl=
e=3D"color:rgb(204,120,50)">        </span>}<br>        <span style=3D"colo=
r:rgb(204,120,50);font-weight:bold">else if constexpr </span>(uses_allocato=
r &amp;&amp; ctr_3)<br>        {<br>            construct_impl(p<span style=
=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(181,182,227)">=
std</span>::forward&lt;<span style=3D"color:rgb(185,188,209)">Args</span>&g=
t;(args)...<span style=3D"color:rgb(204,120,50)">, </span>*<span style=3D"c=
olor:rgb(204,120,50);font-weight:bold">this</span>)<span style=3D"color:rgb=
(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">        </s=
pan>}<br>        <span style=3D"color:rgb(204,120,50);font-weight:bold">els=
e<br></span><span style=3D"color:rgb(204,120,50);font-weight:bold">        =
</span>{<br>            <span style=3D"color:rgb(204,120,50);font-weight:bo=
ld">static_assert</span>(<span style=3D"color:rgb(181,182,227)">dependent_f=
alse</span>&lt;<span style=3D"color:rgb(185,188,209)">U</span>&gt;::<span s=
tyle=3D"color:rgb(147,115,165)">value</span><span style=3D"color:rgb(204,12=
0,50)">, </span><span style=3D"color:rgb(106,135,89)">&quot;No valid constr=
uctor&quot;</span>)<span style=3D"color:rgb(204,120,50)">;<br></span><span =
style=3D"color:rgb(204,120,50)">        </span>}<br>    }<br><br>    <span =
style=3D"color:rgb(204,120,50);font-weight:bold">template</span>&lt;<span s=
tyle=3D"color:rgb(204,120,50);font-weight:bold">typename </span><span style=
=3D"color:rgb(185,188,209)">U</span>&gt;<br>    <span style=3D"color:rgb(20=
4,120,50);font-weight:bold">void </span><span style=3D"color:rgb(255,198,10=
9)">destroy</span>(<span style=3D"color:rgb(185,188,209)">U </span>* p)<br>=
    {<br>        <span style=3D"color:rgb(204,120,50);font-weight:bold">if =
constexpr</span>(<span style=3D"color:rgb(185,188,209)">trait</span>::<span=
 style=3D"color:rgb(185,188,209)">has_explicit_stateful_destroy</span>::<sp=
an style=3D"color:rgb(147,115,165)">value</span>)<br>        {<br>         =
   <span style=3D"color:rgb(128,128,128)">// Stateful destroy<br></span><sp=
an style=3D"color:rgb(128,128,128)">            </span><span style=3D"color=
:rgb(185,188,209)">Policy</span>::<span style=3D"color:rgb(185,188,209)">de=
stroy</span>(<span style=3D"color:rgb(185,188,209)">base</span>::<span styl=
e=3D"color:rgb(147,115,165)">m_resource</span><span style=3D"color:rgb(204,=
120,50)">, </span>p)<span style=3D"color:rgb(204,120,50)">;<br></span><span=
 style=3D"color:rgb(204,120,50)">        </span>}<br>        <span style=3D=
"color:rgb(204,120,50);font-weight:bold">else<br></span><span style=3D"colo=
r:rgb(204,120,50);font-weight:bold">        </span>{<br>            <span s=
tyle=3D"color:rgb(185,188,209)">trait</span>::<span style=3D"color:rgb(185,=
188,209)">destroy_method</span>::<span style=3D"color:rgb(185,188,209)">des=
troy</span>(p)<span style=3D"color:rgb(204,120,50)">;<br></span><span style=
=3D"color:rgb(204,120,50)">        </span>}<br>    }<br><br>    <span style=
=3D"color:rgb(204,120,50);font-weight:bold">void </span><span style=3D"colo=
r:rgb(255,198,109)">deallocate</span>(<span style=3D"color:rgb(185,188,209)=
">T </span>* p<span style=3D"color:rgb(204,120,50)">, </span><span style=3D=
"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(185,188,209)"=
>size_t </span>n)<br>    {<br>        <span style=3D"color:rgb(204,120,50);=
font-weight:bold">if constexpr</span>(<span style=3D"color:rgb(185,188,209)=
">trait</span>::<span style=3D"color:rgb(185,188,209)">has_explicit_statefu=
l_deallocate</span>::<span style=3D"color:rgb(147,115,165)">value</span>)<b=
r>        {<br>            <span style=3D"color:rgb(128,128,128)">// Statef=
ul deallocate<br></span><span style=3D"color:rgb(128,128,128)">            =
</span><span style=3D"color:rgb(185,188,209)">Policy</span>::<span style=3D=
"color:rgb(185,188,209)">deallocate</span>(<span style=3D"color:rgb(185,188=
,209)">base</span>::<span style=3D"color:rgb(147,115,165)">m_resource</span=
><span style=3D"color:rgb(204,120,50)">, </span>p<span style=3D"color:rgb(2=
04,120,50)">, </span>n)<span style=3D"color:rgb(204,120,50)">;<br></span><s=
pan style=3D"color:rgb(204,120,50)">        </span>}<br>        <span style=
=3D"color:rgb(204,120,50);font-weight:bold">else<br></span><span style=3D"c=
olor:rgb(204,120,50);font-weight:bold">        </span>{<br>            <spa=
n style=3D"color:rgb(185,188,209)">trait</span>::<span style=3D"color:rgb(1=
85,188,209)">deallocate_method</span>::<span style=3D"color:rgb(185,188,209=
)">deallocate</span>(p<span style=3D"color:rgb(204,120,50)">, </span>n)<spa=
n style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,=
120,50)">        </span>}<br>    }<br><br><br><span style=3D"color:rgb(204,=
120,50);font-weight:bold">private</span>:<br><br>    <span style=3D"color:r=
gb(204,120,50);font-weight:bold">template</span>&lt;<span style=3D"color:rg=
b(204,120,50);font-weight:bold">class </span><span style=3D"color:rgb(185,1=
88,209)">U</span><span style=3D"color:rgb(204,120,50)">, </span><span style=
=3D"color:rgb(204,120,50);font-weight:bold">class</span>... <span style=3D"=
color:rgb(185,188,209)">Args</span>&gt;<br>    <span style=3D"color:rgb(204=
,120,50);font-weight:bold">void </span><span style=3D"color:rgb(255,198,109=
)">construct_impl</span>(<span style=3D"color:rgb(185,188,209)">U </span>* =
p<span style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(18=
5,188,209)">Args </span>&amp;&amp; ... args)<br>    {<br>        <span styl=
e=3D"color:rgb(204,120,50);font-weight:bold">if constexpr</span>(<span styl=
e=3D"color:rgb(185,188,209)">trait</span>::<span style=3D"color:rgb(185,188=
,209)">has_explicit_stateful_construct</span>::<span style=3D"color:rgb(147=
,115,165)">value</span>)<br>        {<br>            <span style=3D"color:r=
gb(128,128,128)">// Stateful construct<br></span><span style=3D"color:rgb(1=
28,128,128)">            </span><span style=3D"color:rgb(185,188,209)">Poli=
cy</span>::<span style=3D"color:rgb(185,188,209)">construct</span>(<span st=
yle=3D"color:rgb(185,188,209)">base</span>::<span style=3D"color:rgb(147,11=
5,165)">m_resource</span><span style=3D"color:rgb(204,120,50)">, </span>p<s=
pan style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(181,1=
82,227)">std</span>::forward&lt;<span style=3D"color:rgb(185,188,209)">Args=
</span>&gt;(args)...)<span style=3D"color:rgb(204,120,50)">;<br></span><spa=
n style=3D"color:rgb(204,120,50)">        </span>}<br>        <span style=
=3D"color:rgb(204,120,50);font-weight:bold">else<br></span><span style=3D"c=
olor:rgb(204,120,50);font-weight:bold">        </span>{<br>            <spa=
n style=3D"color:rgb(185,188,209)">trait</span>::<span style=3D"color:rgb(1=
85,188,209)">construct_method</span>::<span style=3D"color:rgb(185,188,209)=
">construct</span>(p<span style=3D"color:rgb(204,120,50)">, </span><span st=
yle=3D"color:rgb(181,182,227)">std</span>::forward&lt;<span style=3D"color:=
rgb(185,188,209)">Args</span>&gt;(args)...)<span style=3D"color:rgb(204,120=
,50)">;<br></span><span style=3D"color:rgb(204,120,50)">        </span>}<br=
>    }<br>}<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D=
"color:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50);fon=
t-weight:bold">template</span>&lt;<span style=3D"color:rgb(204,120,50);font=
-weight:bold">class </span><span style=3D"color:rgb(185,188,209)">T</span><=
span style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(204,=
120,50);font-weight:bold">class </span><span style=3D"color:rgb(185,188,209=
)">U</span><span style=3D"color:rgb(204,120,50)">, </span><span style=3D"co=
lor:rgb(204,120,50);font-weight:bold">typename </span><span style=3D"color:=
rgb(185,188,209)">Policy</span>&gt;<br><span style=3D"color:rgb(204,120,50)=
;font-weight:bold">bool operator</span><span style=3D"color:rgb(255,198,109=
)">=3D=3D</span>(<span style=3D"color:rgb(204,120,50);font-weight:bold">con=
st </span><span style=3D"color:rgb(181,182,227)">policy_based_allocator</sp=
an>&lt;<span style=3D"color:rgb(185,188,209)">T</span><span style=3D"color:=
rgb(204,120,50)">, </span><span style=3D"color:rgb(185,188,209)">Policy</sp=
an>&gt; &amp; lhs<span style=3D"color:rgb(204,120,50)">, </span><span style=
=3D"color:rgb(204,120,50);font-weight:bold">const </span><span style=3D"col=
or:rgb(181,182,227)">policy_based_allocator</span>&lt;<span style=3D"color:=
rgb(185,188,209)">U</span><span style=3D"color:rgb(204,120,50)">, </span><s=
pan style=3D"color:rgb(185,188,209)">Policy</span>&gt; &amp; rhs)<br>{<br> =
   <span style=3D"color:rgb(204,120,50);font-weight:bold">if constexpr </sp=
an>(<span style=3D"color:rgb(181,182,227)">policy_based_allocator</span>&lt=
;<span style=3D"color:rgb(185,188,209)">T</span><span style=3D"color:rgb(20=
4,120,50)">, </span><span style=3D"color:rgb(185,188,209)">Policy</span>&gt=
;::<span style=3D"color:rgb(185,188,209)">is_always_equal</span>::<span sty=
le=3D"color:rgb(147,115,165)">value</span>)<br>    {<br>        <span style=
=3D"color:rgb(204,120,50);font-weight:bold">return true</span><span style=
=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)=
">    </span>}<br>    <span style=3D"color:rgb(204,120,50);font-weight:bold=
">else<br></span><span style=3D"color:rgb(204,120,50);font-weight:bold">   =
 </span>{<br>        <span style=3D"color:rgb(204,120,50);font-weight:bold"=
>return </span>lhs.<span style=3D"color:rgb(147,115,165)">m_resource </span=
>=3D=3D rhs.<span style=3D"color:rgb(147,115,165)">m_resource</span><span s=
tyle=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120=
,50)">    </span>}<br>}<br><br><span style=3D"color:rgb(204,120,50);font-we=
ight:bold">template</span>&lt;<span style=3D"color:rgb(204,120,50);font-wei=
ght:bold">class </span><span style=3D"color:rgb(185,188,209)">T</span><span=
 style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(204,120,=
50);font-weight:bold">class </span><span style=3D"color:rgb(185,188,209)">U=
</span><span style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:=
rgb(204,120,50);font-weight:bold">typename </span><span style=3D"color:rgb(=
185,188,209)">Policy</span>&gt;<br><span style=3D"color:rgb(204,120,50);fon=
t-weight:bold">bool operator</span><span style=3D"color:rgb(255,198,109)">!=
=3D</span>(<span style=3D"color:rgb(204,120,50);font-weight:bold">const </s=
pan><span style=3D"color:rgb(181,182,227)">policy_based_allocator</span>&lt=
;<span style=3D"color:rgb(185,188,209)">T</span><span style=3D"color:rgb(20=
4,120,50)">, </span><span style=3D"color:rgb(185,188,209)">Policy</span>&gt=
; &amp; lhs<span style=3D"color:rgb(204,120,50)">, </span><span style=3D"co=
lor:rgb(204,120,50);font-weight:bold">const </span><span style=3D"color:rgb=
(181,182,227)">policy_based_allocator</span>&lt;<span style=3D"color:rgb(18=
5,188,209)">U</span><span style=3D"color:rgb(204,120,50)">, </span><span st=
yle=3D"color:rgb(185,188,209)">Policy</span>&gt; &amp; rhs)<br>{<br>    <sp=
an style=3D"color:rgb(204,120,50);font-weight:bold">return </span>!(lhs <sp=
an style=3D"color:rgb(95,140,138)">=3D=3D </span>rhs)<span style=3D"color:r=
gb(204,120,50)">;<br></span>}<br><br><br><span style=3D"color:rgb(204,120,5=
0);font-weight:bold">template</span>&lt;<span style=3D"color:rgb(204,120,50=
);font-weight:bold">class </span><span style=3D"color:rgb(185,188,209)">All=
oc</span>&gt;<br><span style=3D"color:rgb(204,120,50);font-weight:bold">str=
uct </span><span style=3D"color:rgb(181,182,227)">allocator_traits_demo<br>=
</span>{<br><span style=3D"color:rgb(204,120,50);font-weight:bold">private<=
/span>:<br>    <span style=3D"color:rgb(204,120,50);font-weight:bold">templ=
ate</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">class =
</span><span style=3D"color:rgb(185,188,209)">U</span>&gt;<br>    <span sty=
le=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"c=
olor:rgb(185,188,209)">detect_policy </span>=3D <span style=3D"color:rgb(20=
4,120,50);font-weight:bold">typename </span><span style=3D"color:rgb(185,18=
8,209)">U</span>::<span style=3D"color:rgb(185,188,209)">policy</span><span=
 style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,1=
20,50)"><br></span><span style=3D"color:rgb(204,120,50);font-weight:bold">p=
ublic</span>:<br>    <span style=3D"color:rgb(204,120,50);font-weight:bold"=
>using </span><span style=3D"color:rgb(185,188,209)">has_policy </span>=3D =
<span style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb=
(181,182,227)">experimental</span>::<span style=3D"color:rgb(185,188,209)">=
is_detected</span>&lt;<span style=3D"color:rgb(185,188,209)">detect_policy<=
/span><span style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:r=
gb(185,188,209)">Alloc</span>&gt;<span style=3D"color:rgb(204,120,50)">;<br=
></span>}<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"c=
olor:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50)"><br>=
</span><span style=3D"color:rgb(128,128,128)">//default<br></span><span sty=
le=3D"color:rgb(204,120,50);font-weight:bold">template</span>&lt;<span styl=
e=3D"color:rgb(204,120,50);font-weight:bold">typename </span><span style=3D=
"color:rgb(185,188,209)">Alloc</span><span style=3D"color:rgb(204,120,50)">=
, </span><span style=3D"color:rgb(204,120,50);font-weight:bold">typename </=
span><span style=3D"color:rgb(185,188,209)">Enable </span>=3D <span style=
=3D"color:rgb(204,120,50);font-weight:bold">void</span>&gt;<br><span style=
=3D"color:rgb(204,120,50);font-weight:bold">struct </span><span style=3D"co=
lor:rgb(181,182,227)">allocator_delete </span>: <span style=3D"color:rgb(18=
5,188,209)">Alloc<br></span>{<br>    <span style=3D"color:rgb(204,120,50);f=
ont-weight:bold">using </span><span style=3D"color:rgb(185,188,209)">alloc_=
traits </span>=3D <span style=3D"color:rgb(185,188,209)">std</span>::<span =
style=3D"color:rgb(181,182,227)">allocator_traits</span>&lt;<span style=3D"=
color:rgb(185,188,209)">Alloc</span>&gt;<span style=3D"color:rgb(204,120,50=
)">;<br></span><span style=3D"color:rgb(204,120,50)">    </span><span style=
=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"col=
or:rgb(185,188,209)">pointer </span>=3D <span style=3D"color:rgb(204,120,50=
);font-weight:bold">typename </span><span style=3D"color:rgb(185,188,209)">=
alloc_traits</span>::<span style=3D"color:rgb(185,188,209)">pointer</span><=
span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(2=
04,120,50)"><br></span><span style=3D"color:rgb(204,120,50)">    </span><sp=
an style=3D"color:rgb(204,120,50);font-weight:bold">template</span>&lt;<spa=
n style=3D"color:rgb(204,120,50);font-weight:bold">class </span><span style=
=3D"color:rgb(185,188,209)">OtherAlloc</span>&gt;<br>    <span style=3D"col=
or:rgb(204,120,50);font-weight:bold">explicit </span><span style=3D"color:r=
gb(255,198,109)">allocator_delete</span>(<span style=3D"color:rgb(185,188,2=
09)">OtherAlloc </span>&amp;&amp; alloc)<br>            : <span style=3D"co=
lor:rgb(185,188,209)">Alloc</span>{<span style=3D"color:rgb(185,188,209)">s=
td</span>::<span style=3D"color:rgb(185,188,209)">forward</span>&lt;<span s=
tyle=3D"color:rgb(185,188,209)">OtherAlloc</span>&gt;(alloc)} {}<br><br>   =
 <span style=3D"color:rgb(204,120,50);font-weight:bold">void operator</span=
><span style=3D"color:rgb(255,198,109)">(</span>)(<span style=3D"color:rgb(=
185,188,209)">pointer </span>p)<br>    {<br>        <span style=3D"color:rg=
b(128,128,128)">//Use allocator<br></span><span style=3D"color:rgb(128,128,=
128)">        </span><span style=3D"color:rgb(185,188,209)">alloc_traits</s=
pan>::<span style=3D"color:rgb(185,188,209)">destroy</span>(*<span style=3D=
"color:rgb(204,120,50);font-weight:bold">this</span><span style=3D"color:rg=
b(204,120,50)">, </span>p)<span style=3D"color:rgb(204,120,50)">;<br></span=
><span style=3D"color:rgb(204,120,50)">        </span><span style=3D"color:=
rgb(185,188,209)">alloc_traits</span>::<span style=3D"color:rgb(185,188,209=
)">deallocate</span>(*<span style=3D"color:rgb(204,120,50);font-weight:bold=
">this</span><span style=3D"color:rgb(204,120,50)">, </span>p<span style=3D=
"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(104,151,187)">1</=
span>)<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"colo=
r:rgb(204,120,50)">    </span>}<span style=3D"color:rgb(204,120,50)">;<br><=
/span>}<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"col=
or:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50);font-we=
ight:bold">template</span>&lt;<span style=3D"color:rgb(204,120,50);font-wei=
ght:bold">class </span><span style=3D"color:rgb(185,188,209)">U</span>&gt;<=
br><span style=3D"color:rgb(204,120,50);font-weight:bold">using </span><spa=
n style=3D"color:rgb(185,188,209)">detect_policy_requires_stateful_deleter =
</span>=3D <span style=3D"color:rgb(181,182,227)">std</span>::<span style=
=3D"color:rgb(181,182,227)">negation</span>&lt;<span style=3D"color:rgb(204=
,120,50);font-weight:bold">typename </span><span style=3D"color:rgb(181,182=
,227)">allocator_policy_traits</span>&lt;<span style=3D"color:rgb(204,120,5=
0);font-weight:bold">typename </span><span style=3D"color:rgb(185,188,209)"=
>U</span>::<span style=3D"color:rgb(185,188,209)">policy</span>&gt;::<span =
style=3D"color:rgb(185,188,209)">requires_stateful_deleter</span>&gt;<span =
style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,12=
0,50)"><br></span><span style=3D"color:rgb(204,120,50);font-weight:bold">te=
mplate</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">typ=
ename </span><span style=3D"color:rgb(185,188,209)">Alloc</span>&gt;<br><sp=
an style=3D"color:rgb(204,120,50);font-weight:bold">using </span><span styl=
e=3D"color:rgb(185,188,209)">stateless_deleter_due_to_policy </span>=3D <sp=
an style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(18=
1,182,227)">experimental</span>::<span style=3D"color:rgb(185,188,209)">det=
ected_or_t</span>&lt;<span style=3D"color:rgb(181,182,227)">std</span>::<sp=
an style=3D"color:rgb(185,188,209)">false_type</span><span style=3D"color:r=
gb(204,120,50)">, </span><span style=3D"color:rgb(185,188,209)">detect_poli=
cy_requires_stateful_deleter</span><span style=3D"color:rgb(204,120,50)">, =
</span><span style=3D"color:rgb(185,188,209)">Alloc</span>&gt;<span style=
=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)=
"><br></span><span style=3D"color:rgb(204,120,50);font-weight:bold">templat=
e</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">typename=
 </span><span style=3D"color:rgb(185,188,209)">Alloc</span>&gt;<br><span st=
yle=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"=
color:rgb(185,188,209)">stateless_deleter_due_to_stateless </span>=3D <span=
 style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(181,=
182,227)">is_empty</span>&lt;<span style=3D"color:rgb(185,188,209)">Alloc</=
span>&gt;<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"c=
olor:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50);font-=
weight:bold">template</span>&lt;<span style=3D"color:rgb(204,120,50);font-w=
eight:bold">typename </span><span style=3D"color:rgb(185,188,209)">Alloc</s=
pan>&gt;<br><span style=3D"color:rgb(204,120,50);font-weight:bold">using </=
span><span style=3D"color:rgb(185,188,209)">stateless_deleter </span>=3D <s=
pan style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(1=
81,182,227)">disjunction</span>&lt;<br>        <span style=3D"color:rgb(185=
,188,209)">stateless_deleter_due_to_stateless</span>&lt;<span style=3D"colo=
r:rgb(185,188,209)">Alloc</span>&gt;<span style=3D"color:rgb(204,120,50)">,=
<br></span><span style=3D"color:rgb(204,120,50)">        </span><span style=
=3D"color:rgb(185,188,209)">stateless_deleter_due_to_policy</span>&lt;<span=
 style=3D"color:rgb(185,188,209)">Alloc</span>&gt;<br>&gt;<span style=3D"co=
lor:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)"><br>=
</span><span style=3D"color:rgb(204,120,50);font-weight:bold">template</spa=
n>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">typename </spa=
n><span style=3D"color:rgb(185,188,209)">Alloc</span>&gt;<br><span style=3D=
"color:rgb(204,120,50);font-weight:bold">static constexpr bool </span>state=
less_deleter_v =3D <span style=3D"color:rgb(185,188,209)">stateless_deleter=
</span>&lt;<span style=3D"color:rgb(185,188,209)">Alloc</span>&gt;::<span s=
tyle=3D"color:rgb(147,115,165)">value</span><span style=3D"color:rgb(204,12=
0,50)">;<br></span><span style=3D"color:rgb(204,120,50)"><br></span><span s=
tyle=3D"color:rgb(204,120,50)"><br></span><span style=3D"color:rgb(128,128,=
128)">//Stateless specialization<br></span><span style=3D"color:rgb(204,120=
,50);font-weight:bold">template</span>&lt;<span style=3D"color:rgb(204,120,=
50);font-weight:bold">typename </span><span style=3D"color:rgb(185,188,209)=
">Alloc</span>&gt;<br><span style=3D"color:rgb(204,120,50);font-weight:bold=
">struct </span><span style=3D"color:rgb(181,182,227)">allocator_delete</sp=
an>&lt;<br>        <span style=3D"color:rgb(185,188,209)">Alloc</span><span=
 style=3D"color:rgb(204,120,50)">,<br></span><span style=3D"color:rgb(204,1=
20,50)">        </span><span style=3D"color:rgb(181,182,227)">std</span>::<=
span style=3D"color:rgb(185,188,209)">enable_if_t</span>&lt;stateless_delet=
er_v&lt;<span style=3D"color:rgb(185,188,209)">Alloc</span>&gt;&gt;<br>&gt;=
 <span style=3D"color:rgb(128,128,128)">/*No Alloc storage*/<br></span>{<br=
>    <span style=3D"color:rgb(204,120,50);font-weight:bold">using </span><s=
pan style=3D"color:rgb(185,188,209)">alloc_traits </span>=3D <span style=3D=
"color:rgb(185,188,209)">std</span>::<span style=3D"color:rgb(181,182,227)"=
>allocator_traits</span>&lt;<span style=3D"color:rgb(185,188,209)">Alloc</s=
pan>&gt;<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"co=
lor:rgb(204,120,50)">    </span><span style=3D"color:rgb(204,120,50);font-w=
eight:bold">using </span><span style=3D"color:rgb(185,188,209)">pointer </s=
pan>=3D <span style=3D"color:rgb(204,120,50);font-weight:bold">typename </s=
pan><span style=3D"color:rgb(185,188,209)">alloc_traits</span>::<span style=
=3D"color:rgb(185,188,209)">pointer</span><span style=3D"color:rgb(204,120,=
50)">;<br></span><span style=3D"color:rgb(204,120,50)">    </span><span sty=
le=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"c=
olor:rgb(185,188,209)">value_type </span>=3D <span style=3D"color:rgb(204,1=
20,50);font-weight:bold">typename </span><span style=3D"color:rgb(185,188,2=
09)">alloc_traits</span>::<span style=3D"color:rgb(185,188,209)">value_type=
</span><span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"col=
or:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50)">    </=
span><span style=3D"color:rgb(204,120,50);font-weight:bold">template</span>=
&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">class </span><sp=
an style=3D"color:rgb(185,188,209)">OtherAlloc</span>&gt;<br>    <span styl=
e=3D"color:rgb(204,120,50);font-weight:bold">explicit </span><span style=3D=
"color:rgb(255,198,109)">allocator_delete</span>(<span style=3D"color:rgb(1=
85,188,209)">OtherAlloc </span>&amp;&amp;) <span style=3D"color:rgb(204,120=
,50);font-weight:bold">noexcept </span>{}<br><br>    <span style=3D"color:r=
gb(204,120,50);font-weight:bold">void operator</span><span style=3D"color:r=
gb(255,198,109)">(</span>)(<span style=3D"color:rgb(185,188,209)">pointer <=
/span>p)<br>    {<br>        <span style=3D"color:rgb(204,120,50);font-weig=
ht:bold">if constexpr </span>(<span style=3D"color:rgb(185,188,209)">alloca=
tor_traits_demo</span>&lt;<span style=3D"color:rgb(185,188,209)">Alloc</spa=
n>&gt;::<span style=3D"color:rgb(185,188,209)">has_policy</span>::<span sty=
le=3D"color:rgb(147,115,165)">value</span>)<br>        {<br>            <sp=
an style=3D"color:rgb(204,120,50);font-weight:bold">using </span><span styl=
e=3D"color:rgb(185,188,209)">policy </span>=3D <span style=3D"color:rgb(204=
,120,50);font-weight:bold">typename </span><span style=3D"color:rgb(185,188=
,209)">Alloc</span>::<span style=3D"color:rgb(185,188,209)">policy</span><s=
pan style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(20=
4,120,50)">            </span><span style=3D"color:rgb(204,120,50);font-wei=
ght:bold">using </span><span style=3D"color:rgb(185,188,209)">policy_trait =
</span>=3D <span style=3D"color:rgb(181,182,227)">allocator_policy_traits</=
span>&lt;<span style=3D"color:rgb(185,188,209)">policy</span>&gt;<span styl=
e=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50=
)">            </span><span style=3D"color:rgb(185,188,209)">policy_trait</=
span>::<span style=3D"color:rgb(185,188,209)">destroy_method</span>::<span =
style=3D"color:rgb(185,188,209)">destroy</span>(p)<span style=3D"color:rgb(=
204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">            =
</span><span style=3D"color:rgb(185,188,209)">policy_trait</span>::<span st=
yle=3D"color:rgb(185,188,209)">deallocate_method</span>::<span style=3D"col=
or:rgb(185,188,209)">deallocate</span>(p<span style=3D"color:rgb(204,120,50=
)">, </span><span style=3D"color:rgb(104,151,187)">1</span>)<span style=3D"=
color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">  =
      </span>}<br>        <span style=3D"color:rgb(204,120,50);font-weight:=
bold">else if constexpr </span>(<span style=3D"color:rgb(185,188,209)">std<=
/span>::<span style=3D"color:rgb(152,118,170);font-style:italic">is_empty_v=
</span>&lt;<span style=3D"color:rgb(185,188,209)">Alloc</span>&gt;)<br>    =
    {<br>            <span style=3D"color:rgb(204,120,50);font-weight:bold"=
>auto </span>a =3D <span style=3D"color:rgb(185,188,209)">Alloc</span>{}<sp=
an style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204=
,120,50)">            </span>a.<span style=3D"color:rgb(152,118,170);font-s=
tyle:italic">destroy</span>(p)<span style=3D"color:rgb(204,120,50)">;<br></=
span><span style=3D"color:rgb(204,120,50)">            </span>a.<span style=
=3D"color:rgb(152,118,170);font-style:italic">deallocate</span>(p<span styl=
e=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(104,151,187)"=
>1</span>)<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"=
color:rgb(204,120,50)">        </span>}<br><br>    }<span style=3D"color:rg=
b(204,120,50)">;<br></span>}<span style=3D"color:rgb(204,120,50)">;<br></sp=
an><span style=3D"color:rgb(204,120,50)"><br></span><span style=3D"color:rg=
b(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50);font-weight:=
bold">template</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:b=
old">typename </span><span style=3D"color:rgb(185,188,209)">T</span><span s=
tyle=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(204,120,50=
);font-weight:bold">typename </span><span style=3D"color:rgb(185,188,209)">=
Alloc</span><span style=3D"color:rgb(204,120,50)">, </span><span style=3D"c=
olor:rgb(204,120,50);font-weight:bold">typename </span>... <span style=3D"c=
olor:rgb(185,188,209)">Args</span>&gt;<br><span style=3D"color:rgb(204,120,=
50);font-weight:bold">auto </span><span style=3D"color:rgb(255,198,109)">al=
locate_unique</span>(<span style=3D"color:rgb(185,188,209)">Alloc </span><s=
pan style=3D"color:rgb(204,120,50);font-weight:bold">const </span>&amp; all=
ocator<span style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:r=
gb(185,188,209)">Args </span>&amp;&amp; ... args)<br>{<br>    <span style=
=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"col=
or:rgb(185,188,209)">value_type </span>=3D <span style=3D"color:rgb(181,182=
,227)">std</span>::<span style=3D"color:rgb(185,188,209)">remove_cv_t</span=
>&lt;<span style=3D"color:rgb(185,188,209)">T</span>&gt;<span style=3D"colo=
r:rgb(204,120,50)">; </span><span style=3D"color:rgb(128,128,128)">// Clean=
 the type<br></span><span style=3D"color:rgb(128,128,128)">    </span><span=
 style=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=
=3D"color:rgb(185,188,209)">alloc_traits </span>=3D <span style=3D"color:rg=
b(204,120,50);font-weight:bold">typename </span><span style=3D"color:rgb(18=
1,182,227)">std</span>::<span style=3D"color:rgb(181,182,227)">allocator_tr=
aits</span>&lt;<span style=3D"color:rgb(185,188,209)">Alloc</span>&gt;::<br=
>    <span style=3D"color:rgb(204,120,50);font-weight:bold">template </span=
><span style=3D"color:rgb(185,188,209)">rebind_traits</span>&lt;<span style=
=3D"color:rgb(185,188,209)">value_type</span>&gt;<span style=3D"color:rgb(2=
04,120,50)">; </span><span style=3D"color:rgb(128,128,128)">// Get actual a=
llocator needed<br></span><span style=3D"color:rgb(128,128,128)">    </span=
><span style=3D"color:rgb(204,120,50);font-weight:bold">using </span><span =
style=3D"color:rgb(185,188,209)">pointer </span>=3D <span style=3D"color:rg=
b(204,120,50);font-weight:bold">typename </span><span style=3D"color:rgb(18=
5,188,209)">alloc_traits</span>::<span style=3D"color:rgb(185,188,209)">poi=
nter</span><span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D=
"color:rgb(204,120,50)">    </span><span style=3D"color:rgb(204,120,50);fon=
t-weight:bold">using </span><span style=3D"color:rgb(185,188,209)">allocato=
r_type </span>=3D <span style=3D"color:rgb(204,120,50);font-weight:bold">ty=
pename </span><span style=3D"color:rgb(185,188,209)">alloc_traits</span>::<=
span style=3D"color:rgb(185,188,209)">allocator_type</span><span style=3D"c=
olor:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">   =
 </span><span style=3D"color:rgb(204,120,50);font-weight:bold">using </span=
><span style=3D"color:rgb(185,188,209)">deleter_T </span>=3D <span style=3D=
"color:rgb(181,182,227)">allocator_delete</span>&lt;<span style=3D"color:rg=
b(185,188,209)">allocator_type</span>&gt;<span style=3D"color:rgb(204,120,5=
0)">; </span><span style=3D"color:rgb(128,128,128)">// type of custom delet=
e we will use<br></span><span style=3D"color:rgb(128,128,128)"><br></span><=
span style=3D"color:rgb(128,128,128)">    </span><span style=3D"color:rgb(2=
04,120,50);font-weight:bold">auto </span>allocator_T =3D <span style=3D"col=
or:rgb(185,188,209)">allocator_type</span>{allocator}<span style=3D"color:r=
gb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)"><br></spa=
n><span style=3D"color:rgb(204,120,50)">    </span><span style=3D"color:rgb=
(204,120,50);font-weight:bold">auto </span>mem =3D <span style=3D"color:rgb=
(185,188,209)">alloc_traits</span>::allocate(allocator_T<span style=3D"colo=
r:rgb(204,120,50)">, </span><span style=3D"color:rgb(104,151,187)">1</span>=
)<span style=3D"color:rgb(204,120,50)">; </span><span style=3D"color:rgb(12=
8,128,128)">// will throw is can not allocate<br></span><span style=3D"colo=
r:rgb(128,128,128)">    </span><span style=3D"color:rgb(204,120,50);font-we=
ight:bold">auto </span>hold_deleter =3D [&amp;](<span style=3D"color:rgb(18=
5,188,209)">pointer </span>p) { <span style=3D"color:rgb(185,188,209)">allo=
c_traits</span>::deallocate(allocator_T<span style=3D"color:rgb(204,120,50)=
">, </span>p<span style=3D"color:rgb(204,120,50)">, </span><span style=3D"c=
olor:rgb(104,151,187)">1</span>)<span style=3D"color:rgb(204,120,50)">; </s=
pan>}<span style=3D"color:rgb(204,120,50)">; </span><span style=3D"color:rg=
b(128,128,128)">// Custom deleter<br></span><span style=3D"color:rgb(128,12=
8,128)">    </span><span style=3D"color:rgb(204,120,50);font-weight:bold">a=
uto </span>holder =3D <span style=3D"color:rgb(181,182,227)">std</span>::un=
ique_ptr&lt;<span style=3D"color:rgb(185,188,209)">value_type</span><span s=
tyle=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(204,120,50=
);font-weight:bold">decltype</span>(hold_deleter)&gt;(mem<span style=3D"col=
or:rgb(204,120,50)">, </span>hold_deleter)<span style=3D"color:rgb(204,120,=
50)">; </span><span style=3D"color:rgb(128,128,128)">// RAII protect mem<br=
></span><span style=3D"color:rgb(128,128,128)">    </span><span style=3D"co=
lor:rgb(204,120,50);font-weight:bold">auto </span>deleter =3D <span style=
=3D"color:rgb(185,188,209)">deleter_T</span>{allocator_T}<span style=3D"col=
or:rgb(204,120,50)">; </span><span style=3D"color:rgb(128,128,128)">// Make=
 actual custom deleter (may throw) do this before construction<br></span><s=
pan style=3D"color:rgb(128,128,128)">    </span><span style=3D"color:rgb(18=
5,188,209)">alloc_traits</span>::construct(allocator_T<span style=3D"color:=
rgb(204,120,50)">, </span>holder.get()<span style=3D"color:rgb(204,120,50)"=
>, </span><span style=3D"color:rgb(181,182,227)">std</span>::forward&lt;<sp=
an style=3D"color:rgb(185,188,209)">Args</span>&gt;(args)...)<span style=3D=
"color:rgb(204,120,50)">; </span><span style=3D"color:rgb(128,128,128)">// =
Construct in mem (may throw)<br></span><span style=3D"color:rgb(128,128,128=
)">    </span><span style=3D"color:rgb(204,120,50);font-weight:bold">return=
 </span><span style=3D"color:rgb(181,182,227)">std</span>::unique_ptr&lt;<s=
pan style=3D"color:rgb(185,188,209)">value_type</span><span style=3D"color:=
rgb(204,120,50)">, </span><span style=3D"color:rgb(185,188,209)">deleter_T<=
/span>&gt;(holder.release()<span style=3D"color:rgb(204,120,50)">,<br></spa=
n><span style=3D"color:rgb(204,120,50)">                                   =
               </span><span style=3D"color:rgb(181,182,227)">std</span>::mo=
ve(deleter))<span style=3D"color:rgb(204,120,50)">; </span><span style=3D"c=
olor:rgb(128,128,128)">// repackage with new deleter<br></span>}<br><br><sp=
an style=3D"color:rgb(128,128,128)">//*********************USER CODE BELLOW=
<br></span><span style=3D"color:rgb(128,128,128)"><br></span><span style=3D=
"color:rgb(128,128,128)">// allocator resource that owns a slab of memory a=
nd allocated from that slab<br></span><span style=3D"color:rgb(204,120,50);=
font-weight:bold">struct </span><span style=3D"color:rgb(181,182,227)">slab=
_allocator_resource<br></span>{<br>    <span style=3D"color:rgb(204,120,50)=
;font-weight:bold">explicit </span><span style=3D"color:rgb(255,198,109)">s=
lab_allocator_resource</span>(<span style=3D"color:rgb(181,182,227)">std</s=
pan>::<span style=3D"color:rgb(185,188,209)">size_t </span>spaceNeeded) :<b=
r>            <span style=3D"color:rgb(147,115,165)">m_buffer</span>(<span =
style=3D"color:rgb(181,182,227)">std</span>::malloc(spaceNeeded))<span styl=
e=3D"color:rgb(204,120,50)">,<br></span><span style=3D"color:rgb(204,120,50=
)">            </span><span style=3D"color:rgb(147,115,165)">m_freeBegin</s=
pan>(<span style=3D"color:rgb(147,115,165)">m_buffer</span>)<span style=3D"=
color:rgb(204,120,50)">,<br></span><span style=3D"color:rgb(204,120,50)">  =
          </span><span style=3D"color:rgb(147,115,165)">m_freeSpace</span>(=
spaceNeeded)<br>    {<br>        <span style=3D"color:rgb(204,120,50);font-=
weight:bold">if </span>(!<span style=3D"color:rgb(147,115,165)">m_buffer</s=
pan>) <span style=3D"color:rgb(204,120,50);font-weight:bold">throw </span><=
span style=3D"color:rgb(181,182,227)">std</span>::bad_alloc()<span style=3D=
"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)"> =
   </span>}<br><br>    ~<span style=3D"color:rgb(255,198,109)">slab_allocat=
or_resource</span>() { <span style=3D"color:rgb(181,182,227)">std</span>::f=
ree(<span style=3D"color:rgb(147,115,165)">m_buffer</span>)<span style=3D"c=
olor:rgb(204,120,50)">; </span>}<br><br>    <span style=3D"color:rgb(204,12=
0,50);font-weight:bold">template</span>&lt;<span style=3D"color:rgb(204,120=
,50);font-weight:bold">typename </span><span style=3D"color:rgb(185,188,209=
)">T</span>&gt;<br>    [[nodiscard]] <span style=3D"color:rgb(185,188,209)"=
>T </span>* <span style=3D"color:rgb(255,198,109)">allocate</span>(<span st=
yle=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(185,188=
,209)">size_t </span>n)<br>    {<br>        <span style=3D"color:rgb(204,12=
0,50);font-weight:bold">return static_cast</span>&lt;<span style=3D"color:r=
gb(185,188,209)">T </span>*&gt;(allocate_bytes(<span style=3D"color:rgb(204=
,120,50);font-weight:bold">alignof</span>(<span style=3D"color:rgb(185,188,=
209)">T</span>)<span style=3D"color:rgb(204,120,50)">, </span><span style=
=3D"color:rgb(204,120,50);font-weight:bold">sizeof</span>(<span style=3D"co=
lor:rgb(185,188,209)">T</span>) * n))<span style=3D"color:rgb(204,120,50)">=
;<br></span><span style=3D"color:rgb(204,120,50)">    </span>}<br><br><span=
 style=3D"color:rgb(204,120,50);font-weight:bold">private</span>:<br>    <s=
pan style=3D"color:rgb(204,120,50);font-weight:bold">void </span>* <span st=
yle=3D"color:rgb(255,198,109)">allocate_bytes</span>(<span style=3D"color:r=
gb(181,182,227)">std</span>::<span style=3D"color:rgb(185,188,209)">size_t =
</span>align<span style=3D"color:rgb(204,120,50)">, </span><span style=3D"c=
olor:rgb(181,182,227)">std</span>::<span style=3D"color:rgb(185,188,209)">s=
ize_t </span>bytes)<br>    {<br>        <span style=3D"color:rgb(204,120,50=
);font-weight:bold">auto </span>mem =3D <span style=3D"color:rgb(181,182,22=
7)">std</span>::align(align<span style=3D"color:rgb(204,120,50)">, </span>b=
ytes<span style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb=
(147,115,165)">m_freeBegin</span><span style=3D"color:rgb(204,120,50)">, </=
span><span style=3D"color:rgb(147,115,165)">m_freeSpace</span>)<span style=
=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)=
">        </span><span style=3D"color:rgb(204,120,50);font-weight:bold">if =
</span>(!mem) <span style=3D"color:rgb(204,120,50);font-weight:bold">throw =
</span><span style=3D"color:rgb(181,182,227)">std</span>::bad_alloc()<span =
style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,12=
0,50)">        </span><span style=3D"color:rgb(147,115,165)">m_freeBegin </=
span>=3D <span style=3D"color:rgb(204,120,50);font-weight:bold">static_cast=
</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">char </sp=
an>*&gt;(<span style=3D"color:rgb(147,115,165)">m_freeBegin</span>) + bytes=
<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(=
204,120,50)">        </span><span style=3D"color:rgb(147,115,165)">m_freeSp=
ace </span>-=3D bytes<span style=3D"color:rgb(204,120,50)">;<br></span><spa=
n style=3D"color:rgb(204,120,50)">        </span><span style=3D"color:rgb(2=
04,120,50);font-weight:bold">return </span>mem<span style=3D"color:rgb(204,=
120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">    </span>}<br>=
<br>    <span style=3D"color:rgb(204,120,50);font-weight:bold">void </span>=
* <span style=3D"color:rgb(147,115,165)">m_buffer</span><span style=3D"colo=
r:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">    </=
span><span style=3D"color:rgb(204,120,50);font-weight:bold">void </span>* <=
span style=3D"color:rgb(147,115,165)">m_freeBegin</span><span style=3D"colo=
r:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">    </=
span><span style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"colo=
r:rgb(185,188,209)">size_t </span><span style=3D"color:rgb(147,115,165)">m_=
freeSpace</span><span style=3D"color:rgb(204,120,50)">;<br></span>}<span st=
yle=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,=
50)"><br></span><span style=3D"color:rgb(128,128,128)">// Cooperative alloc=
ator policy for the slab_allocator_resource<br></span><span style=3D"color:=
rgb(128,128,128)">// static methods are important (needed for detection)<br=
></span><span style=3D"color:rgb(204,120,50);font-weight:bold">struct </spa=
n><span style=3D"color:rgb(181,182,227)">slab_allocator_resource_policy<br>=
</span>{<br>    <span style=3D"color:rgb(204,120,50);font-weight:bold">usin=
g </span><span style=3D"color:rgb(185,188,209)">resource </span>=3D <span s=
tyle=3D"color:rgb(181,182,227)">slab_allocator_resource</span><span style=
=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)=
"><br></span><span style=3D"color:rgb(204,120,50)">    </span><span style=
=3D"color:rgb(128,128,128)">// explicit stateful allocate<br></span><span s=
tyle=3D"color:rgb(128,128,128)">    </span><span style=3D"color:rgb(204,120=
,50);font-weight:bold">template</span>&lt;<span style=3D"color:rgb(204,120,=
50);font-weight:bold">typename </span><span style=3D"color:rgb(185,188,209)=
">T</span>&gt;<br>    <span style=3D"color:rgb(204,120,50);font-weight:bold=
">static </span><span style=3D"color:rgb(185,188,209)">T </span>* <span sty=
le=3D"color:rgb(255,198,109)">allocate</span>(<span style=3D"color:rgb(185,=
188,209)">resource </span>* s<span style=3D"color:rgb(204,120,50)">, </span=
><span style=3D"color:rgb(181,182,227)">std</span>::<span style=3D"color:rg=
b(185,188,209)">size_t </span>n)<br>    {<br>        <span style=3D"color:r=
gb(204,120,50);font-weight:bold">return </span>s-&gt;allocate&lt;<span styl=
e=3D"color:rgb(185,188,209)">T</span>&gt;(n)<span style=3D"color:rgb(204,12=
0,50)">;<br></span><span style=3D"color:rgb(204,120,50)">    </span>}<br><b=
r>    <span style=3D"color:rgb(128,128,128)">// use a common policy method<=
br></span><span style=3D"color:rgb(128,128,128)">    </span><span style=3D"=
color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"color:r=
gb(185,188,209)">deallocate_method </span>=3D <span style=3D"color:rgb(181,=
182,227)">deallocate_as_noop</span><span style=3D"color:rgb(204,120,50)">;<=
br></span>}<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D=
"color:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50)"><b=
r></span><span style=3D"color:rgb(204,120,50);font-weight:bold">struct </sp=
an><span style=3D"color:rgb(181,182,227)">slab_allocator_resource_policy_no=
t_stateless<br></span>{<br>    <span style=3D"color:rgb(204,120,50);font-we=
ight:bold">using </span><span style=3D"color:rgb(185,188,209)">resource </s=
pan>=3D <span style=3D"color:rgb(181,182,227)">slab_allocator_resource</spa=
n><span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rg=
b(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50)">    </span>=
<span style=3D"color:rgb(128,128,128)">// explicit stateful allocate<br></s=
pan><span style=3D"color:rgb(128,128,128)">    </span><span style=3D"color:=
rgb(204,120,50);font-weight:bold">template</span>&lt;<span style=3D"color:r=
gb(204,120,50);font-weight:bold">typename </span><span style=3D"color:rgb(1=
85,188,209)">T</span>&gt;<br>    <span style=3D"color:rgb(204,120,50);font-=
weight:bold">static </span><span style=3D"color:rgb(185,188,209)">T </span>=
* <span style=3D"color:rgb(255,198,109)">allocate</span>(<span style=3D"col=
or:rgb(185,188,209)">resource </span>* s<span style=3D"color:rgb(204,120,50=
)">, </span><span style=3D"color:rgb(181,182,227)">std</span>::<span style=
=3D"color:rgb(185,188,209)">size_t </span>n)<br>    {<br>        <span styl=
e=3D"color:rgb(204,120,50);font-weight:bold">return </span>s-&gt;allocate&l=
t;<span style=3D"color:rgb(185,188,209)">T</span>&gt;(n)<span style=3D"colo=
r:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">    </=
span>}<br><br>    <span style=3D"color:rgb(204,120,50);font-weight:bold">te=
mplate</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">typ=
ename </span><span style=3D"color:rgb(185,188,209)">T</span>&gt;<br>    <sp=
an style=3D"color:rgb(204,120,50);font-weight:bold">static void </span><spa=
n style=3D"color:rgb(255,198,109)">deallocate</span>(<span style=3D"color:r=
gb(185,188,209)">resource </span>* s<span style=3D"color:rgb(204,120,50)">,=
 </span><span style=3D"color:rgb(185,188,209)">T </span>* p<span style=3D"c=
olor:rgb(204,120,50)">, </span><span style=3D"color:rgb(181,182,227)">std</=
span>::<span style=3D"color:rgb(185,188,209)">size_t </span>n) <span style=
=3D"color:rgb(204,120,50);font-weight:bold">noexcept<br></span><span style=
=3D"color:rgb(204,120,50);font-weight:bold">    </span>{<br>        <span s=
tyle=3D"color:rgb(128,128,128)">//using stateful method signature for illus=
tration purposes only<br></span><span style=3D"color:rgb(128,128,128)">    =
</span>}<br>}<span style=3D"color:rgb(204,120,50)">;<br></span><span style=
=3D"color:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50)"=
><br></span><span style=3D"color:rgb(204,120,50);font-weight:bold">template=
</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">typename =
</span><span style=3D"color:rgb(185,188,209)">T</span>&gt;<br><span style=
=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D"col=
or:rgb(185,188,209)">slab_allocator </span>=3D <span style=3D"color:rgb(181=
,182,227)">policy_based_allocator</span>&lt;<span style=3D"color:rgb(185,18=
8,209)">T</span><span style=3D"color:rgb(204,120,50)">, </span><span style=
=3D"color:rgb(181,182,227)">slab_allocator_resource_policy</span>&gt;<span =
style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,12=
0,50)"><br></span><span style=3D"color:rgb(204,120,50);font-weight:bold">te=
mplate</span>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">typ=
ename </span><span style=3D"color:rgb(185,188,209)">T</span>&gt;<br><span s=
tyle=3D"color:rgb(204,120,50);font-weight:bold">using </span><span style=3D=
"color:rgb(185,188,209)">slab_allocator_not_stateless </span>=3D <span styl=
e=3D"color:rgb(181,182,227)">policy_based_allocator</span>&lt;<span style=
=3D"color:rgb(185,188,209)">T</span><span style=3D"color:rgb(204,120,50)">,=
 </span><span style=3D"color:rgb(181,182,227)">slab_allocator_resource_poli=
cy_not_stateless</span>&gt;<span style=3D"color:rgb(204,120,50)">;<br></spa=
n><span style=3D"color:rgb(204,120,50)"><br></span><span style=3D"color:rgb=
(204,120,50);font-weight:bold">int </span><span style=3D"color:rgb(255,198,=
109)">main</span>()<br>{<br>    <span style=3D"color:rgb(204,120,50);font-w=
eight:bold">auto </span>res =3D slab_allocator_resource{<span style=3D"colo=
r:rgb(104,151,187)">1024</span>}<span style=3D"color:rgb(204,120,50)">;<br>=
</span><span style=3D"color:rgb(204,120,50)">    </span>{<br>        <span =
style=3D"color:rgb(204,120,50);font-weight:bold">auto </span>vec =3D <span =
style=3D"color:rgb(181,182,227)">std</span>::vector&lt;<span style=3D"color=
:rgb(204,120,50);font-weight:bold">char</span><span style=3D"color:rgb(204,=
120,50)">, </span><span style=3D"color:rgb(185,188,209)">slab_allocator</sp=
an>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">char</span>&g=
t;&gt;{&amp;res}<span style=3D"color:rgb(204,120,50)">;<br></span><span sty=
le=3D"color:rgb(204,120,50)">        </span>vec.reserve(<span style=3D"colo=
r:rgb(104,151,187)">10</span>)<span style=3D"color:rgb(204,120,50)">; </spa=
n><span style=3D"color:rgb(128,128,128)">//10 bytes used<br></span><span st=
yle=3D"color:rgb(128,128,128)"><br></span><span style=3D"color:rgb(128,128,=
128)">        </span><span style=3D"color:rgb(204,120,50);font-weight:bold"=
>auto </span>a =3D vec.get_allocator()<span style=3D"color:rgb(204,120,50)"=
>;<br></span><span style=3D"color:rgb(204,120,50)"><br></span><span style=
=3D"color:rgb(204,120,50)">        </span><span style=3D"color:rgb(128,128,=
128)">//stateless deleter from policy<br></span><span style=3D"color:rgb(12=
8,128,128)">        </span><span style=3D"color:rgb(204,120,50);font-weight=
:bold">auto </span>ptr1 =3D allocate_unique&lt;<span style=3D"color:rgb(204=
,120,50);font-weight:bold">char</span>&gt;(a<span style=3D"color:rgb(204,12=
0,50)">, </span><span style=3D"color:rgb(106,135,89)">&#39;a&#39;</span>)<s=
pan style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(20=
4,120,50)">        </span><span style=3D"color:rgb(204,120,50);font-weight:=
bold">static_assert</span>(<span style=3D"color:rgb(204,120,50);font-weight=
:bold">sizeof</span>(ptr1) =3D=3D <span style=3D"color:rgb(204,120,50);font=
-weight:bold">sizeof</span>(<span style=3D"color:rgb(204,120,50);font-weigh=
t:bold">void </span>*))<span style=3D"color:rgb(204,120,50)">;<br></span><s=
pan style=3D"color:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204=
,120,50)">        </span><span style=3D"color:rgb(128,128,128)">//stateless=
 deleter from std::allocator<br></span><span style=3D"color:rgb(128,128,128=
)">        </span><span style=3D"color:rgb(204,120,50);font-weight:bold">au=
to </span>ptr2 =3D allocate_unique&lt;<span style=3D"color:rgb(204,120,50);=
font-weight:bold">char</span>&gt;(<span style=3D"color:rgb(181,182,227)">st=
d</span>::allocator&lt;<span style=3D"color:rgb(204,120,50);font-weight:bol=
d">char</span>&gt;{}<span style=3D"color:rgb(204,120,50)">, </span><span st=
yle=3D"color:rgb(106,135,89)">&#39;a&#39;</span>)<span style=3D"color:rgb(2=
04,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">        </spa=
n><span style=3D"color:rgb(204,120,50);font-weight:bold">static_assert</spa=
n>(<span style=3D"color:rgb(204,120,50);font-weight:bold">sizeof</span>(ptr=
2) =3D=3D <span style=3D"color:rgb(204,120,50);font-weight:bold">sizeof</sp=
an>(<span style=3D"color:rgb(204,120,50);font-weight:bold">void </span>*))<=
span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(2=
04,120,50)"><br></span><span style=3D"color:rgb(204,120,50)">        </span=
><span style=3D"color:rgb(128,128,128)">//existing allocate_shared (unaware=
 of policy)<br></span><span style=3D"color:rgb(128,128,128)">        </span=
><span style=3D"color:rgb(204,120,50);font-weight:bold">auto </span>ptr3 =
=3D <span style=3D"color:rgb(181,182,227)">std</span>::allocate_shared&lt;<=
span style=3D"color:rgb(204,120,50);font-weight:bold">char</span>&gt;(a<spa=
n style=3D"color:rgb(204,120,50)">, </span><span style=3D"color:rgb(106,135=
,89)">&#39;a&#39;</span>)<span style=3D"color:rgb(204,120,50)">;<br></span>=
<span style=3D"color:rgb(204,120,50)">        </span><span style=3D"color:r=
gb(204,120,50);font-weight:bold">static_assert</span>(<span style=3D"color:=
rgb(204,120,50);font-weight:bold">sizeof</span>(ptr3) &gt; <span style=3D"c=
olor:rgb(204,120,50);font-weight:bold">sizeof</span>(<span style=3D"color:r=
gb(204,120,50);font-weight:bold">void </span>*))<span style=3D"color:rgb(20=
4,120,50)">;<br></span><span style=3D"color:rgb(204,120,50)"><br></span><sp=
an style=3D"color:rgb(204,120,50)">        </span><span style=3D"color:rgb(=
128,128,128)">//existing allocate_shared (doesn&#39;t optimize for stateles=
s allocators)<br></span><span style=3D"color:rgb(128,128,128)">        </sp=
an><span style=3D"color:rgb(204,120,50);font-weight:bold">auto </span>ptr4 =
=3D <span style=3D"color:rgb(181,182,227)">std</span>::allocate_shared&lt;<=
span style=3D"color:rgb(204,120,50);font-weight:bold">char</span>&gt;(<span=
 style=3D"color:rgb(181,182,227)">std</span>::allocator&lt;<span style=3D"c=
olor:rgb(204,120,50);font-weight:bold">char</span>&gt;{}<span style=3D"colo=
r:rgb(204,120,50)">, </span><span style=3D"color:rgb(106,135,89)">&#39;a&#3=
9;</span>)<span style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"=
color:rgb(204,120,50)">        </span><span style=3D"color:rgb(204,120,50);=
font-weight:bold">static_assert</span>(<span style=3D"color:rgb(204,120,50)=
;font-weight:bold">sizeof</span>(ptr4) &gt; <span style=3D"color:rgb(204,12=
0,50);font-weight:bold">sizeof</span>(<span style=3D"color:rgb(204,120,50);=
font-weight:bold">void </span>*))<span style=3D"color:rgb(204,120,50)">;<br=
></span><span style=3D"color:rgb(204,120,50)">    </span>}<br>    {<br>    =
    <span style=3D"color:rgb(204,120,50);font-weight:bold">auto </span>a =
=3D <span style=3D"color:rgb(185,188,209)">slab_allocator_not_stateless</sp=
an>&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">char</span>&g=
t;{&amp;res}<span style=3D"color:rgb(204,120,50)">;<br></span><span style=
=3D"color:rgb(204,120,50)"><br></span><span style=3D"color:rgb(204,120,50)"=
>        </span><span style=3D"color:rgb(128,128,128)">//stateful deleter f=
rom policy<br></span><span style=3D"color:rgb(128,128,128)">        </span>=
<span style=3D"color:rgb(204,120,50);font-weight:bold">auto </span>ptr5 =3D=
 allocate_unique&lt;<span style=3D"color:rgb(204,120,50);font-weight:bold">=
char</span>&gt;(a<span style=3D"color:rgb(204,120,50)">, </span><span style=
=3D"color:rgb(106,135,89)">&#39;a&#39;</span>)<span style=3D"color:rgb(204,=
120,50)">;<br></span><span style=3D"color:rgb(204,120,50)">        </span><=
span style=3D"color:rgb(204,120,50);font-weight:bold">static_assert</span>(=
<span style=3D"color:rgb(204,120,50);font-weight:bold">sizeof</span>(ptr5) =
&gt; <span style=3D"color:rgb(204,120,50);font-weight:bold">sizeof</span>(<=
span style=3D"color:rgb(204,120,50);font-weight:bold">void </span>*))<span =
style=3D"color:rgb(204,120,50)">;<br></span><span style=3D"color:rgb(204,12=
0,50)">    </span>}<br><br>}</font></pre></div><div>Things to note:</div><d=
iv><ul><li>Each method signature dictates if it is stateful or not</li><li>=
Mechanism to refer to common implementations</li><li>Policy has no state</l=
i><li>Allocator conditionally has state</li><li>Deleter conditionally has s=
tate</li><li>Tried to make a policy which is simple to write and an easy fa=
cility to make a good quality allocator (I may have missed stuff in pursuit=
 of making a &quot;simple&quot; policy)</li><li>allocate_unique can takes a=
 stateful allocator and make a unique_ptr that has a stateless deleter</li>=
</ul></div><div>I propose:</div><div><ul><li>allocate_unique and allocate_s=
hared should optimize for stateless allocators</li><li>something like polic=
y_based_allocator which exposes what parts are stateful or stateless</li><l=
i>OR another way to do this .... <br></li></ul></div><div>Requesting though=
ts on:</div><div><ul><li>Everything. I hacked this together a few months ag=
o and cleaned it up to post here. <br></li></ul></div></div></div></div></d=
iv></div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CANgTfEgpE%3Dm-rnYRGfRgRWv6r_82Zn4f%3=
DXkup%3DuohpHmm3_PFA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANgTfEgpE%=
3Dm-rnYRGfRgRWv6r_82Zn4f%3DXkup%3DuohpHmm3_PFA%40mail.gmail.com</a>.<br />

--00000000000048004b05786cfb06--

.