220 18008 <FD6B0DFD-A89E-4ED9-8963-362BF73EDE69@mac.com> article
Path: news.gmane.org!not-for-mail
From: David Krauss <potswa@mac.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: First draft: Non-copyable call wrapper, std::unique_function
Date: Wed, 20 May 2015 08:08:37 +0800
Lines: 297
Approved: news@gmane.org
Message-ID: <FD6B0DFD-A89E-4ED9-8963-362BF73EDE69@mac.com>
References: <59ED9069-2650-44E2-B00E-0E56ED37B83D@gmail.com>
 <27a788e7-4912-4a58-8201-79138ddf15a3@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2098\))
Content-Type: multipart/alternative;
 boundary="Apple-Mail=_B22101B2-87A8-4B2B-9FAB-58B1A13F5CFF"
X-Trace: ger.gmane.org 1432080568 16834 80.91.229.3 (20 May 2015 00:09:28 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Wed, 20 May 2015 00:09:28 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBAABBJNB56VAKGQEACDYTHA@isocpp.org Wed May 20 02:09:12 2015
Return-path: <std-proposals+bncBAABBJNB56VAKGQEACDYTHA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ob0-f197.google.com ([209.85.214.197])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBAABBJNB56VAKGQEACDYTHA@isocpp.org>)
	id 1YurZO-0003rn-SX
	for gclcip-std-proposals@m.gmane.org; Wed, 20 May 2015 02:09:11 +0200
Original-Received: by obblk5 with SMTP id lk5sf44924732obb.2
        for <gclcip-std-proposals@m.gmane.org>; Tue, 19 May 2015 17:09:09 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:from:content-type:message-id:mime-version
         :subject:date:references:to:in-reply-to:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=Okio6cSdFXdZ8zodIcxddFO6qdVaVU8qN5FuISeYF4E=;
        b=HzRakrsoeFHO5IIZKZUCSm3IiI/jJRjsoCC/A0OytF8B5O5/fNgBWDbaIgqn4gS+XQ
         uZFcHXLUCrmQ7W3RYmnS57+7SoiNiy8ZxHkrIx7HfeC7mXxS/d9ZQ3zzG9XJ9Ah2aQ5y
         JPeUN63+m8zmBdlF04vNb9VrZj5K0bx8vqfcgL8tgO6WwRvBVF4DZJbhe4MZG7RjGwJE
         ZcJgXrkEQtO+BjCGQQGOFsWnZhCATLpK0QYnr5eMNUPdlZo+NBBdBH4G0m+zgPqLquyC
         RW5LH4sU1FY6NnAVcmqlbi9AF+0tPy+amkwK1bebZ+OZT9gRseSrhXuQD/cMENXXHTXY
         5jPA==
X-Gm-Message-State: ALoCoQlD8U11RrJ3P45o/nJGTlVpaQGAdq55C4rghrwY0Ay2KS94AvBizlT7gV3DMUWx+/CYybJD
X-Received: by 10.182.29.70 with SMTP id i6mr44212386obh.27.1432080549758;
        Tue, 19 May 2015 17:09:09 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.50.33.5 with SMTP id n5ls1084987igi.27.canary; Tue, 19 May
 2015 17:09:08 -0700 (PDT)
X-Received: by 10.68.194.227 with SMTP id hz3mr8625001pbc.112.1432080548932;
        Tue, 19 May 2015 17:09:08 -0700 (PDT)
Original-Received: from nk11p04mm-asmtp001.mac.com (nk11p04mm-asmtpout001.mac.com. [17.158.236.236])
        by mx.google.com with ESMTPS id kv16si23658218pab.207.2015.05.19.17.09.08
        for <std-proposals@isocpp.org>
        (version=TLSv1.2 cipher=AES128-GCM-SHA256 bits=128/128);
        Tue, 19 May 2015 17:09:08 -0700 (PDT)
Received-SPF: pass (google.com: domain of potswa@mac.com designates 17.158.236.236 as permitted sender) client-ip=17.158.236.236;
Original-Received: from [172.20.10.2] (unknown [121.54.44.93])
 by nk11p04mm-asmtp001.mac.com
 (Oracle Communications Messaging Server 7.0.5.35.0 64bit (built Dec  4 2014))
 with ESMTPSA id <0NOM009JVGEEKO10@nk11p04mm-asmtp001.mac.com> for
 std-proposals@isocpp.org; Wed, 20 May 2015 00:09:07 +0000 (GMT)
X-Proofpoint-Virus-Version: vendor=fsecure
 engine=2.50.10432:5.14.151,1.0.33,0.0.0000
 definitions=2015-05-19_08:2015-05-19,2015-05-19,1970-01-01 signatures=0
X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0
 suspectscore=1 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0
 reason=mlx scancount=1 engine=7.0.1-1412110000 definitions=main-1505200000
In-reply-to: <27a788e7-4912-4a58-8201-79138ddf15a3@isocpp.org>
X-Mailer: Apple Mail (2.2098)
X-Original-Sender: potswa@mac.com
X-Original-Authentication-Results: mx.google.com;       spf=pass (google.com:
 domain of potswa@mac.com designates 17.158.236.236 as permitted sender)
 smtp.mail=potswa@mac.com;       dmarc=pass (p=NONE dis=NONE) header.from=mac.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:18008
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/18008>

--Apple-Mail=_B22101B2-87A8-4B2B-9FAB-58B1A13F5CFF
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9305=E2=80=9320, at 1:42 AM, Nicol Bolas <jmckesson@gmail.c=
om> wrote:
>=20
> On Tuesday, May 19, 2015 at 12:07:03 PM UTC-4, David Krauss wrote:
> Here=E2=80=99s a first draft of a non-copyable polymorphic call wrapper p=
roposal: http://bit.ly/uniqfun <http://bit.ly/uniqfun>
>=20
> It'd probably be a good idea to let someone know if a link goes to Dropbo=
x to download a PDF, or if it's just a HTML page on the web. You know, with=
out having to click the link.

Ah. It=E2=80=99s a PDF. I tried to put the extension inside the link, but f=
or some reason Bitly doesn=E2=80=99t allow it.

> Well, that would help. At least it would let us know the kind of work tha=
t would be involved in doing a move-transfer from `function` to `unique_fun=
ction`. The concern there being the changes to `function`'s implementation =
that would need to be made.

Unfortunately, prototyping it once will only provide information about one =
std::function implementation.

Having reviewed GNU=E2=80=99s, I think will involve adding a __move_functor=
 verb after __clone_functor, which may already be needed for conformance: I=
t never calls the target move constructor, but [func.wrap.func.con]/11 ment=
ions doing so.

But I=E2=80=99m still at square one: I=E2=80=99ll probably do it as a Clang=
 extension, because their license allows other implementations to borrow.

> But I don't like the idea of considering `any`s to be at all equivalent t=
o or transformable between `function`s. While their implementations are ver=
y similar, the objects are conceptually quite distinct. Just like `vector` =
and `string`. As such, I don't think we should explicitly support transform=
ing one into the other.

That sort of thing will only be proposed later. I think the use-case could =
become more apparent following a first round of extensions.

For now, I=E2=80=99m only using the any name in the common interfaces. Alte=
rnate names would be appreciated.

> I see you have `allocate_assign` and `emplace_assign`. It seems to me tha=
t you should follow the existing std::function convention. `allocate_assign=
` is conceptually equivalent to `function::assign`, so you should probably =
just call it that.

I guess so. I don=E2=80=99t like how assign always requires an allocator, a=
nd reverses the order of arguments compared to the constructor.

> Also, I see no reason why it shouldn't also be able to work like `functio=
n::assign`.

Can you elaborate?

There draft should individually specify those functions. The new assign/all=
ocate_assign performs

unique_function( allocator_arg_t, a, any_piecewise_construct_tag<F>, std::f=
orward<Args>(args)... ).swap(*this);

(This is an overspecification, since it requires an extraneous move in the =
small-function optimization case, but the style is how std::function is cur=
rently specified.)

> Similarly, `emplace_assign` should simply be called `emplace`. These soun=
d more like the standard=20

Ehh, but emplace always does an insert operation, not an overwrite operatio=
n.

> I'm going to assume that you intended to add an `operator()` overload in =
there somewhere. ;) However, unlike Casey Carter, I would not suggest attem=
pting to fix the thread safety problem until the committee has decided how =
they're going to fix it in `std::function`. We don't want two completely di=
fferent fixes involved.

I initially wrote the synopsis including all the member signatures of std::=
function. That was really messy, so I rewrote it with using declarations. T=
he private-inheritance thing was really distracting and misleading so I jus=
t put a one-line comment instead.

I=E2=80=99ll add a second comment line, since I guess a <functional> propos=
al that never mentions the call operator is weird.

> That's not to say that something shouldn't be done. It's more to say that=
 this proposal should hold off on committing to any one solution until more=
 is known.

There=E2=80=99s a separate proposal, which I actually split this one from:

> std::function has some rough edges. Its interface is a product of evoluti=
on, and not necessarily the expression of a consistent theory. A model is p=
resented to describe what std::function already safely does. Evolutionary, =
not-immediately-breaking solutions to all the problems presented in N4159 a=
re proposed, plus further extensions.
>=20
> Specifically, this proposal includes:
>=20
> 	=E2=80=A2 Specializations over cv-qualified and ref-qualified signatures
> 	=E2=80=A2 Multiple signatures in a single specialization
> 	=E2=80=A2 Interface unification with std::any from the Library Fundament=
als TS
> 	=E2=80=A2 A functor adapter template critical_section for adding thread =
safety
>=20
> So, std::unique_function< void() &, void() const &, void() && > would be =
a handle to a non-copyable function object which discriminates the major ac=
cess styles.

Stay tuned. It=E2=80=99s Deusy.

> Lastly, bikeshedding. I'm not sure that `unique` is the right word. Oh, i=
t conjures up thoughts of `unique_ptr`, which makes you think "move only". =
But `unique_ptr` is about ownership of memory, while `unique_function` is j=
ust about being a move-only function wrapper. At the same time, I cannot co=
me up with a more explicit name that doesn't sound silly (like `move_only_f=
unction`).

It=E2=80=99s not about the memory, it=E2=80=99s about the object in the mem=
ory. The ownership idea is the same. There=E2=80=99s the small-function opt=
imization, but it doesn=E2=80=99t really make a conceptual difference. It g=
ets disabled if there=E2=80=99s no move constructor.

move_only_function doesn=E2=80=99t fit because targets may be copyable or n=
on-movable.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_B22101B2-87A8-4B2B-9FAB-58B1A13F5CFF
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9305=
=E2=80=9320, at 1:42 AM, Nicol Bolas &lt;<a href=3D"mailto:jmckesson@gmail.=
com" class=3D"">jmckesson@gmail.com</a>&gt; wrote:</div><br class=3D"Apple-=
interchange-newline"><div class=3D""><div dir=3D"ltr" class=3D"">On Tuesday=
, May 19, 2015 at 12:07:03 PM UTC-4, David Krauss wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word" class=3D"">=
Here=E2=80=99s a first draft of a non-copyable polymorphic call wrapper pro=
posal:&nbsp;<a href=3D"http://bit.ly/uniqfun" target=3D"_blank" rel=3D"nofo=
llow" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%=
2Fbit.ly%2Funiqfun\46sa\75D\46sntz\0751\46usg\75AFQjCNHpv1IQvwAGd50WXzFZsNA=
yV4dpRA';return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\=
75http%3A%2F%2Fbit.ly%2Funiqfun\46sa\75D\46sntz\0751\46usg\75AFQjCNHpv1IQvw=
AGd50WXzFZsNAyV4dpRA';return true;" class=3D"">http://bit.ly/<wbr class=3D"=
">uniqfun</a></div></blockquote><div class=3D""><br class=3D"">It'd probabl=
y be a good idea to let someone know if a link goes to Dropbox to download =
a PDF, or if it's just a HTML page on the web. You know, without having to =
click the link.<br class=3D""></div></div></div></blockquote><div><br class=
=3D""></div><div>Ah. It=E2=80=99s a PDF. I tried to put the extension insid=
e the link, but for some reason Bitly doesn=E2=80=99t allow it.</div><br cl=
ass=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"l=
tr" class=3D""><div class=3D"">Well, that would help. At least it would let=
 us know the kind of work that would be involved in doing a move-transfer f=
rom `function` to `unique_function`. The concern there being the changes to=
 `function`'s implementation that would need to be made.</div></div></div><=
/blockquote><div><br class=3D""></div><div>Unfortunately, prototyping it on=
ce will only provide information about one <font face=3D"Courier" class=3D"=
">std::function</font> implementation.</div><div><br class=3D""></div><div>=
Having reviewed GNU=E2=80=99s, I think will involve adding a <font face=3D"=
Courier" class=3D"">__move_functor</font> verb after <font face=3D"Courier"=
 class=3D"">__clone_functor</font>, which may already be needed for conform=
ance: It never calls the target move constructor, but [func.wrap.func.con]/=
11 mentions doing so.</div><div><br class=3D""></div><div>But I=E2=80=99m s=
till at square one: I=E2=80=99ll probably do it as a Clang extension, becau=
se their license allows other implementations to borrow.</div><br class=3D"=
"><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" cla=
ss=3D""><div class=3D"">But I don't like the idea of considering `any`s to =
be at all equivalent to or transformable between `function`s. While their i=
mplementations are very similar, the objects are conceptually quite distinc=
t. Just like `vector` and `string`. As such, I don't think we should explic=
itly support transforming one into the other.<br class=3D""></div></div></d=
iv></blockquote><div><br class=3D""></div><div>That sort of thing will only=
 be proposed later. I think the use-case could become more apparent followi=
ng a first round of extensions.</div><div><br class=3D""></div><div>For now=
, I=E2=80=99m only using the <font face=3D"Courier" class=3D"">any</font> n=
ame in the common interfaces. Alternate names would be appreciated.</div><d=
iv><br class=3D""></div><blockquote type=3D"cite" class=3D""><div class=3D"=
"><div dir=3D"ltr" class=3D""><div class=3D"">I see you have `allocate_assi=
gn` and `emplace_assign`. It seems to me that you should follow the existin=
g std::function convention. `allocate_assign` is conceptually equivalent to=
 `function::assign`, so you should probably just call it that. </div></div>=
</div></blockquote><div><br class=3D""></div><div>I guess so. I don=E2=80=
=99t like how <font face=3D"Courier" class=3D"">assign</font> always requir=
es an allocator, and reverses the order of arguments compared to the constr=
uctor.</div><br class=3D""><blockquote type=3D"cite" class=3D""><div class=
=3D""><div dir=3D"ltr" class=3D""><div class=3D"">Also, I see no reason why=
 it shouldn't also be able to work like `function::assign`.</div></div></di=
v></blockquote><div><br class=3D""></div><div>Can you elaborate?</div><div>=
<br class=3D""></div><div>There draft should individually specify those fun=
ctions. The new <font face=3D"Courier" class=3D"">assign</font>/<font face=
=3D"Courier" class=3D"">allocate_assign</font> performs</div><div><br class=
=3D""></div><div><font face=3D"Courier" class=3D"">unique_function(&nbsp;al=
locator_arg_t, a, any_piecewise_construct_tag&lt;F&gt;, std::forward&lt;Arg=
s&gt;(args)... ).swap(*this);</font></div><div><br class=3D""></div><div>(T=
his is an overspecification, since it requires an extraneous move in the sm=
all-function optimization case, but the style is how <font face=3D"Courier"=
 class=3D"">std::function</font> is currently specified.)</div><br class=3D=
""><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" cl=
ass=3D""><div class=3D"">Similarly, `emplace_assign` should simply be calle=
d `emplace`. These sound more like the standard <br class=3D""></div></div>=
</div></blockquote><div><br class=3D""></div><div>Ehh, but <font face=3D"Co=
urier" class=3D"">emplace</font>&nbsp;always does an insert operation, not =
an overwrite operation.</div><br class=3D""><blockquote type=3D"cite" class=
=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div class=3D"">I'm going=
 to assume that you intended to add an `operator()` overload in there somew=
here. ;) However, unlike Casey Carter, I would not suggest attempting to fi=
x the thread safety problem until the committee has decided how they're goi=
ng to fix it in `std::function`. We don't want two completely different fix=
es involved.<br class=3D""></div></div></div></blockquote><div><br class=3D=
""></div><div>I initially wrote the synopsis including all the member signa=
tures of <font face=3D"Courier" class=3D"">std::function</font>. That was r=
eally messy, so I rewrote it with&nbsp;<font face=3D"Courier" class=3D"">us=
ing</font> declarations. The private-inheritance thing was really distracti=
ng and misleading so I just put a one-line comment instead.</div><div><br c=
lass=3D""></div><div>I=E2=80=99ll add a second comment line, since I guess =
a <font face=3D"Courier" class=3D"">&lt;functional&gt;</font> proposal that=
 never mentions the call operator is weird.</div><br class=3D""><blockquote=
 type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D""><div =
class=3D"">That's not to say that something shouldn't be done. It's more to=
 say that this proposal should hold off on committing to any one solution u=
ntil more is known.<br class=3D""></div></div></div></blockquote><div><br c=
lass=3D""></div><div>There=E2=80=99s a separate proposal, which I actually =
split this one from:</div><div><br class=3D""></div><div><blockquote type=
=3D"cite" class=3D"">std::function&nbsp;has some rough edges. Its interface=
 is a product of evolution, and not necessarily the expression of a consist=
ent theory. A model is presented to describe what&nbsp;std::function&nbsp;a=
lready safely does. Evolutionary, not-immediately-breaking&nbsp;solutions t=
o all the problems presented in N4159 are proposed, plus further extensions=
..<br class=3D""><br class=3D"">Specifically, this proposal includes:<br cla=
ss=3D""><br class=3D""><div class=3D""><span class=3D"Apple-tab-span" style=
=3D"white-space:pre">	</span>=E2=80=A2 Specializations over cv-qualified an=
d ref-qualified signatures<br class=3D""></div><div class=3D""><span class=
=3D"Apple-tab-span" style=3D"white-space: pre;">	</span>=E2=80=A2 Multiple =
signatures in a single specialization</div><div class=3D""><span class=3D"A=
pple-tab-span" style=3D"white-space:pre">	</span>=E2=80=A2 Interface unific=
ation with&nbsp;std::any&nbsp;from the Library Fundamentals TS<br class=3D"=
"></div><div><span class=3D"Apple-tab-span" style=3D"white-space: pre;">	</=
span>=E2=80=A2&nbsp;A functor adapter template&nbsp;critical_section&nbsp;f=
or adding thread safety</div></blockquote><blockquote type=3D"cite" class=
=3D""><br class=3D""></blockquote><blockquote type=3D"cite" class=3D"">So,&=
nbsp;std::unique_function&lt; void() &amp;, void() const &amp;, void() &amp=
;&amp; &gt;&nbsp;would be a handle to a non-copyable function object which =
discriminates the major access styles.<br class=3D""></blockquote><br class=
=3D""></div><div>Stay tuned. It=E2=80=99s Deusy.</div><br class=3D""><block=
quote type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=3D"">=
<div class=3D"">Lastly, bikeshedding. I'm not sure that `unique` is the rig=
ht word. Oh, it conjures up thoughts of `unique_ptr`, which makes you think=
 "move only". But `unique_ptr` is about ownership of memory, while `unique_=
function` is just about being a move-only function wrapper. At the same tim=
e, I cannot come up with a more explicit name that doesn't sound silly (lik=
e `move_only_function`).<br class=3D""></div></div></div></blockquote><div>=
<br class=3D""></div></div>It=E2=80=99s not about the memory, it=E2=80=99s =
about the object in the memory. The ownership idea is the same. There=E2=80=
=99s the small-function optimization, but it doesn=E2=80=99t really make a =
conceptual difference. It gets disabled if there=E2=80=99s no move construc=
tor.<div class=3D""><br class=3D""></div><div class=3D""><font face=3D"Cour=
ier" class=3D"">move_only_function</font> doesn=E2=80=99t fit because targe=
ts may be copyable or non-movable.</div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
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 />

--Apple-Mail=_B22101B2-87A8-4B2B-9FAB-58B1A13F5CFF--

.
