Topic: [std-proposals] Winked-out optimization on gen
Author: Gareth Lloyd <gareth@ignition-web.co.uk>
Date: Mon, 15 Oct 2018 16:48:57 +0100
Raw View
--000000000000a2b152057846600d
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
A generic collection can take an arbitrary allocator to control its
allocation behaviour. That allocator may be monotonic, as in deallocation
is a noop. This means that for types that were allocated and constructed
with this allocator then the destruction, if is_trivially_destructible, and
deallocation would be noops. This has a performance benefit when used in
your own types because the destruction of your internal structures can be
=E2=80=9CWinked-out=E2=80=9D, you just don=E2=80=99t have to do it.
On initial inspection this all looks great, take C++17
polymorphic_allocator and a monotonic_buffer_resource, turn up optimization
and LTO, devirtualization kicks in, calls are inlined, and destruction of
our collection should be =E2=80=9Cwinked-out=E2=80=9D right?
Wrong. This works fine for vector, but not for node structures like list.
The root problem is no compiler (msvc/gcc/clang) optimizes away empty loops
that have a data dependent traversal. 6.8.2.2 Forward progress hints to me
that compilers can. (http://eel.is/c++draft/intro.progress#1).
int init_int();
void * init_ptr();
void foo()
{
//loop eliminated
for(auto i =3D init_int(); i; --i);
//loop not eliminated
for(
auto p =3D init_ptr();
p;
p =3D *(void**)p
);
}
foo():
sub rsp, 8
call init_int()
call init_ptr()
test rax, rax
je .L1
..L3:
mov rax, QWORD PTR [rax]
test rax, rax
jne .L3
..L1:
add rsp, 8
ret
So that is one part of the story, compilers could implement this
optimization if I=E2=80=99m understanding the standard correctly. This all =
happens
outside the language. With pmr it is perfectly fine that a pmr container is
not statically determined to be trivially_destructible. But you may want to
have generic containers which take another allocator via compile time
polymorphism which enables the =E2=80=9Cwinked-out=E2=80=9D optimization ir=
respective of
optimizer used and additionally you also want the generic container to
itself be trivially_destructible.
For a generic collection to be potentially trivially destructible it cannot
provide its own destructor. Look at the following illustrative code:
#include <type_traits>
#include <iostream>
#include <memory>
#include <experimental/type_traits>
// Example memory resource
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 =3D std::align(align, bytes, m_freeBegin, m_freeSpace);
if (!mem) throw std::bad_alloc();
m_freeBegin =3D static_cast<char *>(m_freeBegin) + bytes;
m_freeSpace -=3D bytes;
return mem;
}
void * m_buffer;
void * m_freeBegin;
std::size_t m_freeSpace;
};
// Example allocator
template<typename T>
struct my_alloc
{
using noop_deallocate =3D std::true_type; // Indicate it is a noop
deallocate
using value_type =3D T;
my_alloc() =3D delete;
my_alloc(slab_allocator_resource* res) : res{res} {}
template <class U> constexpr my_alloc(const my_alloc<U>&) noexcept {}
[[nodiscard]] T* allocate(std::size_t n) { return res->allocate<T>(n); }
slab_allocator_resource * res;
};
//Proposed something like this into allocator_traits
template<typename Alloc>
struct allocator_traits_demo
{
private:
template<class U> using detect_noop_deallocate =3D typename
U::noop_deallocate;
public:
using is_noop_deallocate =3D
std::experimental::detected_or_t<std::false_type,
detect_noop_deallocate, Alloc>;
};
template<typename T>
struct node
{
node * m_next =3D nullptr;
T m_value =3D T{};
explicit node(T value, node * next =3D nullptr)
: m_next{next},
m_value{value} {}
};
template<typename T, typename Alloc>
struct list_impl : Alloc
{
//**************REGULAR IMPLEMENTATION DETAIL START
using allocator_type =3D typename std::allocator_traits<Alloc>::template
rebind_alloc<node<T>>;
list_impl() =3D default;
explicit list_impl(allocator_type const & a) : Alloc{a} {}
void push(T v)
{
auto a =3D allocator_type{*this};
auto new_node =3D a.allocate(1);
a.construct(new_node, v, m_head);
m_head =3D new_node;
}
node<T> * m_head =3D nullptr;
//**************REGULAR IMPLEMENTATION DETAIL END
//**************CONDITIONAL DTR START
using use_default_dtr =3D std::conjunction<
std::is_trivially_destructible<node<T>>,
typename allocator_traits_demo<allocator_type>::is_noop_deallocate
>;
void non_trivial_dtr() //may be required depending on T and Alloc
{
auto a =3D allocator_type{*this};
auto current_node =3D m_head;
while (current_node !=3D nullptr)
{
auto old_node =3D current_node;
current_node =3D current_node->m_next;
a.destroy(old_node);
a.deallocate(old_node, 1);
}
};
// Not possible to SFINAE
//
//template<typename =3D
std::enable_if_t<std::negation<use_default_dtr>::value>>
//~list_impl(){ non_trivial_dtr(); }
//**************CONDITIONAL DTR END
};
//**************CONDITIONAL DTR SHIM START
template<typename Impl>
struct add_destructor : Impl
{
using Impl::Impl;
~add_destructor()
{
Impl::non_trivial_dtr();
}
};
template <typename T, typename Alloc =3D std::allocator<int>>
using list =3D std::conditional_t<
list_impl<T,Alloc>::use_default_dtr::value, // Use condition
list_impl<T, Alloc>, // ignore dtr
add_destructor<list_impl<T,Alloc>> // apply dtr
>;
//**************CONDITIONAL DTR SHIM END
int main()
{
using sut1_t =3D list<int, my_alloc<int>>;
using sut2_t =3D list<sut1_t, my_alloc<sut1_t>>;
std::cout
<< std::boolalpha
<< "list of ints is trivially destructible: "
<< std::is_trivially_destructible_v<sut1_t> << '\n'
<< "list of lists of ints is trivially destructible: "
<< std::is_trivially_destructible_v<sut2_t> << '\n';
};
Things to notice
1) Need to detect something within the allocator so that we can modify
the generic data type accordingly. i.e. noop_deallocate
2) In my example a strong coupling between the allocator and the
resource is shown, for a more general allocator a detector may be required
to propagate that something from the resource to a generic allocator
3) The data type uses this information along with other information to
form a condition for if the non-trivial destructor is required
4) Enable if technique does not work
5) Type needs wrapping to add the non-trivial destructor if it is
required
I propose:
=C2=B7 Something like noop_deallocate to be added as an optional mem=
ber
type of the allocator
=C2=B7 A corresponding detector added to allocator_traits
Requesting thoughts on:
=C2=B7 What should be the approach to make conditional destruction e=
asier
to implement?
--=20
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 e=
mail 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/CANgTfEgump4cfQOAVXoRtYZKNF99kbw7KyaVw42ifXyC_6C=
FGA%40mail.gmail.com.
--000000000000a2b152057846600d
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><p class=3D"MsoNormal" style=3D"margin:0cm 0cm 8pt;line-he=
ight:107%;font-size:11pt;font-family:"Calibri",sans-serif">A gene=
ric collection can take an arbitrary allocator to
control its allocation behaviour. That allocator may be monotonic, as in de=
allocation
is a noop. This means that for types that were allocated and constructed wi=
th
this allocator then the destruction, if is_trivially_destructible, and
deallocation would be noops. This has a performance benefit when used in yo=
ur
own types because the destruction of your internal structures can be =E2=80=
=9CWinked-out=E2=80=9D,
you just don=E2=80=99t have to do it.<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 8pt;line-height:107%;font-si=
ze:11pt;font-family:"Calibri",sans-serif">On initial inspection t=
his all looks great, take C++17 polymorphic_allocator
and a monotonic_buffer_resource, turn up optimization and LTO, devirtualiza=
tion
kicks in, calls are inlined, and destruction of our collection should be =
=E2=80=9Cwinked-out=E2=80=9D
right? <span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 8pt;line-height:107%;font-si=
ze:11pt;font-family:"Calibri",sans-serif">Wrong. This works fine =
for vector, but not for node structures
like list. The root problem is no compiler (msvc/gcc/clang) optimizes away =
empty
loops that have a data dependent traversal. 6.8.2.2 Forward progress hints =
to
me that compilers can. (<a href=3D"http://eel.is/c++draft/intro.progress#1"=
style=3D"color:rgb(5,99,193);text-decoration:underline">http://eel.is/c++d=
raft/intro.progress#1</a>).<span></span></p>
<table class=3D"gmail-MsoTableGrid" style=3D"border-collapse:collapse;borde=
r:medium none" cellspacing=3D"0" cellpadding=3D"0" border=3D"1">
<tbody><tr>
<td style=3D"width:262pt;border:1pt solid windowtext;padding:0cm 5.4pt" w=
idth=3D"349" valign=3D"top">
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue">int</span><span style=3D"f=
ont-size:10pt;font-family:Consolas;color:black"> init_int(); <span></span><=
/span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue">void </span><span style=3D=
"font-size:10pt;font-family:Consolas;color:black">* init_ptr();</span><span=
style=3D"font-size:10pt;font-family:Consolas"><span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue">void</span><span style=3D"=
font-size:10pt;font-family:Consolas;color:black"> foo()</span><span style=
=3D"font-size:10pt;font-family:Consolas"><span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:black">{</span><span style=3D"fo=
nt-size:10pt;font-family:Consolas"><span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:green"><span>=C2=A0 </span>//loo=
p
eliminated</span><span style=3D"font-size:10pt;font-family:Consolas"><spa=
n></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>for</s=
pan><span style=3D"font-size:10pt;font-family:Consolas;color:black">(</span=
><span style=3D"font-size:10pt;font-family:Consolas;color:blue">auto</span>=
<span style=3D"font-size:10pt;font-family:Consolas;color:black">
i =3D init_int(); i; --i); </span><span style=3D"font-size:10pt;font-fami=
ly:Consolas"><span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:green"><span>=C2=A0</span></span=
></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:green"><span>=C2=A0 </span>//loo=
p
not eliminated</span><span style=3D"font-size:10pt;font-family:Consolas">=
<span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>for</s=
pan><span style=3D"font-size:10pt;font-family:Consolas;color:black">(<span>=
</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 =
</span></span><span style=3D"font-size:10pt;font-family:Consolas;color:blue=
">auto</span><span style=3D"font-size:10pt;font-family:Consolas;color:black=
">
p =3D init_ptr(); <span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 =
</span>p; <span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 =
</span>p =3D *(</span><span style=3D"font-size:10pt;font-family:Consolas;co=
lor:blue">void</span><span style=3D"font-size:10pt;font-family:Consolas;col=
or:black">**)p<span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:black"><span>=C2=A0 </span>); </=
span><span style=3D"font-size:10pt;font-family:Consolas"><span></span></spa=
n></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:black">}</span><span style=3D"fo=
nt-size:12pt;font-family:"Times New Roman",serif"><span></span></=
span></p>
</td>
<td style=3D"width:188.8pt;border-color:windowtext windowtext windowtext =
currentcolor;border-style:solid solid solid none;border-width:1pt 1pt 1pt m=
edium;padding:0cm 5.4pt" width=3D"252" valign=3D"top">
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:teal">foo():</span><span style=
=3D"font-size:10pt;font-family:Consolas"><span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>sub</s=
pan><span style=3D"font-size:10pt;font-family:Consolas;color:black">
</span><span style=3D"font-size:10pt;font-family:Consolas;color:rgb(72,10=
0,170)">rsp</span><span style=3D"font-size:10pt;font-family:Consolas;color:=
black">, </span><span style=3D"font-size:10pt;font-family:Consolas;color:rg=
b(9,136,90)">8</span><span style=3D"font-size:10pt;font-family:Consolas"><s=
pan></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>call</=
span><span style=3D"font-size:10pt;font-family:Consolas;color:black">
</span><span style=3D"font-size:10pt;font-family:Consolas;color:teal">ini=
t_int</span><span style=3D"font-size:10pt;font-family:Consolas;color:black"=
>()</span><span style=3D"font-size:10pt;font-family:Consolas"><span></span>=
</span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>call</=
span><span style=3D"font-size:10pt;font-family:Consolas;color:black">
</span><span style=3D"font-size:10pt;font-family:Consolas;color:teal">ini=
t_ptr</span><span style=3D"font-size:10pt;font-family:Consolas;color:black"=
>()</span><span style=3D"font-size:10pt;font-family:Consolas"><span></span>=
</span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>test</=
span><span style=3D"font-size:10pt;font-family:Consolas;color:black">
</span><span style=3D"font-size:10pt;font-family:Consolas;color:rgb(72,10=
0,170)">rax</span><span style=3D"font-size:10pt;font-family:Consolas;color:=
black">, </span><span style=3D"font-size:10pt;font-family:Consolas;color:rg=
b(72,100,170)">rax</span><span style=3D"font-size:10pt;font-family:Consolas=
"><span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>je</sp=
an><span style=3D"font-size:10pt;font-family:Consolas;color:black">
</span><span style=3D"font-size:10pt;font-family:Consolas;color:teal">.L1=
</span><span style=3D"font-size:10pt;font-family:Consolas"><span></span></s=
pan></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:teal">.L3:</span><span style=3D"=
font-size:10pt;font-family:Consolas"><span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>mov</s=
pan><span style=3D"font-size:10pt;font-family:Consolas;color:black">
</span><span style=3D"font-size:10pt;font-family:Consolas;color:rgb(72,10=
0,170)">rax</span><span style=3D"font-size:10pt;font-family:Consolas;color:=
black">, </span><span style=3D"font-size:10pt;font-family:Consolas;color:gr=
ay">QWORD</span><span style=3D"font-size:10pt;font-family:Consolas;color:bl=
ack">
</span><span style=3D"font-size:10pt;font-family:Consolas;color:gray">PTR=
</span><span style=3D"font-size:10pt;font-family:Consolas;color:black"> [</=
span><span style=3D"font-size:10pt;font-family:Consolas;color:rgb(72,100,17=
0)">rax</span><span style=3D"font-size:10pt;font-family:Consolas;color:blac=
k">]</span><span style=3D"font-size:10pt;font-family:Consolas"><span></span=
></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>test</=
span><span style=3D"font-size:10pt;font-family:Consolas;color:black">
</span><span style=3D"font-size:10pt;font-family:Consolas;color:rgb(72,10=
0,170)">rax</span><span style=3D"font-size:10pt;font-family:Consolas;color:=
black">, </span><span style=3D"font-size:10pt;font-family:Consolas;color:rg=
b(72,100,170)">rax</span><span style=3D"font-size:10pt;font-family:Consolas=
"><span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>jne</s=
pan><span style=3D"font-size:10pt;font-family:Consolas;color:black">
</span><span style=3D"font-size:10pt;font-family:Consolas;color:teal">.L3=
</span><span style=3D"font-size:10pt;font-family:Consolas"><span></span></s=
pan></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:teal">.L1:</span><span style=3D"=
font-size:10pt;font-family:Consolas"><span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>add</s=
pan><span style=3D"font-size:10pt;font-family:Consolas;color:black">
</span><span style=3D"font-size:10pt;font-family:Consolas;color:rgb(72,10=
0,170)">rsp</span><span style=3D"font-size:10pt;font-family:Consolas;color:=
black">, </span><span style=3D"font-size:10pt;font-family:Consolas;color:rg=
b(9,136,90)">8</span><span style=3D"font-size:10pt;font-family:Consolas"><s=
pan></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:norma=
l;font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D=
"font-size:10pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>ret</s=
pan><span style=3D"font-size:12pt;font-family:"Times New Roman",s=
erif"><span></span></span></p>
</td>
</tr>
</tbody></table>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 8pt;line-height:107%;font-si=
ze:11pt;font-family:"Calibri",sans-serif">So that is one part of =
the story, compilers could implement
this optimization if I=E2=80=99m understanding the standard correctly. This=
all happens
outside the language. With pmr it is perfectly fine that a pmr container is=
not
statically determined to be trivially_destructible. But you may want to hav=
e
generic containers which take another allocator via compile time polymorphi=
sm which
enables the =E2=80=9Cwinked-out=E2=80=9D optimization irrespective of optim=
izer used and additionally
you also want the generic container to itself be trivially_destructible.<sp=
an></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 8pt;line-height:107%;font-si=
ze:11pt;font-family:"Calibri",sans-serif">For a generic collectio=
n to be potentially trivially destructible
it cannot provide its own destructor. Look at the following illustrative co=
de:<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">#include</span><span style=3D=
"font-size:7pt;font-family:Consolas;color:black"> <type_traits></span=
><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">#include</span><span style=3D=
"font-size:7pt;font-family:Consolas;color:black"> <iostream></span><s=
pan></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">#include</span><span style=3D=
"font-size:7pt;font-family:Consolas;color:black"> <memory></span><spa=
n></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">#include</span><span style=3D=
"font-size:7pt;font-family:Consolas;color:black"> <experimental/type_tra=
its></span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green">// Example memory
resource</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">struct</span><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"> slab_allocator_resource</sp=
an><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">{</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>explicit<=
/span><span style=3D"font-size:7pt;font-family:Consolas;color:black"> slab_=
allocator_resource(std::size_t spaceNeeded)</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan>: m_buffer(std::malloc(spaceNeeded)),</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 </span>m_freeBegin(m_buffer),</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 </span>m_freeSpace(spaceNeeded)</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>{</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0=C2=A0=C2=A0 </sp=
an>if</span><span style=3D"font-size:7pt;font-family:Consolas;color:black">=
(!m_buffer) </span><span style=3D"font-size:7pt;font-family:Consolas;color=
:blue">throw</span><span style=3D"font-size:7pt;font-family:Consolas;color:=
black"> std::bad_alloc();</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>}</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>~slab_al=
locator_resource() {
std::free(m_buffer); }</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>template<=
/span><span style=3D"font-size:7pt;font-family:Consolas;color:black"><</=
span><span style=3D"font-size:7pt;font-family:Consolas;color:blue">typename=
</span><span style=3D"font-size:7pt;font-family:Consolas;color:black"> T>=
;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:gray"><span>=C2=A0 </span>[[nodisca=
rd]]</span><span style=3D"font-size:7pt;font-family:Consolas;color:black"> =
T * allocate(std::size_t n)</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>{</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0=C2=A0=C2=A0 </sp=
an>return</span><span style=3D"font-size:7pt;font-family:Consolas;color:bla=
ck"> </span><span style=3D"font-size:7pt;font-family:Consolas;color:blue">s=
tatic_cast</span><span style=3D"font-size:7pt;font-family:Consolas;color:bl=
ack"><T *>(allocate_bytes(</span><span style=3D"font-size:7pt;font-fa=
mily:Consolas;color:blue">alignof</span><span style=3D"font-size:7pt;font-f=
amily:Consolas;color:black">(T), </span><span style=3D"font-size:7pt;font-f=
amily:Consolas;color:blue">sizeof</span><span style=3D"font-size:7pt;font-f=
amily:Consolas;color:black">(T) * n));</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>}</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>private</=
span><span style=3D"font-size:7pt;font-family:Consolas;color:black">:</span=
><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>void</spa=
n><span style=3D"font-size:7pt;font-family:Consolas;color:black"> * allocat=
e_bytes(std::size_t align, std::size_t
bytes)</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>{</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0=C2=A0=C2=A0 </sp=
an>auto</span><span style=3D"font-size:7pt;font-family:Consolas;color:black=
"> mem =3D std::align(align, bytes, m_freeBegin,
m_freeSpace);</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0=C2=A0=C2=A0 </sp=
an>if</span><span style=3D"font-size:7pt;font-family:Consolas;color:black">=
(!mem) </span><span style=3D"font-size:7pt;font-family:Consolas;color:blue=
">throw</span><span style=3D"font-size:7pt;font-family:Consolas;color:black=
"> std::bad_alloc();</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan>m_freeBegin =3D </span><span style=3D"font-size:7pt;font-family:Consola=
s;color:blue">static_cast</span><span style=3D"font-size:7pt;font-family:Co=
nsolas;color:black"><</span><span style=3D"font-size:7pt;font-family:Con=
solas;color:blue">char</span><span style=3D"font-size:7pt;font-family:Conso=
las;color:black"> *>(m_freeBegin) + bytes;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan>m_freeSpace -=3D bytes;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0=C2=A0=C2=A0 </sp=
an>return</span><span style=3D"font-size:7pt;font-family:Consolas;color:bla=
ck"> mem;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>}</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>void</spa=
n><span style=3D"font-size:7pt;font-family:Consolas;color:black"> * m_buffe=
r;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>void</spa=
n><span style=3D"font-size:7pt;font-family:Consolas;color:black"> * m_freeB=
egin;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>std::siz=
e_t m_freeSpace;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">};</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green">// Example allocator</span><=
span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">template</span><span style=3D=
"font-size:7pt;font-family:Consolas;color:black"><</span><span style=3D"=
font-size:7pt;font-family:Consolas;color:blue">typename</span><span style=
=3D"font-size:7pt;font-family:Consolas;color:black"> T></span><span></sp=
an></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">struct</span><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"> my_alloc</span><span></span=
></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">{</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>using</sp=
an><span style=3D"font-size:7pt;font-family:Consolas;color:black"> noop_dea=
llocate =3D std::true_type; </span><span style=3D"font-size:7pt;font-family=
:Consolas;color:green">// Indicate it is a noop deallocate</span><span></sp=
an></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>using</sp=
an><span style=3D"font-size:7pt;font-family:Consolas;color:black"> value_ty=
pe =3D T;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>my_alloc=
() =3D </span><span style=3D"font-size:7pt;font-family:Consolas;color:blue"=
>delete</span><span style=3D"font-size:7pt;font-family:Consolas;color:black=
">;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>my_alloc=
(slab_allocator_resource* res) :
res{res} {}</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>template<=
/span><span style=3D"font-size:7pt;font-family:Consolas;color:black"> <<=
/span><span style=3D"font-size:7pt;font-family:Consolas;color:blue">class</=
span><span style=3D"font-size:7pt;font-family:Consolas;color:black"> U> =
</span><span style=3D"font-size:7pt;font-family:Consolas;color:blue">conste=
xpr</span><span style=3D"font-size:7pt;font-family:Consolas;color:black"> m=
y_alloc(</span><span style=3D"font-size:7pt;font-family:Consolas;color:blue=
">const</span><span style=3D"font-size:7pt;font-family:Consolas;color:black=
"> my_alloc<U>&) </span><span style=3D"font-size:7pt;font-family:=
Consolas;color:blue">noexcept</span><span style=3D"font-size:7pt;font-famil=
y:Consolas;color:black"> {}</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:gray"><span>=C2=A0 </span>[[nodisca=
rd]]</span><span style=3D"font-size:7pt;font-family:Consolas;color:black"> =
T* allocate(std::size_t n) { </span><span style=3D"font-size:7pt;font-famil=
y:Consolas;color:blue">return</span><span style=3D"font-size:7pt;font-famil=
y:Consolas;color:black"> res->allocate<T>(n); }</span><span></span=
></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>slab_all=
ocator_resource * res;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">};</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green">//Proposed something
like this into allocator_traits</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">template</span><span style=3D=
"font-size:7pt;font-family:Consolas;color:black"><</span><span style=3D"=
font-size:7pt;font-family:Consolas;color:blue">typename</span><span style=
=3D"font-size:7pt;font-family:Consolas;color:black"> Alloc></span><span>=
</span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">struct</span><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"> allocator_traits_demo </spa=
n><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">{</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>private</=
span><span style=3D"font-size:7pt;font-family:Consolas;color:black">: </spa=
n><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>template<=
/span><span style=3D"font-size:7pt;font-family:Consolas;color:black"><</=
span><span style=3D"font-size:7pt;font-family:Consolas;color:blue">class</s=
pan><span style=3D"font-size:7pt;font-family:Consolas;color:black"> U> <=
/span><span style=3D"font-size:7pt;font-family:Consolas;color:blue">using</=
span><span style=3D"font-size:7pt;font-family:Consolas;color:black"> detect=
_noop_deallocate =3D </span><span style=3D"font-size:7pt;font-family:Consol=
as;color:blue">typename</span><span style=3D"font-size:7pt;font-family:Cons=
olas;color:black"> U::noop_deallocate;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0</span></span></p=
>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>public</s=
pan><span style=3D"font-size:7pt;font-family:Consolas;color:black">:</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>using</sp=
an><span style=3D"font-size:7pt;font-family:Consolas;color:black"> is_noop_=
deallocate =3D </span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0
</span>std::experimental::detected_or_t<std::false_type,
detect_noop_deallocate, Alloc>;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">};</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">template</span><span style=3D=
"font-size:7pt;font-family:Consolas;color:black"><</span><span style=3D"=
font-size:7pt;font-family:Consolas;color:blue">typename</span><span style=
=3D"font-size:7pt;font-family:Consolas;color:black"> T></span><span></sp=
an></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">struct</span><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"> node</span><span></span></p=
>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">{</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>node * m=
_next =3D </span><span style=3D"font-size:7pt;font-family:Consolas;color:bl=
ue">nullptr</span><span style=3D"font-size:7pt;font-family:Consolas;color:b=
lack">;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>T m_valu=
e =3D T{};</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>explicit<=
/span><span style=3D"font-size:7pt;font-family:Consolas;color:black"> node(=
T value, node * next =3D </span><span style=3D"font-size:7pt;font-family:Co=
nsolas;color:blue">nullptr</span><span style=3D"font-size:7pt;font-family:C=
onsolas;color:black">) </span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan>: m_next{next},</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 </span>m_value{value} {}</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">};</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">template</span><span style=3D=
"font-size:7pt;font-family:Consolas;color:black"><</span><span style=3D"=
font-size:7pt;font-family:Consolas;color:blue">typename</span><span style=
=3D"font-size:7pt;font-family:Consolas;color:black"> T, </span><span style=
=3D"font-size:7pt;font-family:Consolas;color:blue">typename</span><span sty=
le=3D"font-size:7pt;font-family:Consolas;color:black"> Alloc></span><spa=
n></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">struct</span><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"> list_impl : Alloc</span><sp=
an></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">{</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green"><span>=C2=A0 </span>//******=
********REGULAR IMPLEMENTATION DETAIL
START</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>using</sp=
an><span style=3D"font-size:7pt;font-family:Consolas;color:black"> allocato=
r_type =3D </span><span style=3D"font-size:7pt;font-family:Consolas;color:b=
lue">typename</span><span style=3D"font-size:7pt;font-family:Consolas;color=
:black"> std::allocator_traits<Alloc>::</span><span style=3D"font-siz=
e:7pt;font-family:Consolas;color:blue">template</span><span style=3D"font-s=
ize:7pt;font-family:Consolas;color:black"> rebind_alloc<node<T>>=
;;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0</span></span></=
p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>list_imp=
l() =3D </span><span style=3D"font-size:7pt;font-family:Consolas;color:blue=
">default</span><span style=3D"font-size:7pt;font-family:Consolas;color:bla=
ck">;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>explicit<=
/span><span style=3D"font-size:7pt;font-family:Consolas;color:black"> list_=
impl(allocator_type </span><span style=3D"font-size:7pt;font-family:Consola=
s;color:blue">const</span><span style=3D"font-size:7pt;font-family:Consolas=
;color:black"> & a) : Alloc{a} {}</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>void</spa=
n><span style=3D"font-size:7pt;font-family:Consolas;color:black"> push(T v)=
</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>{</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0=C2=A0=C2=A0 </sp=
an>auto</span><span style=3D"font-size:7pt;font-family:Consolas;color:black=
"> a =3D allocator_type{*</span><span style=3D"font-size:7pt;font-family:Co=
nsolas;color:blue">this</span><span style=3D"font-size:7pt;font-family:Cons=
olas;color:black">};</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0=C2=A0=C2=A0 </sp=
an>auto</span><span style=3D"font-size:7pt;font-family:Consolas;color:black=
"> new_node =3D a.allocate(</span><span style=3D"font-size:7pt;font-family:=
Consolas;color:rgb(9,136,90)">1</span><span style=3D"font-size:7pt;font-fam=
ily:Consolas;color:black">);</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan>a.construct(new_node, v, m_head);</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan>m_head =3D new_node;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>}</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0</span></span></=
p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>node<=
T> * m_head =3D </span><span style=3D"font-size:7pt;font-family:Consolas=
;color:blue">nullptr</span><span style=3D"font-size:7pt;font-family:Consola=
s;color:black">;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green"><span>=C2=A0 </span>//******=
********REGULAR IMPLEMENTATION DETAIL
END</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green"><span>=C2=A0 </span>//******=
********CONDITIONAL DTR START</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>using</sp=
an><span style=3D"font-size:7pt;font-family:Consolas;color:black"> use_defa=
ult_dtr =3D std::conjunction<</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0
</span>std::is_trivially_destructible<node<T>>,</span><span></s=
pan></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0=C2=A0=C2=A0 </sp=
an>typename</span><span style=3D"font-size:7pt;font-family:Consolas;color:b=
lack">
allocator_traits_demo<allocator_type>::is_noop_deallocate</span><span=
></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>>;<sp=
an></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>void</spa=
n><span style=3D"font-size:7pt;font-family:Consolas;color:black"> non_trivi=
al_dtr() </span><span style=3D"font-size:7pt;font-family:Consolas;color:gre=
en">//may be required depending on T and Alloc</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>{</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0=C2=A0=C2=A0 </sp=
an>auto</span><span style=3D"font-size:7pt;font-family:Consolas;color:black=
"> a =3D allocator_type{*</span><span style=3D"font-size:7pt;font-family:Co=
nsolas;color:blue">this</span><span style=3D"font-size:7pt;font-family:Cons=
olas;color:black">};</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0=C2=A0=C2=A0 </sp=
an>auto</span><span style=3D"font-size:7pt;font-family:Consolas;color:black=
"> current_node =3D m_head;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0=C2=A0=C2=A0 </sp=
an>while</span><span style=3D"font-size:7pt;font-family:Consolas;color:blac=
k"> (current_node !=3D </span><span style=3D"font-size:7pt;font-family:Cons=
olas;color:blue">nullptr</span><span style=3D"font-size:7pt;font-family:Con=
solas;color:black">)</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan>{</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 </span>auto</span><span style=3D"font-size:7pt;font-family:Consol=
as;color:black"> old_node =3D current_node;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 </span>current_node =3D current_node->m_next;</span><span></sp=
an></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 </span>a.destroy(old_node);</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 </span>a.deallocate(old_node, </span><span style=3D"font-size:7pt=
;font-family:Consolas;color:rgb(9,136,90)">1</span><span style=3D"font-size=
:7pt;font-family:Consolas;color:black">);</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan>}</span><span style=3D"font-size:7pt;font-family:Consolas"><span></span=
></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>};<span>=
</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0</span></span></=
p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green"><span>=C2=A0 </span>// Not
possible to SFINAE</span><span style=3D"font-size:7pt;font-family:Consolas"=
><span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green"><span>=C2=A0 </span>//</span=
><span style=3D"font-size:7pt;font-family:Consolas"><span></span></span></p=
>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green"><span>=C2=A0 </span>//templa=
te<typename
=3D std::enable_if_t<std::negation<use_default_dtr>::value>>=
</span><span style=3D"font-size:7pt;font-family:Consolas"><span></span></sp=
an></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green"><span>=C2=A0 </span>//~list_=
impl(){
non_trivial_dtr(); }</span><span style=3D"font-size:7pt;font-family:Consola=
s"><span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green"><span>=C2=A0 </span>//******=
********CONDITIONAL DTR END</span><span style=3D"font-size:7pt;font-family:=
Consolas"><span></span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">};</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green">//**************CONDITIONAL
DTR SHIM START</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">template</span><span style=3D=
"font-size:7pt;font-family:Consolas;color:black"><</span><span style=3D"=
font-size:7pt;font-family:Consolas;color:blue">typename</span><span style=
=3D"font-size:7pt;font-family:Consolas;color:black"> Impl></span><span><=
/span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">struct</span><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"> add_destructor : Impl</span=
><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">{</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>using</sp=
an><span style=3D"font-size:7pt;font-family:Consolas;color:black"> Impl::Im=
pl;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>~add_des=
tructor()</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>{</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan>Impl::non_trivial_dtr();</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>}</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">};</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">template</span><span style=3D=
"font-size:7pt;font-family:Consolas;color:black"> <</span><span style=3D=
"font-size:7pt;font-family:Consolas;color:blue">typename</span><span style=
=3D"font-size:7pt;font-family:Consolas;color:black"> T, </span><span style=
=3D"font-size:7pt;font-family:Consolas;color:blue">typename</span><span sty=
le=3D"font-size:7pt;font-family:Consolas;color:black"> Alloc =3D std::alloc=
ator<</span><span style=3D"font-size:7pt;font-family:Consolas;color:blue=
">int</span><span style=3D"font-size:7pt;font-family:Consolas;color:black">=
>></span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">using</span><span style=3D"fo=
nt-size:7pt;font-family:Consolas;color:black"> list =3D std::conditional_t&=
lt;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0
</span>list_impl<T,Alloc>::use_default_dtr::value, </span><span style=
=3D"font-size:7pt;font-family:Consolas;color:green">// Use condition</span>=
<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>list_imp=
l<T, Alloc>, </span><span style=3D"font-size:7pt;font-family:Consolas=
;color:green">// ignore dtr</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0
</span>add_destructor<list_impl<T,Alloc>> </span><span style=3D=
"font-size:7pt;font-family:Consolas;color:green">// apply dtr</span><span><=
/span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">>;</span><span></span></p=
>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:green">//**************CONDITIONAL
DTR SHIM END</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue">int</span><span style=3D"font=
-size:7pt;font-family:Consolas;color:black"> main()</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">{</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>using</sp=
an><span style=3D"font-size:7pt;font-family:Consolas;color:black"> sut1_t =
=3D list<</span><span style=3D"font-size:7pt;font-family:Consolas;color:=
blue">int</span><span style=3D"font-size:7pt;font-family:Consolas;color:bla=
ck">, my_alloc<</span><span style=3D"font-size:7pt;font-family:Consolas;=
color:blue">int</span><span style=3D"font-size:7pt;font-family:Consolas;col=
or:black">>>;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:blue"><span>=C2=A0 </span>using</sp=
an><span style=3D"font-size:7pt;font-family:Consolas;color:black"> sut2_t =
=3D list<sut1_t,
my_alloc<sut1_t>>;</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0</span></span></=
p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0 </span>std::cou=
t </span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan><< std::boolalpha</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan><< </span><span style=3D"font-size:7pt;font-family:Consolas;color=
:rgb(163,21,21)">"list of ints is trivially
destructible: "</span><span style=3D"font-size:7pt;font-family:Consola=
s;color:black"> </span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan><<
std::is_trivially_destructible_v<sut1_t> << </span><span style=
=3D"font-size:7pt;font-family:Consolas;color:rgb(163,21,21)">'\n'</=
span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan><< </span><span style=3D"font-size:7pt;font-family:Consolas;color=
:rgb(163,21,21)">"list of lists of ints is
trivially destructible: "</span><span style=3D"font-size:7pt;font-fami=
ly:Consolas;color:black"> </span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black"><span>=C2=A0=C2=A0=C2=A0 </s=
pan><<
std::is_trivially_destructible_v<sut2_t> << </span><span style=
=3D"font-size:7pt;font-family:Consolas;color:rgb(163,21,21)">'\n'</=
span><span style=3D"font-size:7pt;font-family:Consolas;color:black">;</span=
><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 0.0001pt;line-height:normal;=
font-size:11pt;font-family:"Calibri",sans-serif"><span style=3D"f=
ont-size:7pt;font-family:Consolas;color:black">};</span><span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 8pt;line-height:107%;font-si=
ze:11pt;font-family:"Calibri",sans-serif"><span style=3D"font-siz=
e:7pt;line-height:107%;font-family:Consolas"><span>=C2=A0</span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 8pt;line-height:107%;font-si=
ze:11pt;font-family:"Calibri",sans-serif">Things to notice<span><=
/span></p>
<p class=3D"gmail-MsoListParagraphCxSpFirst" style=3D"margin:0cm 0cm 0.0001=
pt 36pt;line-height:107%;font-size:11pt;font-family:"Calibri",san=
s-serif"><span><span>1)<span style=3D"font:7pt "Times New Roman""=
>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0
</span></span></span>Need to detect something within the allocator so
that we can modify the generic data type accordingly. i.e. noop_deallocate<=
span></span></p>
<p class=3D"gmail-MsoListParagraphCxSpMiddle" style=3D"margin:0cm 0cm 0.000=
1pt 36pt;line-height:107%;font-size:11pt;font-family:"Calibri",sa=
ns-serif"><span><span>2)<span style=3D"font:7pt "Times New Roman"=
">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0
</span></span></span>In my example a strong coupling between the
allocator and the resource is shown, for a more general allocator a detecto=
r
may be required to propagate that something from the resource to a generic
allocator<span></span></p>
<p class=3D"gmail-MsoListParagraphCxSpMiddle" style=3D"margin:0cm 0cm 0.000=
1pt 36pt;line-height:107%;font-size:11pt;font-family:"Calibri",sa=
ns-serif"><span><span>3)<span style=3D"font:7pt "Times New Roman"=
">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0
</span></span></span>The data type uses this information along with
other information to form a condition for if the non-trivial destructor is
required<span></span></p>
<p class=3D"gmail-MsoListParagraphCxSpMiddle" style=3D"margin:0cm 0cm 0.000=
1pt 36pt;line-height:107%;font-size:11pt;font-family:"Calibri",sa=
ns-serif"><span><span>4)<span style=3D"font:7pt "Times New Roman"=
">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0
</span></span></span>Enable if technique does not work<span></span></p>
<p class=3D"gmail-MsoListParagraphCxSpLast" style=3D"margin:0cm 0cm 8pt 36p=
t;line-height:107%;font-size:11pt;font-family:"Calibri",sans-seri=
f"><span><span>5)<span style=3D"font:7pt "Times New Roman"">=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0
</span></span></span>Type needs wrapping to add the non-trivial
destructor if it is required<span></span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 8pt;line-height:107%;font-si=
ze:11pt;font-family:"Calibri",sans-serif"><span>=C2=A0</span></p>
<p class=3D"MsoNormal" style=3D"margin:0cm 0cm 8pt;line-height:107%;font-si=
ze:11pt;font-family:"Calibri",sans-serif">I propose:<span></span>=
</p>
<p class=3D"gmail-MsoListParagraphCxSpFirst" style=3D"margin:0cm 0cm 0.0001=
pt 38.55pt;line-height:107%;font-size:11pt;font-family:"Calibri",=
sans-serif"><span style=3D"font-family:Symbol"><span>=C2=B7<span style=3D"f=
ont:7pt "Times New Roman"">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0
</span></span></span>Something like noop_deallocate to be added as an
optional member type of the allocator<span></span></p>
<p class=3D"gmail-MsoListParagraphCxSpMiddle" style=3D"margin:0cm 0cm 0.000=
1pt 38.55pt;line-height:107%;font-size:11pt;font-family:"Calibri"=
,sans-serif"><span style=3D"font-family:Symbol"><span>=C2=B7<span style=3D"=
font:7pt "Times New Roman"">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0
</span></span></span>A corresponding detector added to allocator_traits<spa=
n></span></p>
<p class=3D"gmail-MsoListParagraphCxSpMiddle" style=3D"margin:0cm 0cm 0.000=
1pt;line-height:107%;font-size:11pt;font-family:"Calibri",sans-se=
rif"><br>
Requesting thoughts on:<span></span></p>
<p class=3D"gmail-MsoListParagraphCxSpMiddle" style=3D"margin:0cm 0cm 0.000=
1pt 36pt;line-height:107%;font-size:11pt;font-family:"Calibri",sa=
ns-serif"><span style=3D"font-family:Symbol"><span>=C2=B7<span style=3D"fon=
t:7pt "Times New Roman"">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0
</span></span></span>What should be the approach to make conditional
destruction easier to implement? <br></p><p class=3D"gmail-MsoListParagraph=
CxSpMiddle" style=3D"margin:0cm 0cm 0.0001pt 36pt;line-height:107%;font-siz=
e:11pt;font-family:"Calibri",sans-serif"><span></span></p>
<p class=3D"gmail-MsoListParagraphCxSpLast" style=3D"margin:0cm 0cm 8pt;lin=
e-height:107%;font-size:11pt;font-family:"Calibri",sans-serif"><s=
pan>=C2=A0</span></p>
</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CANgTfEgump4cfQOAVXoRtYZKNF99kbw7KyaV=
w42ifXyC_6CFGA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANgTfEgump4cfQOA=
VXoRtYZKNF99kbw7KyaVw42ifXyC_6CFGA%40mail.gmail.com</a>.<br />
--000000000000a2b152057846600d--
.