Topic: New type of "new"/"delete" override
Author: Myriachan <myriachan@gmail.com>
Date: Tue, 21 Jul 2015 12:37:40 -0700 (PDT)
Raw View
------=_Part_1381_38275595.1437507460740
Content-Type: multipart/alternative;
boundary="----=_Part_1382_2021806374.1437507460742"
------=_Part_1382_2021806374.1437507460742
Content-Type: text/plain; charset=UTF-8
In trying to implement a custom memory allocator, there are many annoyances
that come up that make C++ difficult to work with. Particularly, the
syntax of the new and delete operators means that using a custom memory
allocator often involves macros that are semantically different from new
and delete. When private and protected constructors and destructors get
involved, things get especially annoying, because the allocator code can't
call the constructor or destructor itself.
I thought of an idea that would help with this issue, though it is
admittedly rather crazy.
I would add a new type of operator new overload:
template <typename Type, typename Constructor>
Type *operator new valloc_new(const Constructor &constructor)
noexcept(noexcept(constructor(static_cast<Type *>(nullptr))))
{
static_assert(alignof(Type) <= PAGE_SIZE, "only allocations of
alignment PAGE_SIZE or less are supported") ;
std::size_t headerSize = 0;
// Custom implementations aren't required to use new_handlers
void *memory = VirtualAlloc(nullptr, headerSize + sizeof(Type),
MEM_COMMIT, PAGE_READWRITE);
if (!memory)
{
throw std::bad_alloc("out of memory");
}
try
{
return constructor(memory);
}
catch (...)
{
VirtualFree(memory, 0, MEM_RELEASE);
throw;
}
}
template <typename Type, typename Destructor>
void operator delete valloc_delete(Type *object, const Destructor &
destructor)
{
if (object == nullptr)
{
return;
}
// Get the base address of the most-derived object
void *memory = const_cast<std::remove_cv_t<Type> *>(object);
if (std::is_polymorphic<Type>::value)
{
memory = dynamic_cast<void *>(const_cast<std::remove_cv_t<Type> *>(
object));
}
destructor(object);
VirtualFree(memory, 0, MEM_RELEASE);
}
Now valloc_new and valloc_delete in the proper scope will syntactically
function the same way as the new and delete keywords, in a way becoming
keywords themselves. I think that it would be worthwhile to allow these to
be scoped to namespaces or classes.
The private constructor/destructor problem is solved, because they are
passed in as lambdas (or function pointers, at implementation discretion).
We can redefine the basic implementation of the "new" keyword to be an
implementation-defined template function that calls ::operator new(size_t)
and does other things, like dynamic_cast<void *> if the type is
polymorphic. Overriding the global new would work by replacing this
template or its overloads.
template <typename Type, typename Constructor, typename... Args>
Type *operator new new(const Constructor &constructor, Args &&...args)
noexcept(
noexcept(constructor(static_cast<Type *>(nullptr))) &&
noexcept(::operator new(std::size_t(), std::forward<Args>(args
)...)));
Melissa
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1382_2021806374.1437507460742
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">In trying to implement a custom memory allocator, there ar=
e many annoyances that come up that make C++ difficult to work with.=C2=A0 =
Particularly, the syntax of the <span style=3D"font-family: courier new,mon=
ospace;">new</span> and <span style=3D"font-family: courier new,monospace;"=
>delete</span> operators means that using a custom memory allocator often i=
nvolves macros that are semantically different from <span style=3D"font-fam=
ily: courier new,monospace;">new</span> and <span style=3D"font-family: cou=
rier new,monospace;">delete</span>.=C2=A0 When private and protected constr=
uctors and destructors get involved, things get especially annoying, becaus=
e the allocator code can't call the constructor or destructor itself.<b=
r><br>I thought of an idea that would help with this issue, though it is ad=
mittedly rather crazy.<br><br>I would add a new type of <span style=3D"font=
-family: courier new,monospace;">operator new</span> overload:<br><br><div =
class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border=
-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wr=
ap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #008;" class=3D"styled-by-prettify">template</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;"=
class=3D"styled-by-prettify">Type</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">typename</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Const=
ructor</span><span style=3D"color: #660;" class=3D"styled-by-prettify">>=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
><span style=3D"color: #606;" class=3D"styled-by-prettify">Type</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">operator</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">new</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> valloc_new</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">const</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Const=
ructor</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">constructor</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 noexcept=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">noexcept</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">constructor</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">static_cast</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">Type</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">*>(</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">nullptr</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">))))</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>static_assert</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">align=
of</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #606;" class=3D"styled-by-prettify">Type</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify"><=3D</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> PAGE_SIZE</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">"only allocations of alignment PAGE_SIZE or less are su=
pported"</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 st=
d</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">size_t headerSize=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 </span><span style=3D=
"color: #800;" class=3D"styled-by-prettify">// Custom implementations aren&=
#39;t required to use new_handlers</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">*</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">memory </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #606;" class=3D"styled-by-prettify">VirtualAllo=
c</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">nullptr</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> headerSize </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">+</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">sizeof</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D"st=
yled-by-prettify">Type</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">),</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> MEM_COMMIT</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> PAG=
E_READWRITE</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>if</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(!</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">memory</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">throw</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">bad_alloc</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #080;=
" class=3D"styled-by-prettify">"out of memory"</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">try</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> constructor</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify">memory</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">catch</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(...)</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span st=
yle=3D"color: #606;" class=3D"styled-by-prettify">VirtualFree</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">memory</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"=
styled-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> MEM_RELEASE</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">throw</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">template</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">Type</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">typename</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">De=
structor</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">operator</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">delete</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> valloc_delete</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #606;" =
class=3D"styled-by-prettify">Type</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">*</span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">object</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Destructor</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">destructor</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">if</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">object</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">nullptr</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 </span><span st=
yle=3D"color: #800;" class=3D"styled-by-prettify">// Get the base address o=
f the most-derived object</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
memory </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">const_cast</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">remove_cv_t</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #606;"=
class=3D"styled-by-prettify">Type</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">*>(</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">object</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>if</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">is_polymorphic</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">Type</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">>::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">value</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 memory </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">dynamic_cast</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify"><</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">*>(</span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>const_cast</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
><</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">remove_cv_t</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span st=
yle=3D"color: #606;" class=3D"styled-by-prettify">Type</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">></span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">*>(</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">object</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">));</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br><br>=C2=A0 =C2=A0 destructor</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">object</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color: #606;" c=
lass=3D"styled-by-prettify">VirtualFree</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">memory</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">0<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> MEM_RELEASE</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">}</span></div></code></div><br><=
br><br>Now <span style=3D"font-family: courier new,monospace;">valloc_new</=
span> and <span style=3D"font-family: courier new,monospace;">valloc_delete=
</span> in the proper scope will syntactically function the same way as the=
<span style=3D"font-family: courier new,monospace;">new</span> and <span s=
tyle=3D"font-family: courier new,monospace;">delete</span> keywords, in a w=
ay becoming keywords themselves.=C2=A0 I think that it would be worthwhile =
to allow these to be scoped to namespaces or classes.<br><br>The private co=
nstructor/destructor problem is solved, because they are passed in as lambd=
as (or function pointers, at implementation discretion).<br><br>We can rede=
fine the basic implementation of the "new" keyword to be an imple=
mentation-defined template function that calls <span style=3D"font-family: =
courier new,monospace;">::operator new(size_t)</span> and does other things=
, like <span style=3D"font-family: courier new,monospace;">dynamic_cast<=
void *></span> if the type is polymorphic.=C2=A0 Overriding the global n=
ew would work by replacing this template or its overloads.<br><br><div clas=
s=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-col=
or: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: =
break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color:=
#008;" class=3D"styled-by-prettify">typename</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" cla=
ss=3D"styled-by-prettify">Type</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">typename</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Construct=
or</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">...</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;=
" class=3D"styled-by-prettify">Args</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #606;" class=3D"styled-=
by-prettify">Type</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">*<=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">operator</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">new</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">new</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Constructor</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&</span><span style=3D"color: #000;" class=3D"styled-by-prettify">con=
structor</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #606;" class=3D"styled-by-prettify">Args</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&&...</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">args</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 noexcept</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 noexcept=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">constructor</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">static_cast</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">Type</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">*>(</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">nullptr</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">)))</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&&</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 noexcept</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(::</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">operator</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">new</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">size_t</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(),</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">forward</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify"><</span><span style=3D"color: #606;" cl=
ass=3D"styled-by-prettify">Args</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">>(</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">args</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">)...)));</span></div></code></div><br><br>Melissa</div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1382_2021806374.1437507460742--
------=_Part_1381_38275595.1437507460740--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Tue, 21 Jul 2015 14:24:06 -0700
Raw View
--bcaec52d52dd2feea4051b69467a
Content-Type: text/plain; charset=UTF-8
On Tue, Jul 21, 2015 at 12:37 PM, Myriachan <myriachan@gmail.com> wrote:
> In trying to implement a custom memory allocator, there are many
> annoyances that come up that make C++ difficult to work with.
> Particularly, the syntax of the new and delete operators means that using
> a custom memory allocator often involves macros that are semantically
> different from new and delete.
>
Can you explain a bit more about the problem? It's really not clear to me
what the motivation for this change is. Why can't you / don't you want to
use a custom placement operator new for this?
> When private and protected constructors and destructors get involved,
> things get especially annoying, because the allocator code can't call the
> constructor or destructor itself.
>
> I thought of an idea that would help with this issue, though it is
> admittedly rather crazy.
>
> I would add a new type of operator new overload:
>
> template <typename Type, typename Constructor>
> Type *operator new valloc_new(const Constructor &constructor)
> noexcept(noexcept(constructor(static_cast<Type *>(nullptr))))
> {
> static_assert(alignof(Type) <= PAGE_SIZE, "only allocations of
> alignment PAGE_SIZE or less are supported") ;
>
> std::size_t headerSize = 0;
>
> // Custom implementations aren't required to use new_handlers
> void *memory = VirtualAlloc(nullptr, headerSize + sizeof(Type),
> MEM_COMMIT, PAGE_READWRITE);
> if (!memory)
> {
> throw std::bad_alloc("out of memory");
> }
>
> try
> {
> return constructor(memory);
> }
> catch (...)
> {
> VirtualFree(memory, 0, MEM_RELEASE);
> throw;
> }
> }
>
> template <typename Type, typename Destructor>
> void operator delete valloc_delete(Type *object, const Destructor &
> destructor)
> {
> if (object == nullptr)
> {
> return;
> }
>
> // Get the base address of the most-derived object
> void *memory = const_cast<std::remove_cv_t<Type> *>(object);
> if (std::is_polymorphic<Type>::value)
> {
> memory = dynamic_cast<void *>(const_cast<std::remove_cv_t<Type>
> *>(object));
> }
>
> destructor(object);
>
> VirtualFree(memory, 0, MEM_RELEASE);
> }
>
>
>
> Now valloc_new and valloc_delete in the proper scope will syntactically
> function the same way as the new and delete keywords, in a way becoming
> keywords themselves. I think that it would be worthwhile to allow these to
> be scoped to namespaces or classes.
>
> The private constructor/destructor problem is solved, because they are
> passed in as lambdas (or function pointers, at implementation discretion).
>
> We can redefine the basic implementation of the "new" keyword to be an
> implementation-defined template function that calls ::operator new(size_t)
> and does other things, like dynamic_cast<void *> if the type is
> polymorphic. Overriding the global new would work by replacing this
> template or its overloads.
>
> template <typename Type, typename Constructor, typename... Args>
> Type *operator new new(const Constructor &constructor, Args &&...args)
> noexcept(
> noexcept(constructor(static_cast<Type *>(nullptr))) &&
> noexcept(::operator new(std::size_t(), std::forward<Args>(args
> )...)));
>
>
> Melissa
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--bcaec52d52dd2feea4051b69467a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Jul 21, 2015 at 12:37 PM, Myriachan <span dir=3D"ltr"><<a href=3D"ma=
ilto:myriachan@gmail.com" target=3D"_blank">myriachan@gmail.com</a>></sp=
an> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">In trying to =
implement a custom memory allocator, there are many annoyances that come up=
that make C++ difficult to work with.=C2=A0 Particularly, the syntax of th=
e <span style=3D"font-family:courier new,monospace">new</span> and <span st=
yle=3D"font-family:courier new,monospace">delete</span> operators means tha=
t using a custom memory allocator often involves macros that are semantical=
ly different from <span style=3D"font-family:courier new,monospace">new</sp=
an> and <span style=3D"font-family:courier new,monospace">delete</span>.</d=
iv></blockquote><div><br></div><div>Can you explain a bit more about the pr=
oblem? It's really not clear to me what the motivation for this change =
is. Why can't you / don't you want to use a custom placement operat=
or new for this?</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr">When private and protected constructors and destructors get inv=
olved, things get especially annoying, because the allocator code can't=
call the constructor or destructor itself.<br><br>I thought of an idea tha=
t would help with this issue, though it is admittedly rather crazy.<br><br>=
I would add a new type of <span style=3D"font-family:courier new,monospace"=
>operator new</span> overload:<br><br><div style=3D"background-color:rgb(25=
0,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1p=
x;word-wrap:break-word"><code><div><span style=3D"color:#008">template</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660"><</span>=
<span style=3D"color:#008">typename</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#606">Type</span><span style=3D"color:#660">,</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">typename</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#606">Constructor=
</span><span style=3D"color:#660">></span><span style=3D"color:#000"><br=
></span><span style=3D"color:#606">Type</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">*</span><span style=3D"color:#008">operato=
r</span><span style=3D"color:#000"> </span><span style=3D"color:#008">new</=
span><span style=3D"color:#000"> valloc_new</span><span style=3D"color:#660=
">(</span><span style=3D"color:#008">const</span><span style=3D"color:#000"=
> </span><span style=3D"color:#606">Constructor</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">&</span><span style=3D"color:#=
000">constructor</span><span style=3D"color:#660">)</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 noexcept</span><span style=3D"color:#660">(</sp=
an><span style=3D"color:#000">noexcept</span><span style=3D"color:#660">(</=
span><span style=3D"color:#000">constructor</span><span style=3D"color:#660=
">(</span><span style=3D"color:#008">static_cast</span><span style=3D"color=
:#660"><</span><span style=3D"color:#606">Type</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">*>(</span><span style=3D"colo=
r:#008">nullptr</span><span style=3D"color:#660">))))</span><span style=3D"=
color:#000"><br></span><span style=3D"color:#660">{</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">static_assert=
</span><span style=3D"color:#660">(</span><span style=3D"color:#008">aligno=
f</span><span style=3D"color:#660">(</span><span style=3D"color:#606">Type<=
/span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660"><=3D</span><span style=3D"color:#000"> PAGE_=
SIZE</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#080">"only allocations of alignment PAGE_S=
IZE or less are supported"</span><span style=3D"color:#660">)</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"><br><br>=C2=A0 =C2=A0 std</span><span style=3D"color:#6=
60">::</span><span style=3D"color:#000">size_t headerSize </span><span styl=
e=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span style=
=3D"color:#066">0</span><span style=3D"color:#660">;</span><span style=3D"c=
olor:#000"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color:#800">// Custo=
m implementations aren't required to use new_handlers</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">void</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">*</span><=
span style=3D"color:#000">memory </span><span style=3D"color:#660">=3D</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#606">VirtualAllo=
c</span><span style=3D"color:#660">(</span><span style=3D"color:#008">nullp=
tr</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> hea=
derSize </span><span style=3D"color:#660">+</span><span style=3D"color:#000=
"> </span><span style=3D"color:#008">sizeof</span><span style=3D"color:#660=
">(</span><span style=3D"color:#606">Type</span><span style=3D"color:#660">=
),</span><span style=3D"color:#000"> MEM_COMMIT</span><span style=3D"color:=
#660">,</span><span style=3D"color:#000"> PAGE_READWRITE</span><span style=
=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </spa=
n><span style=3D"color:#008">if</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">(!</span><span style=3D"color:#000">memory</span><=
span style=3D"color:#660">)</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><b=
r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">throw</span=
><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span>=
<span style=3D"color:#000">bad_alloc</span><span style=3D"color:#660">(</sp=
an><span style=3D"color:#080">"out of memory"</span><span style=
=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </spa=
n><span style=3D"color:#660">}</span><span style=3D"color:#000"><br><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#008">try</span><span style=3D"color=
:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">{</span><span st=
yle=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"co=
lor:#008">return</span><span style=3D"color:#000"> constructor</span><span =
style=3D"color:#660">(</span><span style=3D"color:#000">memory</span><span =
style=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =
</span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:#008">catch</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">(...)</span><span style=3D"c=
olor:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">{</span><spa=
n style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color:#606">VirtualFree</span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">memory</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> </span><span style=3D"color:#066">0</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> MEM_RELEASE</span><span=
style=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0=
=C2=A0 =C2=A0 </span><span style=3D"color:#008">throw</span><span style=3D=
"color:#660">;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color:#660">}</span><span style=3D"color:#000"><br></span><spa=
n style=3D"color:#660">}</span><span style=3D"color:#000"><br><br></span><s=
pan style=3D"color:#008">template</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660"><</span><span style=3D"color:#008">typename</=
span><span style=3D"color:#000"> </span><span style=3D"color:#606">Type</sp=
an><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#008">typename</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#606">Destructor</span><span style=3D"color:#660">>=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">voi=
d</span><span style=3D"color:#000"> </span><span style=3D"color:#008">opera=
tor</span><span style=3D"color:#000"> </span><span style=3D"color:#008">del=
ete</span><span style=3D"color:#000"> valloc_delete</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#606">Type</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">*</span><span style=3D"color:#00=
8">object</span><span style=3D"color:#660">,</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#008">const</span><span style=3D"color:#000=
"> </span><span style=3D"color:#606">Destructor</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">&</span><span style=3D"color:#=
000">destructor</span><span style=3D"color:#660">)</span><span style=3D"col=
or:#000"><br></span><span style=3D"color:#660">{</span><span style=3D"color=
:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">if</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">(</span><span style=
=3D"color:#008">object</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">nullptr</span><span style=3D"color:#660">)</span><span styl=
e=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">{</spa=
n><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span s=
tyle=3D"color:#008">return</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}</=
span><span style=3D"color:#000"><br><br>=C2=A0 =C2=A0 </span><span style=3D=
"color:#800">// Get the base address of the most-derived object</span><span=
style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">v=
oid</span><span style=3D"color:#000"> </span><span style=3D"color:#660">*</=
span><span style=3D"color:#000">memory </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#008">con=
st_cast</span><span style=3D"color:#660"><</span><span style=3D"color:#0=
00">std</span><span style=3D"color:#660">::</span><span style=3D"color:#000=
">remove_cv_t</span><span style=3D"color:#660"><</span><span style=3D"co=
lor:#606">Type</span><span style=3D"color:#660">></span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">*>(</span><span style=3D"c=
olor:#008">object</span><span style=3D"color:#660">);</span><span style=3D"=
color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">if</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#000">std</span><span style=3D"color:#660">::</span><span sty=
le=3D"color:#000">is_polymorphic</span><span style=3D"color:#660"><</spa=
n><span style=3D"color:#606">Type</span><span style=3D"color:#660">>::</=
span><span style=3D"color:#000">value</span><span style=3D"color:#660">)</s=
pan><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"colo=
r:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
memory </span><span style=3D"color:#660">=3D</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#008">dynamic_cast</span><span style=3D"col=
or:#660"><</span><span style=3D"color:#008">void</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">*>(</span><span style=3D"co=
lor:#008">const_cast</span><span style=3D"color:#660"><</span><span styl=
e=3D"color:#000">std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">remove_cv_t</span><span style=3D"color:#660"><</span><sp=
an style=3D"color:#606">Type</span><span style=3D"color:#660">></span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">*>(</span><s=
pan style=3D"color:#008">object</span><span style=3D"color:#660">));</span>=
<span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#6=
60">}</span><span style=3D"color:#000"><br><br>=C2=A0 =C2=A0 destructor</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#008">object</sp=
an><span style=3D"color:#660">);</span><span style=3D"color:#000"><br><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:#606">VirtualFree</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">memory</span><span sty=
le=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D=
"color:#066">0</span><span style=3D"color:#660">,</span><span style=3D"colo=
r:#000"> MEM_RELEASE</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#660">}</span></div></code>=
</div><br><br><br>Now <span style=3D"font-family:courier new,monospace">val=
loc_new</span> and <span style=3D"font-family:courier new,monospace">valloc=
_delete</span> in the proper scope will syntactically function the same way=
as the <span style=3D"font-family:courier new,monospace">new</span> and <s=
pan style=3D"font-family:courier new,monospace">delete</span> keywords, in =
a way becoming keywords themselves.=C2=A0 I think that it would be worthwhi=
le to allow these to be scoped to namespaces or classes.<br><br>The private=
constructor/destructor problem is solved, because they are passed in as la=
mbdas (or function pointers, at implementation discretion).<br><br>We can r=
edefine the basic implementation of the "new" keyword to be an im=
plementation-defined template function that calls <span style=3D"font-famil=
y:courier new,monospace">::operator new(size_t)</span> and does other thing=
s, like <span style=3D"font-family:courier new,monospace">dynamic_cast<v=
oid *></span> if the type is polymorphic.=C2=A0 Overriding the global ne=
w would work by replacing this template or its overloads.<br><br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px;word-wrap:break-word"><code><div><span style=
=3D"color:#008">template</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660"><</span><span style=3D"color:#008">typename</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#606">Type</span><span =
style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">typename</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#606">Constructor</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">typename</span><s=
pan style=3D"color:#660">...</span><span style=3D"color:#000"> </span><span=
style=3D"color:#606">Args</span><span style=3D"color:#660">></span><spa=
n style=3D"color:#000"><br></span><span style=3D"color:#606">Type</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">*</span><span st=
yle=3D"color:#008">operator</span><span style=3D"color:#000"> </span><span =
style=3D"color:#008">new</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#008">new</span><span style=3D"color:#660">(</span><span style=
=3D"color:#008">const</span><span style=3D"color:#000"> </span><span style=
=3D"color:#606">Constructor</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">&</span><span style=3D"color:#000">constructor</sp=
an><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#606">Args</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">&&...</span><span style=3D"color:#000">args<=
/span><span style=3D"color:#660">)</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 noexcept</span><span style=3D"color:#660">(</span><span style=3D=
"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 noexcept</span><span style=3D"=
color:#660">(</span><span style=3D"color:#000">constructor</span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#008">static_cast</span><span=
style=3D"color:#660"><</span><span style=3D"color:#606">Type</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">*>(</span><spa=
n style=3D"color:#008">nullptr</span><span style=3D"color:#660">)))</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">&&</sp=
an><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 noexcept</spa=
n><span style=3D"color:#660">(::</span><span style=3D"color:#008">operator<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">new</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#000">std</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#000">size_t</span=
><span style=3D"color:#660">(),</span><span style=3D"color:#000"> std</span=
><span style=3D"color:#660">::</span><span style=3D"color:#000">forward</sp=
an><span style=3D"color:#660"><</span><span style=3D"color:#606">Args</s=
pan><span style=3D"color:#660">>(</span><span style=3D"color:#000">args<=
/span><span style=3D"color:#660">)...)));</span></div></code></div><br><br>=
Melissa</div><span class=3D"HOEnZb"><font color=3D"#888888">
<p></p>
-- <br>
<br>
--- <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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--bcaec52d52dd2feea4051b69467a--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 21 Jul 2015 17:14:50 -0700
Raw View
On Tuesday 21 July 2015 12:37:40 Myriachan wrote:
> In trying to implement a custom memory allocator, there are many annoyances
> that come up that make C++ difficult to work with. Particularly, the
> syntax of the new and delete operators means that using a custom memory
> allocator often involves macros that are semantically different from new
> and delete. When private and protected constructors and destructors get
> involved, things get especially annoying, because the allocator code can't
> call the constructor or destructor itself.
>
> I thought of an idea that would help with this issue, though it is
> admittedly rather crazy.
Besides the need for extra typing, why can't you do:
struct valloc_t {};
extern valloc_t valloc;
void *operator new(std::size_t size, valloc_t);
void operator delete(void *, valloc_t);
And thus:
auto i = new (valloc) MyObject;
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Farid Mehrabi <farid.mehrabi@gmail.com>
Date: Wed, 22 Jul 2015 20:26:35 +0430
Raw View
--001a114938b4189814051b78d32c
Content-Type: text/plain; charset=UTF-8
none-public members can only be accesses via either a member or a subclass
or a friend, so if you need to access those functions in any generic
class/function you can just make the appropriate instance a friend. One
good implementation can be a generic class/function forwarding to a member
of its operand; thus allowing library user to control implementation
throughout sub-typing(similar to new/delete):
template<typename T> my_ptr
{
template<typename ...Args> my_ptr (Args&...a):
ptr{new(T::my_new()T{a...})}
{
...//blah blah blah
};
~my_ptr()
{
...//blah blah blah
ptr->my_delete();
ptr->~T();
};
my_raw_ptr<T> ptr;
...//blah blah blah
};
No need for any new core lang feature.
regards,
FM.
2015-07-22 0:07 GMT+04:30 Myriachan <myriachan@gmail.com>:
> In trying to implement a custom memory allocator, there are many
> annoyances that come up that make C++ difficult to work with.
> Particularly, the syntax of the new and delete operators means that using
> a custom memory allocator often involves macros that are semantically
> different from new and delete. When private and protected constructors
> and destructors get involved, things get especially annoying, because the
> allocator code can't call the constructor or destructor itself.
>
> I thought of an idea that would help with this issue, though it is
> admittedly rather crazy.
>
> I would add a new type of operator new overload:
>
> template <typename Type, typename Constructor>
> Type *operator new valloc_new(const Constructor &constructor)
> noexcept(noexcept(constructor(static_cast<Type *>(nullptr))))
> {
> static_assert(alignof(Type) <= PAGE_SIZE, "only allocations of
> alignment PAGE_SIZE or less are supported") ;
>
> std::size_t headerSize = 0;
>
> // Custom implementations aren't required to use new_handlers
> void *memory = VirtualAlloc(nullptr, headerSize + sizeof(Type),
> MEM_COMMIT, PAGE_READWRITE);
> if (!memory)
> {
> throw std::bad_alloc("out of memory");
> }
>
> try
> {
> return constructor(memory);
> }
> catch (...)
> {
> VirtualFree(memory, 0, MEM_RELEASE);
> throw;
> }
> }
>
> template <typename Type, typename Destructor>
> void operator delete valloc_delete(Type *object, const Destructor &
> destructor)
> {
> if (object == nullptr)
> {
> return;
> }
>
> // Get the base address of the most-derived object
> void *memory = const_cast<std::remove_cv_t<Type> *>(object);
> if (std::is_polymorphic<Type>::value)
> {
> memory = dynamic_cast<void *>(const_cast<std::remove_cv_t<Type>
> *>(object));
> }
>
> destructor(object);
>
> VirtualFree(memory, 0, MEM_RELEASE);
> }
>
>
>
> Now valloc_new and valloc_delete in the proper scope will syntactically
> function the same way as the new and delete keywords, in a way becoming
> keywords themselves. I think that it would be worthwhile to allow these to
> be scoped to namespaces or classes.
>
> The private constructor/destructor problem is solved, because they are
> passed in as lambdas (or function pointers, at implementation discretion).
>
> We can redefine the basic implementation of the "new" keyword to be an
> implementation-defined template function that calls ::operator new(size_t)
> and does other things, like dynamic_cast<void *> if the type is
> polymorphic. Overriding the global new would work by replacing this
> template or its overloads.
>
> template <typename Type, typename Constructor, typename... Args>
> Type *operator new new(const Constructor &constructor, Args &&...args)
> noexcept(
> noexcept(constructor(static_cast<Type *>(nullptr))) &&
> noexcept(::operator new(std::size_t(), std::forward<Args>(args
> )...)));
>
>
> Melissa
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
how am I supposed to end the twisted road of your hair in such a dark
night??
unless the candle of your face does shed some light upon my way!!!
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a114938b4189814051b78d32c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"rtl"><div class=3D"gmail_default" style=3D"text-align:left;font=
-family:'arial narrow',sans-serif;font-size:large" dir=3D"ltr">none=
-public members can only be accesses via either a member or a subclass or a=
friend, so if you need to access those functions in any generic class/func=
tion you can just make the appropriate instance a friend. One good implemen=
tation can be a generic class/function forwarding to a member of its operan=
d; thus allowing library user to control implementation throughout sub-typi=
ng(similar to new/delete):</div><div class=3D"gmail_default" style=3D"text-=
align:left;font-family:'arial narrow',sans-serif;font-size:large" d=
ir=3D"ltr"><br></div><div class=3D"gmail_default" style=3D"text-align:left;=
font-family:'arial narrow',sans-serif;font-size:large" dir=3D"ltr">=
template<typename T> my_ptr</div><div class=3D"gmail_default" style=
=3D"text-align:left;font-family:'arial narrow',sans-serif;font-size=
:large" dir=3D"ltr">{</div><div class=3D"gmail_default" style=3D"text-align=
:left;font-family:'arial narrow',sans-serif;font-size:large" dir=3D=
"ltr">=C2=A0 =C2=A0 =C2=A0 template<typename ...Args> my_ptr =C2=A0 (=
Args&...a):</div><div class=3D"gmail_default" style=3D"text-align:left;=
font-family:'arial narrow',sans-serif;font-size:large" dir=3D"ltr">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ptr{new(T::my_new()T{a...}=
)}</div><div class=3D"gmail_default" style=3D"text-align:left;font-family:&=
#39;arial narrow',sans-serif;font-size:large" dir=3D"ltr">=C2=A0 =C2=A0=
=C2=A0 {</div><div class=3D"gmail_default" style=3D"text-align:left;font-f=
amily:'arial narrow',sans-serif;font-size:large" dir=3D"ltr">=C2=A0=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0...//blah blah blah</div><div cla=
ss=3D"gmail_default" style=3D"text-align:left;font-family:'arial narrow=
',sans-serif;font-size:large" dir=3D"ltr">=C2=A0 =C2=A0 =C2=A0 };</div>=
<div class=3D"gmail_default" style=3D"text-align:left;font-family:'aria=
l narrow',sans-serif;font-size:large" dir=3D"ltr">=C2=A0 =C2=A0 =C2=A0=
=C2=A0</div><div class=3D"gmail_default" style=3D"text-align:left;font-fami=
ly:'arial narrow',sans-serif;font-size:large" dir=3D"ltr">=C2=A0 =
=C2=A0 =C2=A0~my_ptr()</div><div class=3D"gmail_default" style=3D"text-alig=
n:left;font-family:'arial narrow',sans-serif;font-size:large" dir=
=3D"ltr">=C2=A0 =C2=A0 =C2=A0{</div><div class=3D"gmail_default" dir=3D"ltr=
" style=3D"font-family:'arial narrow',sans-serif;font-size:large">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0...//blah blah blah</div><d=
iv class=3D"gmail_default" style=3D"text-align:left;font-family:'arial =
narrow',sans-serif;font-size:large" dir=3D"ltr">=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 ptr->my_delete();<br></div><div class=3D"gmail_defa=
ult" style=3D"text-align:left;font-family:'arial narrow',sans-serif=
;font-size:large" dir=3D"ltr">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ptr=
->~T();</div><div class=3D"gmail_default" style=3D"text-align:left;font-=
family:'arial narrow',sans-serif;font-size:large" dir=3D"ltr">=C2=
=A0 =C2=A0 =C2=A0};</div><div class=3D"gmail_default" style=3D"text-align:l=
eft;font-family:'arial narrow',sans-serif;font-size:large" dir=3D"l=
tr"><br></div><div class=3D"gmail_default" style=3D"text-align:left;font-fa=
mily:'arial narrow',sans-serif;font-size:large" dir=3D"ltr">=C2=A0 =
=C2=A0 =C2=A0my_raw_ptr<T> ptr;</div><div class=3D"gmail_default" sty=
le=3D"text-align:left;font-family:'arial narrow',sans-serif;font-si=
ze:large" dir=3D"ltr"><div class=3D"gmail_default" dir=3D"ltr">=C2=A0 =C2=
=A0 =C2=A0...//blah blah blah</div></div><div class=3D"gmail_default" style=
=3D"text-align:left;font-family:'arial narrow',sans-serif;font-size=
:large" dir=3D"ltr">};</div><div class=3D"gmail_default" style=3D"text-alig=
n:left;font-family:'arial narrow',sans-serif;font-size:large" dir=
=3D"ltr"><br></div><div class=3D"gmail_default" style=3D"text-align:left;fo=
nt-family:'arial narrow',sans-serif;font-size:large" dir=3D"ltr">No=
need for any new core lang feature.</div><div class=3D"gmail_default" styl=
e=3D"text-align:left;font-family:'arial narrow',sans-serif;font-siz=
e:large" dir=3D"ltr"><br></div><div class=3D"gmail_default" style=3D"text-a=
lign:left;font-family:'arial narrow',sans-serif;font-size:large" di=
r=3D"ltr">regards,</div><div class=3D"gmail_default" style=3D"text-align:le=
ft;font-family:'arial narrow',sans-serif;font-size:large" dir=3D"lt=
r">FM.</div></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote"=
><div dir=3D"ltr">2015-07-22 0:07 GMT+04:30 Myriachan <span dir=3D"ltr"><=
;<a href=3D"mailto:myriachan@gmail.com" target=3D"_blank">myriachan@gmail.c=
om</a>></span>:</div><blockquote class=3D"gmail_quote" style=3D"margin:0=
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">In =
trying to implement a custom memory allocator, there are many annoyances th=
at come up that make C++ difficult to work with.=C2=A0 Particularly, the sy=
ntax of the <span style=3D"font-family:courier new,monospace">new</span> an=
d <span style=3D"font-family:courier new,monospace">delete</span> operators=
means that using a custom memory allocator often involves macros that are =
semantically different from <span style=3D"font-family:courier new,monospac=
e">new</span> and <span style=3D"font-family:courier new,monospace">delete<=
/span>.=C2=A0 When private and protected constructors and destructors get i=
nvolved, things get especially annoying, because the allocator code can'=
;t call the constructor or destructor itself.<br><br>I thought of an idea t=
hat would help with this issue, though it is admittedly rather crazy.<br><b=
r>I would add a new type of <span style=3D"font-family:courier new,monospac=
e">operator new</span> overload:<br><br><div style=3D"background-color:rgb(=
250,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:=
1px;word-wrap:break-word"><code><div><span style=3D"color:#008">template</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660"><</spa=
n><span style=3D"color:#008">typename</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#606">Type</span><span style=3D"color:#660">,</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#008">typename</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#606">Construct=
or</span><span style=3D"color:#660">></span><span style=3D"color:#000"><=
br></span><span style=3D"color:#606">Type</span><span style=3D"color:#000">=
</span><span style=3D"color:#660">*</span><span style=3D"color:#008">opera=
tor</span><span style=3D"color:#000"> </span><span style=3D"color:#008">new=
</span><span style=3D"color:#000"> valloc_new</span><span style=3D"color:#6=
60">(</span><span style=3D"color:#008">const</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#606">Constructor</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">&</span><span style=3D"color=
:#000">constructor</span><span style=3D"color:#660">)</span><span style=3D"=
color:#000"><br>=C2=A0 =C2=A0 noexcept</span><span style=3D"color:#660">(</=
span><span style=3D"color:#000">noexcept</span><span style=3D"color:#660">(=
</span><span style=3D"color:#000">constructor</span><span style=3D"color:#6=
60">(</span><span style=3D"color:#008">static_cast</span><span style=3D"col=
or:#660"><</span><span style=3D"color:#606">Type</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">*>(</span><span style=3D"co=
lor:#008">nullptr</span><span style=3D"color:#660">))))</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">static_=
assert</span><span style=3D"color:#660">(</span><span style=3D"color:#008">=
alignof</span><span style=3D"color:#660">(</span><span style=3D"color:#606"=
>Type</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660"><=3D</span><span style=3D"color:#000">=
PAGE_SIZE</span><span style=3D"color:#660">,</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#080">"only allocations of alignment =
PAGE_SIZE or less are supported"</span><span style=3D"color:#660">)</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">;</span><=
span style=3D"color:#000"><br><br>=C2=A0 =C2=A0 std</span><span style=3D"co=
lor:#660">::</span><span style=3D"color:#000">size_t headerSize </span><spa=
n style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#066">0</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color:#800">// =
Custom implementations aren't required to use new_handlers</span><span =
style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">vo=
id</span><span style=3D"color:#000"> </span><span style=3D"color:#660">*</s=
pan><span style=3D"color:#000">memory </span><span style=3D"color:#660">=3D=
</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Virtua=
lAlloc</span><span style=3D"color:#660">(</span><span style=3D"color:#008">=
nullptr</span><span style=3D"color:#660">,</span><span style=3D"color:#000"=
> headerSize </span><span style=3D"color:#660">+</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">sizeof</span><span style=3D"color=
:#660">(</span><span style=3D"color:#606">Type</span><span style=3D"color:#=
660">),</span><span style=3D"color:#000"> MEM_COMMIT</span><span style=3D"c=
olor:#660">,</span><span style=3D"color:#000"> PAGE_READWRITE</span><span s=
tyle=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 <=
/span><span style=3D"color:#008">if</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">(!</span><span style=3D"color:#000">memory</sp=
an><span style=3D"color:#660">)</span><span style=3D"color:#000"><br>=C2=A0=
=C2=A0 </span><span style=3D"color:#660">{</span><span style=3D"color:#000=
"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">throw</=
span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</s=
pan><span style=3D"color:#000">bad_alloc</span><span style=3D"color:#660">(=
</span><span style=3D"color:#080">"out of memory"</span><span sty=
le=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color:#660">}</span><span style=3D"color:#000"><br><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:#008">try</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">{</span><span=
style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D=
"color:#008">return</span><span style=3D"color:#000"> constructor</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#000">memory</span><sp=
an style=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#660">}</span><span style=3D"color:#000"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color:#008">catch</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">(...)</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">{</span=
><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span st=
yle=3D"color:#606">VirtualFree</span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#000">memory</span><span style=3D"color:#660">,</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#066">0</span><span st=
yle=3D"color:#660">,</span><span style=3D"color:#000"> MEM_RELEASE</span><s=
pan style=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">throw</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span=
><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#660">}</span><span style=3D"color:#000"><br><br></span=
><span style=3D"color:#008">template</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660"><</span><span style=3D"color:#008">typenam=
e</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Type<=
/span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">typename</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#606">Destructor</span><span style=3D"color:#660">&=
gt;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">=
void</span><span style=3D"color:#000"> </span><span style=3D"color:#008">op=
erator</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
delete</span><span style=3D"color:#000"> valloc_delete</span><span style=3D=
"color:#660">(</span><span style=3D"color:#606">Type</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">*</span><span style=3D"color:=
#008">object</span><span style=3D"color:#660">,</span><span style=3D"color:=
#000"> </span><span style=3D"color:#008">const</span><span style=3D"color:#=
000"> </span><span style=3D"color:#606">Destructor</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#660">&</span><span style=3D"colo=
r:#000">destructor</span><span style=3D"color:#660">)</span><span style=3D"=
color:#000"><br></span><span style=3D"color:#660">{</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">if</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#008">object</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#008">nullptr</span><span style=3D"color:#660">)</span><span st=
yle=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span=
style=3D"color:#008">return</span><span style=3D"color:#660">;</span><span=
style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}=
</span><span style=3D"color:#000"><br><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#800">// Get the base address of the most-derived object</span><s=
pan style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008=
">void</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
*</span><span style=3D"color:#000">memory </span><span style=3D"color:#660"=
>=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#008">co=
nst_cast</span><span style=3D"color:#660"><</span><span style=3D"color:#=
000">std</span><span style=3D"color:#660">::</span><span style=3D"color:#00=
0">remove_cv_t</span><span style=3D"color:#660"><</span><span style=3D"c=
olor:#606">Type</span><span style=3D"color:#660">></span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">*>(</span><span style=3D"=
color:#008">object</span><span style=3D"color:#660">);</span><span style=3D=
"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">if</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">std</span><span style=3D"color:#660">::</span><span st=
yle=3D"color:#000">is_polymorphic</span><span style=3D"color:#660"><</sp=
an><span style=3D"color:#606">Type</span><span style=3D"color:#660">>::<=
/span><span style=3D"color:#000">value</span><span style=3D"color:#660">)</=
span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"col=
or:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0=
memory </span><span style=3D"color:#660">=3D</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#008">dynamic_cast</span><span style=3D"co=
lor:#660"><</span><span style=3D"color:#008">void</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">*>(</span><span style=3D"c=
olor:#008">const_cast</span><span style=3D"color:#660"><</span><span sty=
le=3D"color:#000">std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">remove_cv_t</span><span style=3D"color:#660"><</span><sp=
an style=3D"color:#606">Type</span><span style=3D"color:#660">></span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">*>(</span><s=
pan style=3D"color:#008">object</span><span style=3D"color:#660">));</span>=
<span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#6=
60">}</span><span style=3D"color:#000"><br><br>=C2=A0 =C2=A0 destructor</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#008">object</sp=
an><span style=3D"color:#660">);</span><span style=3D"color:#000"><br><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:#606">VirtualFree</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">memory</span><span sty=
le=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D=
"color:#066">0</span><span style=3D"color:#660">,</span><span style=3D"colo=
r:#000"> MEM_RELEASE</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#660">}</span></div></code>=
</div><br><br><br>Now <span style=3D"font-family:courier new,monospace">val=
loc_new</span> and <span style=3D"font-family:courier new,monospace">valloc=
_delete</span> in the proper scope will syntactically function the same way=
as the <span style=3D"font-family:courier new,monospace">new</span> and <s=
pan style=3D"font-family:courier new,monospace">delete</span> keywords, in =
a way becoming keywords themselves.=C2=A0 I think that it would be worthwhi=
le to allow these to be scoped to namespaces or classes.<br><br>The private=
constructor/destructor problem is solved, because they are passed in as la=
mbdas (or function pointers, at implementation discretion).<br><br>We can r=
edefine the basic implementation of the "new" keyword to be an im=
plementation-defined template function that calls <span style=3D"font-famil=
y:courier new,monospace">::operator new(size_t)</span> and does other thing=
s, like <span style=3D"font-family:courier new,monospace">dynamic_cast<v=
oid *></span> if the type is polymorphic.=C2=A0 Overriding the global ne=
w would work by replacing this template or its overloads.<br><br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px;word-wrap:break-word"><code><div><span style=
=3D"color:#008">template</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660"><</span><span style=3D"color:#008">typename</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#606">Type</span><span =
style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">typename</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#606">Constructor</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">typename</span><s=
pan style=3D"color:#660">...</span><span style=3D"color:#000"> </span><span=
style=3D"color:#606">Args</span><span style=3D"color:#660">></span><spa=
n style=3D"color:#000"><br></span><span style=3D"color:#606">Type</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">*</span><span st=
yle=3D"color:#008">operator</span><span style=3D"color:#000"> </span><span =
style=3D"color:#008">new</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#008">new</span><span style=3D"color:#660">(</span><span style=
=3D"color:#008">const</span><span style=3D"color:#000"> </span><span style=
=3D"color:#606">Constructor</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">&</span><span style=3D"color:#000">constructor</sp=
an><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#606">Args</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">&&...</span><span style=3D"color:#000">args<=
/span><span style=3D"color:#660">)</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 noexcept</span><span style=3D"color:#660">(</span><span style=3D=
"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 noexcept</span><span style=3D"=
color:#660">(</span><span style=3D"color:#000">constructor</span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#008">static_cast</span><span=
style=3D"color:#660"><</span><span style=3D"color:#606">Type</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">*>(</span><spa=
n style=3D"color:#008">nullptr</span><span style=3D"color:#660">)))</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">&&</sp=
an><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 noexcept</spa=
n><span style=3D"color:#660">(::</span><span style=3D"color:#008">operator<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">new</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#000">std</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#000">size_t</span=
><span style=3D"color:#660">(),</span><span style=3D"color:#000"> std</span=
><span style=3D"color:#660">::</span><span style=3D"color:#000">forward</sp=
an><span style=3D"color:#660"><</span><span style=3D"color:#606">Args</s=
pan><span style=3D"color:#660">>(</span><span style=3D"color:#000">args<=
/span><span style=3D"color:#660">)...)));</span></div></code></div><br><br>=
Melissa</div><span class=3D"HOEnZb"><font color=3D"#888888">
<p></p>
-- <br>
<br>
--- <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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br><br clear=3D"all"><div><br></div>-- <b=
r><div class=3D"gmail_signature"><div dir=3D"rtl"><div><div dir=3D"ltr">how=
am I supposed to end the twisted road of=C2=A0 your hair in such a dark ni=
ght??<br>unless the candle of your face does shed some light upon my way!!!=
<br></div></div></div></div>
</div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a114938b4189814051b78d32c--
.
Author: Myriachan <myriachan@gmail.com>
Date: Wed, 22 Jul 2015 17:00:57 -0700 (PDT)
Raw View
------=_Part_105_1375384339.1437609657292
Content-Type: multipart/alternative;
boundary="----=_Part_106_45744693.1437609657292"
------=_Part_106_45744693.1437609657292
Content-Type: text/plain; charset=UTF-8
On Tuesday, July 21, 2015 at 2:24:08 PM UTC-7, Richard Smith wrote:
> Can you explain a bit more about the problem? It's really not clear to me
> what the motivation for this change is. Why can't you / don't you want to
> use a custom placement operator new for this?
>
On Tuesday, July 21, 2015 at 5:14:55 PM UTC-7, Thiago Macieira wrote:
>
> Besides the need for extra typing, why can't you do:
>
> auto i = new (valloc) MyObject;
>
>
The problem with this is that there's no good way to delete the object.
"delete i;" is incorrect, because it calls the wrong deallocator. operator
delete(void *, valloc_t) is only called when the constructor throws an
exception, not for regular deallocation.
You would need a custom delete function in order to do this. For example:
template <typename T>
void delete_valloc(T *object)
{
if (!object)
{
return;
}
void *memory = const_cast<std::remove_cv_t<T> *>(object);
if (std::is_polymorphic<T>::value)
{
memory = dynamic_cast<void *>(const_cast<std::remove_cv_t<T>
*>(object));
}
object->~T();
operator delete(memory, valloc);
}
The problem with the above is that it does not work when T::~T() is private
or protected. There is a workaround using macros, though:
template <typename T>
void delete_valloc_internal(T *object, void (*destructor)(T *))
{
if (!object)
{
return;
}
void *memory = const_cast<std::remove_cv_t<T> *>(object);
if (std::is_polymorphic<T>::value)
{
memory = dynamic_cast<void *>(const_cast<std::remove_cv_t<T>
*>(object));
}
object->~T();
operator delete(memory, valloc);
}
#define delete_valloc(...) \
::delete_valloc_internal((__VA_ARGS__), [](decltype(__VA_ARGS__)
object) { \
typedef std::remove_cv_t<decltype(*object)> Type; \
object->~Type(); \
})
Now the problem becomes that you can't use a lambda-expression with
delete_valloc(), due to the decltype(). For example, using a fake
not-really-STL container type:
delete_valloc(*some_container.find([](some_type value) -> bool { return
value == 1234; }));
However, this gets worse. When you involve array allocations, you simply
can't use "new[]" at all. Array new stores the number of elements in an
implementation-defined manner without telling the operator new[] function.
Yet, when destructing, even though there's no way to invoke something like
"delete[](valloc) object"--it isn't supported--you still need the number of
elements for calling the destructors. In order to reliably get that, you
have to save it manually, meaning that you can't use standard "new[]".
There are a lot of different annoyances with this; just like with delete, a
macro implementing "new" or "new[]" would need the lambda trick in order to
call into private constructors. Additionally, a macro would need to take
the count value as a parameter. Due to the potential for commas in the
type name or in the count expression, and because you can't have two "..."s
in macro parameter lists, the syntax can get awkward.
It is possible to do all this, but only using very awkward syntax, and with
strange restrictions. A fully-general solution like the one I suggested
would allow everything to be done in a consistent manner.
On Wednesday, July 22, 2015 at 8:57:16 AM UTC-7, Farid Mehrabi wrote:
>
> none-public members can only be accesses via either a member or a subclass
> or a friend, so if you need to access those functions in any generic
> class/function you can just make the appropriate instance a friend. One
> good implementation can be a generic class/function forwarding to a member
> of its operand; thus allowing library user to control implementation
> throughout sub-typing(similar to new/delete):
>
>
It ought not be required to use "friend" like that. That gets annoying
quickly, and impedes reuse of libraries.
Melissa
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_106_45744693.1437609657292
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, July 21, 2015 at 2:24:08 PM UTC-7, Richard Smi=
th wrote:<br><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1=
px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote"><div=
>Can
you explain a bit more about the problem? It's really not clear to me=
=20
what the motivation for this change is. Why can't you / don't you w=
ant=20
to use a custom placement operator new for this?</div></blockquote><br>On T=
uesday, July 21, 2015 at 5:14:55 PM UTC-7, Thiago Macieira wrote:<blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;">Besides the need for extra typing, why c=
an't you do:
<br>
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0auto i =3D new (valloc)=
MyObject;
<br><br></blockquote><div>=C2=A0<br>The problem with this is that there'=
;s no good way to delete the object.=C2=A0 "delete i;" is incorre=
ct, because it calls the wrong deallocator.=C2=A0 operator delete(void *, v=
alloc_t) is only called when the constructor throws an exception, not for r=
egular deallocation.<br><br>You would need a custom delete function in orde=
r to do this.=C2=A0 For example:<br><br>template <typename T><br>void=
delete_valloc(T *object)<br>{<br>=C2=A0=C2=A0=C2=A0 if (!object)<br>=C2=A0=
=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return;<br>=C2=
=A0=C2=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 void *memory =3D const_cast<=
std::remove_cv_t<T> *>(object);<br>=C2=A0=C2=A0=C2=A0 if (std::is_=
polymorphic<T>::value)<br>=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 memory =3D dynamic_cast<void *>(const_cast&l=
t;std::remove_cv_t<T> *>(object));<br>=C2=A0=C2=A0=C2=A0 }<br>=C2=
=A0=C2=A0=C2=A0 object->~T();<br>=C2=A0=C2=A0=C2=A0 operator delete(memo=
ry, valloc);<br>}<br><br>The problem with the above is that it does not wor=
k when T::~T() is private or protected.=C2=A0 There is a workaround using m=
acros, though:<br><br>template <typename T><br>void delete_valloc_int=
ernal(T *object, void (*destructor)(T *))<br>{<br>=C2=A0=C2=A0=C2=A0 if (!o=
bject)<br>=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 return;<br>=C2=A0=C2=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 void *memory =
=3D const_cast<std::remove_cv_t<T> *>(object);<br>=C2=A0=C2=A0=
=C2=A0 if (std::is_polymorphic<T>::value)<br>=C2=A0=C2=A0=C2=A0 {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 memory =3D dynamic_cast<void =
*>(const_cast<std::remove_cv_t<T> *>(object));<br>=C2=A0=C2=
=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 object->~T();<br>=C2=A0=C2=A0=C2=A0 op=
erator delete(memory, valloc);<br>}<br><br>#define delete_valloc(...) \<br>=
=C2=A0=C2=A0=C2=A0 ::delete_valloc_internal((__VA_ARGS__), [](decltype(__VA=
_ARGS__) object) { \<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 typedef =
std::remove_cv_t<decltype(*object)> Type; \<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 object->~Type(); \<br>=C2=A0=C2=A0=C2=A0 })<br><br=
>Now the problem becomes that you can't use a lambda-expression with de=
lete_valloc(), due to the decltype().=C2=A0 For example, using a fake not-r=
eally-STL container type:<br><br>delete_valloc(*some_container.find([](some=
_type value) -> bool { return value =3D=3D 1234; }));<br><br>However, th=
is gets worse.=C2=A0 When you involve array allocations, you simply can'=
;t use "new[]" at all.=C2=A0 Array new stores the number of eleme=
nts in an implementation-defined manner without telling the operator new[] =
function.=C2=A0 Yet, when destructing, even though there's no way to in=
voke something like "delete[](valloc) object"--it isn't suppo=
rted--you still need the number of elements for calling the destructors.=C2=
=A0 In order to reliably get that, you have to save it manually, meaning th=
at you can't use standard "new[]".<br><br>There are a lot of =
different annoyances with this; just like with delete, a macro implementing=
"new" or "new[]" would need the lambda trick in order =
to call into private constructors.=C2=A0 Additionally, a macro would need t=
o take the count value as a parameter.=C2=A0 Due to the potential for comma=
s in the type name or in the count expression, and because you can't ha=
ve two "..."s in macro parameter lists, the syntax can get awkwar=
d.<br><br>It is possible to do all this, but only using very awkward syntax=
, and with strange restrictions.=C2=A0 A fully-general solution like the on=
e I suggested would allow everything to be done in a consistent manner.<br>=
<br></div>On Wednesday, July 22, 2015 at 8:57:16 AM UTC-7, Farid Mehrabi wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"rtl"><div styl=
e=3D"text-align: left;" dir=3D"ltr"><font size=3D"2"><span style=3D"font-fa=
mily: arial,sans-serif;">none-public members can only be accesses via eithe=
r a member or a subclass or a friend, so if you need to access those functi=
ons in any generic class/function you can just make the appropriate instanc=
e a friend. One good implementation can be a generic class/function forward=
ing to a member of its operand; thus allowing library user to control imple=
mentation throughout sub-typing(similar to new/delete):</span></font></div>=
<div style=3D"text-align:left;font-family:'arial narrow',sans-serif=
;font-size:large" dir=3D"ltr"><br></div></div></blockquote><div>=C2=A0<br>I=
t ought not be required to use "friend" like that.=C2=A0 That get=
s annoying quickly, and impedes reuse of libraries.<br><br>Melissa<br></div=
></div>
<p></p>
-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_106_45744693.1437609657292--
------=_Part_105_1375384339.1437609657292--
.