Re: [capy] Andrzej's feedback

Andrzej Krzemienski via Boost <[email protected]> Wed, 8 Jul 2026 08:22:12 +0200
Newsgroups gmane.comp.lib.boost.devel
Message-ID <CAOenAXgSkt9e8Sh6PTngcPuOLrU9EsohcJNg=CHb7okpz3pWTg@mail.gmail.com>
--000000000000e78eec0656138745
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

=C5=9Br., 8 lip 2026 o 02:19 Andrzej Krzemienski <[email protected]> napis=
a=C5=82(a):

>
>
> wt., 7 lip 2026 o 00:58 Vinnie Falco <[email protected]> napisa=C5=
=82(a):
>
>> On Mon, Jul 6, 2026 at 2:53=E2=80=AFPM Andrzej Krzemienski <akrzemi1@gma=
il.com>
>> wrote:
>>
>>> Slightly as a nit-pick, I have just learnt that you also have to study
>>> the not-proposed Boost.HTTP to be able to review the concept BufferSing=
, as
>>> it has no real model in Capy or Corosio.
>>>
>>
>> Yeah, that's fair. And I think maybe we can include an example or
>> something so there is some review surface.
>>
>>
>>> Why does the doc page describing the launching of coroutines (
>>>> https://develop.capy.cpp.al/capy/4.coroutines/4b.launching.html) have
>>>> a red warning box?
>>>>
>>>
>> Well the two-call syntax can be abused. Don't do that.
>>
>>
>>> Some people do not like thread_local based on its implementation
>>> difficulties: requires dynamic memory allocation (and no custom allocat=
or
>>> can be provided), is not implementable on some architectures.
>>>
>>
>> Okay but that's for implementors. The user doesn't have to worry about
>> that. If thread_local is not available on a particular architecture, the
>> implementation can fall back to the global allocator. Or in more practic=
al
>> terms it simply uses a plain global variable. It turns out that the
>> platforms without thread_local also tend to not have threads (P4182R2 wh=
ich
>> I can't seem to find at the moment... Mungo?)
>>
>>
>>> My discomfort is not about the feature itself, but how it is used. The
>>> usage is based on the assumption that the read from the variable happen=
s
>>> (1) immediately after the write (no intervening accesses) and (2) on th=
e
>>> same thread. And since you cannot enforce that, you have to trust the u=
ser,
>>> and maybe even trust your luck.
>>>
>>
>> We *can* guarantee it. Section 8.3:
>>
>> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4172r1.pdf
>>
>>
>>> But because this hack is made to move the complexity out of the user's
>>> sight, the user will not cooperate (they do not know that they have to)=
.
>>>
>>
>> The user doesn't have to cooperate. The launch function has the burden.
>> P4172 describes three audiences:
>>
>> 1. Application developer
>> 2. Framework author
>> 3. I/O library author
>>
>> The Framework author has the responsibility of making sure that the
>> launch functions and task types they create follow the rules. These auth=
ors
>> are fewer in number with a higher level of skill. The expectations are
>> reasonable.
>>
>>
>>> I am not even sure how this can be implemented for non-task IoAwaitable=
s
>>> when in a thread executing the coroutine may be different than the thre=
ad
>>> resuming the coroutine, in a thread pool executor.
>>>
>>
>> Non-task awaitables do not have an associated coroutine, so they don't
>> have to handle it. They just put their state into the calling coroutines
>> frame, without requiring an allocation. These are written by I/O library
>> authors (group 3 above). Corosio is full of them. read_some_awaitable, a=
nd
>> so on.
>>
>>
>>> Also, as with any other hacks, they work under the assumption that
>>> no-one else is doing their own hacks at the same time. Boost.LEAF uses =
the
>>> TLS hack, and it only works until you have to interoperate with a corou=
tine
>>> library.
>>>
>>
>> There is no monolithic "TLS hack." It is not some light switch that is
>> turned on and off. Boost.LEAF and Capy each use their own thread local
>> variables to achieve their ends. Since the variables have different
>> linkages, they are separate from each other and work together Just Fine.
>>
>> Show me the specific interaction where you think these libraries do not
>> compose?
>>
>>
>>> In fact, I wish that the problem of environment propagation were
>>> addressed by a dedicated language feature that indicates the intention
>>> explicitly and allows the compiler to verify the correct usage.
>>>
>>
>> Changing the language should be DIFFICULT and EARNED. Engineers are too
>> hasty to beg the language for features to make their lives easier. Note,=
 we
>> did not go running hat in hand to wg21 saying "please solve this in the
>> language." We especially do not say "we need co_yield to act as a final
>> suspend."
>>
>> Instead, we come up with our own solution which does not require changes
>> to the language. It is not perfect, but it gives 16.3 million potential
>> users of networking a path to use coroutines for composition, instead of
>> callbacks. And then we can get field experience will may LATER justify a
>> change to the language. But only after we have at least 9 years under ou=
r
>> belt.
>>
>>
>>> My discomfort is not about the strangeness of the notation but about ho=
w
>>> easy it is to misuse it. The red warning box in the docs confirms this.
>>> BTW, the example in the warning box is wrong. That code would not compi=
le
>>> (and rightly so). But there are others that would compile and silently =
get
>>> a different behavior.
>>>
>>
>> You say "there are others" plural. But only give one example. Maybe it i=
s
>> a legitimate example but the way you phrase it implies a wider scope tha=
n
>> exist. Please enumerate actual problems so they can be engaged one by on=
e,
>> and not unfalsifiable generalizations.
>>
>>   3. Having to use pass they stop_token via await_ready (and therefore
>>> risk UB when stop_token is queried before the first suspend).
>>>
>>
>> What? Show the undefined behavior you think is happening, please.
>>
>>
>>> I imagine a coroutine where a part of its body is executed
>>>> immediately, without suspension. I can imagine a stop being requested =
from
>>>> a different thread executing a different continuation. Say, calling
>>>> .cancel() on some IO object.
>>>>
>>>
>> You can imagine all you like but please, show concrete examples. The
>> example you just gave, calling cancel() on "some I/O object" from a
>> different thread, is undefined behavior.
>>
>> ALL I/O objects in Corosio are NOT THREAD SAFE. You cannot access them
>> concurrently.
>>
>> Please show a concrete example of undefined behavior.
>>
>>
>>>  I did not mean C++26 executors as the alternative. I was thinking more
>>> in the vein of https://github.com/ClickHouse/silk.
>>>
>>
>> Stackful coroutines ("fiber" in silk parlance) are wonderful. And Nat
>> Goodspeed should not have waited over twelve years to get them in the
>> standard. They do not replace stackless coroutines, nor do they compete
>> with them. They are a legitimate tool which solves the same problem with=
 a
>> different set of tradeoffs.
>>
>> C++ needs them, just as much as it needs frame-opaque stackless
>> coroutines. And I would argue the language needs frame visible coroutine=
s
>> as well. This is not contested and I have written a paper saying so:
>>
>> *Benefits of Frame-Visible Coroutines for Senders*
>> https://isocpp.org/files/papers/P4166R0.pdf
>>
>> However, they are unsuited to a large class of I/O problems, networking
>> in particular.
>>
>> Jamie, do you want to build your system on fibers, or stackless
>> coroutines?
>>
>>
>>> I am in favour of doing the right thing rather than doing what the
>>> Standard does. They can of course coincide, but the guidance from the
>>> standard alone is insufficient motivation.
>>>
>>
>> That's a false premise. In this case the Right thing and the Standard
>> thing are the same thing: error_code for common outcomes and transient
>> states, and exceptions for exceptional outcomes.
>>
>>
>>> Who said they are supposed to be "errors"? `error_code` is just a label=
.
>>>> You are attaching semantic significance to the type name.
>>>>
>>>
>>> I am not sure if you are serious. I indeed attach semantic significance
>>> to the type name. Why did you call the type providing access to a UDP
>>> socket in Corosio `udp_socket`? You could have called it `sun_flower` a=
nd
>>> then insist that people should not attach semantic significance to type
>>> names.
>>>
>>
>> Of course I am serious. And I did not choose the name error_code. It is
>> what it is, and it cannot be changed. That said, this is how it is being
>> used. To argue "you shouldn't use it that way" is not a serious debate w=
hen
>> the customs have already been adopted. And I would say, that returning
>> distinguishable, successful outcomes from error_code is fully in scope.
>> Again I point to Boost.System:
>>
>>
>> https://github.com/boostorg/system/blob/bc7c00fa67501ceadfde8e9208355023=
40e8b899/include/boost/system/detail/error_code.hpp#L287
>>
>> Why does `bool failed()` exist, if according to you there should only be
>> one value of "success?" Was Peter Dimov wrong?
>>
>>
>>>  In this case I do not buy the "ASIO got that right" argument.
>>>>
>>>> Asio doesn't have any dual-stream interfaces.
>>>>
>>>
>>> ASIO uses type error_code to signal non-errors.
>>>
>>
>> A quarter-century of established practice. Show me your alternative. The=
n
>> let's compare.
>>
>
> I am answering before going to sleep, so this may not be a complete answe=
r
> that you deserve, but I do not want you to wait another day for the reply=
.
>
> I expressed my discomfort with the double call syntax. I chose word
> discomfort to convey that I am not opposed to the solution (I wouldn't be
> able to come up with a better one without violating other goals), but I
> note that unlike a lot of other features in Boost, we do not get this "ea=
sy
> to use correctly, hard to use incorrectly" effect. For examples of how th=
is
> can be misused. One has already been provided, I think by Rainer:
>
> run_async(exec)(the_job(1, "8080"));
>
> And `the_job` may be a factory function or a getter, or a wrapper
> function. It is generally a reasonable thing to do, but not when the
> double-call syntax (with TLS under the hood) is in action and the slight
> misordering of the sight effects may break the system.
>
> Another example is when somebody decides to refactor the code in order no=
t
> to repeat themselves:
>
> auto exec_runner =3D  run_async(exec);
> /// ...
> run_all_coros(move(exec_runner), {my_job1(), my_job2(), my_job3()});
>
> The argument of "three audiences" has been made a couple of times. I hear
> that there is going to be a "I/O library author". When writing a custom I=
/O
> functionality they may need to provide their own IoAwaitable. I read that
> such an "author has the responsibility of making sure that the launch
> functions and task types they create follow the rules". Can you point me =
to
> the place where these rules are written down with the level of detail
> necessary for the  "I/O library author"  to do their job correctly?
>
> The interesting case is when we have an IoAwaitable (to be associated wit=
h
> a coroutine) that does not have the initial suspend and does execute *par=
t*
> of the coroutine's body before suspending. If in that part of the body
> (before the first real suspend I -- the ordinary programmer, not I/O
> provider) get the stop_token with `co_await this_coro`, I will get a null
> pointer dereference. I enclose an example that demonstrates this.
>

My apologies. Providing a complicated example in the middle of the night
had little chances of succeeding. I sent you something that is not an
IoAwaitable. I now enclose an example of an IoAwaitable that gives the
impression of being correctly implemented -- could pass a review -- but
that triggers UB in some cases. This one is a bit longer.

Regards,
&rzej;


>
> Now, going back to error_code and Boost.System.
> If we forego the naming issue, the idea behind the error code is that you=
r
> functions have weak postcondition: everything is a success. Having obtain=
ed
> the status code is success. Then you can inspect it and make the call on
> what to do next. In this view, the
> function std::error_category::failed(),mentioned by others would not make
> sense, as this would have been the decision made by someone else -- not t=
he
> caller.
>
> It makes sense to use error_code at the level of stream operations. I am
> not sure the same technique makes sense at higher levels.
> Function when_all definately does not follow the Boost.System model, as i=
t
> assumes any non-zero code is a failure.
> Function read_at_least -- using error_code to represent a precondition
> violation -- might be in the spirit of  Boost.System, but this is so
> confusing: to refuse to communicate what is obviously a bug in the caller=
.
>
> I also think the function normalize_openssl_shutdown_read_error goes
> against the idea of  Boost.System, as I understand it. My understanding h=
as
> always been that error codes once produced stay as they are (this may be
> valuable information to whoever processes them at the higher level), and
> users use different conditions at different application levels to interpr=
et
> the original code in a way suitable at their level. In contrast,
> normalize_openssl_shutdown_read_error discards the original value and jus=
t
> produces another.
>
> Regards,
> &rzej;
>
>

--000000000000e78eec0656138745
Content-Type: text/plain; charset="US-ASCII"; name="stop_token_failure_2.cpp"
Content-Disposition: attachment; filename="stop_token_failure_2.cpp"
Content-Transfer-Encoding: base64
Content-ID: <f_mrbowvhk0>
X-Attachment-Id: f_mrbowvhk0

Ly8KLy8gQSBmb290Z3VuIHRoYXQgc3Vydml2ZXMgImRvaW5nIGV2ZXJ5dGhpbmcgcmlnaHQiLgov
LwovLyBUaGlzIHByb2dyYW0gZGVmaW5lcyBhIGN1c3RvbSBjb3JvdXRpbmUgcmV0dXJuIHR5cGUs
IG15X3Rhc2s8RWFnZXIsIFQ+LCB0aGF0OgovLwovLyAgICogc2F0aXNmaWVzIGNhcHk6OklvQXdh
aXRhYmxlICh0aGVyZSBpcyBhIHN0YXRpY19hc3NlcnQgYmVsb3cgcHJvdmluZyBpdCksCi8vICAg
KiBpbXBsZW1lbnRzIHRoZSB0d28tYXJndW1lbnQgYXdhaXRfc3VzcGVuZChoYW5kbGUsIGlvX2Vu
diBjb25zdCopIGFuZAovLyAgICAgZmFpdGhmdWxseSBzdG9yZXMgdGhlIGVudmlyb25tZW50IHZp
YSBzZXRfZW52aXJvbm1lbnQoKSwKLy8gICAqIHByb3ZpZGVzIGEgdHJhbnNmb3JtX2F3YWl0YWJs
ZSB0aGF0IGluamVjdHMgdGhlIGVudmlyb25tZW50IGludG8gbmVzdGVkCi8vICAgICBJb0F3YWl0
YWJsZXMsIGV4YWN0bHkgbGlrZSBjYXB5Ojp0YXNrLgovLwovLyBJbiBvdGhlciB3b3JkcywgdGhl
IHR5cGUgZm9sbG93cyB0aGUgSW9Bd2FpdGFibGUgcHJvdG9jb2wgY29ycmVjdGx5LgovLwovLyBU
aGUgT05MWSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHNhZmUgcGF0aCBhbmQgdGhlIHVuZGVmaW5l
ZC1iZWhhdmlvciBwYXRoIGlzCi8vIGEgc2luZ2xlIHdvcmQgaW4gaW5pdGlhbF9zdXNwZW5kKCk6
Ci8vCi8vICAgICBFYWdlciA9PSBmYWxzZSAgLT4gIHN0ZDo6c3VzcGVuZF9hbHdheXMgICAobGF6
eTogZW52IGluc3RhbGxlZCBmaXJzdCkKLy8gICAgIEVhZ2VyID09IHRydWUgICAtPiAgc3RkOjpz
dXNwZW5kX25ldmVyICAgICAoYm9keSBydW5zIGJlZm9yZSBlbnYgZXhpc3RzKQovLwovLyBUaGUg
Y29yb3V0aW5lIGJvZHkgdGhlbiBkb2VzIHNvbWV0aGluZyBlbnRpcmVseSByZWFzb25hYmxlOiBy
dW4gYSBsaXR0bGUKLy8gc2V0dXAsIHRoZW4gY2hlY2sgdGhlIHN0b3AgdG9rZW4gYmVmb3JlIHN0
YXJ0aW5nIGV4cGVuc2l2ZSB3b3JrLiBXaXRoIHRoZQovLyBsYXp5IHZhcmlhbnQgdGhpcyB3b3Jr
cy4gV2l0aCB0aGUgZWFnZXIgdmFyaWFudCB0aGUgYm9keSBydW5zIGJlZm9yZQovLyBhd2FpdF9z
dXNwZW5kIHdhcyBldmVyIGNhbGxlZCwgc28gdGhlIHByb21pc2UncyBlbnZfIGlzIHN0aWxsIG51
bGxwdHIsIGFuZAovLwovLyAgICAgY29fYXdhaXQgY2FweTo6dGhpc19jb3JvOjpzdG9wX3Rva2Vu
Ci8vCi8vIGRlcmVmZXJlbmNlcyBpdCBpbnNpZGUgaW9fYXdhaXRhYmxlX3Byb21pc2VfYmFzZTo6
YXdhaXRfdHJhbnNmb3JtOgovLwovLyAgICogRGVidWcgYnVpbGQgKGFzc2VydGlvbnMgb24pOiBC
T09TVF9DQVBZX0FTU0VSVChlbnZfKSBmaXJlcyAtPiBhYm9ydC4KLy8gICAqIFJlbGVhc2UgYnVp
bGQgKE5ERUJVRyk6ICAgICAgZW52Xy0+c3RvcF90b2tlbiBkZXJlZmVyZW5jZXMgbnVsbCAtPiBV
Qi4KLy8KLy8gTm90aGluZyBpbiB0aGUgY2FsbCBzaXRlIGxvb2tzIHdyb25nOiBhcHAoKSBpcyBh
biBvcmRpbmFyeSBjYXB5Ojp0YXNrIHRoYXQKLy8gc2ltcGx5IGBjb19hd2FpdGBzIHRoZSBjaGls
ZCwgbGF1bmNoZWQgd2l0aCBydW5fYXN5bmMgb24gYSB0aHJlYWRfcG9vbC4KLy8KCiNpbmNsdWRl
IDxib29zdC9jYXB5LmhwcD4KI2luY2x1ZGUgPGJvb3N0L2NhcHkvY29uY2VwdC9pb19hd2FpdGFi
bGUuaHBwPgojaW5jbHVkZSA8Ym9vc3QvY2FweS9leC9pb19hd2FpdGFibGVfcHJvbWlzZV9iYXNl
LmhwcD4KI2luY2x1ZGUgPGJvb3N0L2NhcHkvZXgvaW9fZW52LmhwcD4KI2luY2x1ZGUgPGJvb3N0
L2NhcHkvZXgvdGhpc19jb3JvLmhwcD4KCiNpbmNsdWRlIDxjb3JvdXRpbmU+CiNpbmNsdWRlIDxl
eGNlcHRpb24+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPG9wdGlvbmFsPgojaW5jbHVk
ZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDx1dGlsaXR5PgoKbmFtZXNwYWNlIGNhcHkgPSBib29z
dDo6Y2FweTsKCm5hbWVzcGFjZSBmb290Z3VuIHsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gUmVzdWx0IHN0
b3JhZ2UgZm9yIG15X3Rhc2s8RWFnZXIsIFQ+LgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnRlbXBsYXRlPGNsYXNz
IFQ+CnN0cnVjdCB0YXNrX3Jlc3VsdAp7CiAgICBzdGQ6Om9wdGlvbmFsPFQ+IHZhbHVlXzsKICAg
IHN0ZDo6ZXhjZXB0aW9uX3B0ciBlcnJfOwogICAgdm9pZCByZXR1cm5fdmFsdWUoVCB2KSB7IHZh
bHVlXy5lbXBsYWNlKHN0ZDo6bW92ZSh2KSk7IH0KICAgIHZvaWQgdW5oYW5kbGVkX2V4Y2VwdGlv
bigpIG5vZXhjZXB0IHsgZXJyXyA9IHN0ZDo6Y3VycmVudF9leGNlcHRpb24oKTsgfQogICAgc3Rk
OjpleGNlcHRpb25fcHRyIGV4Y2VwdGlvbigpIGNvbnN0IG5vZXhjZXB0IHsgcmV0dXJuIGVycl87
IH0KICAgIFQmIHJlc3VsdCgpIHsgcmV0dXJuICp2YWx1ZV87IH0KfTsKCnRlbXBsYXRlPD4Kc3Ry
dWN0IHRhc2tfcmVzdWx0PHZvaWQ+CnsKICAgIHN0ZDo6ZXhjZXB0aW9uX3B0ciBlcnJfOwogICAg
dm9pZCByZXR1cm5fdm9pZCgpIG5vZXhjZXB0IHt9CiAgICB2b2lkIHVuaGFuZGxlZF9leGNlcHRp
b24oKSBub2V4Y2VwdCB7IGVycl8gPSBzdGQ6OmN1cnJlbnRfZXhjZXB0aW9uKCk7IH0KICAgIHN0
ZDo6ZXhjZXB0aW9uX3B0ciBleGNlcHRpb24oKSBjb25zdCBub2V4Y2VwdCB7IHJldHVybiBlcnJf
OyB9Cn07CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIEEgcHJvdG9jb2wtY29uZm9ybWluZyBjdXN0b20gSW9B
d2FpdGFibGUgY29yb3V0aW5lIHR5cGUuCi8vCi8vIFRoZSBvbmx5IGtub2IgaXMgYEVhZ2VyYCwg
d2hpY2ggc2VsZWN0cyBpbml0aWFsX3N1c3BlbmQoKS4gRXZlcnl0aGluZyBlbHNlCi8vIGlzIHRo
ZSB0ZXh0Ym9vayBpbXBsZW1lbnRhdGlvbi4KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp0ZW1wbGF0ZTxib29sIEVh
Z2VyLCBjbGFzcyBUID0gdm9pZD4KY2xhc3MgbXlfdGFzawp7CnB1YmxpYzoKICAgIHN0cnVjdCBw
cm9taXNlX3R5cGUKICAgICAgICA6IGNhcHk6OmlvX2F3YWl0YWJsZV9wcm9taXNlX2Jhc2U8cHJv
bWlzZV90eXBlPgogICAgICAgICwgdGFza19yZXN1bHQ8VD4KICAgIHsKICAgICAgICBteV90YXNr
IGdldF9yZXR1cm5fb2JqZWN0KCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBteV90YXNr
ewogICAgICAgICAgICAgICAgc3RkOjpjb3JvdXRpbmVfaGFuZGxlPHByb21pc2VfdHlwZT46OmZy
b21fcHJvbWlzZSgqdGhpcyl9OwogICAgICAgIH0KCiAgICAgICAgLy8gVEhFIGtub2IuIEJvdGgg
YXJlIGxlZ2FsOyBvbmx5IHRoZSB0aW1pbmcgb2YgdGhlIGJvZHkgZGlmZmVycy4KICAgICAgICBh
dXRvIGluaXRpYWxfc3VzcGVuZCgpIG5vZXhjZXB0CiAgICAgICAgewogICAgICAgICAgICBpZiBj
b25zdGV4cHIoRWFnZXIpCiAgICAgICAgICAgICAgICByZXR1cm4gc3RkOjpzdXNwZW5kX25ldmVy
e307ICAvLyBib2R5IHJ1bnMgYXQgY29uc3RydWN0aW9uCiAgICAgICAgICAgIGVsc2UKICAgICAg
ICAgICAgICAgIHJldHVybiBzdGQ6OnN1c3BlbmRfYWx3YXlze307IC8vIGJvZHkgd2FpdHMgdW50
aWwgcmVzdW1lZAogICAgICAgIH0KCiAgICAgICAgYXV0byBmaW5hbF9zdXNwZW5kKCkgbm9leGNl
cHQKICAgICAgICB7CiAgICAgICAgICAgIHN0cnVjdCBhd2FpdGVyCiAgICAgICAgICAgIHsKICAg
ICAgICAgICAgICAgIHByb21pc2VfdHlwZSogcDsKICAgICAgICAgICAgICAgIGJvb2wgYXdhaXRf
cmVhZHkoKSBjb25zdCBub2V4Y2VwdCB7IHJldHVybiBmYWxzZTsgfQogICAgICAgICAgICAgICAg
c3RkOjpjb3JvdXRpbmVfaGFuZGxlPD4KICAgICAgICAgICAgICAgIGF3YWl0X3N1c3BlbmQoc3Rk
Ojpjb3JvdXRpbmVfaGFuZGxlPD4pIGNvbnN0IG5vZXhjZXB0CiAgICAgICAgICAgICAgICB7CiAg
ICAgICAgICAgICAgICAgICAgcmV0dXJuIHAtPmNvbnRpbnVhdGlvbigpOwogICAgICAgICAgICAg
ICAgfQogICAgICAgICAgICAgICAgdm9pZCBhd2FpdF9yZXN1bWUoKSBjb25zdCBub2V4Y2VwdCB7
fQogICAgICAgICAgICB9OwogICAgICAgICAgICByZXR1cm4gYXdhaXRlcnt0aGlzfTsKICAgICAg
ICB9CgogICAgICAgIC8vIEZhaXRoZnVsIHByb3RvY29sIGJlaGF2aW9yOiBpbmplY3QgZW52IGlu
dG8gbmVzdGVkIElvQXdhaXRhYmxlcywKICAgICAgICAvLyBqdXN0IGxpa2UgY2FweTo6dGFzayBk
b2VzLgogICAgICAgIHRlbXBsYXRlPGNsYXNzIEE+CiAgICAgICAgc3RydWN0IHRyYW5zZm9ybV9h
d2FpdGVyCiAgICAgICAgewogICAgICAgICAgICBzdGQ6OmRlY2F5X3Q8QT4gYV87CiAgICAgICAg
ICAgIHByb21pc2VfdHlwZSogcF87CiAgICAgICAgICAgIGJvb2wgYXdhaXRfcmVhZHkoKSB7IHJl
dHVybiBhXy5hd2FpdF9yZWFkeSgpOyB9CiAgICAgICAgICAgIGF1dG8gYXdhaXRfc3VzcGVuZChz
dGQ6OmNvcm91dGluZV9oYW5kbGU8PiBoKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBy
ZXR1cm4gYV8uYXdhaXRfc3VzcGVuZChoLCBwXy0+ZW52aXJvbm1lbnQoKSk7CiAgICAgICAgICAg
IH0KICAgICAgICAgICAgZGVjbHR5cGUoYXV0bykgYXdhaXRfcmVzdW1lKCkgeyByZXR1cm4gYV8u
YXdhaXRfcmVzdW1lKCk7IH0KICAgICAgICB9OwoKICAgICAgICB0ZW1wbGF0ZTxjbGFzcyBBPgog
ICAgICAgIGF1dG8gdHJhbnNmb3JtX2F3YWl0YWJsZShBJiYgYSkKICAgICAgICB7CiAgICAgICAg
ICAgIHN0YXRpY19hc3NlcnQoY2FweTo6SW9Bd2FpdGFibGU8c3RkOjpkZWNheV90PEE+PiwKICAg
ICAgICAgICAgICAgICJjb19hd2FpdCBpbnNpZGUgbXlfdGFzayByZXF1aXJlcyBhbiBJb0F3YWl0
YWJsZSIpOwogICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtX2F3YWl0ZXI8QT57c3RkOjpmb3J3
YXJkPEE+KGEpLCB0aGlzfTsKICAgICAgICB9CiAgICB9OwoKICAgIG15X3Rhc2sobXlfdGFzayYm
IG8pIG5vZXhjZXB0IDogaF8oc3RkOjpleGNoYW5nZShvLmhfLCB7fSkpIHt9CiAgICBteV90YXNr
KG15X3Rhc2sgY29uc3QmKSA9IGRlbGV0ZTsKICAgIH5teV90YXNrKCkgeyBpZihoXykgaF8uZGVz
dHJveSgpOyB9CgogICAgLy8tLS0tIElvQXdhaXRhYmxlIGludGVyZmFjZTogdGhlICJJIGZvbGxv
d2VkIHRoZSBwcm90b2NvbCIgcGFydCAtLS0tCgogICAgYm9vbCBhd2FpdF9yZWFkeSgpIGNvbnN0
IG5vZXhjZXB0IHsgcmV0dXJuIGZhbHNlOyB9CgogICAgc3RkOjpjb3JvdXRpbmVfaGFuZGxlPD4K
ICAgIGF3YWl0X3N1c3BlbmQoc3RkOjpjb3JvdXRpbmVfaGFuZGxlPD4gY29udCwgY2FweTo6aW9f
ZW52IGNvbnN0KiBlbnYpCiAgICB7CiAgICAgICAgaF8ucHJvbWlzZSgpLnNldF9jb250aW51YXRp
b24oY29udCk7CiAgICAgICAgaF8ucHJvbWlzZSgpLnNldF9lbnZpcm9ubWVudChlbnYpOyAvLyBz
dG9yZWQgZmFpdGhmdWxseSwgYXMgcmVxdWlyZWQKICAgICAgICByZXR1cm4gaF87CiAgICB9Cgog
ICAgVCBhd2FpdF9yZXN1bWUoKQogICAgewogICAgICAgIGF1dG8mIHAgPSBoXy5wcm9taXNlKCk7
CiAgICAgICAgaWYocC5leGNlcHRpb24oKSkKICAgICAgICAgICAgc3RkOjpyZXRocm93X2V4Y2Vw
dGlvbihwLmV4Y2VwdGlvbigpKTsKICAgICAgICBpZiBjb25zdGV4cHIoIXN0ZDo6aXNfdm9pZF92
PFQ+KQogICAgICAgICAgICByZXR1cm4gc3RkOjptb3ZlKHAucmVzdWx0KCkpOwogICAgfQoKICAg
IC8vLS0tLSBJb1J1bm5hYmxlIGJpdHMgLS0tLQogICAgc3RkOjpjb3JvdXRpbmVfaGFuZGxlPHBy
b21pc2VfdHlwZT4gaGFuZGxlKCkgY29uc3Qgbm9leGNlcHQgeyByZXR1cm4gaF87IH0KICAgIHZv
aWQgcmVsZWFzZSgpIG5vZXhjZXB0IHsgaF8gPSB7fTsgfQoKcHJpdmF0ZToKICAgIGV4cGxpY2l0
IG15X3Rhc2soc3RkOjpjb3JvdXRpbmVfaGFuZGxlPHByb21pc2VfdHlwZT4gaCkgbm9leGNlcHQg
OiBoXyhoKSB7fQogICAgc3RkOjpjb3JvdXRpbmVfaGFuZGxlPHByb21pc2VfdHlwZT4gaF87Cn07
CgovLyBQcm9vZiB0aGF0IHRoZSB0eXBlIGZvbGxvd3MgdGhlIHByb3RvY29sOiBib3RoIHZhcmlh
bnRzIEFSRSBJb0F3YWl0YWJsZXMuCnN0YXRpY19hc3NlcnQoY2FweTo6SW9Bd2FpdGFibGU8bXlf
dGFzazxmYWxzZSwgaW50Pj4sCiAgICAibGF6eSBteV90YXNrIG11c3Qgc2F0aXNmeSBJb0F3YWl0
YWJsZSIpOwpzdGF0aWNfYXNzZXJ0KGNhcHk6OklvQXdhaXRhYmxlPG15X3Rhc2s8dHJ1ZSwgaW50
Pj4sCiAgICAiZWFnZXIgbXlfdGFzayBtdXN0IHNhdGlzZnkgSW9Bd2FpdGFibGUiKTsKCi8vLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0KLy8gQSBwZXJmZWN0bHkgcmVhc29uYWJsZSBjb3JvdXRpbmUgYm9keS4KLy8tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLQppbmxpbmUgaW50CmV4cGVuc2l2ZV9zZXR1cCgpCnsKICAgIHN0ZDo6Y291dCA8PCAi
ICAgIFtjaGlsZF0gcnVubmluZyBzZXR1cCB3b3JrIGluIHRoZSBlYWdlciBwcmVmaXguLi5cbiI7
CiAgICByZXR1cm4gNDE7Cn0KCnRlbXBsYXRlPGJvb2wgRWFnZXI+Cm15X3Rhc2s8RWFnZXIsIGlu
dD4KY29tcHV0ZSgpCnsKICAgIC8vIC0tLS0gYm9keSB0aGF0IHJ1bnMgYmVmb3JlIHRoZSBmaXJz
dCByZWFsIHN1c3BlbnNpb24gLS0tLQogICAgaW50IHBhcnRpYWwgPSBleHBlbnNpdmVfc2V0dXAo
KTsKCiAgICAvLyBMb29rcyBjb21wbGV0ZWx5IHJlYXNvbmFibGU6IGNoZWNrIGZvciBjYW5jZWxs
YXRpb24gYmVmb3JlIGRvaW5nIHRoZQogICAgLy8gZXhwZW5zaXZlIEkvTyBiZWxvdy4gRm9yIEVh
Z2VyPT10cnVlIHRoaXMgZXhlY3V0ZXMgYmVmb3JlIGF3YWl0X3N1c3BlbmQKICAgIC8vIGV2ZXIg
cmFuLCBzbyB0aGUgcHJvbWlzZSBlbnZfIGlzIHN0aWxsIG51bGxwdHIuCiAgICBhdXRvIHRva2Vu
ID0gY29fYXdhaXQgY2FweTo6dGhpc19jb3JvOjpzdG9wX3Rva2VuOyAvLyBFYWdlciAtPiBudWxs
IGRlcmVmIC8gVUIKICAgIGlmKHRva2VuLnN0b3BfcmVxdWVzdGVkKCkpCiAgICAgICAgY29fcmV0
dXJuIDA7CgogICAgLy8gKFJlYWwgY29kZSB3b3VsZCBjb19hd2FpdCBhY3R1YWwgSS9PIGhlcmUu
KQogICAgY29fcmV0dXJuIHBhcnRpYWwgKyAxOwp9Cgp9IC8vIG5hbWVzcGFjZSBmb290Z3VuCgov
Ly0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tCi8vIEFuIG9yZGluYXJ5LWxvb2tpbmcgYXBwbGljYXRpb24gY29yb3V0aW5l
LiBOb3RoaW5nIGhlcmUgaGludHMgYXQgdHJvdWJsZS4KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpjYXB5Ojp0YXNr
PD4KYXBwKCkKewogICAgLy8gMSkgTGF6eSB2YXJpYW50OiBpZGVudGljYWwgYm9keSwgaWRlbnRp
Y2FsIHByb3RvY29sIC0+IHdvcmtzLgogICAgc3RkOjpjb3V0IDw8ICJbYXBwXSBhd2FpdGluZyBM
QVpZIGNvbXB1dGUoKS4uLlxuIjsKICAgIGludCBhID0gY29fYXdhaXQgZm9vdGd1bjo6Y29tcHV0
ZTxmYWxzZT4oKTsKICAgIHN0ZDo6Y291dCA8PCAiW2FwcF0gbGF6eSByZXN1bHQgPSAiIDw8IGEg
PDwgIlxuXG4iOwoKICAgIC8vIDIpIEVhZ2VyIHZhcmlhbnQ6IG9ubHkgaW5pdGlhbF9zdXNwZW5k
KCkgZGlmZmVycyAtPiBVQiB3aGlsZSB0aGUKICAgIC8vICAgIG9wZXJhbmQgYmVsb3cgaXMgYmVp
bmcgY29uc3RydWN0ZWQgKGl0cyBib2R5IHJ1bnMgaW1tZWRpYXRlbHkpLgogICAgc3RkOjpjb3V0
IDw8ICJbYXBwXSBhd2FpdGluZyBFQUdFUiBjb21wdXRlKCkuLi5cbiI7CiAgICBzdGQ6OmNvdXQu
Zmx1c2goKTsKICAgIGludCBiID0gY29fYXdhaXQgZm9vdGd1bjo6Y29tcHV0ZTx0cnVlPigpOwog
ICAgc3RkOjpjb3V0IDw8ICJbYXBwXSBlYWdlciByZXN1bHQgPSAiIDw8IGIgPDwgIiAobmV2ZXIg
cmVhY2hlZClcbiI7CiAgICBjb19yZXR1cm47Cn0KCmludAptYWluKCkKewogICAgY2FweTo6dGhy
ZWFkX3Bvb2wgcG9vbDsKICAgIGNhcHk6OnJ1bl9hc3luYyhwb29sLmdldF9leGVjdXRvcigpKShh
cHAoKSk7CiAgICBwb29sLmpvaW4oKTsKICAgIHJldHVybiAwOwp9Cg==
--000000000000e78eec0656138745
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Boost mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://lists.boost.org/mailman3/lists/boost.lists.boost.org/
Archived at: https://lists.boost.org/archives/list/[email protected]/message/EKPTHT3W3VQBG7EKDHDYWCSRNRWO3CBW/ 

--000000000000e78eec0656138745--