Topic: Thoughts on more complete delegate/function system


Author: mihailnajdenov@gmail.com
Date: Wed, 20 Dec 2017 04:46:47 -0800 (PST)
Raw View
------=_Part_2343_1535643428.1513774007293
Content-Type: multipart/alternative;
 boundary="----=_Part_2344_1734646187.1513774007294"

------=_Part_2344_1734646187.1513774007294
Content-Type: text/plain; charset="UTF-8"

Hello, here is some thoughts of what I consider a 'a more complete"
delegate system (not ordered by importance and probably missing some points)

   1. Have a way to declare pure call-only interface, aka function_view.
   This will be more safe version the C function pointer and/or function
   pointer + void*
   2. Have a way to declare delegate-storing interface, where I intend to
   store the delegate I am passed for future use. However, it would be really,
   *really* nice not to be locked in particular implementation like, for
   instance std::function
   3. Have control over the delegate storage, in particular allocations.
   Much like we have std::vector and std::array - sometimes a fixed, non
   allocation size is needed, sometimes it is not. But these are not the only
   options - a CoW might be preferred solution to use, as said - it would be
   *really* nice not to be locked in a implementation of delegate storage -
   fixed-sized, dynamic-sized, small-object-optimized, CoW,
   read-only-ref-counted - all make sense at some point and on some scenarios!
   4. Being able to store any callable object, be it copyable or
   movebale-only
   5. Function argument and return type conversions should just work like a
   normal function call, overloads should work also.

I might be missing some points, but still think a system like this would be
very powerful, making the delegate a first class object.

I must note, I don't consider template argument a delegate - it is just a
placeholder for a potential delegate implementation.

*About a possible implementation*

One look of the requirements, it becomes apparent - no single class will
ever be able to fulfill the list.
But what if we split this into three fundamental classes:

   - function view
   - owning function view
   - function target

And here is an important note -* none of these make any memory allocations*.
All they care is type erasure on the original callable, but type-safe
invocations of it.

Let's elaborate on these

*Function view* - it wraps any callable and deals only with pointers. It
constructs itself implicitly for any callable object. The size is* tiny, *trivially
copyable as it deals with (non owning) pointers

void call(function_view<void(int)> f)
{
  f(12);
}

using fp = void(*)(int);
fp = ...;

// call ANYTHING with as little overhead as possible (no allocations, no
templates, one pointer indirection)

call(fp);

call([](int){});

call(MyFunction{&c, &C::memberfunc});



*Owning function view *- it wraps any callable and provides an interface to
store the original callable. This interface is either a reference to a
Function Target of an owning concrete delegate OR a non-owning Function
Target which wraps an anonymous callable.
Size is *small, *trivially copyable as it deals with (non owning) pointers
in either way.

void possible_store(owning_function_view<void(int)> f)
{
  if(something)
   auto copy = MyFunction(f); //< commit to representation (copies from
target, allocates)
  else
    store_other(f); //< pass along
}

possible_store(MyFunction{}); //< will bind to existing Function Target (no
allocations)

possible_store([](int){}) //< will init a Function Target, as reference to
the lambda object (no allocations)



*Function Target.* This class is weird. It "stores" the original callable
in type-erased fashion with two caveats.
First it is not typed erased in terms of calling the original object, so it
is safe to call the target with the original arguments and a pointer to the
original object. It is type-erased only on the original object type.
Second  it actually does not store anything - it just knows how to
reproduce the original object, but does no longer has any idea of its type.

To have a copy of the original object, one must feed Function Target memory
- Function Target will tell you how much of it and it will recreate the
object in that memory the correct way, alignment and everything.

And that is the base.

At this point we have separation b/w what delegate is - a type erased
callable object on one side, and its storage on the other.
Consuming a target, we can have n-number of different real delegate classes
with relatively low cost in terms of code bloat, as all concrete delegates
will share the common, (partially) type erased Target.

We can have a functor of fixed size, capable of storing from just few
dozens bytes (for pmf use) to big functor, intended to be part of some
class, already heap allocated, so no extra allocations will be needed (a
class, implementing an interface, like QRunnable for instance)
We can have a classical, std::function like implementation with a SBO, or
we can have a CoW implementation.

All these need to just consume a target by coping/moving the original
object into private memory.

template<class R, class... A>
struct SomeFunc<R(A...)>
{
   ...
   using F = TargetFactory<R(A...)>; //< all implementation reuse the same,
for this signature, Target implementation

  SomeFunc(const typename F::Target& t)
  {
    this->allocate(t.size());

    this->_target = F::createTargetAsCopyIn(this->data(), this->size(), t);
  }
  ...
};


SomeFunc can use any storage policy it wants!

*If a Allocators are to be used, it is here, *not as part of a core concept
class*. *


*Some code*

I have a crude, incomplete, and possibly buggy implementation
here: https://wandbox.org/nojs/gcc-7.2.0/permlink/fFRJRe3FSqBPtkdA

Note that, the names in the code are different from the above used (it is
too bug-prone to rename in Wandbox);

function_view => Fn
owning_function_view => OwningFnRef
Function Target => Storage
TargetFactory => Fn is reused


It also has some simple trivial implementations of concrete delegates

FixedFunc<Signature, Size> - for fixed storage functors
DynamicFunc<Signature> - for auto-resizable functors;

But these are not the main point - many other and better can be written.

Not implemented:
I don't support moving the original callable (if it is move-only, though
the Target/Storage itself can be moved around, but not copied (as it is
owning)).
I don't have support for trivially copyable callables, but I am not sure if
it is really needed (might be microoptimization)
Finally, I don't do any transformation on the signature.
All these are trivial expect the last one - it will be a template hell even
if possible.


*Conclusion*

Although, to pass callable object around, templates serve well in library
code, in user code they often are not acceptable interface change.
A callable interface, not depending on the type of the callable, will
always be needed, even more so today, when the type might be unknown like
in the case of lambdas and the popularity of functional programming.

But because the requirement for such a class are so broad, implementations
of it tend to be heavyweight, hard to define (does it need allocator?) and
not fitting all needs.

I believe, by defining well few core traits of such objects, we can have
multiple concrete implementations of these traits.

Not unlike the way we can have multiple string representations (and
basically all are interchangeable by a way of some sort of coping), only
because we have the base of char* + size + encoding.

The point is to have something similar, a base representation of a
callable, so that *Target to a delegate implementation should be what is
char* + size + encoding to a string implementation.*
This can radically change things for the better.


That wraps it up, thanks for Your time.


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

------=_Part_2344_1734646187.1513774007294
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hello, here is some thoughts of what I consider a &#3=
9;a more complete&quot; delegate system (not ordered by importance and prob=
ably missing some points)</div><ol><li>Have a way to declare pure call-only=
 interface, aka function_view. This will be more safe version the C functio=
n pointer and/or function pointer + void*</li><li>Have a way to declare del=
egate-storing interface, where I intend to store the delegate I am passed f=
or future use. However, it would be really, <i>really</i> nice not to be lo=
cked in particular implementation like, for instance std::function</li><li>=
Have control over the delegate storage, in particular allocations. Much lik=
e we have std::vector and std::array - sometimes a fixed, non allocation si=
ze is needed, sometimes it is not. But these are not the only options - a C=
oW might be preferred solution to use, as said - it would be <i>really</i> =
nice not to be locked in a implementation of delegate storage - fixed-sized=
, dynamic-sized, small-object-optimized, CoW, read-only-ref-counted - all m=
ake sense at some point and on some scenarios!=C2=A0</li><li>Being able to =
store any callable object, be it copyable or movebale-only</li><li>Function=
 argument and return type conversions should just work like a normal functi=
on call, overloads should work also.</li></ol><div>I might be missing some =
points, but still think a system like this would be very powerful, making t=
he delegate a first class object.</div><div><br></div><div> <span style=3D"=
display: inline !important; float: none; background-color: transparent; col=
or: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,s=
ans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-=
weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-dec=
oration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-=
width: 0px; white-space: normal; word-spacing: 0px;">I must note, I don&#39=
;t consider template argument a delegate - it is just a placeholder for a p=
otential delegate implementation.=C2=A0</span></div><div><b><br></b></div><=
div><b><font size=3D"4">About a possible implementation</font></b></div><di=
v><b><font size=3D"4"><br></font></b></div><div>One look of the requirement=
s, it becomes apparent - no single class will ever be able to fulfill the l=
ist.=C2=A0</div><div>But what if we split this into three fundamental class=
es:</div><ul><li>function <span style=3D"display: inline !important; float:=
 none; background-color: transparent; color: rgb(34, 34, 34); font-family: =
&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-s=
tyle: normal; font-variant: normal; font-weight: 400; letter-spacing: norma=
l; line-height: 17px; orphans: 2; text-align: left; text-decoration: none; =
text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; whi=
te-space: normal; word-spacing: 0px;">view</span></li><li><span style=3D"di=
splay: inline !important; float: none; background-color: transparent; color=
: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,san=
s-serif; font-size: 13px; font-style: normal; font-variant: normal; font-we=
ight: 400; letter-spacing: normal; line-height: 17px; orphans: 2; text-alig=
n: left; text-decoration: none; text-indent: 0px; text-transform: none; -we=
bkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">ownin=
g function view</span></li><li><span style=3D"display: inline !important; f=
loat: none; background-color: transparent; color: rgb(34, 34, 34); font-fam=
ily: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; f=
ont-style: normal; font-variant: normal; font-weight: 400; letter-spacing: =
normal; line-height: 17px; orphans: 2; text-align: left; text-decoration: n=
one; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px=
; white-space: normal; word-spacing: 0px;">function target</span></li></ul>=
<div>And here is an important note -<i> none of these make any memory alloc=
ations</i>. All they care is type erasure on the original callable, but typ=
e-safe invocations of it.</div><div><br></div><div>Let&#39;s elaborate on t=
hese</div><div><br></div><div><b>Function view</b> - it wraps any callable =
and deals only with pointers. It constructs itself implicitly for any calla=
ble object. The size is<b> tiny, </b><span style=3D"display: inline !import=
ant; float: none; background-color: transparent; color: rgb(34, 34, 34); fo=
nt-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 1=
3px; font-style: normal; font-variant: normal; font-weight: 400; letter-spa=
cing: normal; orphans: 2; text-align: left; text-decoration: none; text-ind=
ent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space=
: normal; word-spacing: 0px;">trivially copyable as it deals with (non owni=
ng) pointers</span></div><div><b><i><br></i></b></div><div class=3D"prettyp=
rint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word;=
 background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div cl=
ass=3D"subprettyprint"><span class=3D"styled-by-prettify" style=3D"color: #=
008;">void</span><span class=3D"styled-by-prettify" style=3D"color: #000;">=
 call</span><span class=3D"styled-by-prettify" style=3D"color: #660;">(</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #000;">function_view<=
/span><span class=3D"styled-by-prettify" style=3D"color: #660;">&lt;</span>=
<span class=3D"styled-by-prettify" style=3D"color: #008;">void</span><span =
class=3D"styled-by-prettify" style=3D"color: #660;">(</span><span class=3D"=
styled-by-prettify" style=3D"color: #008;">int</span><span class=3D"styled-=
by-prettify" style=3D"color: #660;">)&gt;</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #000;"> f</span><span class=3D"styled-by-prettify" =
style=3D"color: #660;">)</span><span class=3D"styled-by-prettify" style=3D"=
color: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"color:=
 #660;">{</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><=
br>=C2=A0 f</span><span class=3D"styled-by-prettify" style=3D"color: #660;"=
>(</span><span class=3D"styled-by-prettify" style=3D"color: #066;">12</span=
><span class=3D"styled-by-prettify" style=3D"color: #660;">);</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=
=3D"styled-by-prettify" style=3D"color: #660;">}</span><span class=3D"style=
d-by-prettify" style=3D"color: #000;"><br><br></span><span class=3D"styled-=
by-prettify" style=3D"color: #008;">using</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #000;"> fp </span><span class=3D"styled-by-prettify=
" style=3D"color: #660;">=3D</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color=
: #008;">void</span><span class=3D"styled-by-prettify" style=3D"color: #660=
;">(*)(</span><span class=3D"styled-by-prettify" style=3D"color: #008;">int=
</span><span class=3D"styled-by-prettify" style=3D"color: #660;">);</span><=
span class=3D"styled-by-prettify" style=3D"color: #000;"><br>fp </span><spa=
n class=3D"styled-by-prettify" style=3D"color: #660;">=3D</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"style=
d-by-prettify" style=3D"color: #660;">...;</span><span class=3D"styled-by-p=
rettify" style=3D"color: #000;"><br><br></span><span class=3D"styled-by-pre=
ttify" style=3D"color: #800;">// call ANYTHING with as little overhead as p=
ossible (no allocations, no templates, one pointer indirection)</span><span=
 class=3D"styled-by-prettify" style=3D"color: #000;"><br><br>call</span><sp=
an class=3D"styled-by-prettify" style=3D"color: #660;">(</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;">fp</span><span class=3D"styl=
ed-by-prettify" style=3D"color: #660;">);</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #000;"><br><br>call</span><span class=3D"styled-by-=
prettify" style=3D"color: #660;">([](</span><span class=3D"styled-by-pretti=
fy" style=3D"color: #008;">int</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #660;">){});</span><span class=3D"styled-by-prettify" style=3D=
"color: #000;"><br><br>call</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">(</span><span class=3D"styled-by-prettify" style=3D"color=
: #606;">MyFunction</span><span class=3D"styled-by-prettify" style=3D"color=
: #660;">{&amp;</span><span class=3D"styled-by-prettify" style=3D"color: #0=
00;">c</span><span class=3D"styled-by-prettify" style=3D"color: #660;">,</s=
pan><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span=
 class=3D"styled-by-prettify" style=3D"color: #660;">&amp;</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #000;">C</span><span class=3D"styl=
ed-by-prettify" style=3D"color: #660;">::</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #000;">memberfunc</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #660;">});</span><span class=3D"styled-by-prettify"=
 style=3D"color: #000;"><br><br></span></div></code></div><div><br></div><d=
iv><br></div><div><b>Owning function view </b>-<span style=3D"display: inli=
ne !important; float: none; background-color: transparent; color: rgb(34, 3=
4, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; fo=
nt-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; =
letter-spacing: normal; orphans: 2; text-align: left; text-decoration: none=
; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; w=
hite-space: normal; word-spacing: 0px;"> it wraps any callable and provides=
 an interface to store the original <span style=3D"display: inline !importa=
nt; float: none; background-color: transparent; color: rgb(34, 34, 34); fon=
t-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13=
px; font-style: normal; font-variant: normal; font-weight: 400; letter-spac=
ing: normal; orphans: 2; text-align: left; text-decoration: none; text-inde=
nt: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space:=
 normal; word-spacing: 0px;">callable.</span> This interface is either a re=
ference to a Function Target of an owning concrete delegate OR a non-owning=
 Function Target which wraps an anonymous callable. </span></div><div><span=
 style=3D"display: inline !important; float: none; background-color: transp=
arent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helveti=
ca&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: nor=
mal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left=
; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-te=
xt-stroke-width: 0px; white-space: normal; word-spacing: 0px;">Size is <b>s=
mall, </b>trivially copyable as it deals with (non owning) pointers in eith=
er way.</span></div><div><span style=3D"display: inline !important; float: =
none; background-color: transparent; color: rgb(34, 34, 34); font-family: &=
quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-st=
yle: normal; font-variant: normal; font-weight: 400; letter-spacing: normal=
; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; te=
xt-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; wo=
rd-spacing: 0px;"><br></span></div><div><div class=3D"subprettyprint"><div =
class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-w=
rap: break-word; background-color: rgb(250, 250, 250);"><span style=3D"text=
-align: left; color: rgb(34, 34, 34); text-transform: none; text-indent: 0p=
x; letter-spacing: normal; font-family: &quot;Arial&quot;,&quot;Helvetica&q=
uot;,sans-serif; font-size: 13px; font-variant: normal; word-spacing: 0px; =
display: inline !important; white-space: normal; orphans: 2; float: none; -=
webkit-text-stroke-width: 0px; background-color: transparent;"><code class=
=3D"prettyprint"><span class=3D"styled-by-prettify" style=3D"color: #008;">=
void</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> possi=
ble_store</span><span class=3D"styled-by-prettify" style=3D"color: #660;">(=
</span><span class=3D"styled-by-prettify" style=3D"color: #000;">owning_fun=
ction_view</span><span class=3D"styled-by-prettify" style=3D"color: #660;">=
&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #008;">void</=
span><span class=3D"styled-by-prettify" style=3D"color: #660;">(</span><spa=
n class=3D"styled-by-prettify" style=3D"color: #008;">int</span><span class=
=3D"styled-by-prettify" style=3D"color: #660;">)&gt;</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #000;"> f</span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">)</span><span class=3D"styled-by-prettify=
" style=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" styl=
e=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #000;"><br>=C2=A0 </span><span class=3D"styled-by-prettify" style=3D"col=
or: #008;">if</span><span class=3D"styled-by-prettify" style=3D"color: #660=
;">(</span><span class=3D"styled-by-prettify" style=3D"color: #000;">someth=
ing</span><span class=3D"styled-by-prettify" style=3D"color: #660;">)</span=
><span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=
=A0</span><span class=3D"styled-by-prettify" style=3D"color: #008;">auto</s=
pan><span class=3D"styled-by-prettify" style=3D"color: #000;"> copy </span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">=3D</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"s=
tyled-by-prettify" style=3D"color: #606;">MyFunction</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">(</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;">f</span><span class=3D"styled-by-prettify"=
 style=3D"color: #660;">);</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color=
: #800;">//&lt; commit to representation (copies from target, allocates)</s=
pan><span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 </=
span><span class=3D"styled-by-prettify" style=3D"color: #008;">else</span><=
span class=3D"styled-by-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 =
store_other</span><span class=3D"styled-by-prettify" style=3D"color: #660;"=
>(</span><span class=3D"styled-by-prettify" style=3D"color: #000;">f</span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">);</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"st=
yled-by-prettify" style=3D"color: #800;">//&lt; pass along</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">}</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"><br><br></span><span style=3D"display: inl=
ine !important; float: none; background-color: transparent; color: rgb(0, 0=
, 0); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font=
-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; le=
tter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; =
text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; whi=
te-space: normal; word-spacing: 0px;"><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;">possible_store</span><span class=3D"styled-by-prettify=
" style=3D"color: #660;">(</span><span class=3D"styled-by-prettify" style=
=3D"color: #606;">MyFunction</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">{});</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;"> </span><span>//&lt; will bind to existing Function Target=C2=
=A0<span style=3D"display: inline !important; float: none; background-color=
: transparent; color: rgb(136, 0, 0); font-family: &quot;Arial&quot;,&quot;=
Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-varia=
nt: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-alig=
n: left; text-decoration: none; text-indent: 0px; text-transform: none; -we=
bkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">(no a=
llocations)</span><b><i><u><sub><sup><strike><br></strike></sup></sub></u><=
/i></b></span><span><span class=3D"styled-by-prettify" style=3D"color: #000=
;"><br>possible_store</span><span class=3D"styled-by-prettify" style=3D"col=
or: #660;">([](</span><span class=3D"styled-by-prettify" style=3D"color: #0=
08;">int</span><span class=3D"styled-by-prettify" style=3D"color: #660;">){=
})</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span>=
<span class=3D"styled-by-prettify" style=3D"color: #800;">//&lt; will init =
a Function Target, as reference to the lambda object (no allocations)<br><b=
r></span></span></span></code></span></div></div></div><div><i><b><br></b><=
/i></div><div><br></div><div><b>Function Target.</b> This class is weird. I=
t &quot;stores&quot; the original callable in type-erased fashion with two =
caveats. </div><div>First it is not typed erased in terms of calling the or=
iginal object, so it is safe to call the target with the original arguments=
 and a pointer to the original object<span style=3D"text-align: left; color=
: rgb(34, 34, 34); text-transform: none; text-indent: 0px; letter-spacing: =
normal; font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; fo=
nt-size: 13px; font-style: normal; font-variant: normal; text-decoration: n=
one; word-spacing: 0px; display: inline !important; white-space: normal; or=
phans: 2; float: none; -webkit-text-stroke-width: 0px; background-color: tr=
ansparent;">. It is type-erased only on the original object type.</span></d=
iv><div><span style=3D"text-align: left; color: rgb(34, 34, 34); text-trans=
form: none; text-indent: 0px; letter-spacing: normal; font-family: &quot;Ar=
ial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: no=
rmal; font-variant: normal; text-decoration: none; word-spacing: 0px; displ=
ay: inline !important; white-space: normal; orphans: 2; float: none; -webki=
t-text-stroke-width: 0px; background-color: transparent;">Second=C2=A0 it a=
ctually does not store anything - it just knows how to reproduce the origin=
al object, but does no longer has any idea of its type.</span></div><div><s=
pan style=3D"text-align: left; color: rgb(34, 34, 34); text-transform: none=
; text-indent: 0px; letter-spacing: normal; font-family: &quot;Arial&quot;,=
&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font=
-variant: normal; text-decoration: none; word-spacing: 0px; display: inline=
 !important; white-space: normal; orphans: 2; float: none; -webkit-text-str=
oke-width: 0px; background-color: transparent;"><br></span></div><div><span=
 style=3D"text-align: left; color: rgb(34, 34, 34); text-transform: none; t=
ext-indent: 0px; letter-spacing: normal; font-family: &quot;Arial&quot;,&qu=
ot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-va=
riant: normal; text-decoration: none; word-spacing: 0px; display: inline !i=
mportant; white-space: normal; orphans: 2; float: none; -webkit-text-stroke=
-width: 0px; background-color: transparent;">To have a copy of the original=
 object, one must feed Function Target memory - <span style=3D"display: inl=
ine !important; float: none; background-color: transparent; color: rgb(34, =
34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; f=
ont-size: 13px; font-style: normal; font-variant: normal; font-weight: 400;=
 letter-spacing: normal; orphans: 2; text-align: left; text-decoration: non=
e; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; =
white-space: normal; word-spacing: 0px;">Function Target will tell you how =
much of it and it will recreate the object in that memory the correct way, =
alignment and everything.</span></span></div><div><span style=3D"text-align=
: left; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; let=
ter-spacing: normal; font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,s=
ans-serif; font-size: 13px; font-style: normal; font-variant: normal; text-=
decoration: none; word-spacing: 0px; display: inline !important; white-spac=
e: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; backgro=
und-color: transparent;"><br></span></div><div><span style=3D"text-align: l=
eft; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; letter=
-spacing: normal; font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans=
-serif; font-size: 13px; font-style: normal; font-variant: normal; text-dec=
oration: none; word-spacing: 0px; display: inline !important; white-space: =
normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; background=
-color: transparent;">And that is the base.</span></div><div><span style=3D=
"text-align: left; color: rgb(34, 34, 34); text-transform: none; text-inden=
t: 0px; letter-spacing: normal; font-family: &quot;Arial&quot;,&quot;Helvet=
ica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: no=
rmal; text-decoration: none; word-spacing: 0px; display: inline !important;=
 white-space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0=
px; background-color: transparent;"><br></span></div><div><span style=3D"te=
xt-align: left; color: rgb(34, 34, 34); text-transform: none; text-indent: =
0px; letter-spacing: normal; font-family: &quot;Arial&quot;,&quot;Helvetica=
&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: norma=
l; text-decoration: none; word-spacing: 0px; display: inline !important; wh=
ite-space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px;=
 background-color: transparent;">At this point we have separation b/w what =
delegate is - a type erased callable object on one side, and its storage on=
 the other.=C2=A0</span></div><div><span style=3D"text-align: left; color: =
rgb(34, 34, 34); text-transform: none; text-indent: 0px; letter-spacing: no=
rmal; font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font=
-size: 13px; font-style: normal; font-variant: normal; text-decoration: non=
e; word-spacing: 0px; display: inline !important; white-space: normal; orph=
ans: 2; float: none; -webkit-text-stroke-width: 0px; background-color: tran=
sparent;">Consuming a target, we can have n-number of different real delega=
te classes with relatively low cost in terms of code bloat, as all concrete=
 delegates will share the common, (partially) type erased Target.</span></d=
iv><div><span style=3D"text-align: left; color: rgb(34, 34, 34); text-trans=
form: none; text-indent: 0px; letter-spacing: normal; font-family: &quot;Ar=
ial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: no=
rmal; font-variant: normal; text-decoration: none; word-spacing: 0px; displ=
ay: inline !important; white-space: normal; orphans: 2; float: none; -webki=
t-text-stroke-width: 0px; background-color: transparent;"><br></span></div>=
<div><span style=3D"text-align: left; color: rgb(34, 34, 34); text-transfor=
m: none; text-indent: 0px; letter-spacing: normal; font-family: &quot;Arial=
&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: norma=
l; font-variant: normal; text-decoration: none; word-spacing: 0px; display:=
 inline !important; white-space: normal; orphans: 2; float: none; -webkit-t=
ext-stroke-width: 0px; background-color: transparent;">We can have a functo=
r of fixed size, capable of storing from just few dozens bytes (for pmf use=
) to big functor, intended to be part of some class, already heap allocated=
, so no extra allocations will be needed (a class, implementing an interfac=
e, like QRunnable for instance)</span></div><div><span style=3D"text-align:=
 left; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; lett=
er-spacing: normal; font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sa=
ns-serif; font-size: 13px; font-style: normal; font-variant: normal; text-d=
ecoration: none; word-spacing: 0px; display: inline !important; white-space=
: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; backgrou=
nd-color: transparent;">We can have a classical, std::function like impleme=
ntation with a SBO, or we can have a CoW implementation.</span></div><div><=
span style=3D"text-align: left; color: rgb(34, 34, 34); text-transform: non=
e; text-indent: 0px; letter-spacing: normal; font-family: &quot;Arial&quot;=
,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; fon=
t-variant: normal; text-decoration: none; word-spacing: 0px; display: inlin=
e !important; white-space: normal; orphans: 2; float: none; -webkit-text-st=
roke-width: 0px; background-color: transparent;"><br></span></div><div><spa=
n style=3D"text-align: left; color: rgb(34, 34, 34); text-transform: none; =
text-indent: 0px; letter-spacing: normal; font-family: &quot;Arial&quot;,&q=
uot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-v=
ariant: normal; text-decoration: none; word-spacing: 0px; display: inline !=
important; white-space: normal; orphans: 2; float: none; -webkit-text-strok=
e-width: 0px; background-color: transparent;">All these need to just consum=
e a target by coping/moving the original object into private memory.</span>=
</div><div><span style=3D"text-align: left; color: rgb(34, 34, 34); text-tr=
ansform: none; text-indent: 0px; letter-spacing: normal; font-family: &quot=
;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style:=
 normal; font-variant: normal; text-decoration: none; word-spacing: 0px; di=
splay: inline !important; white-space: normal; orphans: 2; float: none; -we=
bkit-text-stroke-width: 0px; background-color: transparent;"><br></span></d=
iv><div><span style=3D"text-align: left; color: rgb(34, 34, 34); text-trans=
form: none; text-indent: 0px; letter-spacing: normal; font-family: &quot;Ar=
ial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: no=
rmal; font-variant: normal; text-decoration: none; word-spacing: 0px; displ=
ay: inline !important; white-space: normal; orphans: 2; float: none; -webki=
t-text-stroke-width: 0px; background-color: transparent;"><div class=3D"pre=
ttyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-w=
ord; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><di=
v class=3D"subprettyprint"><span class=3D"styled-by-prettify" style=3D"colo=
r: #606;"><font color=3D"#004000" face=3D"Arial" style=3D"background-color:=
 transparent;">template&lt;class R, class... A&gt;<br>struct SomeFunc&lt;R(=
A...)&gt;<br>{</font></span></div><div class=3D"subprettyprint"><span class=
=3D"styled-by-prettify" style=3D"color: #606;"><font color=3D"#004000" face=
=3D"Arial" style=3D"background-color: transparent;">=C2=A0=C2=A0 ...<br>=C2=
=A0=C2=A0 using F =3D=C2=A0<span style=3D"display: inline !important; float=
: none; background-color: transparent; color: rgb(0, 64, 0); font-family: A=
rial; font-size: 13px; font-style: normal; font-variant: normal; font-weigh=
t: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decorati=
on: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width=
: 0px; white-space: normal; word-spacing: 0px;">TargetFactory&lt;R(A...)&gt=
;; //&lt; all implementation reuse the same, for this signature, Target imp=
lementation</span><br>=C2=A0=C2=A0<br></font></span></div><div class=3D"sub=
prettyprint"><span class=3D"styled-by-prettify" style=3D"color: #606;"><fon=
t color=3D"#004000" face=3D"Arial" style=3D"background-color: transparent;"=
>=C2=A0 <span style=3D"display: inline !important; float: none; background-=
color: transparent; color: rgb(0, 64, 0); font-family: Arial; font-size: 13=
px; font-style: normal; font-variant: normal; font-weight: 400; letter-spac=
ing: normal; orphans: 2; text-align: left; text-decoration: none; text-inde=
nt: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space:=
 normal; word-spacing: 0px;">SomeFunc</span>(const typename F::Target&amp; =
t)<br>=C2=A0 {<br>=C2=A0 =C2=A0 this-&gt;allocate(t.size());<br><br></font>=
</span></div><div class=3D"subprettyprint"><span class=3D"styled-by-prettif=
y" style=3D"color: #606;"><font color=3D"#004000" face=3D"Arial" style=3D"b=
ackground-color: transparent;">=C2=A0 =C2=A0 this-&gt;_target =3D <span sty=
le=3D"display: inline !important; float: none; background-color: transparen=
t; color: rgb(0, 64, 0); font-family: Arial; font-size: 13px; font-style: n=
ormal; font-variant: normal; font-weight: 400; letter-spacing: normal; orph=
ans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-tra=
nsform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spa=
cing: 0px;">F</span>::createTargetAsCopyIn(this-&gt;data(), this-&gt;size()=
, t);<br>=C2=A0 }<br>=C2=A0 ...<br>};</font></span><span class=3D"styled-by=
-prettify" style=3D"color: #660;"></span></div></code></div><br></span></di=
v><div><br></div><div>SomeFunc can use any storage policy it wants!</div><d=
iv><br></div><div><i>If a Allocators are to be used, it is here, </i>not as=
 part of a core concept class<i>.=C2=A0</i></div><div><i><br></i></div><div=
><i><br></i></div><div><font size=3D"4"><b>Some code</b></font></div><div><=
br></div><div>I have a crude, incomplete, and possibly buggy implementation=
 here:=C2=A0https://wandbox.org/nojs/gcc-7.2.0/permlink/fFRJRe3FSqBPtkdA</d=
iv><div><br></div><div>Note that, the names in the code are different from =
the above used (it is too bug-prone to rename in Wandbox);</div><div><br></=
div><div>function_view =3D&gt; Fn</div><div><span class=3D"styled-by-pretti=
fy" style=3D"background-color: transparent; border-bottom-color: rgb(102, 1=
02, 0); border-bottom-style: none; border-bottom-width: 0px; border-image-o=
utset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-im=
age-source: none; border-image-width: 1; border-left-color: rgb(102, 102, 0=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(102, 102, 0); border-right-style: none; border-right-width: 0px; border-to=
p-color: rgb(102, 102, 0); border-top-style: none; border-top-width: 0px; c=
olor: rgb(102, 102, 0); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;He=
lvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-var=
iant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px;=
 margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-=
bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-=
align: left; text-decoration: none; text-indent: 0px; text-transform: none;=
 -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><=
/span><span class=3D"styled-by-prettify" style=3D"background-color: transpa=
rent; border-bottom-color: rgb(0, 0, 0); border-bottom-style: none; border-=
bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; bo=
rder-image-slice: 100%; border-image-source: none; border-image-width: 1; b=
order-left-color: rgb(0, 0, 0); border-left-style: none; border-left-width:=
 0px; border-right-color: rgb(0, 0, 0); border-right-style: none; border-ri=
ght-width: 0px; border-top-color: rgb(0, 0, 0); border-top-style: none; bor=
der-top-width: 0px; color: rgb(0, 0, 0); font-family: &amp;quot;Arial&amp;q=
uot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style:=
 normal; font-variant: normal; font-weight: 400; letter-spacing: normal; ma=
rgin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orp=
hans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; paddin=
g-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; text=
-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; word=
-spacing: 0px;">owning_function_view =3D&gt;=C2=A0OwningFnRef</span></div><=
div><span class=3D"styled-by-prettify" style=3D"background-color: transpare=
nt; border-bottom-color: rgb(0, 0, 0); border-bottom-style: none; border-bo=
ttom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; bord=
er-image-slice: 100%; border-image-source: none; border-image-width: 1; bor=
der-left-color: rgb(0, 0, 0); border-left-style: none; border-left-width: 0=
px; border-right-color: rgb(0, 0, 0); border-right-style: none; border-righ=
t-width: 0px; border-top-color: rgb(0, 0, 0); border-top-style: none; borde=
r-top-width: 0px; color: rgb(0, 0, 0); font-family: &amp;quot;Arial&amp;quo=
t;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: n=
ormal; font-variant: normal; font-weight: 400; letter-spacing: normal; marg=
in-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orpha=
ns: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-=
top: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-t=
ransform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-s=
pacing: 0px;">Function Target =3D&gt; Storage</span></div><div><span class=
=3D"styled-by-prettify" style=3D"margin: 0px; padding: 0px; border: 0px rgb=
(0, 0, 0); border-image: none; text-align: left; color: rgb(0, 0, 0); text-=
transform: none; text-indent: 0px; letter-spacing: normal; font-size: 13px;=
 font-variant: normal; word-spacing: 0px; white-space: normal; orphans: 2; =
-webkit-text-stroke-width: 0px; background-color: transparent;"><span style=
=3D"background-color: transparent; border-bottom-color: rgb(0, 64, 0); bord=
er-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bo=
rder-image-repeat: stretch; border-image-slice: 100%; border-image-source: =
none; border-image-width: 1; border-left-color: rgb(0, 64, 0); border-left-=
style: none; border-left-width: 0px; border-right-color: rgb(0, 64, 0); bor=
der-right-style: none; border-right-width: 0px; border-top-color: rgb(0, 64=
, 0); border-top-style: none; border-top-width: 0px; color: rgb(0, 64, 0); =
display: inline; float: none; font-family: Arial; font-size: 13px; font-sty=
le: normal; font-variant: normal; font-weight: 400; letter-spacing: normal;=
 margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; =
orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; pad=
ding-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; t=
ext-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; w=
ord-spacing: 0px;">TargetFactory =3D&gt; Fn is reused</span></span></div><d=
iv><span class=3D"styled-by-prettify" style=3D"background-color: transparen=
t; border-bottom-color: rgb(0, 0, 0); border-bottom-style: none; border-bot=
tom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; borde=
r-image-slice: 100%; border-image-source: none; border-image-width: 1; bord=
er-left-color: rgb(0, 0, 0); border-left-style: none; border-left-width: 0p=
x; border-right-color: rgb(0, 0, 0); border-right-style: none; border-right=
-width: 0px; border-top-color: rgb(0, 0, 0); border-top-style: none; border=
-top-width: 0px; color: rgb(0, 0, 0); font-family: &amp;quot;Arial&amp;quot=
;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: no=
rmal; font-variant: normal; font-weight: 400; letter-spacing: normal; margi=
n-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphan=
s: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-t=
op: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-tr=
ansform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-sp=
acing: 0px;"><b><br></b></span></div><div><span class=3D"styled-by-prettify=
" style=3D"background-color: transparent; border-bottom-color: rgb(0, 0, 0)=
; border-bottom-style: none; border-bottom-width: 0px; border-image-outset:=
 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-so=
urce: none; border-image-width: 1; border-left-color: rgb(0, 0, 0); border-=
left-style: none; border-left-width: 0px; border-right-color: rgb(0, 0, 0);=
 border-right-style: none; border-right-width: 0px; border-top-color: rgb(0=
, 0, 0); border-top-style: none; border-top-width: 0px; color: rgb(0, 0, 0)=
; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans=
-serif; font-size: 13px; font-style: normal; font-variant: normal; font-wei=
ght: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; mar=
gin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-l=
eft: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-deco=
ration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-w=
idth: 0px; white-space: normal; word-spacing: 0px;"><br></span></div><div><=
span class=3D"styled-by-prettify" style=3D"background-color: transparent; b=
order-bottom-color: rgb(0, 0, 0); border-bottom-style: none; border-bottom-=
width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-im=
age-slice: 100%; border-image-source: none; border-image-width: 1; border-l=
eft-color: rgb(0, 0, 0); border-left-style: none; border-left-width: 0px; b=
order-right-color: rgb(0, 0, 0); border-right-style: none; border-right-wid=
th: 0px; border-top-color: rgb(0, 0, 0); border-top-style: none; border-top=
-width: 0px; color: rgb(0, 0, 0); font-family: &amp;quot;Arial&amp;quot;,&a=
mp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal=
; font-variant: normal; font-weight: 400; letter-spacing: normal; margin-bo=
ttom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2=
; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: =
0px; text-align: left; text-decoration: none; text-indent: 0px; text-transf=
orm: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacin=
g: 0px;">It also has some simple trivial implementations of concrete delega=
tes</span></div><div><span class=3D"styled-by-prettify" style=3D"background=
-color: transparent; border-bottom-color: rgb(0, 0, 0); border-bottom-style=
: none; border-bottom-width: 0px; border-image-outset: 0; border-image-repe=
at: stretch; border-image-slice: 100%; border-image-source: none; border-im=
age-width: 1; border-left-color: rgb(0, 0, 0); border-left-style: none; bor=
der-left-width: 0px; border-right-color: rgb(0, 0, 0); border-right-style: =
none; border-right-width: 0px; border-top-color: rgb(0, 0, 0); border-top-s=
tyle: none; border-top-width: 0px; color: rgb(0, 0, 0); font-family: &amp;q=
uot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13=
px; font-style: normal; font-variant: normal; font-weight: 400; letter-spac=
ing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margi=
n-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-rig=
ht: 0px; padding-top: 0px; text-align: left; text-decoration: none; text-in=
dent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-spac=
e: normal; word-spacing: 0px;"><br></span></div><div><span class=3D"styled-=
by-prettify" style=3D"background-color: transparent; border-bottom-color: r=
gb(0, 0, 0); border-bottom-style: none; border-bottom-width: 0px; border-im=
age-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bord=
er-image-source: none; border-image-width: 1; border-left-color: rgb(0, 0, =
0); border-left-style: none; border-left-width: 0px; border-right-color: rg=
b(0, 0, 0); border-right-style: none; border-right-width: 0px; border-top-c=
olor: rgb(0, 0, 0); border-top-style: none; border-top-width: 0px; color: r=
gb(0, 0, 0); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp=
;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: norma=
l; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-lef=
t: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px=
; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left=
; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-te=
xt-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font color=
=3D"#002000">FixedFunc&lt;Signature, Size&gt; - for fixed storage functors<=
/font></span></div><div><span class=3D"styled-by-prettify" style=3D"backgro=
und-color: transparent; border-bottom-color: rgb(0, 0, 0); border-bottom-st=
yle: none; border-bottom-width: 0px; border-image-outset: 0; border-image-r=
epeat: stretch; border-image-slice: 100%; border-image-source: none; border=
-image-width: 1; border-left-color: rgb(0, 0, 0); border-left-style: none; =
border-left-width: 0px; border-right-color: rgb(0, 0, 0); border-right-styl=
e: none; border-right-width: 0px; border-top-color: rgb(0, 0, 0); border-to=
p-style: none; border-top-width: 0px; color: rgb(0, 0, 0); font-family: &am=
p;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size:=
 13px; font-style: normal; font-variant: normal; font-weight: 400; letter-s=
pacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; ma=
rgin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-=
right: 0px; padding-top: 0px; text-align: left; text-decoration: none; text=
-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-s=
pace: normal; word-spacing: 0px;"><font color=3D"#002000">DynamicFunc&lt;Si=
gnature&gt; - for auto-resizable functors;</font></span></div><div><br></di=
v><div>But these are not the main point - many other and better can be writ=
ten.</div><div><br></div><div>Not implemented:</div><div>I don&#39;t suppor=
t moving the original callable (if it is move-only, though the Target/Stora=
ge itself can be moved around, but not copied (as it is owning)).</div><div=
>I don&#39;t have support for trivially copyable callables, but I am not su=
re if it is really needed (might be microoptimization)</div><div>Finally, I=
 don&#39;t do any transformation on the signature.</div><div>All these are =
trivial expect the last one - it will be a template hell even if possible.<=
/div><div><br></div><div><br></div><div><font size=3D"4"><b>Conclusion</b><=
/font></div><div><b><font size=3D"4"><br></font></b></div><div><font size=
=3D"2">Although<span style=3D"display: inline !important; float: none; back=
ground-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial=
&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13.33px; font-style: no=
rmal; font-variant: normal; font-weight: 400; letter-spacing: normal; orpha=
ns: 2; text-align: left; text-decoration: none; text-indent: 0px; text-tran=
sform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spac=
ing: 0px;">, to pass callable object around,</span></font><font size=3D"4">=
 </font><font size=3D"2">templates serve well in library code, in user code=
 they often are not acceptable interface change. </font></div><div><font si=
ze=3D"2">A callable interface, not depending on the type of the callable, w=
ill always be needed, even more so today, when the type might be unknown li=
ke in the case of lambdas and the popularity of functional programming.</fo=
nt></div><div><font size=3D"2"><br></font></div><div><font size=3D"2">But b=
ecause the requirement for such a class are so broad, implementations of it=
 tend to be heavyweight, hard to define (does it need allocator?) and not f=
itting all needs.</font></div><div><font size=3D"2"><br></font></div><div><=
font size=3D"2">I believe, by defining well few core traits of such objects=
, we can have multiple concrete implementations of these traits.</font></di=
v><div><br></div><div><font size=3D"2">Not unlike the way we can </font><fo=
nt size=3D"2">have multiple </font>string representations (and basically al=
l are interchangeable by a way of some sort of coping), only because we hav=
e the base of char* + size + encoding.</div><div><br></div><div>The point i=
s to have something similar, a base representation of a callable, so that <=
i>Target to a delegate implementation should be what is char* + size + enco=
ding to a string implementation.</i></div><div>This can radically change th=
ings for the better.</div><div><i><br></i></div><div><br></div><div>That wr=
aps it up, thanks for Your time.</div><div><br></div><div><br></div></div>

<p></p>

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

------=_Part_2344_1734646187.1513774007294--

------=_Part_2343_1535643428.1513774007293--

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 29 Dec 2017 16:49:03 +0000
Raw View
--001a114092b40642c305617d6985
Content-Type: text/plain; charset="UTF-8"

I'm in favour of this. I avoided replying at first to see if anyone had
anything negative to say about this that I hadn't considered. As I see it,
it's a nice extension of the approach to unite cstrings and strings, but in
the context of function pointers and closures, and I welcome it. The fine
details may need figuring out, but the general idea is great.

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

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

<div dir=3D"auto"><div>I&#39;m in favour of this. I avoided replying at fir=
st to see if anyone had anything negative to say about this that I hadn&#39=
;t considered. As I see it, it&#39;s a nice extension of the approach to un=
ite cstrings and strings, but in the context of function pointers and closu=
res, and I welcome it. The fine details may need figuring out, but the gene=
ral idea is great.</div></div>

<p></p>

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

--001a114092b40642c305617d6985--

.