Topic: [RFC] Call for considering "the big picture" re:
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 18 Mar 2016 11:51:13 -0400
Raw View
This is a multi-part message in MIME format.
--------------010408070207040708050900
Content-Type: text/plain; charset=UTF-8
I was hoping to include this in the next mailing... apparently the
deadline for the same got decided only a handful of days before the
deadline itself.
Anyway... I'm asking for comments, as always. The attached paper is
*not* a proposal, but a discussion of ongoing work related to tuple-like
objects and parameter packs, and a call to consider a "big picture" as
far as where we are going and how we can bring features in this area to
C++ while maintaining consistency.
I know the acknowledgments section is not yet written. The plan is to
fill it in partly based on what feedback I get.
I'll probably be submitting this Sunday afternoon (U.S. time).
--
Matthew
--
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/nch85i%248ob%241%40ger.gmane.org.
--------------010408070207040708050900
Content-Type: text/html; charset=UTF-8;
name="dxxxx-tuple-like-unified-vision.html"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="dxxxx-tuple-like-unified-vision.html"
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjwhRE9DVFlQRSBodG1s
IFBVQkxJQyAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFRyYW5zaXRpb25hbC8vRU4iICJodHRw
Oi8vd3d3LnczLm9yZy9UUi94aHRtbDEvRFREL3hodG1sMS10cmFuc2l0aW9uYWwuZHRkIj4K
PGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHhtbDpsYW5nPSJl
biIgbGFuZz0iZW4iPgo8aGVhZD4KPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBj
b250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiIC8+CjxtZXRhIG5hbWU9ImdlbmVy
YXRvciIgY29udGVudD0iRG9jdXRpbHMgMC4xMTogaHR0cDovL2RvY3V0aWxzLnNvdXJjZWZv
cmdlLm5ldC8iIC8+Cjx0aXRsZT5BIFVuaWZpZWQgVmlzaW9uIGZvciBNYW5pcHVsYXRpbmcg
VHVwbGUtbGlrZSBPYmplY3RzPC90aXRsZT4KPG1ldGEgbmFtZT0iZGF0ZSIgY29udGVudD0i
MjAxNi0wMy0xOCIgLz4KPG1ldGEgbmFtZT0iYXV0aG9yIiBjb250ZW50PSJNYXR0aGV3IFdv
ZWhsa2UgKG13b2VobGtlLmZsb3NzJiM2NDtnbWFpbC5jb20pIiAvPgo8c3R5bGUgdHlwZT0i
dGV4dC9jc3MiPgoKLyoKOkF1dGhvcjogRGF2aWQgR29vZGdlciAoZ29vZGdlckBweXRob24u
b3JnKQo6SWQ6ICRJZDogaHRtbDRjc3MxLmNzcyA3NjE0IDIwMTMtMDItMjEgMTU6NTU6NTFa
IG1pbGRlICQKOkNvcHlyaWdodDogVGhpcyBzdHlsZXNoZWV0IGhhcyBiZWVuIHBsYWNlZCBp
biB0aGUgcHVibGljIGRvbWFpbi4KCkRlZmF1bHQgY2FzY2FkaW5nIHN0eWxlIHNoZWV0IGZv
ciB0aGUgSFRNTCBvdXRwdXQgb2YgRG9jdXRpbHMuCgpTZWUgaHR0cDovL2RvY3V0aWxzLnNm
Lm5ldC9kb2NzL2hvd3RvL2h0bWwtc3R5bGVzaGVldHMuaHRtbCBmb3IgaG93IHRvCmN1c3Rv
bWl6ZSB0aGlzIHN0eWxlIHNoZWV0LgoqLwoKLyogdXNlZCB0byByZW1vdmUgYm9yZGVycyBm
cm9tIHRhYmxlcyBhbmQgaW1hZ2VzICovCi5ib3JkZXJsZXNzLCB0YWJsZS5ib3JkZXJsZXNz
IHRkLCB0YWJsZS5ib3JkZXJsZXNzIHRoIHsKICBib3JkZXI6IDAgfQoKdGFibGUuYm9yZGVy
bGVzcyB0ZCwgdGFibGUuYm9yZGVybGVzcyB0aCB7CiAgLyogT3ZlcnJpZGUgcGFkZGluZyBm
b3IgInRhYmxlLmRvY3V0aWxzIHRkIiB3aXRoICIhIGltcG9ydGFudCIuCiAgICAgVGhlIHJp
Z2h0IHBhZGRpbmcgc2VwYXJhdGVzIHRoZSB0YWJsZSBjZWxscy4gKi8KICBwYWRkaW5nOiAw
IDAuNWVtIDAgMCAhIGltcG9ydGFudCB9CgouZmlyc3QgewogIC8qIE92ZXJyaWRlIG1vcmUg
c3BlY2lmaWMgbWFyZ2luIHN0eWxlcyB3aXRoICIhIGltcG9ydGFudCIuICovCiAgbWFyZ2lu
LXRvcDogMCAhIGltcG9ydGFudCB9CgoubGFzdCwgLndpdGgtc3VidGl0bGUgewogIG1hcmdp
bi1ib3R0b206IDAgISBpbXBvcnRhbnQgfQoKLmhpZGRlbiB7CiAgZGlzcGxheTogbm9uZSB9
CgphLnRvYy1iYWNrcmVmIHsKICB0ZXh0LWRlY29yYXRpb246IG5vbmUgOwogIGNvbG9yOiBi
bGFjayB9CgpibG9ja3F1b3RlLmVwaWdyYXBoIHsKICBtYXJnaW46IDJlbSA1ZW0gOyB9Cgpk
bC5kb2N1dGlscyBkZCB7CiAgbWFyZ2luLWJvdHRvbTogMC41ZW0gfQoKb2JqZWN0W3R5cGU9
ImltYWdlL3N2Zyt4bWwiXSwgb2JqZWN0W3R5cGU9ImFwcGxpY2F0aW9uL3gtc2hvY2t3YXZl
LWZsYXNoIl0gewogIG92ZXJmbG93OiBoaWRkZW47Cn0KCi8qIFVuY29tbWVudCAoYW5kIHJl
bW92ZSB0aGlzIHRleHQhKSB0byBnZXQgYm9sZC1mYWNlZCBkZWZpbml0aW9uIGxpc3QgdGVy
bXMKZGwuZG9jdXRpbHMgZHQgewogIGZvbnQtd2VpZ2h0OiBib2xkIH0KKi8KCmRpdi5hYnN0
cmFjdCB7CiAgbWFyZ2luOiAyZW0gNWVtIH0KCmRpdi5hYnN0cmFjdCBwLnRvcGljLXRpdGxl
IHsKICBmb250LXdlaWdodDogYm9sZCA7CiAgdGV4dC1hbGlnbjogY2VudGVyIH0KCmRpdi5h
ZG1vbml0aW9uLCBkaXYuYXR0ZW50aW9uLCBkaXYuY2F1dGlvbiwgZGl2LmRhbmdlciwgZGl2
LmVycm9yLApkaXYuaGludCwgZGl2LmltcG9ydGFudCwgZGl2Lm5vdGUsIGRpdi50aXAsIGRp
di53YXJuaW5nIHsKICBtYXJnaW46IDJlbSA7CiAgYm9yZGVyOiBtZWRpdW0gb3V0c2V0IDsK
ICBwYWRkaW5nOiAxZW0gfQoKZGl2LmFkbW9uaXRpb24gcC5hZG1vbml0aW9uLXRpdGxlLCBk
aXYuaGludCBwLmFkbW9uaXRpb24tdGl0bGUsCmRpdi5pbXBvcnRhbnQgcC5hZG1vbml0aW9u
LXRpdGxlLCBkaXYubm90ZSBwLmFkbW9uaXRpb24tdGl0bGUsCmRpdi50aXAgcC5hZG1vbml0
aW9uLXRpdGxlIHsKICBmb250LXdlaWdodDogYm9sZCA7CiAgZm9udC1mYW1pbHk6IHNhbnMt
c2VyaWYgfQoKZGl2LmF0dGVudGlvbiBwLmFkbW9uaXRpb24tdGl0bGUsIGRpdi5jYXV0aW9u
IHAuYWRtb25pdGlvbi10aXRsZSwKZGl2LmRhbmdlciBwLmFkbW9uaXRpb24tdGl0bGUsIGRp
di5lcnJvciBwLmFkbW9uaXRpb24tdGl0bGUsCmRpdi53YXJuaW5nIHAuYWRtb25pdGlvbi10
aXRsZSwgLmNvZGUgLmVycm9yIHsKICBjb2xvcjogcmVkIDsKICBmb250LXdlaWdodDogYm9s
ZCA7CiAgZm9udC1mYW1pbHk6IHNhbnMtc2VyaWYgfQoKLyogVW5jb21tZW50IChhbmQgcmVt
b3ZlIHRoaXMgdGV4dCEpIHRvIGdldCByZWR1Y2VkIHZlcnRpY2FsIHNwYWNlIGluCiAgIGNv
bXBvdW5kIHBhcmFncmFwaHMuCmRpdi5jb21wb3VuZCAuY29tcG91bmQtZmlyc3QsIGRpdi5j
b21wb3VuZCAuY29tcG91bmQtbWlkZGxlIHsKICBtYXJnaW4tYm90dG9tOiAwLjVlbSB9Cgpk
aXYuY29tcG91bmQgLmNvbXBvdW5kLWxhc3QsIGRpdi5jb21wb3VuZCAuY29tcG91bmQtbWlk
ZGxlIHsKICBtYXJnaW4tdG9wOiAwLjVlbSB9CiovCgpkaXYuZGVkaWNhdGlvbiB7CiAgbWFy
Z2luOiAyZW0gNWVtIDsKICB0ZXh0LWFsaWduOiBjZW50ZXIgOwogIGZvbnQtc3R5bGU6IGl0
YWxpYyB9CgpkaXYuZGVkaWNhdGlvbiBwLnRvcGljLXRpdGxlIHsKICBmb250LXdlaWdodDog
Ym9sZCA7CiAgZm9udC1zdHlsZTogbm9ybWFsIH0KCmRpdi5maWd1cmUgewogIG1hcmdpbi1s
ZWZ0OiAyZW0gOwogIG1hcmdpbi1yaWdodDogMmVtIH0KCmRpdi5mb290ZXIsIGRpdi5oZWFk
ZXIgewogIGNsZWFyOiBib3RoOwogIGZvbnQtc2l6ZTogc21hbGxlciB9CgpkaXYubGluZS1i
bG9jayB7CiAgZGlzcGxheTogYmxvY2sgOwogIG1hcmdpbi10b3A6IDFlbSA7CiAgbWFyZ2lu
LWJvdHRvbTogMWVtIH0KCmRpdi5saW5lLWJsb2NrIGRpdi5saW5lLWJsb2NrIHsKICBtYXJn
aW4tdG9wOiAwIDsKICBtYXJnaW4tYm90dG9tOiAwIDsKICBtYXJnaW4tbGVmdDogMS41ZW0g
fQoKZGl2LnNpZGViYXIgewogIG1hcmdpbjogMCAwIDAuNWVtIDFlbSA7CiAgYm9yZGVyOiBt
ZWRpdW0gb3V0c2V0IDsKICBwYWRkaW5nOiAxZW0gOwogIGJhY2tncm91bmQtY29sb3I6ICNm
ZmZmZWUgOwogIHdpZHRoOiA0MCUgOwogIGZsb2F0OiByaWdodCA7CiAgY2xlYXI6IHJpZ2h0
IH0KCmRpdi5zaWRlYmFyIHAucnVicmljIHsKICBmb250LWZhbWlseTogc2Fucy1zZXJpZiA7
CiAgZm9udC1zaXplOiBtZWRpdW0gfQoKZGl2LnN5c3RlbS1tZXNzYWdlcyB7CiAgbWFyZ2lu
OiA1ZW0gfQoKZGl2LnN5c3RlbS1tZXNzYWdlcyBoMSB7CiAgY29sb3I6IHJlZCB9CgpkaXYu
c3lzdGVtLW1lc3NhZ2UgewogIGJvcmRlcjogbWVkaXVtIG91dHNldCA7CiAgcGFkZGluZzog
MWVtIH0KCmRpdi5zeXN0ZW0tbWVzc2FnZSBwLnN5c3RlbS1tZXNzYWdlLXRpdGxlIHsKICBj
b2xvcjogcmVkIDsKICBmb250LXdlaWdodDogYm9sZCB9CgpkaXYudG9waWMgewogIG1hcmdp
bjogMmVtIH0KCmgxLnNlY3Rpb24tc3VidGl0bGUsIGgyLnNlY3Rpb24tc3VidGl0bGUsIGgz
LnNlY3Rpb24tc3VidGl0bGUsCmg0LnNlY3Rpb24tc3VidGl0bGUsIGg1LnNlY3Rpb24tc3Vi
dGl0bGUsIGg2LnNlY3Rpb24tc3VidGl0bGUgewogIG1hcmdpbi10b3A6IDAuNGVtIH0KCmgx
LnRpdGxlIHsKICB0ZXh0LWFsaWduOiBjZW50ZXIgfQoKaDIuc3VidGl0bGUgewogIHRleHQt
YWxpZ246IGNlbnRlciB9Cgpoci5kb2N1dGlscyB7CiAgd2lkdGg6IDc1JSB9CgppbWcuYWxp
Z24tbGVmdCwgLmZpZ3VyZS5hbGlnbi1sZWZ0LCBvYmplY3QuYWxpZ24tbGVmdCB7CiAgY2xl
YXI6IGxlZnQgOwogIGZsb2F0OiBsZWZ0IDsKICBtYXJnaW4tcmlnaHQ6IDFlbSB9CgppbWcu
YWxpZ24tcmlnaHQsIC5maWd1cmUuYWxpZ24tcmlnaHQsIG9iamVjdC5hbGlnbi1yaWdodCB7
CiAgY2xlYXI6IHJpZ2h0IDsKICBmbG9hdDogcmlnaHQgOwogIG1hcmdpbi1sZWZ0OiAxZW0g
fQoKaW1nLmFsaWduLWNlbnRlciwgLmZpZ3VyZS5hbGlnbi1jZW50ZXIsIG9iamVjdC5hbGln
bi1jZW50ZXIgewogIGRpc3BsYXk6IGJsb2NrOwogIG1hcmdpbi1sZWZ0OiBhdXRvOwogIG1h
cmdpbi1yaWdodDogYXV0bzsKfQoKLmFsaWduLWxlZnQgewogIHRleHQtYWxpZ246IGxlZnQg
fQoKLmFsaWduLWNlbnRlciB7CiAgY2xlYXI6IGJvdGggOwogIHRleHQtYWxpZ246IGNlbnRl
ciB9CgouYWxpZ24tcmlnaHQgewogIHRleHQtYWxpZ246IHJpZ2h0IH0KCi8qIHJlc2V0IGlu
bmVyIGFsaWdubWVudCBpbiBmaWd1cmVzICovCmRpdi5hbGlnbi1yaWdodCB7CiAgdGV4dC1h
bGlnbjogaW5oZXJpdCB9CgovKiBkaXYuYWxpZ24tY2VudGVyICogeyAqLwovKiAgIHRleHQt
YWxpZ246IGxlZnQgfSAqLwoKb2wuc2ltcGxlLCB1bC5zaW1wbGUgewogIG1hcmdpbi1ib3R0
b206IDFlbSB9CgpvbC5hcmFiaWMgewogIGxpc3Qtc3R5bGU6IGRlY2ltYWwgfQoKb2wubG93
ZXJhbHBoYSB7CiAgbGlzdC1zdHlsZTogbG93ZXItYWxwaGEgfQoKb2wudXBwZXJhbHBoYSB7
CiAgbGlzdC1zdHlsZTogdXBwZXItYWxwaGEgfQoKb2wubG93ZXJyb21hbiB7CiAgbGlzdC1z
dHlsZTogbG93ZXItcm9tYW4gfQoKb2wudXBwZXJyb21hbiB7CiAgbGlzdC1zdHlsZTogdXBw
ZXItcm9tYW4gfQoKcC5hdHRyaWJ1dGlvbiB7CiAgdGV4dC1hbGlnbjogcmlnaHQgOwogIG1h
cmdpbi1sZWZ0OiA1MCUgfQoKcC5jYXB0aW9uIHsKICBmb250LXN0eWxlOiBpdGFsaWMgfQoK
cC5jcmVkaXRzIHsKICBmb250LXN0eWxlOiBpdGFsaWMgOwogIGZvbnQtc2l6ZTogc21hbGxl
ciB9CgpwLmxhYmVsIHsKICB3aGl0ZS1zcGFjZTogbm93cmFwIH0KCnAucnVicmljIHsKICBm
b250LXdlaWdodDogYm9sZCA7CiAgZm9udC1zaXplOiBsYXJnZXIgOwogIGNvbG9yOiBtYXJv
b24gOwogIHRleHQtYWxpZ246IGNlbnRlciB9CgpwLnNpZGViYXItdGl0bGUgewogIGZvbnQt
ZmFtaWx5OiBzYW5zLXNlcmlmIDsKICBmb250LXdlaWdodDogYm9sZCA7CiAgZm9udC1zaXpl
OiBsYXJnZXIgfQoKcC5zaWRlYmFyLXN1YnRpdGxlIHsKICBmb250LWZhbWlseTogc2Fucy1z
ZXJpZiA7CiAgZm9udC13ZWlnaHQ6IGJvbGQgfQoKcC50b3BpYy10aXRsZSB7CiAgZm9udC13
ZWlnaHQ6IGJvbGQgfQoKcHJlLmFkZHJlc3MgewogIG1hcmdpbi1ib3R0b206IDAgOwogIG1h
cmdpbi10b3A6IDAgOwogIGZvbnQ6IGluaGVyaXQgfQoKcHJlLmxpdGVyYWwtYmxvY2ssIHBy
ZS5kb2N0ZXN0LWJsb2NrLCBwcmUubWF0aCwgcHJlLmNvZGUgewogIG1hcmdpbi1sZWZ0OiAy
ZW0gOwogIG1hcmdpbi1yaWdodDogMmVtIH0KCnByZS5jb2RlIC5sbiB7IGNvbG9yOiBncmV5
OyB9IC8qIGxpbmUgbnVtYmVycyAqLwpwcmUuY29kZSwgY29kZSB7IGJhY2tncm91bmQtY29s
b3I6ICNlZWVlZWUgfQpwcmUuY29kZSAuY29tbWVudCwgY29kZSAuY29tbWVudCB7IGNvbG9y
OiAjNUM2NTc2IH0KcHJlLmNvZGUgLmtleXdvcmQsIGNvZGUgLmtleXdvcmQgeyBjb2xvcjog
IzNCMEQwNjsgZm9udC13ZWlnaHQ6IGJvbGQgfQpwcmUuY29kZSAubGl0ZXJhbC5zdHJpbmcs
IGNvZGUgLmxpdGVyYWwuc3RyaW5nIHsgY29sb3I6ICMwQzU0MDQgfQpwcmUuY29kZSAubmFt
ZS5idWlsdGluLCBjb2RlIC5uYW1lLmJ1aWx0aW4geyBjb2xvcjogIzM1MkI4NCB9CnByZS5j
b2RlIC5kZWxldGVkLCBjb2RlIC5kZWxldGVkIHsgYmFja2dyb3VuZC1jb2xvcjogI0RFQjBB
MX0KcHJlLmNvZGUgLmluc2VydGVkLCBjb2RlIC5pbnNlcnRlZCB7IGJhY2tncm91bmQtY29s
b3I6ICNBM0QyODl9CgpzcGFuLmNsYXNzaWZpZXIgewogIGZvbnQtZmFtaWx5OiBzYW5zLXNl
cmlmIDsKICBmb250LXN0eWxlOiBvYmxpcXVlIH0KCnNwYW4uY2xhc3NpZmllci1kZWxpbWl0
ZXIgewogIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmIDsKICBmb250LXdlaWdodDogYm9sZCB9
CgpzcGFuLmludGVycHJldGVkIHsKICBmb250LWZhbWlseTogc2Fucy1zZXJpZiB9CgpzcGFu
Lm9wdGlvbiB7CiAgd2hpdGUtc3BhY2U6IG5vd3JhcCB9CgpzcGFuLnByZSB7CiAgd2hpdGUt
c3BhY2U6IHByZSB9CgpzcGFuLnByb2JsZW1hdGljIHsKICBjb2xvcjogcmVkIH0KCnNwYW4u
c2VjdGlvbi1zdWJ0aXRsZSB7CiAgLyogZm9udC1zaXplIHJlbGF0aXZlIHRvIHBhcmVudCAo
aDEuLmg2IGVsZW1lbnQpICovCiAgZm9udC1zaXplOiA4MCUgfQoKdGFibGUuY2l0YXRpb24g
ewogIGJvcmRlci1sZWZ0OiBzb2xpZCAxcHggZ3JheTsKICBtYXJnaW4tbGVmdDogMXB4IH0K
CnRhYmxlLmRvY2luZm8gewogIG1hcmdpbjogMmVtIDRlbSB9Cgp0YWJsZS5kb2N1dGlscyB7
CiAgbWFyZ2luLXRvcDogMC41ZW0gOwogIG1hcmdpbi1ib3R0b206IDAuNWVtIH0KCnRhYmxl
LmZvb3Rub3RlIHsKICBib3JkZXItbGVmdDogc29saWQgMXB4IGJsYWNrOwogIG1hcmdpbi1s
ZWZ0OiAxcHggfQoKdGFibGUuZG9jdXRpbHMgdGQsIHRhYmxlLmRvY3V0aWxzIHRoLAp0YWJs
ZS5kb2NpbmZvIHRkLCB0YWJsZS5kb2NpbmZvIHRoIHsKICBwYWRkaW5nLWxlZnQ6IDAuNWVt
IDsKICBwYWRkaW5nLXJpZ2h0OiAwLjVlbSA7CiAgdmVydGljYWwtYWxpZ246IHRvcCB9Cgp0
YWJsZS5kb2N1dGlscyB0aC5maWVsZC1uYW1lLCB0YWJsZS5kb2NpbmZvIHRoLmRvY2luZm8t
bmFtZSB7CiAgZm9udC13ZWlnaHQ6IGJvbGQgOwogIHRleHQtYWxpZ246IGxlZnQgOwogIHdo
aXRlLXNwYWNlOiBub3dyYXAgOwogIHBhZGRpbmctbGVmdDogMCB9CgovKiAiYm9va3RhYnMi
IHN0eWxlIChubyB2ZXJ0aWNhbCBsaW5lcykgKi8KdGFibGUuZG9jdXRpbHMuYm9va3RhYnMg
ewogIGJvcmRlcjogMHB4OwogIGJvcmRlci10b3A6IDJweCBzb2xpZDsKICBib3JkZXItYm90
dG9tOiAycHggc29saWQ7CiAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsKfQp0YWJsZS5k
b2N1dGlscy5ib29rdGFicyAqIHsKICBib3JkZXI6IDBweDsKfQp0YWJsZS5kb2N1dGlscy5i
b29rdGFicyB0aCB7CiAgYm9yZGVyLWJvdHRvbTogdGhpbiBzb2xpZDsKICB0ZXh0LWFsaWdu
OiBsZWZ0Owp9CgpoMSB0dC5kb2N1dGlscywgaDIgdHQuZG9jdXRpbHMsIGgzIHR0LmRvY3V0
aWxzLApoNCB0dC5kb2N1dGlscywgaDUgdHQuZG9jdXRpbHMsIGg2IHR0LmRvY3V0aWxzIHsK
ICBmb250LXNpemU6IDEwMCUgfQoKdWwuYXV0by10b2MgewogIGxpc3Qtc3R5bGUtdHlwZTog
bm9uZSB9Cgo8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5Pgo8ZGl2IGNsYXNzPSJkb2N1bWVudCIg
aWQ9ImEtdW5pZmllZC12aXNpb24tZm9yLW1hbmlwdWxhdGluZy10dXBsZS1saWtlLW9iamVj
dHMiPgo8aDEgY2xhc3M9InRpdGxlIj5BIFVuaWZpZWQgVmlzaW9uIGZvciBNYW5pcHVsYXRp
bmcgVHVwbGUtbGlrZSBPYmplY3RzPC9oMT4KPHRhYmxlIGNsYXNzPSJkb2NpbmZvIiBmcmFt
ZT0idm9pZCIgcnVsZXM9Im5vbmUiPgo8Y29sIGNsYXNzPSJkb2NpbmZvLW5hbWUiIC8+Cjxj
b2wgY2xhc3M9ImRvY2luZm8tY29udGVudCIgLz4KPHRib2R5IHZhbGlnbj0idG9wIj4KPHRy
IGNsYXNzPSJmaWVsZCI+PHRoIGNsYXNzPSJkb2NpbmZvLW5hbWUiPkRvY3VtZW50OjwvdGg+
PHRkIGNsYXNzPSJmaWVsZC1ib2R5Ij5EWFhYWFIwIChUQkQpPC90ZD4KPC90cj4KPHRyPjx0
aCBjbGFzcz0iZG9jaW5mby1uYW1lIj5EYXRlOjwvdGg+Cjx0ZD4yMDE2LTAzLTE4PC90ZD48
L3RyPgo8dHIgY2xhc3M9ImZpZWxkIj48dGggY2xhc3M9ImRvY2luZm8tbmFtZSI+UHJvamVj
dDo8L3RoPjx0ZCBjbGFzcz0iZmllbGQtYm9keSI+SVNPL0lFQyBKVEMxIFNDMjIgV0cyMSBQ
cm9ncmFtbWluZyBMYW5ndWFnZSBDKys8L3RkPgo8L3RyPgo8dHIgY2xhc3M9ImZpZWxkIj48
dGggY2xhc3M9ImRvY2luZm8tbmFtZSI+QXVkaWVuY2U6PC90aD48dGQgY2xhc3M9ImZpZWxk
LWJvZHkiPkV2b2x1dGlvbiBXb3JraW5nIEdyb3VwPC90ZD4KPC90cj4KPHRyPjx0aCBjbGFz
cz0iZG9jaW5mby1uYW1lIj5BdXRob3I6PC90aD4KPHRkPk1hdHRoZXcgV29laGxrZSAoPGEg
Y2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0ibWFpbHRvOm13b2VobGtlLmZsb3Nz
JiM2NDtnbWFpbC5jb20iPm13b2VobGtlLmZsb3NzJiM2NDtnbWFpbC5jb208L2E+KTwvdGQ+
PC90cj4KPC90Ym9keT4KPC90YWJsZT4KPHN0eWxlPgogIGh0bWwgeyBjb2xvcjogYmxhY2s7
IGJhY2tncm91bmQ6IHdoaXRlOyB9CiAgdGFibGUuZG9jaW5mbyB7IG1hcmdpbjogMmVtIDA7
IH0KPC9zdHlsZT48ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0iYWJzdHJhY3QiPgo8aDE+PGEg
Y2xhc3M9InRvYy1iYWNrcmVmIiBocmVmPSIjaWQ5Ij5BYnN0cmFjdDwvYT48L2gxPgo8cD5U
aGVyZSBpcyBtdWNoIGFjdGl2aXR5IGFuZCBkaXNjdXNzaW9uIHN1cnJvdW5kaW5nIHR1cGxl
LWxpa2Ugb2JqZWN0cywgd2l0aCBtYW55IGZlYXR1cmVzIGJlaW5nIHJlcXVlc3RlZCBhbmQg
bWFueSBwYXBlcnMgc3VibWl0dGVkIG9yIHBsYW5uZWQuIEl0IGlzIGltcG9ydGFudCB0aGF0
IHdlIGVzdGFibGlzaCBhIHBsYW4gZm9yIHdoZXJlIHdlIGFyZSBnb2luZyB0aGF0IHRha2Vz
IGludG8gYWNjb3VudCBmdXR1cmUgZGlyZWN0aW9ucyBpbiBvcmRlciB0byBhdm9pZCBvdmVy
Y29tcGxpY2F0aW5nIHRoZSBsYW5ndWFnZSBvciBwYWludGluZyBvdXJzZWx2ZXMgaW50byBh
IGNvcm5lciBvZiBpbmNvbXBhdGlibGUgZmVhdHVyZXMuPC9wPgo8ZGl2IGNsYXNzPSJjb250
ZW50cyB0b3BpYyIgaWQ9ImNvbnRlbnRzIj4KPHAgY2xhc3M9InRvcGljLXRpdGxlIGZpcnN0
Ij5Db250ZW50czwvcD4KPHVsIGNsYXNzPSJzaW1wbGUiPgo8bGk+PGEgY2xhc3M9InJlZmVy
ZW5jZSBpbnRlcm5hbCIgaHJlZj0iI2Fic3RyYWN0IiBpZD0iaWQ5Ij5BYnN0cmFjdDwvYT48
L2xpPgo8bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0iI2JhY2tncm91
bmQiIGlkPSJpZDEwIj5CYWNrZ3JvdW5kPC9hPjwvbGk+CjxsaT48YSBjbGFzcz0icmVmZXJl
bmNlIGludGVybmFsIiBocmVmPSIjZGVmaW5pdGlvbnMiIGlkPSJpZDExIj5EZWZpbml0aW9u
czwvYT48L2xpPgo8bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0iI2Fj
Y2VzcyIgaWQ9ImlkMTIiPkFjY2VzczwvYT48dWw+CjxsaT48YSBjbGFzcz0icmVmZXJlbmNl
IGludGVybmFsIiBocmVmPSIjYW4tb3BlcmF0b3ItbGlrZS1hbHRlcm5hdGl2ZSIgaWQ9Imlk
MTMiPkFuIG9wZXJhdG9yLWxpa2UgYWx0ZXJuYXRpdmU8L2E+PC9saT4KPC91bD4KPC9saT4K
PGxpPjxhIGNsYXNzPSJyZWZlcmVuY2UgaW50ZXJuYWwiIGhyZWY9IiNnZW5lcmFsaXplZC11
bnBhY2tpbmciIGlkPSJpZDE0Ij5HZW5lcmFsaXplZCBVbnBhY2tpbmc8L2E+PC9saT4KPGxp
PjxhIGNsYXNzPSJyZWZlcmVuY2UgaW50ZXJuYWwiIGhyZWY9IiN1bmlmaWNhdGlvbi1vZi11
bnBhY2tpbmciIGlkPSJpZDE1Ij5VbmlmaWNhdGlvbiBvZiBVbnBhY2tpbmc8L2E+PC9saT4K
PGxpPjxhIGNsYXNzPSJyZWZlcmVuY2UgaW50ZXJuYWwiIGhyZWY9IiNzbGljaW5nIiBpZD0i
aWQxNiI+U2xpY2luZzwvYT48L2xpPgo8bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5h
bCIgaHJlZj0iI3BhY2stZ2VuZXJhdGlvbi1yZXZpc2l0ZWQiIGlkPSJpZDE3Ij5QYWNrIEdl
bmVyYXRpb24sIFJldmlzaXRlZDwvYT48L2xpPgo8bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBp
bnRlcm5hbCIgaHJlZj0iI3N1bW1hcnkiIGlkPSJpZDE4Ij5TdW1tYXJ5PC9hPjwvbGk+Cjxs
aT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBocmVmPSIjYWNrbm93bGVkZ21lbnRz
IiBpZD0iaWQxOSI+QWNrbm93bGVkZ21lbnRzPC9hPjwvbGk+CjxsaT48YSBjbGFzcz0icmVm
ZXJlbmNlIGludGVybmFsIiBocmVmPSIjZm9vdG5vdGVzIiBpZD0iaWQyMCI+Rm9vdG5vdGVz
PC9hPjwvbGk+CjxsaT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBocmVmPSIjcmVm
ZXJlbmNlcyIgaWQ9ImlkMjEiPlJlZmVyZW5jZXM8L2E+PC9saT4KPC91bD4KPC9kaXY+Cjwv
ZGl2Pgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0iYmFja2dyb3VuZCI+CjxoMT48YSBjbGFz
cz0idG9jLWJhY2tyZWYiIGhyZWY9IiNpZDEwIj5CYWNrZ3JvdW5kPC9hPjwvaDE+CjxwPkF0
IHRoZSAyMDE2IEphY2tzb252aWxsZSBtZWV0aW5nLCA8YSBjbGFzcz0icmVmZXJlbmNlIGV4
dGVybmFsIiBocmVmPSJodHRwOi8vd2cyMS5saW5rL3AwMTQ0Ij5QMDE0NDwvYT4gd2FzIGRp
c2N1c3NlZCBmb3IgdGhlIHNlY29uZCB0aW1lLiBSZWNlcHRpb24gd2FzIGdlbmVyYWxseSBw
b3NpdGl2ZSwgYnV0IHNvbWUgaXNzdWVzIHJlbWFpbmVkIHRvIGJlIGFkZHJlc3NlZC4gSXQg
c2VlbXMgcXVpdGUgY2xlYXIgdGhhdCB0aGlzIGlzIGEgZGVzaXJlZCBkaXJlY3Rpb24gZm9y
IEMrKy4gVW5mb3J0dW5hdGVseSwgPGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJl
Zj0iaHR0cDovL3dnMjEubGluay9wMDE5NyI+UDAxOTc8L2E+LCB3aGljaCB3YXMgc2NoZWR1
bGVkIGZvciBwcmVzZW50YXRpb24gYW5kIGhhcyBzb21lIGltcGFjdCBvbiB0aGUgZGlyZWN0
aW9uIHdoaWNoIDxhIGNsYXNzPSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93
ZzIxLmxpbmsvcDAxNDQiPlAwMTQ0PC9hPiBpcyBmb2xsb3dpbmcsIHdhcyBza2lwcGVkIGR1
ZSB0byB0aW1lIGNvbnN0cmFpbnRzLjwvcD4KPHA+RGlzY3Vzc2lvbiBvbiB0aGUgPHR0IGNs
YXNzPSJkb2N1dGlscyBsaXRlcmFsIj48c3BhbiBjbGFzcz0icHJlIj5zdGQtcHJvcG9zYWxz
PC9zcGFuPjwvdHQ+IGZvcnVtIG9mdGVuIGJyaW5ncyB1cCB0aGUgZGVzaXJlIHRvIGV4dGVu
ZCB1c2Ugb2YgJnF1b3Q7dHVwbGUtbGlrZSZxdW90OyBvYmplY3RzIHRvIGNvbnRleHRzIG90
aGVyIHRoYW4gbmFtZSBiaW5kaW5nIChpLmUuIDxhIGNsYXNzPSJyZWZlcmVuY2UgZXh0ZXJu
YWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAxNDQiPlAwMTQ0PC9hPikuIFRoZXJlIGlz
IGFsc28gc2lnbmlmaWNhbnQgYW5kIHJlbGF0ZWQgZGlzY3Vzc2lvbiBvbiBpbXByb3Zpbmcg
dGhlIHVzYWJpbGl0eSBvZiBwYXJhbWV0ZXIgcGFja3MuIFdlIGZlZWwgdGhhdCBzZXZlcmFs
IG9mIHRoZXNlIGFyZWFzIGFyZSBjbG9zZWx5IHJlbGF0ZWQgYW5kIHdhcnJhbnQgdGhlIGZv
cm1hdGlvbiBvZiBhIGNvbmNyZXRlIGFuZCB1bmlmaWVkIHZpc2lvbiBmb3IgZnV0dXJlIGRp
cmVjdGlvbi48L3A+CjxwPldoaWxlIHdlIHByZXNlbnQgc2V2ZXJhbCBzdWdnZXN0aW9ucyBp
biB0aGlzIHBhcGVyLCB0aGlzIHBhcGVyIGlzIG5vdCBtZWFudCBhcyBhIGZvcm1hbCBwcm9w
b3NhbCwgYnV0IHJhdGhlciBhIHJlY29tbWVuZGF0aW9uIGZvciBhcmVhcyB3aGljaCB3ZSBm
ZWVsIG5lZWQgdG8gYmUgZXhwbG9yZWQsIGFuZCBpbiBwYXJ0aWN1bGFyLCBjb25zaWRlcmVk
IGJ5IG90aGVyIHByb3Bvc2FscyBiZWluZyBwdXQgZm9yd2FyZCwgZXNwZWNpYWxseSA8YSBj
bGFzcz0icmVmZXJlbmNlIGV4dGVybmFsIiBocmVmPSJodHRwOi8vd2cyMS5saW5rL3AwMTQ0
Ij5QMDE0NDwvYT4uPC9wPgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9ImRlZmlu
aXRpb25zIj4KPGgxPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkMTEiPkRlZmlu
aXRpb25zPC9hPjwvaDE+CjxwPkEgJnF1b3Q7dHVwbGUgbGlrZSZxdW90OyBpcyBhbnkgb2Jq
ZWN0IGNvbnNpc3Rpbmcgb2Ygb25lIG9yICh1c3VhbGx5KSBtb3JlIG9ydGhvZ29uYWwgdmFs
dWVzIChpbiBtYXRoZW1hdGljYWwgbm90YXRpb24sIGEgJnF1b3Q7cHJvZHVjdCB0eXBlJnF1
b3Q7KS4gVGhlIGNhbm9uaWNhbCBleGFtcGxlIGlzIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48
c3BhbiBjbGFzcz0ibmFtZSI+c3RkPC9zcGFuPjxzcGFuIGNsYXNzPSJvcGVyYXRvciI+Ojo8
L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUiPnR1cGxlPC9zcGFuPjwvY29kZT4sIGJ1dCBvdGhl
ciBleGFtcGxlcyBpbmNsdWRlIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0i
bmFtZSI+c3RkPC9zcGFuPjxzcGFuIGNsYXNzPSJvcGVyYXRvciI+Ojo8L3NwYW4+PHNwYW4g
Y2xhc3M9Im5hbWUiPmFycmF5PC9zcGFuPjwvY29kZT4gb3Igc2ltaWxhciBmaXhlZC1zaXpl
IHZlY3RvciB0eXBlcyBhbmQgbW9zdCBhZ2dyZWdhdGVzLCBhcyB3ZWxsIGFzIHNvbWUgbm9u
LWFnZ3JlZ2F0ZSB1c2VyIHR5cGVzIGluY2x1ZGluZyBvbmVzIHdpdGggbm8gcHVibGljIE5T
RE0nczxhIGNsYXNzPSJmb290bm90ZS1yZWZlcmVuY2UiIGhyZWY9IiNwdCIgaWQ9ImlkMSI+
WzFdPC9hPi48L3A+CjxwPiZxdW90O1VucGFja2luZyZxdW90OyByZWZlcnMgdG8gdGhlIGNv
bnZlcnNpb24gb2YgYSB0dXBsZS1saWtlIG9iamVjdCBpbnRvIGl0cyBjb21wb25lbnQgcGFy
dHMuIFRoaXMgaW5jbHVkZXMgYm90aCBuYW1lLWJpbmRpbmcgdW5wYWNraW5nIChpLmUuIDxh
IGNsYXNzPSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAx
NDQiPlAwMTQ0PC9hPikgYW5kICZxdW90O2dlbmVyYWxpemVkIHVucGFja2luZyZxdW90OyB3
aGVyZSB0aGUgY29tcG9uZW50cyBhcmUgdXNlZCBpbiBhIG5vbi1iaW5kaW5nIGNvbnRleHQ7
IGZvciBleGFtcGxlLCBhcyB2YWx1ZXMgaW4gYSBmdW5jdGlvbiBwYXJhbWV0ZXIgbGlzdC4g
TmFtZS1iaW5kaW5nIHVucGFja2luZyBpcyBhbHNvIGNhbGxlZCAmcXVvdDtzdHJ1Y3R1cmVk
IGJpbmRpbmcmcXVvdDsgYW5kLCBoaXN0b3JpY2FsbHksICZxdW90O2Fzc2lnbm1lbnQgdW5w
YWNraW5nJnF1b3Q7LiBXZSBwcmVmZXIgdGhlIHRlcm0gJnF1b3Q7bmFtZS1iaW5kaW5nIHVu
cGFja2luZyZxdW90OyBhcyBpdCBkb2VzIG5vdCBjYWxsIGludG8gcXVlc3Rpb24gaXNzdWVz
IG9mICZxdW90O3RydWUgYXNzaWdubWVudCZxdW90OyB2ZXJzdXMgYWxpYXNpbmcgd2hlcmUg
PGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDovL3dnMjEubGluay9w
MDE0NCI+UDAxNDQ8L2E+IHNwZWNpZmljYWxseSBkZXNpcmVzIHRvIGF2b2lkIGNlcnRhaW4g
b3ZlcmhlYWRzLCBhbmQgdGhlIHVzZSBvZiAmcXVvdDt1bnBhY2tpbmcmcXVvdDsgc2VydmVz
IHRvIGNvbm5lY3QgdHdvIGNsb3NlbHkgcmVsYXRlZCBjb25jZXB0cy48L3A+CjwvZGl2Pgo8
ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0iYWNjZXNzIj4KPGgxPjxhIGNsYXNzPSJ0b2MtYmFj
a3JlZiIgaHJlZj0iI2lkMTIiPkFjY2VzczwvYT48L2gxPgo8cD5PbmUgb2YgdGhlIGFjdGl2
ZSBxdWVzdGlvbnMgYXJvdW5kIDxhIGNsYXNzPSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9
Imh0dHA6Ly93ZzIxLmxpbmsvcDAxNDQiPlAwMTQ0PC9hPiByZWdhcmRzIHRoZSBjdXN0b21p
emF0aW9uIHBvaW50LiBXZSBmZWVsIHN0cm9uZ2x5IHRoYXQgdGhlIGN1c3RvbWl6YXRpb24g
cG9pbnQgZm9yIG5hbWUtYmluZGluZyB1bnBhY2tpbmcgc2hvdWxkIGJlIHRoZSBzYW1lIGFz
IHVzZWQgYnkgZ2VuZXJhbGl6ZWQgdW5wYWNraW5nIGFuZCBieSBleGlzdGluZyBhbmQgcHJv
cG9zZWQgdXRpbGl0eSBmdW5jdGlvbnMgKGUuZy4gPGNvZGUgY2xhc3M9ImNwcCBjKysiPjxz
cGFuIGNsYXNzPSJuYW1lIj5zdGQ8L3NwYW4+PHNwYW4gY2xhc3M9Im9wZXJhdG9yIj46Ojwv
c3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+YXBwbHk8L3NwYW4+PC9jb2RlPiBhbmQgPGNvZGUg
Y2xhc3M9ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJuYW1lIj5zdGQ8L3NwYW4+PHNwYW4gY2xh
c3M9Im9wZXJhdG9yIj46Ojwvc3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+bWFrZV9mcm9tX3R1
cGxlPC9zcGFuPjwvY29kZT4pIHRoYXQgYWN0IG9uIHR1cGxlLWxpa2Ugb2JqZWN0cy4gVGhp
cyBpcyBpbXBvcnRhbnQgZm9yIHRoZSBzYWtlIG9mIGNvbnNpc3RlbmN5OyB0aGVzZSBvcGVy
YXRpb25zIGFyZSBleHRyZW1lbHkgc2ltaWxhciwgYW5kIHVzaW5nIGRpZmZlcmVudCBjdXN0
b21pemF0aW9uIHBvaW50cyB3aWxsIGxpa2VseSByZXN1bHQgaW4gY29uZnVzaW9uIGFuZCB0
ZWFjaGluZyBkaWZmaWN1bHR5LjwvcD4KPHA+VGhhdCBzYWlkLCB3ZSBmZWVsIGxlc3Mgc3Ry
b25nbHkgYWJvdXQgdGhlIGV4YWN0IG5hdHVyZSBvZiB0aG9zZSBjdXN0b21pemF0aW9uIHBv
aW50cywgcHJvdmlkaW5nIHRoYXQgdGhvc2UgcG9pbnRzIHdoaWNoIGFyZSBldmVudHVhbGx5
IHVzZWQgcHJvdmlkZSBzYXRpc2ZhY3RvcnkgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkuPC9w
Pgo8cD5BdCBwcmVzZW50LCB0aGVzZSBjdXN0b21pemF0aW9uIHBvaW50cyBhcmU6PC9wPgo8
ZGwgY2xhc3M9ImRvY3V0aWxzIj4KPGR0Pjxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBj
bGFzcz0ibmFtZSI+Z2V0PC9zcGFuPjxzcGFuIGNsYXNzPSJvcGVyYXRvciI+Jmx0Ozwvc3Bh
bj48c3BhbiBjbGFzcz0ibmFtZSI+Tjwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPiZn
dDs8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4oPC9zcGFuPjxzcGFuIGNsYXNz
PSJuYW1lIj5UPC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+KTwvc3Bhbj48L2Nv
ZGU+OjwvZHQ+CjxkZD5BY2Nlc3MgdGhlIE4ndGggdmFsdWUgb2YgdGhlIHR1cGxlLWxpa2Us
IHdoZXJlIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0ibGl0ZXJhbCBudW1i
ZXIgaW50ZWdlciI+MDwvc3Bhbj4gPHNwYW4gY2xhc3M9Im9wZXJhdG9yIj4mbHQ7PC9zcGFu
PiA8c3BhbiBjbGFzcz0ibmFtZSI+Tjwvc3Bhbj4gPHNwYW4gY2xhc3M9Im9wZXJhdG9yIj4m
bHQ7PC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+dHVwbGVfc2l6ZTwvc3Bhbj48c3BhbiBj
bGFzcz0icHVuY3R1YXRpb24iPig8L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUiPlQ8L3NwYW4+
PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4pPC9zcGFuPjwvY29kZT4uPC9kZD4KPGR0Pjxj
b2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0ibmFtZSI+Y29uc3RleHByPC9zcGFu
PiA8c3BhbiBjbGFzcz0ibmFtZSI+dHVwbGVfc2l6ZTwvc3Bhbj48c3BhbiBjbGFzcz0icHVu
Y3R1YXRpb24iPig8L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUiPlQ8L3NwYW4+PHNwYW4gY2xh
c3M9InB1bmN0dWF0aW9uIj4pPC9zcGFuPjwvY29kZT46PC9kdD4KPGRkPlJldHVybnMgdGhl
IHNpemUgb2YgKGkuZS4gbnVtYmVyIG9mIGVsZW1lbnRzIGluKSB0aGUgdHVwbGUtbGlrZS48
L2RkPgo8L2RsPgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0iYW4tb3BlcmF0b3ItbGlrZS1h
bHRlcm5hdGl2ZSI+CjxoMj48YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhyZWY9IiNpZDEzIj5B
biBvcGVyYXRvci1saWtlIGFsdGVybmF0aXZlPC9hPjwvaDI+CjxwPlNvbWUgY29uY2VybnMg
d2VyZSBleHByZXNzZWQgdGhhdCBvdmVybG9hZGluZyBvbiA8Y29kZSBjbGFzcz0iY3BwIGMr
KyI+PHNwYW4gY2xhc3M9Im5hbWUiPmdldDwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3Ii
PiZsdDs8L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUiPk48L3NwYW4+PHNwYW4gY2xhc3M9Im9w
ZXJhdG9yIj4mZ3Q7PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+KDwvc3Bhbj48
c3BhbiBjbGFzcz0ibmFtZSI+VDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPik8
L3NwYW4+PC9jb2RlPiBpcyBub3QgYXBwcm9wcmlhdGUgZHVlIHRvIGl0cyB1c2UgZm9yIG90
aGVyIG9wZXJhdGlvbnMgdGhhdCBhcmUgbm90IHJlbGF0ZWQgdG8gdHVwbGUtbGlrZSBvYmpl
Y3RzLiBPbmUgYWx0ZXJuYXRpdmUgbWlnaHQgYmUgdG8gaW1wbGVtZW50IGEgbmV3IG9wZXJh
dG9yIHR5cGU6PC9wPgo8cHJlIGNsYXNzPSJjb2RlIGMrKyBsaXRlcmFsLWJsb2NrIj4KPHNw
YW4gY2xhc3M9ImtleXdvcmQiPm9wZXJhdG9yPC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSBm
dW5jdGlvbiI+Z2V0PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+KDwvc3Bhbj48
c3BhbiBjbGFzcz0ia2V5d29yZCI+YXV0bzwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3Ii
PiZhbXA7PC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+dHVwbGU8L3NwYW4+PHNwYW4gY2xh
c3M9InB1bmN0dWF0aW9uIj4sPC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+Y29uc3RleHBy
PC9zcGFuPiA8c3BhbiBjbGFzcz0ia2V5d29yZCB0eXBlIj5zaXplX3Q8L3NwYW4+IDxzcGFu
IGNsYXNzPSJuYW1lIj5pPC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+KTs8L3Nw
YW4+CjxzcGFuIGNsYXNzPSJuYW1lIj5jb25zdGV4cHI8L3NwYW4+IDxzcGFuIGNsYXNzPSJr
ZXl3b3JkIj5vcGVyYXRvcjwvc3Bhbj4gPHNwYW4gY2xhc3M9ImtleXdvcmQiPnNpemVvZjwv
c3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPiZsdDs8L3NwYW4+PHNwYW4gY2xhc3M9Im5h
bWUiPlQ8L3NwYW4+PHNwYW4gY2xhc3M9Im9wZXJhdG9yIj4mZ3Q7PC9zcGFuPjxzcGFuIGNs
YXNzPSJwdW5jdHVhdGlvbiI+KCk7PC9zcGFuPgo8L3ByZT4KPHA+SXQgbWF5IGJlIHJlYXNv
bmFibGUgb3IgZXZlbiBkZXNpcmFibGUgdG8gcmVzdHJpY3QgYWNjZXNzIG9mIHRoZXNlIG9w
ZXJhdG9ycyB0byBlaXRoZXIgZXhwbGljaXQgc3BlbGxpbmcgb3IgdXNlIG9mIGRlZGljYXRl
ZCBzeW50YXg6PC9wPgo8cHJlIGNsYXNzPSJjb2RlIGMrKyBsaXRlcmFsLWJsb2NrIj4KPHNw
YW4gY2xhc3M9Im5hbWUiPk15VHVwbGVMaWtlPC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+
dDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPjs8L3NwYW4+Cgo8c3BhbiBjbGFz
cz0icHVuY3R1YXRpb24iPls8L3NwYW4+PHNwYW4gY2xhc3M9ImxpdGVyYWwgbnVtYmVyIGlu
dGVnZXIiPjA8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj5dPC9zcGFuPjxzcGFu
IGNsYXNzPSJuYW1lIj50PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+Ozwvc3Bh
bj4gPHNwYW4gY2xhc3M9ImNvbW1lbnQgc2luZ2xlIj4vLyBvcGVyYXRvciBnZXQKPC9zcGFu
PjxzcGFuIGNsYXNzPSJrZXl3b3JkIj5zaXplb2Y8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0
dWF0aW9uIj4uLi4oPC9zcGFuPjxzcGFuIGNsYXNzPSJuYW1lIj50PC9zcGFuPjxzcGFuIGNs
YXNzPSJwdW5jdHVhdGlvbiI+KTs8L3NwYW4+IDxzcGFuIGNsYXNzPSJjb21tZW50IHNpbmds
ZSI+Ly8gb3BlcmF0b3Igc2l6ZW9mCjwvc3Bhbj4KPHNwYW4gY2xhc3M9ImtleXdvcmQiPmF1
dG88L3NwYW4+IDxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+Wzwvc3Bhbj48c3BhbiBjbGFz
cz0ibmFtZSI+eDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPiw8L3NwYW4+IDxz
cGFuIGNsYXNzPSJuYW1lIj55PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+XTwv
c3Bhbj4gPHNwYW4gY2xhc3M9Im9wZXJhdG9yIj49PC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFt
ZSI+dDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPjs8L3NwYW4+IDxzcGFuIGNs
YXNzPSJjb21tZW50IHNpbmdsZSI+Ly8gYm90aCwgdmlhIG5hbWUtYmluZGluZyB1bnBhY2tp
bmcsIGNhc2UgMgo8L3NwYW4+CjwvcHJlPgo8cD5XZSBzaG91bGQgbm90ZSB0aGF0LCB3aGls
ZSB0aGVyZSBhcmUgc29tZSBzdHJvbmcgZmVlbGluZ3Mgb24gdGhlc2UgdG9waWNzLCB3ZSBk
byBub3QgZmVlbCB0aGF0IGFueSBwYXJ0aWN1bGFyIHJlc29sdXRpb24gaXMgY3JpdGljYWwg
Zm9yIGFueSBvZiB0aGUgZGlyZWN0aW9ucyB3ZSBhcmUgZXhwbG9yaW5nLiBJbiB0aGlzIGFy
ZWEsIHdlIGZlZWwgb25seSB0aGF0IGEgY29uc2lzdGVudCBhbmQgY2xlYXIgZGlyZWN0aW9u
IGlzIGltcG9ydGFudC48L3A+CjxwPihUeXBlcyBoYXZlIGJlZW4gZWxpZGVkIGluIHRoZSBh
Ym92ZSBleGFtcGxlcywgYXMgdGhleSBhcmUgbm90IGNydWNpYWwgdG8gdGhlIGRpc2N1c3Np
b24uKTwvcD4KPC9kaXY+CjwvZGl2Pgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0iZ2VuZXJh
bGl6ZWQtdW5wYWNraW5nIj4KPGgxPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lk
MTQiPkdlbmVyYWxpemVkIFVucGFja2luZzwvYT48L2gxPgo8cD5HZW5lcmFsaXplZCB1bnBh
Y2tpbmcgaXMgdGhlIGNvbnZlcnNpb24gb2YgYSB0dXBsZS1saWtlIHRvIGEgJnF1b3Q7dmFs
dWUgc2VxdWVuY2UmcXVvdDssIGluIHRoZSBtYW5uZXIgb2YgUHl0aG9uJ3MgPHR0IGNsYXNz
PSJkb2N1dGlscyBsaXRlcmFsIj4qPC90dD4gb3BlcmF0b3IsIHN1Y2ggdGhhdCB0aGUgcmVz
dWx0aW5nIHNlcXVlbmNlIG1heSBiZSB1c2VkIGluIGFueSBwbGFjZSB0aGF0IGEgY29tbWEg
c2VwYXJhdGVkIHNlcXVlbmNlIG1heSBiZSB1c2VkLiBXaGlsZSBmdW5jdGlvbiBwYXJhbWV0
ZXIgbGlzdHMgaXMgdGhlIGNhbm9uaWNhbCBleGFtcGxlLCB0aGlzIHdvdWxkIGFsc28gaW5j
bHVkZSBicmFjZWQgaW5pdGlhbGl6ZXIgbGlzdHMuIEZvbGxvd2luZyBkaXNjdXNzaW9uIG9u
IHRoZSA8dHQgY2xhc3M9ImRvY3V0aWxzIGxpdGVyYWwiPjxzcGFuIGNsYXNzPSJwcmUiPnN0
ZC1wcm9wb3NhbHM8L3NwYW4+PC90dD4gZm9ydW0sIHdlIGJlbGlldmUgdGhhdCB0aGUgbW9z
dCByZWFzb25hYmxlIGFuZCB1c2VmdWwgbWVjaGFuaXNtIG9mIGFjY29tcGxpc2hpbmcgdGhp
cyBpcyB0byBwcm92aWRlIGEgbWVjaGFuaXNtIHdoZXJlYnkgYSB0dXBsZS1saWtlIG1heSBi
ZSBjb252ZXJ0ZWQgaW50byBhIHBhcmFtZXRlciBwYWNrLiBNdWNoIGFzIGluIHRoZSBuYW1l
LWJpbmRpbmcgdW5wYWNraW5nIGNhc2UsIHRoZXJlIGlzIGEgbG9naWNhbCBjb2RlIHRyYW5z
Zm9ybWF0aW9uIHRoYXQgY2FuIGJlIGFwcGxpZWQgZm9yIHRoaXMgcHVycG9zZSwgYnkgcGxh
Y2luZyB0aGUgdHVwbGUtbGlrZSBpbnRvIGEgdGVtcG9yYXJ5ICh3aGVyZSBuZWNlc3Nhcnks
IGkuZS4gaWYgdGhlIHR1cGxlLWxpa2UgaXMgYW4gZXhwcmVzc2lvbiByYXRoZXIgdGhhbiBh
bHJlYWR5IGEgbmFtZWQgdmFyaWFibGUpIGFuZCB0YWtpbmcgdGhlIHBhcmFtZXRlciBwYWNr
IHRvIGJlIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0ibmFtZSI+Z2V0PC9z
cGFuPjxzcGFuIGNsYXNzPSJvcGVyYXRvciI+Jmx0Ozwvc3Bhbj48c3BhbiBjbGFzcz0ibGl0
ZXJhbCBudW1iZXIgaW50ZWdlciI+MDwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPiZn
dDs8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4oPC9zcGFuPjxzcGFuIGNsYXNz
PSJrZXl3b3JkIHR5cGUiPl9fdDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPiks
PC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+Z2V0PC9zcGFuPjxzcGFuIGNsYXNzPSJvcGVy
YXRvciI+Jmx0Ozwvc3Bhbj48c3BhbiBjbGFzcz0ibGl0ZXJhbCBudW1iZXIgaW50ZWdlciI+
MTwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPiZndDs8L3NwYW4+PHNwYW4gY2xhc3M9
InB1bmN0dWF0aW9uIj4oPC9zcGFuPjxzcGFuIGNsYXNzPSJrZXl3b3JkIHR5cGUiPl9fdDwv
c3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPiksPC9zcGFuPiA8c3BhbiBjbGFzcz0i
cHVuY3R1YXRpb24iPi4uLjwvc3Bhbj48L2NvZGU+LiBUaGlzIGV4dGVuZHMgdGhlIHVzYWJs
ZSBzY29wZSB0byBhbnl3aGVyZSBhIGZvbGQgZXhwcmVzc2lvbiBtYXkgYmUgdXNlZC48L3A+
CjxwPldlIGFyZSBhd2FyZSBvZiBhdCBsZWFzdCB0aHJlZSBwb3NzaWJsZSBtZWNoYW5pc21z
IGZvciBpbXBsZW1lbnRpbmcgZ2VuZXJhbGl6ZWQgdW5wYWNraW5nLiBPbmUgb3B0aW9uIGlz
IHRvIGVtcGxveSBhIG5ldyBzeW50YXggdG8gcGVyZm9ybSB0aGlzIG9wZXJhdGlvbiBkaXJl
Y3RseS4gQW5vdGhlciBpcyB0byBtYWtlIG11bHRpcGxlIHJldHVybiB2YWx1ZXMsIHRyZWF0
ZWQgYXMgcGFyYW1ldGVyIHBhY2tzLCBmaXJzdCBjbGFzcyBjaXRpemVucyBvZiB0aGUgbGFu
Z3VhZ2UuIEEgdGhpcmQgaXMgdG8gY3JlYXRlIGEgcGFyYW1ldGVyIHBhY2sgJnF1b3Q7Z2Vu
ZXJhdG9yJnF1b3Q7LiBXaGlsZSB0aGUgbGF0dGVyIHR3byBvcHRpb25zIG1ha2VzIGl0IHBv
c3NpYmxlIHRvIHdyaXRlIGEgZnVuY3Rpb24gKHdoaWNoIG1pZ2h0IHJlYXNvbmFibHkgYmUg
bmFtZWQgPGNvZGUgY2xhc3M9ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJuYW1lIj5zdGQ8L3Nw
YW4+PHNwYW4gY2xhc3M9Im9wZXJhdG9yIj46Ojwvc3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+
dW5wYWNrPC9zcGFuPjwvY29kZT4pIHRoYXQgaXMgYm90aCBlcXVpdmFsZW50IHRvIHRoZSBm
b3JtZXIgYW5kIGFsbG93cyBmb3IgYSBncmVhdCBkZWFsIG9mIGV4cHJlc3NpdmVuZXNzIGFz
IHRvIHdoaWNoIGVsZW1lbnRzIGFyZSByZXR1cm5lZCBhbmQgaW4gd2hhdCBvcmRlciAoc3Vj
aCBhIGZ1bmN0aW9uIGNvdWxkLCBmb3IgZXhhbXBsZSwgdGFrZSBhIHRlbXBsYXRlIHBhcmFt
ZXRlciBzcGVjaWZ5aW5nIHRoZSBzYW1lKSwgd2Ugc3VzcGVjdCB0aGF0IGJvdGggd291bGQg
YmUgc2lnbmlmaWNhbnRseSBtb3JlIGludmFzaXZlPGEgY2xhc3M9ImZvb3Rub3RlLXJlZmVy
ZW5jZSIgaHJlZj0iI3BnIiBpZD0iaWQyIj5bMl08L2E+LiBBcyBhIHJlc3VsdCwgd2UgYXJl
IGluY2xpbmVkIHRvIGxlYW4gdG93YXJkIGEgZGlyZWN0IHN5bnRhY3RpYyBzb2x1dGlvbi48
L3A+CjxwPlNldmVyYWwgcG9zc2libGUgc3ludGF4ZXMgaGF2ZSBiZWVuIHByb3Bvc2VkLCBp
bmNsdWRpbmcgcG9zdGZpeCBvcGVyYXRvciA8dHQgY2xhc3M9ImRvY3V0aWxzIGxpdGVyYWwi
Pn48L3R0Pi4gT3VyIHByZWZlcmVuY2UsIGhvd2V2ZXIsIGlzIHByZWZpeCBvcGVyYXRvciA8
dHQgY2xhc3M9ImRvY3V0aWxzIGxpdGVyYWwiPls6XTwvdHQ+LiAoVGhlIHJlYXNvbnMgZm9y
IHRoZSB0aHJlZS1jaGFyYWN0ZXIgc3BlbGxpbmcgbWF5IGFscmVhZHkgYmUgb2J2aW91cyB0
byB0aG9zZSBmYW1pbGlhciB3aXRoIFB5dGhvbjsgd2Ugd2lsbCBleHBsb3JlIHRoZW0gbGF0
ZXIsIGluIDxhIGNsYXNzPSJyZWZlcmVuY2UgaW50ZXJuYWwiIGhyZWY9IiNzbGljaW5nIj5T
bGljaW5nPC9hPikuIEZvciBleGFtcGxlOjwvcD4KPHByZSBjbGFzcz0iY29kZSBjKysgbGl0
ZXJhbC1ibG9jayI+CjxzcGFuIGNsYXNzPSJrZXl3b3JkIj5zdHJ1Y3Q8L3NwYW4+IDxzcGFu
IGNsYXNzPSJwdW5jdHVhdGlvbiI+ezwvc3Bhbj4gPHNwYW4gY2xhc3M9ImtleXdvcmQgdHlw
ZSI+ZG91YmxlPC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+eDwvc3Bhbj48c3BhbiBjbGFz
cz0icHVuY3R1YXRpb24iPiw8L3NwYW4+IDxzcGFuIGNsYXNzPSJuYW1lIj55PC9zcGFuPjxz
cGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+Ozwvc3Bhbj4gPHNwYW4gY2xhc3M9InB1bmN0dWF0
aW9uIj59PC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+cG9pbnQ8L3NwYW4+IDxzcGFuIGNs
YXNzPSJvcGVyYXRvciI+PTwvc3Bhbj4gPHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4uLi47
PC9zcGFuPgo8c3BhbiBjbGFzcz0ia2V5d29yZCI+YXV0bzwvc3Bhbj4gPHNwYW4gY2xhc3M9
Im5hbWUiPmg8L3NwYW4+IDxzcGFuIGNsYXNzPSJvcGVyYXRvciI+PTwvc3Bhbj4gPHNwYW4g
Y2xhc3M9Im5hbWUiPnN0ZDwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPjo6PC9zcGFu
PjxzcGFuIGNsYXNzPSJuYW1lIj5oeXBvdDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRp
b24iPihbPC9zcGFuPjxzcGFuIGNsYXNzPSJvcGVyYXRvciI+Ojwvc3Bhbj48c3BhbiBjbGFz
cz0icHVuY3R1YXRpb24iPl08L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUiPnBvaW50PC9zcGFu
PjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+Li4uKTs8L3NwYW4+CjwvcHJlPgo8cD5UaGUg
YWRkaXRpb24gb2Ygc3VjaCBzeW50YXggd291bGQgb2J2aWF0ZSBtb3N0ICh0aG91Z2ggcGVy
aGFwcyBub3QgYWxsKSB1c2UgY2FzZXMgZm9yIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3Bh
biBjbGFzcz0ibmFtZSI+c3RkPC9zcGFuPjxzcGFuIGNsYXNzPSJvcGVyYXRvciI+Ojo8L3Nw
YW4+PHNwYW4gY2xhc3M9Im5hbWUiPmFwcGx5PC9zcGFuPjwvY29kZT4gYW5kIDxjb2RlIGNs
YXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0ibmFtZSI+c2Q8L3NwYW4+PHNwYW4gY2xhc3M9
Im9wZXJhdG9yIj46Ojwvc3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+bWFrZV9mcm9tX3R1cGxl
PC9zcGFuPjwvY29kZT4uIEl0IHdvdWxkIGFsc28gcGVybWl0IHRyaXZpYWwgY29udmVyc2lv
bnMgYmV0d2VlbiBkaWZmZXJlbnQgJnF1b3Q7c2ltcGxlJnF1b3Q7IHR5cGVzIHdoaWNoIGFy
ZSBkaXN0aW5jdCBidXQgbGF5b3V0IGNvbXBhdGlibGUsIGJ5IHVucGFja2luZyB0aGUgZmly
c3QgdHlwZSBpbnRvIGEgYnJhY2VkIGluaXRpYWxpemVyIGxpc3QgdXNlZCB0byBjb25zdHJ1
Y3QgdGhlIHNlY29uZC4gV2UgYmVsaWV2ZSB0aGF0IHRoaXMgZmVhdHVyZSB3aWxsIGJlIGF0
IGxlYXN0IGFzIGltcG9ydGFudCBhbmQgdXNlZnVsIGFzIG5hbWUtYmluZGluZyB1bnBhY2tp
bmcuPC9wPgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9InVuaWZpY2F0aW9uLW9m
LXVucGFja2luZyI+CjxoMT48YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhyZWY9IiNpZDE1Ij5V
bmlmaWNhdGlvbiBvZiBVbnBhY2tpbmc8L2E+PC9oMT4KPHA+UG9zc2libHkgdGhlIG1vc3Qg
aW1wb3J0YW50IGFzcGVjdCBvZiA8YSBjbGFzcz0icmVmZXJlbmNlIGV4dGVybmFsIiBocmVm
PSJodHRwOi8vd2cyMS5saW5rL3AwMTk3Ij5QMDE5NzwvYT4gaW4gb3VyIG9waW5pb24gaXMg
dGhlIHByb3Zpc2lvbiBmb3IgYSBzaW5nbGUsIHVuaWZpZWQgbWVjaGFuaXNtIGZvciB1bnBh
Y2tpbmcsIHdoZXRoZXIgaW4gdGhlIG5hbWUtYmluZGluZyBvciBnZW5lcmFsaXplZCBzZW5z
ZXMuIFRoZSBjcml0aWNhbCBhc3BlY3Qgb2YgPGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5h
bCIgaHJlZj0iaHR0cDovL3dnMjEubGluay9wMDE5NyI+UDAxOTc8L2E+LCBhbmQgdGhlIG9u
ZSB0aGF0IHdlIGZlZWwgc3Ryb25nbHkgbmVlZHMgdG8gYmUgY29uc2lkZXJlZCBieSA8YSBj
bGFzcz0icmVmZXJlbmNlIGV4dGVybmFsIiBocmVmPSJodHRwOi8vd2cyMS5saW5rL3AwMTQ0
Ij5QMDE0NDwvYT4sIGlzIHByb3ZpZGluZyBpbXBsaWNpdCBnZW5lcmFsIHR1cGxlLWxpa2Ug
YWNjZXNzIHRvIHNpbXBsZSBkYXRhIHN0cnVjdHVyZXMuIEluIHBhcnRpY3VsYXIsIHdlIGZl
ZWwgdGhhdCBpdCB3b3VsZCBiZSBhIHRyYXZlc3R5IGZvciBuYW1lLWJpbmRpbmcgdW5wYWNr
aW5nIGFuZCBnZW5lcmFsaXplZCB1bnBhY2tpbmcgdG8gdXNlIGRpZmZlcmVudCBjdXN0b21p
emF0aW9uIHBvaW50cyBvciB0byBvdGhlcndpc2UgYmVoYXZlIGRpZmZlcmVudGx5IHdoZW4g
dXNlZCBpbiB3YXlzIHdoZXJlIGludHVpdGlvbiBzdHJvbmdseSBleHBlY3RzIGVxdWl2YWxl
bnQgYmVoYXZpb3IuIEluIHBhcnRpY3VsYXIsIHdlIGZlZWwgc3Ryb25nbHkgdGhhdCwgZm9y
IGEgdHVwbGUtbGlrZSB0eXBlIGhhdmluZyBhIGRlZmF1bHQgZGVzdHJ1Y3RvciwgdGhlIGZv
bGxvd2luZyBzaG91bGQgYmUgZXF1aXZhbGVudCAoYWZ0ZXIgb3B0aW1pemF0aW9ucyk6PC9w
Pgo8cHJlIGNsYXNzPSJjb2RlIGMrKyBsaXRlcmFsLWJsb2NrIj4KPHNwYW4gY2xhc3M9Imtl
eXdvcmQiPmF1dG88L3NwYW4+IDxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+Wzwvc3Bhbj48
c3BhbiBjbGFzcz0ibmFtZSI+eDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPiw8
L3NwYW4+IDxzcGFuIGNsYXNzPSJuYW1lIj55PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVh
dGlvbiI+XTwvc3Bhbj4gPHNwYW4gY2xhc3M9Im9wZXJhdG9yIj49PC9zcGFuPiA8c3BhbiBj
bGFzcz0ibmFtZSI+dDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPjs8L3NwYW4+
CjxzcGFuIGNsYXNzPSJrZXl3b3JkIj5hdXRvPC9zcGFuPiA8c3BhbiBjbGFzcz0icHVuY3R1
YXRpb24iPls8L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUiPng8L3NwYW4+PHNwYW4gY2xhc3M9
InB1bmN0dWF0aW9uIj4sPC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+eTwvc3Bhbj48c3Bh
biBjbGFzcz0icHVuY3R1YXRpb24iPl08L3NwYW4+IDxzcGFuIGNsYXNzPSJvcGVyYXRvciI+
PTwvc3Bhbj4gPHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj57Wzwvc3Bhbj48c3BhbiBjbGFz
cz0ib3BlcmF0b3IiPjo8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj5dPC9zcGFu
PjxzcGFuIGNsYXNzPSJuYW1lIj50PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+
Li4ufTs8L3NwYW4+CjwvcHJlPgo8cD4oVGhpcyBpbGx1c3RyYXRlcyBhIG5lZWQgdG8gYmUg
Y2FyZWZ1bCB3aXRoIGxpZmV0aW1lIHNlbWFudGljczsgaW4gcGFydGljdWxhciwgPGNvZGUg
Y2xhc3M9ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+Wzwvc3Bhbj48c3Bh
biBjbGFzcz0ib3BlcmF0b3IiPjo8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj5d
PC9zcGFuPjwvY29kZT4gc2hvdWxkIGxpa2VseSBlaXRoZXIgZXh0ZW5kIGxpZmV0aW1lIHdo
ZW4gdXNlZCBpbiBhIGJyYWNlZCBpbml0aWFsaXplciBsaXN0LCBvciBzaG91bGQgZXhwbGlj
aXRseSBjcmVhdGUgdmFsdWUgY29waWVzIGluIHN1Y2ggY2FzZS4gVGhlIGZvcm1lciB3b3Vs
ZCBtYWtlIHRoZSBhYm92ZSBlcXVpdmFsZW50IGZvciA8ZW0+YW55PC9lbT4gdHVwbGUtbGlr
ZSwgd2hpbGUgdGhlIGxhdHRlciBtYXkgYmUgdXNlZnVsIGZvciBzZXBhcmF0aW5nIGxpZmV0
aW1lIG9mIHRoZSB0dXBsZS1saWtlIGFuZCBpdHMgY29tcG9uZW50cy4gV2UgZG8gbm90IHJl
Y29tbWVuZCBhIGRpcmVjdGlvbiBhdCB0aGlzIHRpbWUuKTwvcD4KPHA+SXQgc2hvdWxkIGJl
IG5vdGVkIHRoYXQgPGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDov
L3dnMjEubGluay9wMDE5NyI+UDAxOTc8L2E+IHdvdWxkIHByb3ZpZGUgYSBtb2Rlc3QgZW5o
YW5jZW1lbnQgdG8gbmFtZS1iaW5kaW5nIHVucGFja2luZy4gV2hlcmUgPGEgY2xhc3M9InJl
ZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDovL3dnMjEubGluay9wMDE0NCI+UDAxNDQ8
L2E+IGxpbWl0cyBpdHNlbGYgdG8gJnF1b3Q7ZmxhdCZxdW90OyBjbGFzc2VzLCA8YSBjbGFz
cz0icmVmZXJlbmNlIGV4dGVybmFsIiBocmVmPSJodHRwOi8vd2cyMS5saW5rL3AwMTk3Ij5Q
MDE5NzwvYT4gd291bGQgZXh0ZW5kIGltcGxpY2l0IHR1cGxlLWxpa2UgYWNjZXNzIHRvIGFs
bCBjbGFzc2VzIHdoaWNoOjwvcD4KPGJsb2NrcXVvdGU+Cjx1bCBjbGFzcz0ic2ltcGxlIj4K
PGxpPkNvbnRhaW4gbm8gbm9uLXB1YmxpYyBOU0RNJ3M8L2xpPgo8bGk+Q29udGFpbiBubyBt
ZW1iZXJzIG9mIHVuaW9uIHR5cGU8L2xpPgo8bGk+SGF2ZSBubyB2aXJ0dWFsPGEgY2xhc3M9
ImZvb3Rub3RlLXJlZmVyZW5jZSIgaHJlZj0iI3ZiIiBpZD0iaWQzIj5bM108L2E+IGFuZC9v
ciBub24tcHVibGljPGEgY2xhc3M9ImZvb3Rub3RlLXJlZmVyZW5jZSIgaHJlZj0iI2ViIiBp
ZD0iaWQ0Ij5bNF08L2E+IGJhc2UgY2xhc3NlczwvbGk+CjxsaT5IYXZlIG5vIGJhc2UgY2xh
c3NlcyB3aGljaCBkbyBub3QgYWxzbyBtZWV0IHRoZSBwcmVjZWRpbmcgZWxpZ2liaWxpdHkg
Y3JpdGVyaWE8L2xpPgo8L3VsPgo8L2Jsb2NrcXVvdGU+CjxwPldoaWxlIGl0IHdvdWxkIG5v
dCBiZSBhIGNhdGFzdHJvcGhpYyBsb3NzIGlmIG5vbi0mcXVvdDtmbGF0JnF1b3Q7IGNsYXNz
ZXMgd2VyZSBub3Qgc3VwcG9ydGVkLCB3ZSBkbyBmZWVsIHRoYXQgaXQgd291bGQgYmUgbW9z
dCB1bmZvcnR1bmF0ZSBpZiB3ZSBhcmUgbm90IGFibGUg4oCUIGV2ZW50dWFsbHkg4oCUIHRv
IHJlbHkgb24gdGhpcyBpbXBsaWNpdCBhY2Nlc3MgdG8gaW1wbGVtZW50IG5hbWUtYmluZGlu
ZyB1bnBhY2tpbmcsIGFuZCBhY2NvcmRpbmdseSB0byBlbGltaW5hdGUgPGEgY2xhc3M9InJl
ZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDovL3dnMjEubGluay9wMDE0NCI+UDAxNDQ8
L2E+IGNhc2UgMy4gSW4gYWRkaXRpb24gdG8gY29uc2lzdGVuY3ksIHdlIGZlZWwgdGhhdCB0
aGlzIGlzIGltcG9ydGFudCBmb3IgdGhlIHNha2Ugb2Ygc2ltcGxpY2l0eSwgYXMgaXQgZWxp
bWluYXRlcyBhIHNwZWNpYWwgY2FzZSBmcm9tIG5hbWUtYmluZGluZyB1bnBhY2tpbmcuIFdl
IGFyZSBjb25maWRlbnQgdGhhdCB0aGUgcGVyZm9ybWFuY2UgaXNzdWVzICh0aGF0IGlzLCB0
aGUgdW5kZXJzdGFuZGluZyB0aGF0IGNhc2UgMyByZXByZXNlbnRzIG5hbWUgYWxpYXNpbmcg
YW5kIG5laXRoZXIgY29uc3VtZXMgc3RvcmFnZSBiZXlvbmQgdGhhdCByZXF1aXJlZCBmb3Ig
dGhlIHR1cGxlLWxpa2UgaXRzZWxmIG5vciBhZGRzIGFueSBhY2Nlc3MgaW5kaXJlY3Rpb24p
IGNhbiBiZSBzYXRpc2ZhY3RvcmlseSBhZGRyZXNzZWQgdGhyb3VnaCBjb21waWxlciBvcHRp
bWl6YXRpb24sIGtlZXBpbmcgaW4gbWluZCBvZiBjb3Vyc2UgdGhhdCB0aGUgaW1wbGVtZW50
YXRpb25zIG9mIHRoZSAmcXVvdDtnZXQmcXVvdDsgZnVuY3Rpb24gKGhvd2V2ZXIgd2UgdWx0
aW1hdGVseSBzcGVsbCBpdCkgYXJlIGlubGluZSBpbiB0aGVzZSBpbnN0YW5jZXMuPC9wPgo8
cD5UaGUgcHJvYmxlbSB0aGF0IGFyaXNlcyBmcm9tIHRoaXMgYXBwcm9hY2ggaXMgYml0Zmll
bGQgbWVtYmVycy4gQXQgdGhlIDIwMTYgSmFja3NvbnZpbGxlIG1lZXRpbmcsIGF0IGxlYXN0
IG9uZSBpbmRpdmlkdWFsIGV4cHJlc3NlZCBhIHN0cm9uZyBvcGluaW9uIHRoYXQgcHJvdmlk
aW5nIHJlYWQvd3JpdGUgYWNjZXNzIHRvIGJpdGZpZWxkIG1lbWJlcnMgdmlhIG5hbWUtYmlu
ZGluZyB1bnBhY2tpbmcgaXMgYSAmcXVvdDttdXN0IGhhdmUmcXVvdDsgZmVhdHVyZS4gV2Ug
ZW5jb3VyYWdlIGdpdmluZyBzZXJpb3VzIGNvbnNpZGVyYXRpb24gdG8gdGhlIHRydWUgaW1w
b3J0YW5jZSBvZiB0aGlzIGZlYXR1cmUsIGFuZCB0byB3YXlzIHRoYXQgdGhpcyBjb3VsZCBi
ZSBhZGRyZXNzZWQgaW4gYSB3YXkgdGhhdCBkb2VzIG5vdCByZXF1aXJlIHNwZWNpYWwgY2Fz
aW5nLiAoSW4gcGFydGljdWxhciwgd2Ugbm90ZSB0aGF0IHRoZSBnZW5lcmFsIGFiaWxpdHkg
dG8gaGF2ZSBhIHJlZmVyZW5jZSB0byBhIGJpdGZpZWxkIOKAlCBsaWtlbHkgdGhyb3VnaCBz
b21lIG5ldyBsaWJyYXJ5IHR5cGUg4oCUIHNlZW1zIGF0IGxlYXN0IGFzIGludGVyZXN0aW5n
IGFzIGJlaW5nIGFibGUgdG8gbmFtZS1iaW5kIHRvIGEgY29tcG9uZW50IG9mIHN1Y2ggdHlw
ZSBvZiBhIHR1cGxlLWxpa2UuKTwvcD4KPC9kaXY+CjxkaXYgY2xhc3M9InNlY3Rpb24iIGlk
PSJzbGljaW5nIj4KPGgxPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkMTYiPlNs
aWNpbmc8L2E+PC9oMT4KPHA+SW4gb3VyIGVhcmxpZXIgZGlzY3Vzc2lvbiBvbiA8YSBjbGFz
cz0icmVmZXJlbmNlIGludGVybmFsIiBocmVmPSIjYWNjZXNzIj5BY2Nlc3M8L2E+LCB3ZSBt
ZW50aW9uZWQgc3ludGF4IGZvciBhY2Nlc3Npbmcgc3BlY2lmaWMgZWxlbWVudHMgb2YgYSB0
dXBsZS1saWtlLiBXaGlsZSB0aGUgbmVlZCB0byBhY2Nlc3MgaW5kaXZpZHVhbCBlbGVtZW50
cyBpcyBvYnZpb3VzIGFuZCBjbGVhcmx5IGRvZXMgbm90IHJlcXVpcmUgYSBzeW50YWN0aWMg
c29sdXRpb24gKHdlIGFscmVhZHkgaGF2ZSA8Y2l0ZT5zdGQ6OmdldCZsdDtOJmd0OzwvY2l0
ZT4pLCBhbm90aGVyIGRlc2lyZSB0aGF0IGNvbWVzIHVwIG9mdGVuIGlzIHRoZSBhYmlsaXR5
IHRvIHNsaWNlIGEgdHVwbGUtbGlrZTsgZS5nLiB0byBzdHJpcCB0aGUgZmlyc3QgZWxlbWVu
dCBvciB0YWtlIG9ubHkgdGhlIGZpcnN0IE4gZWxlbWVudHMuIEl0IGlzIGZvciB0aGlzIHJl
YXNvbiB0aGF0IHdlIHNlbGVjdGVkIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFz
cz0icHVuY3R1YXRpb24iPls8L3NwYW4+PHNwYW4gY2xhc3M9Im9wZXJhdG9yIj46PC9zcGFu
PjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+XTwvc3Bhbj48L2NvZGU+IGFzIG91ciBwcmVm
ZXJyZWQgc3ludGF4OyBhcyBpbiBQeXRob24sIGl0IHJlYWRpbHkgbGVuZHMgaXRzZWxmIHRv
IGV4dGVuc2lvbjo8L3A+CjxwcmUgY2xhc3M9ImNvZGUgYysrIGxpdGVyYWwtYmxvY2siPgo8
c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPls8L3NwYW4+PHNwYW4gY2xhc3M9ImxpdGVyYWwg
bnVtYmVyIGludGVnZXIiPjE8L3NwYW4+PHNwYW4gY2xhc3M9Im9wZXJhdG9yIj46PC9zcGFu
PjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+XTwvc3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+
dDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPjs8L3NwYW4+IDxzcGFuIGNsYXNz
PSJjb21tZW50IHNpbmdsZSI+Ly8gQWNjZXNzIGVsZW1lbnRzIDEuLiZsdDtOIG9mIHQKPC9z
cGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+Wzwvc3Bhbj48c3BhbiBjbGFzcz0ibGl0
ZXJhbCBudW1iZXIgaW50ZWdlciI+MDwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPjo8
L3NwYW4+PHNwYW4gY2xhc3M9ImxpdGVyYWwgbnVtYmVyIGludGVnZXIiPjI8L3NwYW4+PHNw
YW4gY2xhc3M9InB1bmN0dWF0aW9uIj5dPC9zcGFuPjxzcGFuIGNsYXNzPSJuYW1lIj50PC9z
cGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+Ozwvc3Bhbj4gPHNwYW4gY2xhc3M9ImNv
bW1lbnQgc2luZ2xlIj4vLyBBY2Nlc3MgZWxlbWVudHMgMC4uJmx0OzIgb2YgdAo8L3NwYW4+
PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj5bPC9zcGFuPjxzcGFuIGNsYXNzPSJvcGVyYXRv
ciI+LTwvc3Bhbj48c3BhbiBjbGFzcz0ibGl0ZXJhbCBudW1iZXIgaW50ZWdlciI+Mjwvc3Bh
bj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPjo8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0
aW9uIj5dPC9zcGFuPjxzcGFuIGNsYXNzPSJuYW1lIj50PC9zcGFuPjxzcGFuIGNsYXNzPSJw
dW5jdHVhdGlvbiI+Ozwvc3Bhbj4gPHNwYW4gY2xhc3M9ImNvbW1lbnQgc2luZ2xlIj4vLyBB
Y2Nlc3MgZWxlbWVudHMgTi0yLi4mbHQ7TiBvZiB0Cjwvc3Bhbj48c3BhbiBjbGFzcz0icHVu
Y3R1YXRpb24iPls8L3NwYW4+PHNwYW4gY2xhc3M9ImxpdGVyYWwgbnVtYmVyIGludGVnZXIi
PjM8L3NwYW4+PHNwYW4gY2xhc3M9Im9wZXJhdG9yIj46LTwvc3Bhbj48c3BhbiBjbGFzcz0i
bGl0ZXJhbCBudW1iZXIgaW50ZWdlciI+MTwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRp
b24iPl08L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUiPnQ8L3NwYW4+PHNwYW4gY2xhc3M9InB1
bmN0dWF0aW9uIj47PC9zcGFuPiA8c3BhbiBjbGFzcz0iY29tbWVudCBzaW5nbGUiPi8vIEFj
Y2VzcyBlbGVtZW50cyAzLi4mbHQ7Ti0xIG9mIHQKPC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5j
dHVhdGlvbiI+Wzwvc3Bhbj48c3BhbiBjbGFzcz0ibGl0ZXJhbCBudW1iZXIgaW50ZWdlciI+
NDwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPjo8L3NwYW4+PHNwYW4gY2xhc3M9Imxp
dGVyYWwgbnVtYmVyIGludGVnZXIiPjE8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9u
Ij5dPC9zcGFuPjxzcGFuIGNsYXNzPSJuYW1lIj50PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5j
dHVhdGlvbiI+Ozwvc3Bhbj4gPHNwYW4gY2xhc3M9ImNvbW1lbnQgc2luZ2xlIj4vLyBBY2Nl
c3MgZWxlbWVudCA0IG9mIHQgYXMgYSBwYXJhbWV0ZXIgcGFjawo8L3NwYW4+PHNwYW4gY2xh
c3M9InB1bmN0dWF0aW9uIj5bPC9zcGFuPjxzcGFuIGNsYXNzPSJsaXRlcmFsIG51bWJlciBp
bnRlZ2VyIj40PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+XTwvc3Bhbj48c3Bh
biBjbGFzcz0ibmFtZSI+dDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPjs8L3Nw
YW4+IDxzcGFuIGNsYXNzPSJjb21tZW50IHNpbmdsZSI+Ly8gQWNjZXNzIGVsZW1lbnQgNCBv
ZiB0IGFzIGEgdmFsdWUKPC9zcGFuPgo8L3ByZT4KPHA+VGhpcyBjYW4gYmUgZXh0ZW5kZWQg
dG8gd29yayB3aXRoIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0ibmFtZSI+
Y29uc3RleHByPC9zcGFuPjwvY29kZT4gZXhwcmVzc2lvbnMgZm9yIHRoZSBpbmRpY2VzLiBU
aGUgcGFyc2luZyBpbiB0aGF0IGNhc2UgYmVjb21lcyBsZXNzIHRyaXZpYWwsIGJ1dCB3ZSBi
ZWxpZXZlIHRoYXQgaXQgaXMgc3RpbGwgdW5hbWJpZ3VvdXMgd2l0aCBsYW1iZGEgY2FwdHVy
ZTxhIGNsYXNzPSJmb290bm90ZS1yZWZlcmVuY2UiIGhyZWY9IiNsYyIgaWQ9ImlkNSI+WzVd
PC9hPi4gKE90aGVyIHN5bnRheGVzIG1heSBiZSBwb3NzaWJsZS4pIE1vcmVvdmVyLCB0aGUg
c3ludGF4IGNhbiBiZSByZWFkaWx5IGV4dGVuZGVkIHRvIGFjY2VwdCBtdWx0aXBsZSB2YWx1
ZXMsIHBlcmhhcHMgZXZlbiA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9Im5h
bWUiPmNvbnN0ZXhwcjwvc3Bhbj48L2NvZGU+IHBhcmFtZXRlciBwYWNrcywgd2hpY2ggd291
bGQgcGVybWl0IGRpc2NhcmRpbmcgb2Ygc3BlY2lmaWMgZWxlbWVudHMsIG9yIGV2ZW4gbW9y
ZSBjb21wbGljYXRlZCBvcGVyYXRpb25zIHN1Y2ggYXMgc2VsZWN0aW5nIGV2ZXJ5IG90aGVy
IGVsZW1lbnQgaW4gcmV2ZXJzZSBvcmRlci4gKEhvd2V2ZXIsIHRoaXMgbWF5IGJlIGFuIGFy
ZWEgdGhhdCBwYXJhbWV0ZXIgcGFjayBnZW5lcmF0b3JzIHdvdWxkIHNlcnZlIGJldHRlci4g
SW4gcGFydGljdWxhciwgdGhlcmUgYXJlIGNvbXBsaWNhdGlvbnMgd2l0aCBob3cgdG8gaW1w
bGVtZW50IGV4cGFuc2lvbiBpZiBhIHBhcmFtZXRlciBwYWNrIGlzIGFsbG93ZWQgYXMgYW4g
aW5kZXguKTwvcD4KPHA+SWYgd2UgaGF2ZSA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4g
Y2xhc3M9InB1bmN0dWF0aW9uIj5bPC9zcGFuPjxzcGFuIGNsYXNzPSJvcGVyYXRvciI+Ojwv
c3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPl08L3NwYW4+PC9jb2RlPiBmb3IgZ2Vu
ZXJhbCB1bnBhY2tpbmcsIGl0IGJlY29tZXMgc3RyYWlnaHQgZm9yd2FyZCB0byBleHRlbmQg
aXQgdG8gc2xpY2luZywgYXMgc2hvd24uIE1vcmVvdmVyLCBpdCBiZWNvbWVzICZxdW90O29i
dmlvdXMmcXVvdDsgdG8gZnVydGhlciBleHRlbmQgdGhpcyBzYW1lIHNsaWNpbmcgdG8gdGhp
bmdzIHRoYXQgYXJlIDxlbT5hbHJlYWR5PC9lbT4gcGFyYW1ldGVyIHBhY2tzLCBzYXRpc2Z5
aW5nIGFub3RoZXIgaW1wb3J0YW50IGNvbnRlbXBvcmFyeSB1c2UgY2FzZS4gSW4gcGFydGlj
dWxhciwgd2UgY2FuIG5vdyB3cml0ZSByZWN1cnNpdmUgdmFyaWFkaWMgdGVtcGxhdGUgZnVu
Y3Rpb25zIGxpa2U6PC9wPgo8cHJlIGNsYXNzPSJjb2RlIGMrKyBsaXRlcmFsLWJsb2NrIj4K
PHNwYW4gY2xhc3M9ImtleXdvcmQgdHlwZSI+dm9pZDwvc3Bhbj4gPHNwYW4gY2xhc3M9Im5h
bWUgZnVuY3Rpb24iPnByaW50X2VhY2g8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9u
Ij4oKTwvc3Bhbj4gPHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj57fTwvc3Bhbj4gPHNwYW4g
Y2xhc3M9ImNvbW1lbnQgc2luZ2xlIj4vLyBzZW50aW5lbAo8L3NwYW4+CjxzcGFuIGNsYXNz
PSJrZXl3b3JkIj50ZW1wbGF0ZTwvc3Bhbj4gPHNwYW4gY2xhc3M9Im9wZXJhdG9yIj4mbHQ7
PC9zcGFuPjxzcGFuIGNsYXNzPSJrZXl3b3JkIj50eXBlbmFtZTwvc3Bhbj48c3BhbiBjbGFz
cz0icHVuY3R1YXRpb24iPi4uLjwvc3Bhbj4gPHNwYW4gY2xhc3M9Im5hbWUiPlQ8L3NwYW4+
PHNwYW4gY2xhc3M9Im9wZXJhdG9yIj4mZ3Q7PC9zcGFuPgo8c3BhbiBjbGFzcz0ia2V5d29y
ZCB0eXBlIj52b2lkPC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+cHJpbnRfZWFjaDwvc3Bh
bj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPig8L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUi
PlQ8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4uLi48L3NwYW4+IDxzcGFuIGNs
YXNzPSJuYW1lIj52YWx1ZXM8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4pPC9z
cGFuPgo8c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPns8L3NwYW4+CiAgPHNwYW4gY2xhc3M9
Im5hbWUiPnByaW50X29uZTwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPihbPC9z
cGFuPjxzcGFuIGNsYXNzPSJsaXRlcmFsIG51bWJlciBpbnRlZ2VyIj4wPC9zcGFuPjxzcGFu
IGNsYXNzPSJwdW5jdHVhdGlvbiI+XTwvc3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+dmFsdWVz
PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+KTs8L3NwYW4+CiAgPHNwYW4gY2xh
c3M9Im5hbWUiPnByaW50X2VhY2g8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4o
Wzwvc3Bhbj48c3BhbiBjbGFzcz0ibGl0ZXJhbCBudW1iZXIgaW50ZWdlciI+MTwvc3Bhbj48
c3BhbiBjbGFzcz0ib3BlcmF0b3IiPjo8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9u
Ij5dPC9zcGFuPjxzcGFuIGNsYXNzPSJuYW1lIj52YWx1ZXM8L3NwYW4+PHNwYW4gY2xhc3M9
InB1bmN0dWF0aW9uIj4pOzwvc3Bhbj4KPHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj59PC9z
cGFuPgo8L3ByZT4KPHA+VGhpcyBpcyBhIGZhaXJseSB0cml2aWFsIGV4YW1wbGUgdGhhdCBw
cmV2aW91c2x5IGNvdWxkIGJlIHdyaXR0ZW4gYnkgYnJlYWtpbmcgdGhlIGNvbXBsZXRlIHBh
Y2sgaW50byBhIHNlcGFyYXRlbHkgbmFtZWQgaGVhZCBhcmd1bWVudCBhbmQgdGFpbCBwYWNr
LiBUaGlzLCBob3dldmVyLCBtZXJlbHkgc2NyYXRjaGVzIHRoZSBzdXJmYWNlLiBPbmUgY291
bGQgaW1hZ2luZSBpbXBsZW1lbnRpbmcgYSA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4g
Y2xhc3M9Im5hbWUiPmNvbnN0ZXhwcjwvc3Bhbj48L2NvZGU+IGRpdmlkZS1hbmQtY29ucXVl
ciBzb3J0IGFsZ29yaXRobSB1c2luZyBzbGljaW5nIHRvIHRyaXZpYWxseSBzcGxpdCB0aGUg
aW5jb21pbmcgcGFyYW1ldGVyIHBhY2sgaW4gaGFsZi4gTWFueSBvdGhlciBleGFtcGxlcyB3
aGljaCBjYW4gYmUgcmVhZGlseSBpbXBsZW1lbnRlZCB3aXRoIHNsaWNpbmcgYnV0IHdvdWxk
IGJlIGRpZmZpY3VsdCBhbmQvb3IgZXhwZW5zaXZlIHRvIGltcGxlbWVudCBvdGhlcndpc2Ug
Y2FuIGJlIGltYWdpbmVkLjwvcD4KPC9kaXY+CjxkaXYgY2xhc3M9InNlY3Rpb24iIGlkPSJw
YWNrLWdlbmVyYXRpb24tcmV2aXNpdGVkIj4KPGgxPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIg
aHJlZj0iI2lkMTciPlBhY2sgR2VuZXJhdGlvbiwgUmV2aXNpdGVkPC9hPjwvaDE+CjxwPlBh
cmFtZXRlciBwYWNrIGdlbmVyYXRpb24gaXMsIGluIGdlbmVyYWwsIGFuIGludGVyZXN0aW5n
IGZlYXR1cmUuIFN1Z2dlc3RlZCBleGFtcGxlIHVzZXMgaW5jbHVkZSBnZW5lcmF0aW5nIGFu
IGludGVnZXIgbGlzdDxhIGNsYXNzPSJmb290bm90ZS1yZWZlcmVuY2UiIGhyZWY9IiNpbCIg
aWQ9ImlkNiI+WzZdPC9hPiwgYSB0eXBlIGxpc3QsIGFuZCBwZXJmb3JtaW5nIHZhcmlvdXMg
bWFuaXB1bGF0aW9ucyBvbiBwYXJhbWV0ZXIgcGFja3MuIFdoaWxlIHN1Y2ggbWFuaXB1bGF0
aW9ucyBjb3VsZCBpbmNsdWRlIHNsaWNpbmcgYW5kIHJldmVyc2luZywgd2Ugbm90ZSB0aGF0
IHRoZXNlIG9wZXJhdGlvbnMgYXBwZWFyIHRvIHJlbHkgb24gYSBzeW50YWN0aWMgbWVjaGFu
aXNtIGZvciBleHRyYWN0aW5nIGEgc2luZ2xlIGVsZW1lbnQgZnJvbSBhIHBhY2sgKHJlZmVy
ZW5jZSBpcyBtYWRlIHRvIDxhIGNsYXNzPSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0
dHA6Ly93ZzIxLmxpbmsvbjQyMzUiPk40MjM1PC9hPikuIFdlIGFsc28gd29uZGVyIGlmIHNs
aWNpbmcgb3BlcmF0aW9ucyBpbXBsZW1lbnRlZCBpbiB0aGlzIG1hbm5lciB3b3VsZCBwZXJm
b3JtIHNhdGlzZmFjdG9yaWx5IGNvbXBhcmVkIHRvIHN5bnRhY3RpYyBzbGljaW5nLjwvcD4K
PHA+Q29uc2VxdWVudGx5LCB3ZSBzdGlsbCBuZWVkIGEgc3ludGF4IGZvciBpbmRleGVkIGFj
Y2VzcyBvZiBwYXJhbWV0ZXIgcGFjayBlbGVtZW50cy4gVGhpcyBpbiB0dXJuIGFsbG93cyB1
cyB0byBhcHBseSB0aGUgcHJldmlvdXMgYXJndW1lbnQgaW4gcmV2ZXJzZTsgbmFtZWx5LCB3
aHkgbm90IHNlbGVjdCBhIHN5bnRheCB0aGF0IGlzIG5vbi1hbWJpZ3VvdXMsIGVhc2lseSBl
eHRlbmRlZCB0byBzbGljaW5nLCBhbmQgbWF5IGJlIGFwcGxpZWQgYWxzbyB0byB0dXBsZS1s
aWtlcz8gV2UgZmVlbCB0aGF0IHRoaXMgcmVhc29uaW5nLCBjb21iaW5lZCB3aXRoIHRoZSBm
cmVxdWVuY3kgb2YgYmFzaWMgdW5wYWNraW5nLCBqdXN0aWZpZXMgYSBzeW50YXggZm9yIHRo
ZXNlIG9wZXJhdGlvbnMuPC9wPgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9InN1
bW1hcnkiPgo8aDE+PGEgY2xhc3M9InRvYy1iYWNrcmVmIiBocmVmPSIjaWQxOCI+U3VtbWFy
eTwvYT48L2gxPgo8cD5QcmV2aW91cyBkaXNjdXNzaW9ucyDigJQgYm90aCBpbiBFV0cgYW5k
IG9uIHRoZSA8dHQgY2xhc3M9ImRvY3V0aWxzIGxpdGVyYWwiPjxzcGFuIGNsYXNzPSJwcmUi
PnN0ZC1wcm9wb3NhbHM8L3NwYW4+PC90dD4gZm9ydW0g4oCUIHN1Z2dlc3QgYSBzdHJvbmcg
ZGVzaXJlIGJ5IHRoZSBDKysgY29tbXVuaXR5IHRvIG1vdmUgdGhlIGxhbmd1YWdlIGluIGEg
ZGlyZWN0aW9uIHRoYXQgYmx1cnMgdGhlIGxpbmUgYmV0d2VlbiBjb250YWluZXJzIGFuZCB0
aGVpciBjb250YWluZWQgdmFsdWUgc2VxdWVuY2VzLCBtYWtpbmcgaXQgZWFzeSB0byBtb3Zl
IGZyb20gb25lIHRvIHRoZSBvdGhlciwgYXMgaXMgb2Z0ZW4gZm91bmQgaW4gb3RoZXIgbGFu
Z3VhZ2VzIChlLmcuIFB5dGhvbikuIEF0IHRoZSBzYW1lIHRpbWUsIHRoZXJlIGFyZSBhIG51
bWJlciBvZiBwcm9wb3NhbHMgZWl0aGVyIHB1Ymxpc2hlZCBvciBpbiB0aGUgd29ya3MgdG8g
c2ltcGxpZnkgd29ya2luZyB3aXRoIHBhcmFtZXRlciBwYWNrcy4gVGhlc2UgYXJlYXMgb3Zl
cmxhcC48L3A+CjxwPldlIGhhdmUgb2JzZXJ2ZWQgcmVjZW50bHkgdGhhdCAmcXVvdDtjb21w
bGV4aXR5JnF1b3Q7IGlzIGEgZnJlcXVlbnQgY29tcGxhaW50IG1hZGUgYWdhaW5zdCBDKyss
IGVzcGVjaWFsbHkgdGhhdCBpdCBpcyAmcXVvdDtoYXJkIHRvIHRlYWNoJnF1b3Q7LiBBcyB3
ZSBjb25zaWRlciBmZWF0dXJlcyB0byBzaW1wbGlmeSB3b3JraW5nIHdpdGggdHVwbGUtbGlr
ZSBvYmplY3RzIGFuZC9vciBwYXJhbWV0ZXIgcGFja3MsIHdlIGZlZWwgaXQgaXMgb2YgdXRt
b3N0IGltcG9ydGFuY2UgdG8gZXN0YWJsaXNoIGFuZCBhZGhlcmUgdG8gYSBjb25zaXN0ZW50
IHZpc2lvbiBvZiB0aGVzZSBmdW5jdGlvbnMsIGluIHRlcm1zIG9mIGJvdGggc3ludGF4IGFu
ZCBmdW5jdGlvbi4gV2Ugc3BlY2lmaWNhbGx5IHVyZ2UgdGhhdCBuYW1lLWJpbmRpbmcgdW5w
YWNraW5nIHdvdWxkIGNhcmVmdWxseSBjb25zaWRlciBjdXN0b21pemF0aW9uIHBvaW50czxh
IGNsYXNzPSJmb290bm90ZS1yZWZlcmVuY2UiIGhyZWY9IiNjcCIgaWQ9ImlkNyI+WzddPC9h
PiBhbmQgdGhlIGZ1dHVyZSBwb3NzaWJpbGl0eSBvZiBpbXBsaWNpdCB0dXBsZS1saWtlIGFj
Y2VzcyAoc2VlIGVzcGVjaWFsbHkgPGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJl
Zj0iaHR0cDovL3dnMjEubGluay9wMDE5NyI+UDAxOTc8L2E+KSBhbmQgZ2VuZXJhbGl6ZWQg
dW5wYWNraW5nIGluIG9yZGVyIHRvIHdvcmsgdG93YXJkPGEgY2xhc3M9ImZvb3Rub3RlLXJl
ZmVyZW5jZSIgaHJlZj0iI2ZkIiBpZD0iaWQ4Ij5bOF08L2E+IGEgY29tbW9uIG1lY2hhbmlz
bSBmb3IgYm90aCB0aGF0IHdvdWxkIGVsaW1pbmF0ZSBzcGVjaWFsIGNhc2UgcnVsZXMgc3Bl
Y2lmaWMgdG8gdGhlIGluZGl2aWR1YWwgZmVhdHVyZXMuIFdlIGFsc28gdXJnZSB0aGUgY29t
bWl0dGVlIHRvIGNvbnNpZGVyIHRoZXNlIGlzc3VlcyBhbmQgaG93IHN1Y2ggZmVhdHVyZXMg
cmVsYXRlIChvciBjYW4gYmUgbWFkZSB0byByZWxhdGUpIHRvIHR1cGxlLWxpa2Ugb2JqZWN0
cyBpbiBvcmRlciB0byBtYXhpbWl6ZSBjb25zaXN0ZW5jeSBvZiBvcGVyYXRpb25zIG9uIGJv
dGggb2JqZWN0IHR5cGVzLCBhbmQgd2UgdXJnZSBhdXRob3JzIHdvcmtpbmcgb24gc3VjaCBw
cm9wb3NhbHMgdG8gZG8gbGlrZXdpc2UuIEZpbmFsbHksIHdlIHN0cm9uZ2x5IGVuY291cmFn
ZSBhbnkgYXV0aG9ycyB3b3JraW5nIGluIHRoaXMgcmVhbG0gdG8gbWFpbnRhaW4gY29tbXVu
aWNhdGlvbiBpbiBvcmRlciB0byByZWR1Y2UgdGhlIGRhbmdlcnMgb2YgY29tcGV0aW5nLCBp
bmNvbXBhdGlibGUgcHJvcG9zYWxzIGFuZCB0byBtYXhpbWl6ZSBvdXIgYWJpbGl0eSBhcyBh
IGNvbW11bml0eSB0byBwdXJzdWUgYSB3ZWxsIGNvbnNpZGVyZWQsIGNvbnNpc3RlbnQsIGFu
ZCBtYXhpbWFsbHkgZnVuY3Rpb25hbCBkaXJlY3Rpb24uPC9wPgo8L2Rpdj4KPGRpdiBjbGFz
cz0ic2VjdGlvbiIgaWQ9ImFja25vd2xlZGdtZW50cyI+CjxoMT48YSBjbGFzcz0idG9jLWJh
Y2tyZWYiIGhyZWY9IiNpZDE5Ij5BY2tub3dsZWRnbWVudHM8L2E+PC9oMT4KPCEtLSBUT0RP
IC0tPgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9ImZvb3Rub3RlcyI+CjxoMT48
YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhyZWY9IiNpZDIwIj5Gb290bm90ZXM8L2E+PC9oMT4K
PHRhYmxlIGNsYXNzPSJkb2N1dGlscyBmb290bm90ZSIgZnJhbWU9InZvaWQiIGlkPSJwdCIg
cnVsZXM9Im5vbmUiPgo8Y29sZ3JvdXA+PGNvbCBjbGFzcz0ibGFiZWwiIC8+PGNvbCAvPjwv
Y29sZ3JvdXA+Cjx0Ym9keSB2YWxpZ249InRvcCI+Cjx0cj48dGQgY2xhc3M9ImxhYmVsIj48
YSBjbGFzcz0iZm4tYmFja3JlZiIgaHJlZj0iI2lkMSI+WzFdPC9hPjwvdGQ+PHRkPjxhIGNs
YXNzPSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly9kb2MucXQuaW8vcXQtNS42
L3F2ZWN0b3IzZC5odG1sIj5RVmVjdG9yM0Q8L2E+IGNvbWVzIHRvIG1pbmQgYXMgYW4gZXhh
bXBsZSBvZiBhIHVzZXIgdHlwZSB3aGljaCBpcyDigJQgb3IgYXQgbGVhc3QsIG91Z2h0IHRv
IGJlIOKAlCB0dXBsZS1saWtlIGJ1dCBoYXMgbm8gcHVibGljIGRhdGEgbWVtYmVycy48L3Rk
PjwvdHI+CjwvdGJvZHk+CjwvdGFibGU+Cjx0YWJsZSBjbGFzcz0iZG9jdXRpbHMgZm9vdG5v
dGUiIGZyYW1lPSJ2b2lkIiBpZD0icGciIHJ1bGVzPSJub25lIj4KPGNvbGdyb3VwPjxjb2wg
Y2xhc3M9ImxhYmVsIiAvPjxjb2wgLz48L2NvbGdyb3VwPgo8dGJvZHkgdmFsaWduPSJ0b3Ai
Pgo8dHI+PHRkIGNsYXNzPSJsYWJlbCI+PGEgY2xhc3M9ImZuLWJhY2tyZWYiIGhyZWY9IiNp
ZDIiPlsyXTwvYT48L3RkPjx0ZD5XaGlsZSBpbnRlcmVzdGluZywgdGhlIHBvdGVudGlhbCBm
b3IgcmVzdWx0aW5nIGluIGEgY29tcGxpY2F0ZWQgYW5kIGRpZmZpY3VsdCBpbXBsZW1lbnRh
dGlvbiBzZWVtcyBub24tdHJpdmlhbC4gSW4gcGFydGljdWxhciwgaW1wbGVtZW50aW5nIGFu
IHVucGFja2luZyBmdW5jdGlvbiBpbiB0aGlzIG1hbm5lciByZXF1aXJlcyBub3Qgb25seSBy
ZXR1cm4gdHlwZSBkZWR1Y3Rpb24sIGJ1dCB0aGF0IHN1Y2ggZGVkdWN0aW9uIG1heSBkZWR1
Y2UgYSBkaWZmZXJlbnQgcmVzdWx0IGZvciBlYWNoIHZhbHVlICZxdW90O3lpZWxkZWQmcXVv
dDsuIFRoZSBwcm9wb3NlZCBzb2x1dGlvbiBpcyB0byBhbGxvdyBhIG5ldyAmcXVvdDt0eXBl
JnF1b3Q7IHRoYXQgbWF5IGNvbnRhaW4gbGFuZ3VhZ2UgdG9rZW5zIGluY2x1ZGluZyBsaXRl
cmFsIHZhbHVlcywgdHlwZSBuYW1lcyAoaW5jbHVkaW5nIG5hbWVzIG9mIHRlbXBsYXRlIHR5
cGVzIHdpdGhvdXQgdGVtcGxhdGUgcGFyYW1ldGVycyksIGFuZCBwYXJhbWV0ZXIgcGFja3Mu
PC90ZD48L3RyPgo8L3Rib2R5Pgo8L3RhYmxlPgo8dGFibGUgY2xhc3M9ImRvY3V0aWxzIGZv
b3Rub3RlIiBmcmFtZT0idm9pZCIgaWQ9InZiIiBydWxlcz0ibm9uZSI+Cjxjb2xncm91cD48
Y29sIGNsYXNzPSJsYWJlbCIgLz48Y29sIC8+PC9jb2xncm91cD4KPHRib2R5IHZhbGlnbj0i
dG9wIj4KPHRyPjx0ZCBjbGFzcz0ibGFiZWwiPjxhIGNsYXNzPSJmbi1iYWNrcmVmIiBocmVm
PSIjaWQzIj5bM108L2E+PC90ZD48dGQ+V2hpbGUgcHJlc2VudCBpbiB0aGUgaW5pdGlhbCBy
ZXZpc2lvbiBvZiA8YSBjbGFzcz0icmVmZXJlbmNlIGV4dGVybmFsIiBocmVmPSJodHRwOi8v
d2cyMS5saW5rL3AwMTk3Ij5QMDE5NzwvYT4sIHRoaXMgcmVzdHJpY3Rpb24gaXMgbm90IHNl
ZW4gaW4gPGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDovL3dnMjEu
bGluay9wMDE0NCI+UDAxNDQ8L2E+LCBhbmQgdXBvbiBmdXJ0aGVyIGNvbnNpZGVyYXRpb24s
IG1heSBiZSB1bm5lY2Vzc2FyeS48L3RkPjwvdHI+CjwvdGJvZHk+CjwvdGFibGU+Cjx0YWJs
ZSBjbGFzcz0iZG9jdXRpbHMgZm9vdG5vdGUiIGZyYW1lPSJ2b2lkIiBpZD0iZWIiIHJ1bGVz
PSJub25lIj4KPGNvbGdyb3VwPjxjb2wgY2xhc3M9ImxhYmVsIiAvPjxjb2wgLz48L2NvbGdy
b3VwPgo8dGJvZHkgdmFsaWduPSJ0b3AiPgo8dHI+PHRkIGNsYXNzPSJsYWJlbCI+PGEgY2xh
c3M9ImZuLWJhY2tyZWYiIGhyZWY9IiNpZDQiPls0XTwvYT48L3RkPjx0ZD5UaGlzIGNvdWxk
IHByb2JhYmx5IGJlIHJlbGF4ZWQgdG8gbm9uLXB1YmxpYyA8ZW0+YW5kIG5vbi1lbXB0eTwv
ZW0+IGJhc2UgY2xhc3NlcywgaWYgZGVzaXJlZC48L3RkPjwvdHI+CjwvdGJvZHk+CjwvdGFi
bGU+Cjx0YWJsZSBjbGFzcz0iZG9jdXRpbHMgZm9vdG5vdGUiIGZyYW1lPSJ2b2lkIiBpZD0i
bGMiIHJ1bGVzPSJub25lIj4KPGNvbGdyb3VwPjxjb2wgY2xhc3M9ImxhYmVsIiAvPjxjb2wg
Lz48L2NvbGdyb3VwPgo8dGJvZHkgdmFsaWduPSJ0b3AiPgo8dHI+PHRkIGNsYXNzPSJsYWJl
bCI+PGEgY2xhc3M9ImZuLWJhY2tyZWYiIGhyZWY9IiNpZDUiPls1XTwvYT48L3RkPjx0ZD5B
IG1vcmUgdGhyb3VnaCBleHBsb3JhdGlvbiBpcyBiZXlvbmQgdGhlIHNjb3BlIG9mIHRoaXMg
cGFwZXIsIGJ1dCBjYW4gYmUgZm91bmQgYXQgPGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5h
bCIgaHJlZj0iaHR0cDovL3Blcm1hbGluay5nbWFuZS5vcmcvZ21hbmUuY29tcC5sYW5nLmMr
Ky5pc29jcHAucHJvcG9zYWxzLzI1MjIyIj5odHRwOi8vcGVybWFsaW5rLmdtYW5lLm9yZy9n
bWFuZS5jb21wLmxhbmcuYysrLmlzb2NwcC5wcm9wb3NhbHMvMjUyMjI8L2E+LjwvdGQ+PC90
cj4KPC90Ym9keT4KPC90YWJsZT4KPHRhYmxlIGNsYXNzPSJkb2N1dGlscyBmb290bm90ZSIg
ZnJhbWU9InZvaWQiIGlkPSJpbCIgcnVsZXM9Im5vbmUiPgo8Y29sZ3JvdXA+PGNvbCBjbGFz
cz0ibGFiZWwiIC8+PGNvbCAvPjwvY29sZ3JvdXA+Cjx0Ym9keSB2YWxpZ249InRvcCI+Cjx0
cj48dGQgY2xhc3M9ImxhYmVsIj48YSBjbGFzcz0iZm4tYmFja3JlZiIgaHJlZj0iI2lkNiI+
WzZdPC9hPjwvdGQ+PHRkPlRoZSBwdXJlbHkgdGVtcGxhdGUgaW1wbGVtZW50YXRpb24gb2Yg
PGNvZGUgY2xhc3M9ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJuYW1lIj5zdGQ8L3NwYW4+PHNw
YW4gY2xhc3M9Im9wZXJhdG9yIj46Ojwvc3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+aW50ZWdl
cl9zZXF1ZW5jZTwvc3Bhbj48L2NvZGU+IGlzIGV4dHJlbWVseSBleHBlbnNpdmUsIHRvIHRo
ZSBwb2ludCB0aGF0IG1hbnkgY29tcGlsZXJzIGFyZSBwcm92aWRpbmcgaW1wbGVtZW50YXRp
b25zIGJhc2VkIG9uIGNvbXBpbGVyIGludHJpbnNpY3MuIFBhcmFtZXRlciBwYWNrIGdlbmVy
YXRvcnMgaGF2ZSB0aGUgcG90ZW50aWFsIHRvIHByb3ZpZGUgYSBzYXRpc2ZhY3RvcnkgaW1w
bGVtZW50YXRpb24gd2l0aG91dCBzdWNoIGludHJpbnNpY3MuPC90ZD48L3RyPgo8L3Rib2R5
Pgo8L3RhYmxlPgo8dGFibGUgY2xhc3M9ImRvY3V0aWxzIGZvb3Rub3RlIiBmcmFtZT0idm9p
ZCIgaWQ9ImNwIiBydWxlcz0ibm9uZSI+Cjxjb2xncm91cD48Y29sIGNsYXNzPSJsYWJlbCIg
Lz48Y29sIC8+PC9jb2xncm91cD4KPHRib2R5IHZhbGlnbj0idG9wIj4KPHRyPjx0ZCBjbGFz
cz0ibGFiZWwiPjxhIGNsYXNzPSJmbi1iYWNrcmVmIiBocmVmPSIjaWQ3Ij5bN108L2E+PC90
ZD48dGQ+SXQgaXMgb3VyIHVuZGVyc3RhbmRpbmcgdGhhdCB0aGUgY29tbWl0dGVlIGFuZCB0
aGUgYXV0aG9ycyBvZiA8YSBjbGFzcz0icmVmZXJlbmNlIGV4dGVybmFsIiBocmVmPSJodHRw
Oi8vd2cyMS5saW5rL3AwMTQ0Ij5QMDE0NDwvYT4gYXJlIHdlbGwgYXdhcmUgb2YgdGhlIHN0
cm9uZyBmZWVsaW5ncyBzdXJyb3VuZGluZyBjdXN0b21pemF0aW9uIHBvaW50cyBhbmQgPGVt
PmFyZTwvZW0+IGdpdmluZyB0aGVtIHNlcmlvdXMgY29uc2lkZXJhdGlvbi4gV2Ugd2lzaCB0
byB0YWtlIHRoaXMgb3Bwb3J0dW5pdHkgdG8gdGhhbmsgYW5kIGNvbW1lbmQgdGhlbSBmb3Ig
dGhlc2UgZWZmb3J0cy48L3RkPjwvdHI+CjwvdGJvZHk+CjwvdGFibGU+Cjx0YWJsZSBjbGFz
cz0iZG9jdXRpbHMgZm9vdG5vdGUiIGZyYW1lPSJ2b2lkIiBpZD0iZmQiIHJ1bGVzPSJub25l
Ij4KPGNvbGdyb3VwPjxjb2wgY2xhc3M9ImxhYmVsIiAvPjxjb2wgLz48L2NvbGdyb3VwPgo8
dGJvZHkgdmFsaWduPSJ0b3AiPgo8dHI+PHRkIGNsYXNzPSJsYWJlbCI+PGEgY2xhc3M9ImZu
LWJhY2tyZWYiIGhyZWY9IiNpZDgiPls4XTwvYT48L3RkPjx0ZD5XZSB3b3VsZCBsaWtlIHRv
IHJlaXRlcmF0ZSB0aGF0IHdlIGhhdmUgbm8gb2JqZWN0aW9uIHRvIHNwZWNpYWwgY2FzZSBo
YW5kbGluZyBvZiAmcXVvdDtpbXBsaWNpdGx5IHR1cGxlLWxpa2UmcXVvdDsgdHlwZXMgaW4g
dGhlIHNob3J0IHRlcm0sIGVzcGVjaWFsbHkgaWYgaXQgbWVhbnMgbmFtZS1iaW5kaW5nIHVu
cGFja2luZyBpcyBhdmFpbGFibGUgaW4gQysrMTcsIDxlbT5wcm92aWRlZDwvZW0+IHRoZXJl
IGlzIGEgbG9uZyB0ZXJtIG1pZ3JhdGlvbiByb3V0ZSB0aGF0IHdvdWxkIGFsbG93IHRoaXMg
c3BlY2lhbCBjYXNlIHRvIGJlIHJlcGxhY2VkIHdpdGggbW9yZSBnZW5lcmFsaXplZCBmdW5j
dGlvbmFsaXR5LjwvdGQ+PC90cj4KPC90Ym9keT4KPC90YWJsZT4KPC9kaXY+CjxkaXYgY2xh
c3M9InNlY3Rpb24iIGlkPSJyZWZlcmVuY2VzIj4KPGgxPjxhIGNsYXNzPSJ0b2MtYmFja3Jl
ZiIgaHJlZj0iI2lkMjEiPlJlZmVyZW5jZXM8L2E+PC9oMT4KPHVsPgo8bGk+PHAgY2xhc3M9
ImZpcnN0Ij48YSBjbGFzcz0icmVmZXJlbmNlIGV4dGVybmFsIiBocmVmPSJodHRwOi8vd2cy
MS5saW5rL240MjM1Ij5ONDIzNTwvYT4gU2VsZWN0aW5nIGZyb20gUGFyYW1ldGVyIFBhY2tz
PC9wPgo8cD48YSBjbGFzcz0icmVmZXJlbmNlIGV4dGVybmFsIiBocmVmPSJodHRwOi8vd2cy
MS5saW5rL240MjM1Ij5odHRwOi8vd2cyMS5saW5rL240MjM1PC9hPjwvcD4KPC9saT4KPC91
bD4KPHVsPgo8bGk+PHAgY2xhc3M9ImZpcnN0Ij48YSBjbGFzcz0icmVmZXJlbmNlIGV4dGVy
bmFsIiBocmVmPSJodHRwOi8vd2cyMS5saW5rL3AwMTQ0Ij5QMDE0NDwvYT4gU3RydWN0dXJl
ZCBCaW5kaW5nczwvcD4KPHA+PGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0i
aHR0cDovL3dnMjEubGluay9wMDE0NCI+aHR0cDovL3dnMjEubGluay9wMDE0NDwvYT48L3A+
CjwvbGk+CjwvdWw+Cjx1bD4KPGxpPjxwIGNsYXNzPSJmaXJzdCI+PGEgY2xhc3M9InJlZmVy
ZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDovL3dnMjEubGluay9wMDE5NyI+UDAxOTc8L2E+
IERlZmF1bHQgVHVwbGUtbGlrZSBBY2Nlc3M8L3A+CjxwPjxhIGNsYXNzPSJyZWZlcmVuY2Ug
ZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAxOTciPmh0dHA6Ly93ZzIxLmxp
bmsvcDAxOTc8L2E+PC9wPgo8L2xpPgo8L3VsPgo8IS0tIC4uIC4uIC4uIC4uIC4uIC4uIC4u
IC4uIC4uIC4uIC4uIC4uIC4uIC4uIC4uIC4uIC4uIC4uIC4uIC4uIC4uIC4uIC4uIC4uIC4u
IC0tPgo8IS0tIGthdGU6IGhsIHJlU3RydWN0dXJlZFRleHQgLS0+CjwvZGl2Pgo8L2Rpdj4K
PC9ib2R5Pgo8L2h0bWw+Cg==
--------------010408070207040708050900
Content-Type: text/prs.fallenstein.rst;
name="dxxxx-tuple-like-unified-vision.rst"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="dxxxx-tuple-like-unified-vision.rst"
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D
A Unified Vision for Manipulating Tuple-like Objects
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D
:Document: DXXXXR0 (TBD)
:Date: 2016-03-18
:Project: ISO/IEC JTC1 SC22 WG21 Programming Language C++
:Audience: Evolution Working Group
:Author: Matthew Woehlke (mwoehlke.floss@gmail.com)
=2E. raw:: html
<style>
html { color: black; background: white; }
table.docinfo { margin: 2em 0; }
</style>
=2E. role:: cpp(code)
:language: c++
Abstract
=3D=3D=3D=3D=3D=3D=3D=3D
There is much activity and discussion surrounding tuple-like objects, wit=
h many features being requested and many papers submitted or planned. It =
is important that we establish a plan for where we are going that takes i=
nto account future directions in order to avoid overcomplicating the lang=
uage or painting ourselves into a corner of incompatible features.
=2E. contents::
Background
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
At the 2016 Jacksonville meeting, P0144_ was discussed for the second tim=
e. Reception was generally positive, but some issues remained to be addre=
ssed. It seems quite clear that this is a desired direction for C++. Unfo=
rtunately, P0197_, which was scheduled for presentation and has some impa=
ct on the direction which P0144_ is following, was skipped due to time co=
nstraints.
Discussion on the ``std-proposals`` forum often brings up the desire to e=
xtend use of "tuple-like" objects to contexts other than name binding (i.=
e. P0144_). There is also significant and related discussion on improving=
the usability of parameter packs. We feel that several of these areas ar=
e closely related and warrant the formation of a concrete and unified vis=
ion for future direction.
While we present several suggestions in this paper, this paper is not mea=
nt as a formal proposal, but rather a recommendation for areas which we f=
eel need to be explored, and in particular, considered by other proposals=
being put forward, especially P0144_.
Definitions
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
A "tuple like" is any object consisting of one or (usually) more orthogon=
al values (in mathematical notation, a "product type"). The canonical exa=
mple is :cpp:`std::tuple`, but other examples include :cpp:`std::array` o=
r similar fixed-size vector types and most aggregates, as well as some no=
n-aggregate user types including ones with no public NSDM's\ [#pt]_.
"Unpacking" refers to the conversion of a tuple-like object into its comp=
onent parts. This includes both name-binding unpacking (i.e. P0144_) and =
"generalized unpacking" where the components are used in a non-binding co=
ntext; for example, as values in a function parameter list. Name-binding =
unpacking is also called "structured binding" and, historically, "assignm=
ent unpacking". We prefer the term "name-binding unpacking" as it does no=
t call into question issues of "true assignment" versus aliasing where P0=
144_ specifically desires to avoid certain overheads, and the use of "unp=
acking" serves to connect two closely related concepts.
Access
=3D=3D=3D=3D=3D=3D
One of the active questions around P0144_ regards the customization point=
=2E We feel strongly that the customization point for name-binding unpack=
ing should be the same as used by generalized unpacking and by existing a=
nd proposed utility functions (e.g. :cpp:`std::apply` and :cpp:`std::make=
_from_tuple`) that act on tuple-like objects. This is important for the s=
ake of consistency; these operations are extremely similar, and using dif=
ferent customization points will likely result in confusion and teaching =
difficulty.
That said, we feel less strongly about the exact nature of those customiz=
ation points, providing that those points which are eventually used provi=
de satisfactory backwards compatibility.
At present, these customization points are:
:cpp:`get<N>(T)`:
Access the N'th value of the tuple-like, where :cpp:`0 < N < tuple_si=
ze(T)`.
:cpp:`constexpr tuple_size(T)`:
Returns the size of (i.e. number of elements in) the tuple-like.
An operator-like alternative
----------------------------
Some concerns were expressed that overloading on :cpp:`get<N>(T)` is not =
appropriate due to its use for other operations that are not related to t=
uple-like objects. One alternative might be to implement a new operator t=
ype:
=2E. code:: c++
operator get(auto& tuple, constexpr size_t i);
constexpr operator sizeof<T>();
It may be reasonable or even desirable to restrict access of these operat=
ors to either explicit spelling or use of dedicated syntax:
=2E. code:: c++
MyTupleLike t;
[0]t; // operator get
sizeof...(t); // operator sizeof
auto [x, y] =3D t; // both, via name-binding unpacking, case 2
We should note that, while there are some strong feelings on these topics=
, we do not feel that any particular resolution is critical for any of th=
e directions we are exploring. In this area, we feel only that a consiste=
nt and clear direction is important.
(Types have been elided in the above examples, as they are not crucial to=
the discussion.)
Generalized Unpacking
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Generalized unpacking is the conversion of a tuple-like to a "value seque=
nce", in the manner of Python's ``*`` operator, such that the resulting s=
equence may be used in any place that a comma separated sequence may be u=
sed. While function parameter lists is the canonical example, this would =
also include braced initializer lists. Following discussion on the ``std-=
proposals`` forum, we believe that the most reasonable and useful mechani=
sm of accomplishing this is to provide a mechanism whereby a tuple-like m=
ay be converted into a parameter pack. Much as in the name-binding unpack=
ing case, there is a logical code transformation that can be applied for =
this purpose, by placing the tuple-like into a temporary (where necessary=
, i.e. if the tuple-like is an expression rather than already a named var=
iable) and taking the parameter pack to be :cpp:`get<0>(__t), get<1>(__t)=
, ...`. This extends the usable scope to anywhere a fold expression may b=
e used.
We are aware of at least three possible mechanisms for implementing gener=
alized unpacking. One option is to employ a new syntax to perform this op=
eration directly. Another is to make multiple return values, treated as p=
arameter packs, first class citizens of the language. A third is to creat=
e a parameter pack "generator". While the latter two options makes it pos=
sible to write a function (which might reasonably be named :cpp:`std::unp=
ack`) that is both equivalent to the former and allows for a great deal o=
f expressiveness as to which elements are returned and in what order (suc=
h a function could, for example, take a template parameter specifying the=
same), we suspect that both would be significantly more invasive\ [#pg]_=
=2E As a result, we are inclined to lean toward a direct syntactic soluti=
on.
Several possible syntaxes have been proposed, including postfix operator =
``~``. Our preference, however, is prefix operator ``[:]``. (The reasons =
for the three-character spelling may already be obvious to those familiar=
with Python; we will explore them later, in `Slicing`_). For example:
=2E. code:: c++
struct { double x, y; } point =3D ...;
auto h =3D std::hypot([:]point...);
The addition of such syntax would obviate most (though perhaps not all) u=
se cases for :cpp:`std::apply` and :cpp:`sd::make_from_tuple`. It would a=
lso permit trivial conversions between different "simple" types which are=
distinct but layout compatible, by unpacking the first type into a brace=
d initializer list used to construct the second. We believe that this fea=
ture will be at least as important and useful as name-binding unpacking.
Unification of Unpacking
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Possibly the most important aspect of P0197_ in our opinion is the provis=
ion for a single, unified mechanism for unpacking, whether in the name-bi=
nding or generalized senses. The critical aspect of P0197_, and the one t=
hat we feel strongly needs to be considered by P0144_, is providing impli=
cit general tuple-like access to simple data structures. In particular, w=
e feel that it would be a travesty for name-binding unpacking and general=
ized unpacking to use different customization points or to otherwise beha=
ve differently when used in ways where intuition strongly expects equival=
ent behavior. In particular, we feel strongly that, for a tuple-like type=
having a default destructor, the following should be equivalent (after o=
ptimizations):
=2E. code:: c++
auto [x, y] =3D t;
auto [x, y] =3D {[:]t...};
(This illustrates a need to be careful with lifetime semantics; in partic=
ular, :cpp:`[:]` should likely either extend lifetime when used in a brac=
ed initializer list, or should explicitly create value copies in such cas=
e. The former would make the above equivalent for *any* tuple-like, while=
the latter may be useful for separating lifetime of the tuple-like and i=
ts components. We do not recommend a direction at this time.)
It should be noted that P0197_ would provide a modest enhancement to name=
-binding unpacking. Where P0144_ limits itself to "flat" classes, P0197_ =
would extend implicit tuple-like access to all classes which:
* Contain no non-public NSDM's
* Contain no members of union type
* Have no virtual\ [#vb]_ and/or non-public\ [#eb]_ base classes
* Have no base classes which do not also meet the preceding eligibility=
criteria
While it would not be a catastrophic loss if non-"flat" classes were not =
supported, we do feel that it would be most unfortunate if we are not abl=
e |--| eventually |--| to rely on this implicit access to implement name-=
binding unpacking, and accordingly to eliminate P0144_ case 3. In additio=
n to consistency, we feel that this is important for the sake of simplici=
ty, as it eliminates a special case from name-binding unpacking. We are c=
onfident that the performance issues (that is, the understanding that cas=
e 3 represents name aliasing and neither consumes storage beyond that req=
uired for the tuple-like itself nor adds any access indirection) can be s=
atisfactorily addressed through compiler optimization, keeping in mind of=
course that the implementations of the "get" function (however we ultima=
tely spell it) are inline in these instances.
The problem that arises from this approach is bitfield members. At the 20=
16 Jacksonville meeting, at least one individual expressed a strong opini=
on that providing read/write access to bitfield members via name-binding =
unpacking is a "must have" feature. We encourage giving serious considera=
tion to the true importance of this feature, and to ways that this could =
be addressed in a way that does not require special casing. (In particula=
r, we note that the general ability to have a reference to a bitfield |--=
| likely through some new library type |--| seems at least as interesting=
as being able to name-bind to a component of such type of a tuple-like.)=
Slicing
=3D=3D=3D=3D=3D=3D=3D
In our earlier discussion on `Access`_, we mentioned syntax for accessing=
specific elements of a tuple-like. While the need to access individual e=
lements is obvious and clearly does not require a syntactic solution (we =
already have `std::get<N>`), another desire that comes up often is the ab=
ility to slice a tuple-like; e.g. to strip the first element or take only=
the first N elements. It is for this reason that we selected :cpp:`[:]` =
as our preferred syntax; as in Python, it readily lends itself to extensi=
on:
=2E. code:: c++
[1:]t; // Access elements 1..<N of t
[0:2]t; // Access elements 0..<2 of t
[-2:]t; // Access elements N-2..<N of t
[3:-1]t; // Access elements 3..<N-1 of t
[4:1]t; // Access element 4 of t as a parameter pack
[4]t; // Access element 4 of t as a value
This can be extended to work with :cpp:`constexpr` expressions for the in=
dices. The parsing in that case becomes less trivial, but we believe that=
it is still unambiguous with lambda capture\ [#lc]_. (Other syntaxes may=
be possible.) Moreover, the syntax can be readily extended to accept mul=
tiple values, perhaps even :cpp:`constexpr` parameter packs, which would =
permit discarding of specific elements, or even more complicated operatio=
ns such as selecting every other element in reverse order. (However, this=
may be an area that parameter pack generators would serve better. In par=
ticular, there are complications with how to implement expansion if a par=
ameter pack is allowed as an index.)
If we have :cpp:`[:]` for general unpacking, it becomes straight forward =
to extend it to slicing, as shown. Moreover, it becomes "obvious" to furt=
her extend this same slicing to things that are *already* parameter packs=
, satisfying another important contemporary use case. In particular, we c=
an now write recursive variadic template functions like:
=2E. code:: c++
void print_each() {} // sentinel
template <typename... T>
void print_each(T... values)
{
print_one([0]values);
print_each([1:]values);
}
This is a fairly trivial example that previously could be written by brea=
king the complete pack into a separately named head argument and tail pac=
k. This, however, merely scratches the surface. One could imagine impleme=
nting a :cpp:`constexpr` divide-and-conquer sort algorithm using slicing =
to trivially split the incoming parameter pack in half. Many other exampl=
es which can be readily implemented with slicing but would be difficult a=
nd/or expensive to implement otherwise can be imagined.
Pack Generation, Revisited
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
Parameter pack generation is, in general, an interesting feature. Suggest=
ed example uses include generating an integer list\ [#il]_, a type list, =
and performing various manipulations on parameter packs. While such manip=
ulations could include slicing and reversing, we note that these operatio=
ns appear to rely on a syntactic mechanism for extracting a single elemen=
t from a pack (reference is made to N4235_). We also wonder if slicing op=
erations implemented in this manner would perform satisfactorily compared=
to syntactic slicing.
Consequently, we still need a syntax for indexed access of parameter pack=
elements. This in turn allows us to apply the previous argument in rever=
se; namely, why not select a syntax that is non-ambiguous, easily extende=
d to slicing, and may be applied also to tuple-likes? We feel that this r=
easoning, combined with the frequency of basic unpacking, justifies a syn=
tax for these operations.
Summary
=3D=3D=3D=3D=3D=3D=3D
Previous discussions |--| both in EWG and on the ``std-proposals`` forum =
|--| suggest a strong desire by the C++ community to move the language in=
a direction that blurs the line between containers and their contained v=
alue sequences, making it easy to move from one to the other, as is often=
found in other languages (e.g. Python). At the same time, there are a nu=
mber of proposals either published or in the works to simplify working wi=
th parameter packs. These areas overlap.
We have observed recently that "complexity" is a frequent complaint made =
against C++, especially that it is "hard to teach". As we consider featur=
es to simplify working with tuple-like objects and/or parameter packs, we=
feel it is of utmost importance to establish and adhere to a consistent =
vision of these functions, in terms of both syntax and function. We speci=
fically urge that name-binding unpacking would carefully consider customi=
zation points\ [#cp]_ and the future possibility of implicit tuple-like a=
ccess (see especially P0197_) and generalized unpacking in order to work =
toward\ [#fd]_ a common mechanism for both that would eliminate special c=
ase rules specific to the individual features. We also urge the committee=
to consider these issues and how such features relate (or can be made to=
relate) to tuple-like objects in order to maximize consistency of operat=
ions on both object types, and we urge authors working on such proposals =
to do likewise. Finally, we strongly encourage any authors working in thi=
s realm to maintain communication in order to reduce the dangers of compe=
ting, incompatible proposals and to maximize our ability as a community t=
o pursue a well considered, consistent, and maximally functional directio=
n.
Acknowledgments
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=2E. TODO
Footnotes
=3D=3D=3D=3D=3D=3D=3D=3D=3D
=2E. [#pt] `QVector3D <http://doc.qt.io/qt-5.6/qvector3d.html>`_ comes to=
mind as an example of a user type which is |--| or at least, ought to be=
|--| tuple-like but has no public data members.
=2E. [#pg] While interesting, the potential for resulting in a complicate=
d and difficult implementation seems non-trivial. In particular, implemen=
ting an unpacking function in this manner requires not only return type d=
eduction, but that such deduction may deduce a different result for each =
value "yielded". The proposed solution is to allow a new "type" that may =
contain language tokens including literal values, type names (including n=
ames of template types without template parameters), and parameter packs.=
=2E. [#vb] While present in the initial revision of P0197_, this restrict=
ion is not seen in P0144_, and upon further consideration, may be unneces=
sary.
=2E. [#eb] This could probably be relaxed to non-public *and non-empty* b=
ase classes, if desired.
=2E. [#lc] A more through exploration is beyond the scope of this paper, =
but can be found at `<http://permalink.gmane.org/gmane.comp.lang.c++.isoc=
pp.proposals/25222>`_.
=2E. [#il] The purely template implementation of :cpp:`std::integer_seque=
nce` is extremely expensive, to the point that many compilers are providi=
ng implementations based on compiler intrinsics. Parameter pack generator=
s have the potential to provide a satisfactory implementation without suc=
h intrinsics.
=2E. [#cp] It is our understanding that the committee and the authors of =
P0144_ are well aware of the strong feelings surrounding customization po=
ints and *are* giving them serious consideration. We wish to take this op=
portunity to thank and commend them for these efforts.
=2E. [#fd] We would like to reiterate that we have no objection to specia=
l case handling of "implicitly tuple-like" types in the short term, espec=
ially if it means name-binding unpacking is available in C++17, *provided=
* there is a long term migration route that would allow this special case=
to be replaced with more generalized functionality.
References
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=2E. _N4235: http://wg21.link/n4235
* N4235_ Selecting from Parameter Packs
http://wg21.link/n4235
=2E. _P0144: http://wg21.link/p0144
* P0144_ Structured Bindings
http://wg21.link/p0144
=2E. _P0197: http://wg21.link/p0197
* P0197_ Default Tuple-like Access
http://wg21.link/p0197
=2E. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..=
.. ..
=2E. |--| unicode:: U+02014 .. em dash
=2E. kate: hl reStructuredText
--------------010408070207040708050900--
.
Author: barry.revzin@gmail.com
Date: Fri, 18 Mar 2016 10:08:46 -0700 (PDT)
Raw View
------=_Part_736_1181215708.1458320926198
Content-Type: multipart/alternative;
boundary="----=_Part_737_129874614.1458320926198"
------=_Part_737_129874614.1458320926198
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
You write:
Our preference, however, is prefix operator [:]. (The reasons for the=20
> three-character spelling may already be obvious to those familiar with=20
> Python; we will explore them later, in Slicing=20
> <https://11080372623597421729.googlegroups.com/attach/9601cb656f56e/dxxxx=
-tuple-like-unified-vision.html?part=3D0.1&view=3D1&vt=3DANaJVrFJSYTg6qNEMU=
MaLq0tYZltuDpeHrTRl3ML3E7gLynk50bIZePSF2X87XWUVEcgNnKgDnxwspXAkqa8UNf_Vcvjm=
HibbKHGuYcMcHahkxOCTM7VGKk#slicing>).=20
> For example:
>
> struct { double x, y; } point =3D ...;auto h =3D std::hypot([:]point...);
>
>
But that's not how you unpack a tuple in Python. You'd use the splat=20
operator:
auto h =3D std::hypot(*point);
[:] is for copying, which in C++ we have no need for since we can just use=
=20
=3D.=20
Also, here:
[4:1]t; // Access element 4 of t as a parameter pack
That doesn't make sense. Slice always returns a tuple. If you want just=20
element 4, you'd want [4]t in your syntax. If you want a tuple consisting=
=20
of just the element 4, you'd want [4:5]t;=20
Also, why prefix? You never make the argument for that. That alone is a=20
substantial departure for the norms for indexing in C++ (and Python and=20
other languages).=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/f8b6c0ca-6e91-490f-b301-1cfb7b8a5179%40isocpp.or=
g.
------=_Part_737_129874614.1458320926198
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
You write:<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204=
, 204); border-left-style: solid; padding-left: 1ex;"><p style=3D"color: rg=
b(0, 0, 0); font-family: 'Times New Roman'; font-size: medium;">Our=
preference, however, is prefix operator=C2=A0<tt class=3D"docutils literal=
">[:]</tt>. (The reasons for the three-character spelling may already be ob=
vious to those familiar with Python; we will explore them later, in=C2=A0<a=
class=3D"reference internal" href=3D"https://11080372623597421729.googlegr=
oups.com/attach/9601cb656f56e/dxxxx-tuple-like-unified-vision.html?part=3D0=
..1&view=3D1&vt=3DANaJVrFJSYTg6qNEMUMaLq0tYZltuDpeHrTRl3ML3E7gLynk50=
bIZePSF2X87XWUVEcgNnKgDnxwspXAkqa8UNf_VcvjmHibbKHGuYcMcHahkxOCTM7VGKk#slici=
ng">Slicing</a>). For example:</p><pre class=3D"code c++ literal-block" sty=
le=3D"color: rgb(0, 0, 0); background-color: rgb(238, 238, 238);"><span cla=
ss=3D"keyword" style=3D"color: rgb(59, 13, 6); font-weight: bold;">struct</=
span> <span class=3D"punctuation">{</span> <span class=3D"keyword type" sty=
le=3D"color: rgb(59, 13, 6); font-weight: bold;">double</span> <span class=
=3D"name">x</span><span class=3D"punctuation">,</span> <span class=3D"name"=
>y</span><span class=3D"punctuation">;</span> <span class=3D"punctuation">}=
</span> <span class=3D"name">point</span> <span class=3D"operator">=3D</spa=
n> <span class=3D"punctuation">...;</span>
<span class=3D"keyword" style=3D"color: rgb(59, 13, 6); font-weight: bold;"=
>auto</span> <span class=3D"name">h</span> <span class=3D"operator">=3D</sp=
an> <span class=3D"name">std</span><span class=3D"operator">::</span><span =
class=3D"name">hypot</span><span class=3D"punctuation">([</span><span class=
=3D"operator">:</span><span class=3D"punctuation">]</span><span class=3D"na=
me">point</span><span class=3D"punctuation">...);</span></pre></blockquote>=
<div><br></div><div>But that's not how you unpack a tuple in Python. Yo=
u'd use the splat operator:</div><div><br></div><div><div class=3D"pret=
typrint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-wo=
rd; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div=
class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> h </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D<=
/span><font color=3D"#000000"><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">h=
ypot</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(*</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">point</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">);</span></font></d=
iv></code></div><div><br></div><div>[:] is for copying, which in C++ we hav=
e no need for since we can just use =3D.=C2=A0</div></div><div><br></div><d=
iv>Also, here:</div><div><br></div><div><pre class=3D"code c++ literal-bloc=
k" style=3D"color: rgb(0, 0, 0); background-color: rgb(238, 238, 238);"><sp=
an class=3D"punctuation">[</span><span class=3D"literal number integer">4</=
span><span class=3D"operator">:</span><span class=3D"literal number integer=
">1</span><span class=3D"punctuation">]</span><span class=3D"name">t</span>=
<span class=3D"punctuation">;</span> <span class=3D"comment single" style=
=3D"color: rgb(92, 101, 118);">// Access element 4 of t as a parameter pack
</span></pre></div><div><span class=3D"comment single" style=3D"color: rgb(=
92, 101, 118);"><br></span></div><div>That doesn't make sense. Slice al=
ways returns a tuple. If you want just element 4, you'd want [4]t in yo=
ur syntax. If you want a tuple consisting of just the element 4, you'd =
want [4:5]t;=C2=A0</div><div><br></div><div>Also, why prefix? You never mak=
e the argument for that. That alone is a substantial departure for the norm=
s for indexing in C++ (and Python and other languages).=C2=A0</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f8b6c0ca-6e91-490f-b301-1cfb7b8a5179%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f8b6c0ca-6e91-490f-b301-1cfb7b8a5179=
%40isocpp.org</a>.<br />
------=_Part_737_129874614.1458320926198--
------=_Part_736_1181215708.1458320926198--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 18 Mar 2016 13:54:46 -0400
Raw View
On 2016-03-18 13:08, barry.revzin@gmail.com wrote:
>> Our preference, however, is prefix operator [:]. (The reasons for the
>> three-character spelling may already be obvious to those familiar with
>> Python; we will explore them later, in Slicing). For example:
>>
>> struct { double x, y; } point = ...;auto h = std::hypot([:]point...);
>
> But that's not how you unpack a tuple in Python. You'd use the splat
> operator:
>
> auto h = std::hypot(*point);
That would *only* ever work with first class multiple return values. I'm
not sure how you'd employ it to implement slicing. I'd also be nervous
about supplying a default `operator*` that does unpacking.
> [:] is for copying, which in C++ we have no need for since we can just use
> =.
>
> Also, here:
>
> [4:1]t; // Access element 4 of t as a parameter pack
>
> That doesn't make sense. Slice always returns a tuple. If you want just
> element 4, you'd want [4]t in your syntax.
This isn't Python, though... it's C++. Prefix operator[] is the
constexpr indexing operator. In *all cases* it "unpacks" the operand. In
some cases (`[0]t`) it returns a value. In others it returns a parameter
pack. *This* is why `[:]t` is "generic unpacking"; it is the special
case of sliced unpacking where the slice is "everything".
Also note that you may have a reason to want a parameter pack instead of
a value. Consider especially the case that the indices are not literals;
`[M:N]t` sometimes producing a pack and sometimes producing a value
would be bad (would make generic programming a nightmare).
Anyway, this is highly off topic. The paper isn't proposing this
feature, it's outlining a vision for where we might be going. If you're
getting hung up on syntax points, you have *WILDLY MISSED* the point of
the paper.
That suggests that I need to reword to make this more clear.
> If you want a tuple consisting of just the element 4, you'd want
> [4:5]t;
D'oh... correct, of course. I keep mixing up 'up to index' with 'number
of elements'.
> Also, why prefix? You never make the argument for that.
....because it's off topic. The syntax of unpacking/slicing is not the
point of the paper. (But see footnote 5 (#lc in the reST).)
--
Matthew
--
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/nchfd7%244r4%241%40ger.gmane.org.
.
Author: barry.revzin@gmail.com
Date: Fri, 18 Mar 2016 11:50:01 -0700 (PDT)
Raw View
------=_Part_838_1926820249.1458327001690
Content-Type: multipart/alternative;
boundary="----=_Part_839_1444585129.1458327001690"
------=_Part_839_1444585129.1458327001690
Content-Type: text/plain; charset=UTF-8
>
> Anyway, this is highly off topic. The paper isn't proposing this
> feature, it's outlining a vision for where we might be going. If you're
> getting hung up on syntax points, you have *WILDLY MISSED* the point of
> the paper.
>
The paper reads very much like you are proposing prefix operator[] to
handle indexing and slicing parameter packs. That's what all of the code
fragments use. I don't know how else to interpret this paper other than the
vision that you're outlining is prefix operator[].
The syntax of unpacking/slicing is not the
> point of the paper. (But see footnote 5 (#lc in the reST).)
And the sentence with that footnote is arguing for the advantages of prefix
operator[] over a different proposed syntax.
--
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/0c6bf477-1d55-47ed-9ef7-3f4ef1b83199%40isocpp.org.
------=_Part_839_1444585129.1458327001690
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Anyway, this =
is highly off topic. The paper isn't proposing this
<br>feature, it's outlining a vision for where we might be going. If yo=
u're
<br>getting hung up on syntax points, you have *WILDLY MISSED* the point of
<br>the paper.
<br></blockquote><div><br></div><div>The paper reads very much like you are=
proposing prefix operator[] to handle indexing and slicing parameter packs=
.. That's what all of the code fragments use. I don't know how else =
to interpret this paper other than the vision that you're outlining is =
prefix operator[].=C2=A0</div><div><br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left=
-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;">T=
he syntax of unpacking/slicing is not the=C2=A0<br>point of the paper. (But=
see footnote 5 (#lc in the reST).)=C2=A0</blockquote><div><br></div><div>A=
nd the sentence with that footnote is arguing for the advantages of prefix =
operator[] over a different proposed syntax.=C2=A0</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" 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/0c6bf477-1d55-47ed-9ef7-3f4ef1b83199%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0c6bf477-1d55-47ed-9ef7-3f4ef1b83199=
%40isocpp.org</a>.<br />
------=_Part_839_1444585129.1458327001690--
------=_Part_838_1926820249.1458327001690--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 18 Mar 2016 16:01:26 -0400
Raw View
This is a multi-part message in MIME format.
--------------060305020907090604080801
Content-Type: text/plain; charset=UTF-8
On 2016-03-18 14:50, barry.revzin@gmail.com wrote:
>> Anyway, this is highly off topic. The paper isn't proposing this
>> feature, it's outlining a vision for where we might be going. If you're
>> getting hung up on syntax points, you have *WILDLY MISSED* the point of
>> the paper.
>
> The paper reads very much like you are proposing prefix operator[] to
> handle indexing and slicing parameter packs.
I'm "proposing" that indexing and slicing tuples and parameter packs are
"interesting features"... and to some extent, encouraging that they
should all have the same syntax. What form that syntax takes is a
secondary point, and this paper is *not* the proposal to add such a syntax.
Did you *read* the background and/or summary sections? (Or the
unification section, for that matter?) I've tried very hard to make the
intent clear. If you can suggest a way to do that better, without going
*too* abstract in the sections looking at where we might be going, that
would be appreciated.
Updates attached; maybe the changes will help... (I've tried to reduce
the ratio of "teaser" to important content.)
> That's what all of the code fragments use.
(new) "we urge the reader to keep in mind that syntax shown is used in
this context only as a tool to communicate examples of the future
feature space"
> I don't know how else to interpret this paper other than the
> vision that you're outlining is prefix operator[].
(original) "this paper is [...meant as] a recommendation for areas which
we feel need to be explored, and in particular, considered by other
proposals being put forward"
--
Matthew
--
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/nchmqn%24qv3%241%40ger.gmane.org.
--------------060305020907090604080801
Content-Type: text/html; charset=UTF-8;
name="dxxxx-tuple-like-unified-vision.html"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="dxxxx-tuple-like-unified-vision.html"
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjwhRE9DVFlQRSBodG1s
IFBVQkxJQyAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFRyYW5zaXRpb25hbC8vRU4iICJodHRw
Oi8vd3d3LnczLm9yZy9UUi94aHRtbDEvRFREL3hodG1sMS10cmFuc2l0aW9uYWwuZHRkIj4K
PGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHhtbDpsYW5nPSJl
biIgbGFuZz0iZW4iPgo8aGVhZD4KPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBj
b250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiIC8+CjxtZXRhIG5hbWU9ImdlbmVy
YXRvciIgY29udGVudD0iRG9jdXRpbHMgMC4xMTogaHR0cDovL2RvY3V0aWxzLnNvdXJjZWZv
cmdlLm5ldC8iIC8+Cjx0aXRsZT5BIFVuaWZpZWQgVmlzaW9uIGZvciBNYW5pcHVsYXRpbmcg
VHVwbGUtbGlrZSBPYmplY3RzPC90aXRsZT4KPG1ldGEgbmFtZT0iZGF0ZSIgY29udGVudD0i
MjAxNi0wMy0xOCIgLz4KPG1ldGEgbmFtZT0iYXV0aG9yIiBjb250ZW50PSJNYXR0aGV3IFdv
ZWhsa2UgKG13b2VobGtlLmZsb3NzJiM2NDtnbWFpbC5jb20pIiAvPgo8c3R5bGUgdHlwZT0i
dGV4dC9jc3MiPgoKLyoKOkF1dGhvcjogRGF2aWQgR29vZGdlciAoZ29vZGdlckBweXRob24u
b3JnKQo6SWQ6ICRJZDogaHRtbDRjc3MxLmNzcyA3NjE0IDIwMTMtMDItMjEgMTU6NTU6NTFa
IG1pbGRlICQKOkNvcHlyaWdodDogVGhpcyBzdHlsZXNoZWV0IGhhcyBiZWVuIHBsYWNlZCBp
biB0aGUgcHVibGljIGRvbWFpbi4KCkRlZmF1bHQgY2FzY2FkaW5nIHN0eWxlIHNoZWV0IGZv
ciB0aGUgSFRNTCBvdXRwdXQgb2YgRG9jdXRpbHMuCgpTZWUgaHR0cDovL2RvY3V0aWxzLnNm
Lm5ldC9kb2NzL2hvd3RvL2h0bWwtc3R5bGVzaGVldHMuaHRtbCBmb3IgaG93IHRvCmN1c3Rv
bWl6ZSB0aGlzIHN0eWxlIHNoZWV0LgoqLwoKLyogdXNlZCB0byByZW1vdmUgYm9yZGVycyBm
cm9tIHRhYmxlcyBhbmQgaW1hZ2VzICovCi5ib3JkZXJsZXNzLCB0YWJsZS5ib3JkZXJsZXNz
IHRkLCB0YWJsZS5ib3JkZXJsZXNzIHRoIHsKICBib3JkZXI6IDAgfQoKdGFibGUuYm9yZGVy
bGVzcyB0ZCwgdGFibGUuYm9yZGVybGVzcyB0aCB7CiAgLyogT3ZlcnJpZGUgcGFkZGluZyBm
b3IgInRhYmxlLmRvY3V0aWxzIHRkIiB3aXRoICIhIGltcG9ydGFudCIuCiAgICAgVGhlIHJp
Z2h0IHBhZGRpbmcgc2VwYXJhdGVzIHRoZSB0YWJsZSBjZWxscy4gKi8KICBwYWRkaW5nOiAw
IDAuNWVtIDAgMCAhIGltcG9ydGFudCB9CgouZmlyc3QgewogIC8qIE92ZXJyaWRlIG1vcmUg
c3BlY2lmaWMgbWFyZ2luIHN0eWxlcyB3aXRoICIhIGltcG9ydGFudCIuICovCiAgbWFyZ2lu
LXRvcDogMCAhIGltcG9ydGFudCB9CgoubGFzdCwgLndpdGgtc3VidGl0bGUgewogIG1hcmdp
bi1ib3R0b206IDAgISBpbXBvcnRhbnQgfQoKLmhpZGRlbiB7CiAgZGlzcGxheTogbm9uZSB9
CgphLnRvYy1iYWNrcmVmIHsKICB0ZXh0LWRlY29yYXRpb246IG5vbmUgOwogIGNvbG9yOiBi
bGFjayB9CgpibG9ja3F1b3RlLmVwaWdyYXBoIHsKICBtYXJnaW46IDJlbSA1ZW0gOyB9Cgpk
bC5kb2N1dGlscyBkZCB7CiAgbWFyZ2luLWJvdHRvbTogMC41ZW0gfQoKb2JqZWN0W3R5cGU9
ImltYWdlL3N2Zyt4bWwiXSwgb2JqZWN0W3R5cGU9ImFwcGxpY2F0aW9uL3gtc2hvY2t3YXZl
LWZsYXNoIl0gewogIG92ZXJmbG93OiBoaWRkZW47Cn0KCi8qIFVuY29tbWVudCAoYW5kIHJl
bW92ZSB0aGlzIHRleHQhKSB0byBnZXQgYm9sZC1mYWNlZCBkZWZpbml0aW9uIGxpc3QgdGVy
bXMKZGwuZG9jdXRpbHMgZHQgewogIGZvbnQtd2VpZ2h0OiBib2xkIH0KKi8KCmRpdi5hYnN0
cmFjdCB7CiAgbWFyZ2luOiAyZW0gNWVtIH0KCmRpdi5hYnN0cmFjdCBwLnRvcGljLXRpdGxl
IHsKICBmb250LXdlaWdodDogYm9sZCA7CiAgdGV4dC1hbGlnbjogY2VudGVyIH0KCmRpdi5h
ZG1vbml0aW9uLCBkaXYuYXR0ZW50aW9uLCBkaXYuY2F1dGlvbiwgZGl2LmRhbmdlciwgZGl2
LmVycm9yLApkaXYuaGludCwgZGl2LmltcG9ydGFudCwgZGl2Lm5vdGUsIGRpdi50aXAsIGRp
di53YXJuaW5nIHsKICBtYXJnaW46IDJlbSA7CiAgYm9yZGVyOiBtZWRpdW0gb3V0c2V0IDsK
ICBwYWRkaW5nOiAxZW0gfQoKZGl2LmFkbW9uaXRpb24gcC5hZG1vbml0aW9uLXRpdGxlLCBk
aXYuaGludCBwLmFkbW9uaXRpb24tdGl0bGUsCmRpdi5pbXBvcnRhbnQgcC5hZG1vbml0aW9u
LXRpdGxlLCBkaXYubm90ZSBwLmFkbW9uaXRpb24tdGl0bGUsCmRpdi50aXAgcC5hZG1vbml0
aW9uLXRpdGxlIHsKICBmb250LXdlaWdodDogYm9sZCA7CiAgZm9udC1mYW1pbHk6IHNhbnMt
c2VyaWYgfQoKZGl2LmF0dGVudGlvbiBwLmFkbW9uaXRpb24tdGl0bGUsIGRpdi5jYXV0aW9u
IHAuYWRtb25pdGlvbi10aXRsZSwKZGl2LmRhbmdlciBwLmFkbW9uaXRpb24tdGl0bGUsIGRp
di5lcnJvciBwLmFkbW9uaXRpb24tdGl0bGUsCmRpdi53YXJuaW5nIHAuYWRtb25pdGlvbi10
aXRsZSwgLmNvZGUgLmVycm9yIHsKICBjb2xvcjogcmVkIDsKICBmb250LXdlaWdodDogYm9s
ZCA7CiAgZm9udC1mYW1pbHk6IHNhbnMtc2VyaWYgfQoKLyogVW5jb21tZW50IChhbmQgcmVt
b3ZlIHRoaXMgdGV4dCEpIHRvIGdldCByZWR1Y2VkIHZlcnRpY2FsIHNwYWNlIGluCiAgIGNv
bXBvdW5kIHBhcmFncmFwaHMuCmRpdi5jb21wb3VuZCAuY29tcG91bmQtZmlyc3QsIGRpdi5j
b21wb3VuZCAuY29tcG91bmQtbWlkZGxlIHsKICBtYXJnaW4tYm90dG9tOiAwLjVlbSB9Cgpk
aXYuY29tcG91bmQgLmNvbXBvdW5kLWxhc3QsIGRpdi5jb21wb3VuZCAuY29tcG91bmQtbWlk
ZGxlIHsKICBtYXJnaW4tdG9wOiAwLjVlbSB9CiovCgpkaXYuZGVkaWNhdGlvbiB7CiAgbWFy
Z2luOiAyZW0gNWVtIDsKICB0ZXh0LWFsaWduOiBjZW50ZXIgOwogIGZvbnQtc3R5bGU6IGl0
YWxpYyB9CgpkaXYuZGVkaWNhdGlvbiBwLnRvcGljLXRpdGxlIHsKICBmb250LXdlaWdodDog
Ym9sZCA7CiAgZm9udC1zdHlsZTogbm9ybWFsIH0KCmRpdi5maWd1cmUgewogIG1hcmdpbi1s
ZWZ0OiAyZW0gOwogIG1hcmdpbi1yaWdodDogMmVtIH0KCmRpdi5mb290ZXIsIGRpdi5oZWFk
ZXIgewogIGNsZWFyOiBib3RoOwogIGZvbnQtc2l6ZTogc21hbGxlciB9CgpkaXYubGluZS1i
bG9jayB7CiAgZGlzcGxheTogYmxvY2sgOwogIG1hcmdpbi10b3A6IDFlbSA7CiAgbWFyZ2lu
LWJvdHRvbTogMWVtIH0KCmRpdi5saW5lLWJsb2NrIGRpdi5saW5lLWJsb2NrIHsKICBtYXJn
aW4tdG9wOiAwIDsKICBtYXJnaW4tYm90dG9tOiAwIDsKICBtYXJnaW4tbGVmdDogMS41ZW0g
fQoKZGl2LnNpZGViYXIgewogIG1hcmdpbjogMCAwIDAuNWVtIDFlbSA7CiAgYm9yZGVyOiBt
ZWRpdW0gb3V0c2V0IDsKICBwYWRkaW5nOiAxZW0gOwogIGJhY2tncm91bmQtY29sb3I6ICNm
ZmZmZWUgOwogIHdpZHRoOiA0MCUgOwogIGZsb2F0OiByaWdodCA7CiAgY2xlYXI6IHJpZ2h0
IH0KCmRpdi5zaWRlYmFyIHAucnVicmljIHsKICBmb250LWZhbWlseTogc2Fucy1zZXJpZiA7
CiAgZm9udC1zaXplOiBtZWRpdW0gfQoKZGl2LnN5c3RlbS1tZXNzYWdlcyB7CiAgbWFyZ2lu
OiA1ZW0gfQoKZGl2LnN5c3RlbS1tZXNzYWdlcyBoMSB7CiAgY29sb3I6IHJlZCB9CgpkaXYu
c3lzdGVtLW1lc3NhZ2UgewogIGJvcmRlcjogbWVkaXVtIG91dHNldCA7CiAgcGFkZGluZzog
MWVtIH0KCmRpdi5zeXN0ZW0tbWVzc2FnZSBwLnN5c3RlbS1tZXNzYWdlLXRpdGxlIHsKICBj
b2xvcjogcmVkIDsKICBmb250LXdlaWdodDogYm9sZCB9CgpkaXYudG9waWMgewogIG1hcmdp
bjogMmVtIH0KCmgxLnNlY3Rpb24tc3VidGl0bGUsIGgyLnNlY3Rpb24tc3VidGl0bGUsIGgz
LnNlY3Rpb24tc3VidGl0bGUsCmg0LnNlY3Rpb24tc3VidGl0bGUsIGg1LnNlY3Rpb24tc3Vi
dGl0bGUsIGg2LnNlY3Rpb24tc3VidGl0bGUgewogIG1hcmdpbi10b3A6IDAuNGVtIH0KCmgx
LnRpdGxlIHsKICB0ZXh0LWFsaWduOiBjZW50ZXIgfQoKaDIuc3VidGl0bGUgewogIHRleHQt
YWxpZ246IGNlbnRlciB9Cgpoci5kb2N1dGlscyB7CiAgd2lkdGg6IDc1JSB9CgppbWcuYWxp
Z24tbGVmdCwgLmZpZ3VyZS5hbGlnbi1sZWZ0LCBvYmplY3QuYWxpZ24tbGVmdCB7CiAgY2xl
YXI6IGxlZnQgOwogIGZsb2F0OiBsZWZ0IDsKICBtYXJnaW4tcmlnaHQ6IDFlbSB9CgppbWcu
YWxpZ24tcmlnaHQsIC5maWd1cmUuYWxpZ24tcmlnaHQsIG9iamVjdC5hbGlnbi1yaWdodCB7
CiAgY2xlYXI6IHJpZ2h0IDsKICBmbG9hdDogcmlnaHQgOwogIG1hcmdpbi1sZWZ0OiAxZW0g
fQoKaW1nLmFsaWduLWNlbnRlciwgLmZpZ3VyZS5hbGlnbi1jZW50ZXIsIG9iamVjdC5hbGln
bi1jZW50ZXIgewogIGRpc3BsYXk6IGJsb2NrOwogIG1hcmdpbi1sZWZ0OiBhdXRvOwogIG1h
cmdpbi1yaWdodDogYXV0bzsKfQoKLmFsaWduLWxlZnQgewogIHRleHQtYWxpZ246IGxlZnQg
fQoKLmFsaWduLWNlbnRlciB7CiAgY2xlYXI6IGJvdGggOwogIHRleHQtYWxpZ246IGNlbnRl
ciB9CgouYWxpZ24tcmlnaHQgewogIHRleHQtYWxpZ246IHJpZ2h0IH0KCi8qIHJlc2V0IGlu
bmVyIGFsaWdubWVudCBpbiBmaWd1cmVzICovCmRpdi5hbGlnbi1yaWdodCB7CiAgdGV4dC1h
bGlnbjogaW5oZXJpdCB9CgovKiBkaXYuYWxpZ24tY2VudGVyICogeyAqLwovKiAgIHRleHQt
YWxpZ246IGxlZnQgfSAqLwoKb2wuc2ltcGxlLCB1bC5zaW1wbGUgewogIG1hcmdpbi1ib3R0
b206IDFlbSB9CgpvbC5hcmFiaWMgewogIGxpc3Qtc3R5bGU6IGRlY2ltYWwgfQoKb2wubG93
ZXJhbHBoYSB7CiAgbGlzdC1zdHlsZTogbG93ZXItYWxwaGEgfQoKb2wudXBwZXJhbHBoYSB7
CiAgbGlzdC1zdHlsZTogdXBwZXItYWxwaGEgfQoKb2wubG93ZXJyb21hbiB7CiAgbGlzdC1z
dHlsZTogbG93ZXItcm9tYW4gfQoKb2wudXBwZXJyb21hbiB7CiAgbGlzdC1zdHlsZTogdXBw
ZXItcm9tYW4gfQoKcC5hdHRyaWJ1dGlvbiB7CiAgdGV4dC1hbGlnbjogcmlnaHQgOwogIG1h
cmdpbi1sZWZ0OiA1MCUgfQoKcC5jYXB0aW9uIHsKICBmb250LXN0eWxlOiBpdGFsaWMgfQoK
cC5jcmVkaXRzIHsKICBmb250LXN0eWxlOiBpdGFsaWMgOwogIGZvbnQtc2l6ZTogc21hbGxl
ciB9CgpwLmxhYmVsIHsKICB3aGl0ZS1zcGFjZTogbm93cmFwIH0KCnAucnVicmljIHsKICBm
b250LXdlaWdodDogYm9sZCA7CiAgZm9udC1zaXplOiBsYXJnZXIgOwogIGNvbG9yOiBtYXJv
b24gOwogIHRleHQtYWxpZ246IGNlbnRlciB9CgpwLnNpZGViYXItdGl0bGUgewogIGZvbnQt
ZmFtaWx5OiBzYW5zLXNlcmlmIDsKICBmb250LXdlaWdodDogYm9sZCA7CiAgZm9udC1zaXpl
OiBsYXJnZXIgfQoKcC5zaWRlYmFyLXN1YnRpdGxlIHsKICBmb250LWZhbWlseTogc2Fucy1z
ZXJpZiA7CiAgZm9udC13ZWlnaHQ6IGJvbGQgfQoKcC50b3BpYy10aXRsZSB7CiAgZm9udC13
ZWlnaHQ6IGJvbGQgfQoKcHJlLmFkZHJlc3MgewogIG1hcmdpbi1ib3R0b206IDAgOwogIG1h
cmdpbi10b3A6IDAgOwogIGZvbnQ6IGluaGVyaXQgfQoKcHJlLmxpdGVyYWwtYmxvY2ssIHBy
ZS5kb2N0ZXN0LWJsb2NrLCBwcmUubWF0aCwgcHJlLmNvZGUgewogIG1hcmdpbi1sZWZ0OiAy
ZW0gOwogIG1hcmdpbi1yaWdodDogMmVtIH0KCnByZS5jb2RlIC5sbiB7IGNvbG9yOiBncmV5
OyB9IC8qIGxpbmUgbnVtYmVycyAqLwpwcmUuY29kZSwgY29kZSB7IGJhY2tncm91bmQtY29s
b3I6ICNlZWVlZWUgfQpwcmUuY29kZSAuY29tbWVudCwgY29kZSAuY29tbWVudCB7IGNvbG9y
OiAjNUM2NTc2IH0KcHJlLmNvZGUgLmtleXdvcmQsIGNvZGUgLmtleXdvcmQgeyBjb2xvcjog
IzNCMEQwNjsgZm9udC13ZWlnaHQ6IGJvbGQgfQpwcmUuY29kZSAubGl0ZXJhbC5zdHJpbmcs
IGNvZGUgLmxpdGVyYWwuc3RyaW5nIHsgY29sb3I6ICMwQzU0MDQgfQpwcmUuY29kZSAubmFt
ZS5idWlsdGluLCBjb2RlIC5uYW1lLmJ1aWx0aW4geyBjb2xvcjogIzM1MkI4NCB9CnByZS5j
b2RlIC5kZWxldGVkLCBjb2RlIC5kZWxldGVkIHsgYmFja2dyb3VuZC1jb2xvcjogI0RFQjBB
MX0KcHJlLmNvZGUgLmluc2VydGVkLCBjb2RlIC5pbnNlcnRlZCB7IGJhY2tncm91bmQtY29s
b3I6ICNBM0QyODl9CgpzcGFuLmNsYXNzaWZpZXIgewogIGZvbnQtZmFtaWx5OiBzYW5zLXNl
cmlmIDsKICBmb250LXN0eWxlOiBvYmxpcXVlIH0KCnNwYW4uY2xhc3NpZmllci1kZWxpbWl0
ZXIgewogIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmIDsKICBmb250LXdlaWdodDogYm9sZCB9
CgpzcGFuLmludGVycHJldGVkIHsKICBmb250LWZhbWlseTogc2Fucy1zZXJpZiB9CgpzcGFu
Lm9wdGlvbiB7CiAgd2hpdGUtc3BhY2U6IG5vd3JhcCB9CgpzcGFuLnByZSB7CiAgd2hpdGUt
c3BhY2U6IHByZSB9CgpzcGFuLnByb2JsZW1hdGljIHsKICBjb2xvcjogcmVkIH0KCnNwYW4u
c2VjdGlvbi1zdWJ0aXRsZSB7CiAgLyogZm9udC1zaXplIHJlbGF0aXZlIHRvIHBhcmVudCAo
aDEuLmg2IGVsZW1lbnQpICovCiAgZm9udC1zaXplOiA4MCUgfQoKdGFibGUuY2l0YXRpb24g
ewogIGJvcmRlci1sZWZ0OiBzb2xpZCAxcHggZ3JheTsKICBtYXJnaW4tbGVmdDogMXB4IH0K
CnRhYmxlLmRvY2luZm8gewogIG1hcmdpbjogMmVtIDRlbSB9Cgp0YWJsZS5kb2N1dGlscyB7
CiAgbWFyZ2luLXRvcDogMC41ZW0gOwogIG1hcmdpbi1ib3R0b206IDAuNWVtIH0KCnRhYmxl
LmZvb3Rub3RlIHsKICBib3JkZXItbGVmdDogc29saWQgMXB4IGJsYWNrOwogIG1hcmdpbi1s
ZWZ0OiAxcHggfQoKdGFibGUuZG9jdXRpbHMgdGQsIHRhYmxlLmRvY3V0aWxzIHRoLAp0YWJs
ZS5kb2NpbmZvIHRkLCB0YWJsZS5kb2NpbmZvIHRoIHsKICBwYWRkaW5nLWxlZnQ6IDAuNWVt
IDsKICBwYWRkaW5nLXJpZ2h0OiAwLjVlbSA7CiAgdmVydGljYWwtYWxpZ246IHRvcCB9Cgp0
YWJsZS5kb2N1dGlscyB0aC5maWVsZC1uYW1lLCB0YWJsZS5kb2NpbmZvIHRoLmRvY2luZm8t
bmFtZSB7CiAgZm9udC13ZWlnaHQ6IGJvbGQgOwogIHRleHQtYWxpZ246IGxlZnQgOwogIHdo
aXRlLXNwYWNlOiBub3dyYXAgOwogIHBhZGRpbmctbGVmdDogMCB9CgovKiAiYm9va3RhYnMi
IHN0eWxlIChubyB2ZXJ0aWNhbCBsaW5lcykgKi8KdGFibGUuZG9jdXRpbHMuYm9va3RhYnMg
ewogIGJvcmRlcjogMHB4OwogIGJvcmRlci10b3A6IDJweCBzb2xpZDsKICBib3JkZXItYm90
dG9tOiAycHggc29saWQ7CiAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsKfQp0YWJsZS5k
b2N1dGlscy5ib29rdGFicyAqIHsKICBib3JkZXI6IDBweDsKfQp0YWJsZS5kb2N1dGlscy5i
b29rdGFicyB0aCB7CiAgYm9yZGVyLWJvdHRvbTogdGhpbiBzb2xpZDsKICB0ZXh0LWFsaWdu
OiBsZWZ0Owp9CgpoMSB0dC5kb2N1dGlscywgaDIgdHQuZG9jdXRpbHMsIGgzIHR0LmRvY3V0
aWxzLApoNCB0dC5kb2N1dGlscywgaDUgdHQuZG9jdXRpbHMsIGg2IHR0LmRvY3V0aWxzIHsK
ICBmb250LXNpemU6IDEwMCUgfQoKdWwuYXV0by10b2MgewogIGxpc3Qtc3R5bGUtdHlwZTog
bm9uZSB9Cgo8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5Pgo8ZGl2IGNsYXNzPSJkb2N1bWVudCIg
aWQ9ImEtdW5pZmllZC12aXNpb24tZm9yLW1hbmlwdWxhdGluZy10dXBsZS1saWtlLW9iamVj
dHMiPgo8aDEgY2xhc3M9InRpdGxlIj5BIFVuaWZpZWQgVmlzaW9uIGZvciBNYW5pcHVsYXRp
bmcgVHVwbGUtbGlrZSBPYmplY3RzPC9oMT4KPHRhYmxlIGNsYXNzPSJkb2NpbmZvIiBmcmFt
ZT0idm9pZCIgcnVsZXM9Im5vbmUiPgo8Y29sIGNsYXNzPSJkb2NpbmZvLW5hbWUiIC8+Cjxj
b2wgY2xhc3M9ImRvY2luZm8tY29udGVudCIgLz4KPHRib2R5IHZhbGlnbj0idG9wIj4KPHRy
IGNsYXNzPSJmaWVsZCI+PHRoIGNsYXNzPSJkb2NpbmZvLW5hbWUiPkRvY3VtZW50OjwvdGg+
PHRkIGNsYXNzPSJmaWVsZC1ib2R5Ij5EWFhYWFIwIChUQkQpPC90ZD4KPC90cj4KPHRyPjx0
aCBjbGFzcz0iZG9jaW5mby1uYW1lIj5EYXRlOjwvdGg+Cjx0ZD4yMDE2LTAzLTE4PC90ZD48
L3RyPgo8dHIgY2xhc3M9ImZpZWxkIj48dGggY2xhc3M9ImRvY2luZm8tbmFtZSI+UHJvamVj
dDo8L3RoPjx0ZCBjbGFzcz0iZmllbGQtYm9keSI+SVNPL0lFQyBKVEMxIFNDMjIgV0cyMSBQ
cm9ncmFtbWluZyBMYW5ndWFnZSBDKys8L3RkPgo8L3RyPgo8dHIgY2xhc3M9ImZpZWxkIj48
dGggY2xhc3M9ImRvY2luZm8tbmFtZSI+QXVkaWVuY2U6PC90aD48dGQgY2xhc3M9ImZpZWxk
LWJvZHkiPkV2b2x1dGlvbiBXb3JraW5nIEdyb3VwPC90ZD4KPC90cj4KPHRyPjx0aCBjbGFz
cz0iZG9jaW5mby1uYW1lIj5BdXRob3I6PC90aD4KPHRkPk1hdHRoZXcgV29laGxrZSAoPGEg
Y2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0ibWFpbHRvOm13b2VobGtlLmZsb3Nz
JiM2NDtnbWFpbC5jb20iPm13b2VobGtlLmZsb3NzJiM2NDtnbWFpbC5jb208L2E+KTwvdGQ+
PC90cj4KPC90Ym9keT4KPC90YWJsZT4KPHN0eWxlPgogIGh0bWwgeyBjb2xvcjogYmxhY2s7
IGJhY2tncm91bmQ6IHdoaXRlOyB9CiAgdGFibGUuZG9jaW5mbyB7IG1hcmdpbjogMmVtIDA7
IH0KPC9zdHlsZT48ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0iYWJzdHJhY3QiPgo8aDE+PGEg
Y2xhc3M9InRvYy1iYWNrcmVmIiBocmVmPSIjaWQ4Ij5BYnN0cmFjdDwvYT48L2gxPgo8cD5U
aGVyZSBpcyBtdWNoIGFjdGl2aXR5IGFuZCBkaXNjdXNzaW9uIHN1cnJvdW5kaW5nIHR1cGxl
LWxpa2Ugb2JqZWN0cywgd2l0aCBtYW55IGZlYXR1cmVzIGJlaW5nIHJlcXVlc3RlZCBhbmQg
bWFueSBwYXBlcnMgc3VibWl0dGVkIG9yIHBsYW5uZWQuIEl0IGlzIGltcG9ydGFudCB0aGF0
IHdlIGVzdGFibGlzaCBhIHBsYW4gZm9yIHdoZXJlIHdlIGFyZSBnb2luZyB0aGF0IHRha2Vz
IGludG8gYWNjb3VudCBmdXR1cmUgZGlyZWN0aW9ucyBpbiBvcmRlciB0byBhdm9pZCBvdmVy
Y29tcGxpY2F0aW5nIHRoZSBsYW5ndWFnZSBvciBwYWludGluZyBvdXJzZWx2ZXMgaW50byBh
IGNvcm5lciBvZiBpbmNvbXBhdGlibGUgZmVhdHVyZXMuPC9wPgo8ZGl2IGNsYXNzPSJjb250
ZW50cyB0b3BpYyIgaWQ9ImNvbnRlbnRzIj4KPHAgY2xhc3M9InRvcGljLXRpdGxlIGZpcnN0
Ij5Db250ZW50czwvcD4KPHVsIGNsYXNzPSJzaW1wbGUiPgo8bGk+PGEgY2xhc3M9InJlZmVy
ZW5jZSBpbnRlcm5hbCIgaHJlZj0iI2Fic3RyYWN0IiBpZD0iaWQ4Ij5BYnN0cmFjdDwvYT48
L2xpPgo8bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0iI2JhY2tncm91
bmQiIGlkPSJpZDkiPkJhY2tncm91bmQ8L2E+PC9saT4KPGxpPjxhIGNsYXNzPSJyZWZlcmVu
Y2UgaW50ZXJuYWwiIGhyZWY9IiNwcmVmYWNlIiBpZD0iaWQxMCI+UHJlZmFjZTwvYT48L2xp
Pgo8bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0iI2RlZmluaXRpb25z
IiBpZD0iaWQxMSI+RGVmaW5pdGlvbnM8L2E+PC9saT4KPGxpPjxhIGNsYXNzPSJyZWZlcmVu
Y2UgaW50ZXJuYWwiIGhyZWY9IiNhY2Nlc3MiIGlkPSJpZDEyIj5BY2Nlc3M8L2E+PHVsPgo8
bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0iI2FuLW9wZXJhdG9yLWxp
a2UtYWx0ZXJuYXRpdmUiIGlkPSJpZDEzIj5BbiBvcGVyYXRvci1saWtlIGFsdGVybmF0aXZl
PC9hPjwvbGk+CjwvdWw+CjwvbGk+CjxsaT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFs
IiBocmVmPSIjZ2VuZXJhbGl6ZWQtdW5wYWNraW5nIiBpZD0iaWQxNCI+R2VuZXJhbGl6ZWQg
VW5wYWNraW5nPC9hPjwvbGk+CjxsaT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBo
cmVmPSIjdW5pZmljYXRpb24tb2YtdW5wYWNraW5nIiBpZD0iaWQxNSI+VW5pZmljYXRpb24g
b2YgVW5wYWNraW5nPC9hPjwvbGk+CjxsaT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFs
IiBocmVmPSIjc2xpY2luZyIgaWQ9ImlkMTYiPlNsaWNpbmc8L2E+PC9saT4KPGxpPjxhIGNs
YXNzPSJyZWZlcmVuY2UgaW50ZXJuYWwiIGhyZWY9IiNwYWNrLWdlbmVyYXRpb24tcmV2aXNp
dGVkIiBpZD0iaWQxNyI+UGFjayBHZW5lcmF0aW9uLCBSZXZpc2l0ZWQ8L2E+PC9saT4KPGxp
PjxhIGNsYXNzPSJyZWZlcmVuY2UgaW50ZXJuYWwiIGhyZWY9IiNzdW1tYXJ5IiBpZD0iaWQx
OCI+U3VtbWFyeTwvYT48L2xpPgo8bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIg
aHJlZj0iI2Fja25vd2xlZGdtZW50cyIgaWQ9ImlkMTkiPkFja25vd2xlZGdtZW50czwvYT48
L2xpPgo8bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0iI2Zvb3Rub3Rl
cyIgaWQ9ImlkMjAiPkZvb3Rub3RlczwvYT48L2xpPgo8bGk+PGEgY2xhc3M9InJlZmVyZW5j
ZSBpbnRlcm5hbCIgaHJlZj0iI3JlZmVyZW5jZXMiIGlkPSJpZDIxIj5SZWZlcmVuY2VzPC9h
PjwvbGk+CjwvdWw+CjwvZGl2Pgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9ImJh
Y2tncm91bmQiPgo8aDE+PGEgY2xhc3M9InRvYy1iYWNrcmVmIiBocmVmPSIjaWQ5Ij5CYWNr
Z3JvdW5kPC9hPjwvaDE+CjxwPkF0IHRoZSAyMDE2IEphY2tzb252aWxsZSBtZWV0aW5nLCA8
YSBjbGFzcz0icmVmZXJlbmNlIGV4dGVybmFsIiBocmVmPSJodHRwOi8vd2cyMS5saW5rL3Aw
MTQ0Ij5QMDE0NDwvYT4gd2FzIGRpc2N1c3NlZCBmb3IgdGhlIHNlY29uZCB0aW1lLiBSZWNl
cHRpb24gd2FzIGdlbmVyYWxseSBwb3NpdGl2ZSwgYnV0IHNvbWUgaXNzdWVzIHJlbWFpbmVk
IHRvIGJlIGFkZHJlc3NlZC4gSXQgc2VlbXMgcXVpdGUgY2xlYXIgdGhhdCB0aGlzIGlzIGEg
ZGVzaXJlZCBkaXJlY3Rpb24gZm9yIEMrKy4gVW5mb3J0dW5hdGVseSwgPGEgY2xhc3M9InJl
ZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDovL3dnMjEubGluay9wMDE5NyI+UDAxOTc8
L2E+LCB3aGljaCB3YXMgc2NoZWR1bGVkIGZvciBwcmVzZW50YXRpb24gYW5kIGhhcyBzb21l
IGltcGFjdCBvbiB0aGUgZGlyZWN0aW9uIHdoaWNoIDxhIGNsYXNzPSJyZWZlcmVuY2UgZXh0
ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAxNDQiPlAwMTQ0PC9hPiBpcyBmb2xs
b3dpbmcsIHdhcyBza2lwcGVkIGR1ZSB0byB0aW1lIGNvbnN0cmFpbnRzLjwvcD4KPHA+RGlz
Y3Vzc2lvbiBvbiB0aGUgPHR0IGNsYXNzPSJkb2N1dGlscyBsaXRlcmFsIj48c3BhbiBjbGFz
cz0icHJlIj5zdGQtcHJvcG9zYWxzPC9zcGFuPjwvdHQ+IGZvcnVtIG9mdGVuIGJyaW5ncyB1
cCB0aGUgZGVzaXJlIHRvIGV4dGVuZCB1c2Ugb2YgJnF1b3Q7dHVwbGUtbGlrZSZxdW90OyBv
YmplY3RzIHRvIGNvbnRleHRzIG90aGVyIHRoYW4gbmFtZSBiaW5kaW5nIChpLmUuIDxhIGNs
YXNzPSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAxNDQi
PlAwMTQ0PC9hPikuIFRoZXJlIGlzIGFsc28gc2lnbmlmaWNhbnQgYW5kIHJlbGF0ZWQgZGlz
Y3Vzc2lvbiBvbiBpbXByb3ZpbmcgdGhlIHVzYWJpbGl0eSBvZiBwYXJhbWV0ZXIgcGFja3Mu
IFdlIGZlZWwgdGhhdCBzZXZlcmFsIG9mIHRoZXNlIGFyZWFzIGFyZSBjbG9zZWx5IHJlbGF0
ZWQgYW5kIHdhcnJhbnQgdGhlIGZvcm1hdGlvbiBvZiBhIGNvbmNyZXRlIGFuZCB1bmlmaWVk
IHZpc2lvbiBmb3IgZnV0dXJlIGRpcmVjdGlvbi48L3A+CjwvZGl2Pgo8ZGl2IGNsYXNzPSJz
ZWN0aW9uIiBpZD0icHJlZmFjZSI+CjxoMT48YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhyZWY9
IiNpZDEwIj5QcmVmYWNlPC9hPjwvaDE+CjxwPldlIHByZXNlbnQgc2V2ZXJhbCBzdWdnZXN0
aW9ucyBpbiB0aGlzIHBhcGVyLCBhbG9uZyB3aXRoIGFjY29tcGFueWluZyBzeW50YXguIFdl
IG11c3Qgc3RyZXNzIDxlbT5lbXBoYXRpY2FsbHk8L2VtPiB0aGF0IHRoaXMgcGFwZXIgaXMg
bm90IGludGVuZGVkIHRvIHByb3Bvc2UgYW55IGZlYXR1cmVzIGluIGFuZCBvZiBpdHNlbGYg
KHRoYXQgd2lsbCBjb21lIGxhdGVyKS4gUmF0aGVyLCB3ZSB3aXNoIHRvIG91dGxpbmUgc2V2
ZXJhbCBhcmVhcyBvZiBhbnRpY2lwYXRlZCBmdXR1cmUgZGV2ZWxvcG1lbnQgd2hpY2ggd2Ug
ZmVlbCBuZWVkIHRvIGJlIGV4cGxvcmVkIGFuZCwgaW4gcGFydGljdWxhciwgY29uc2lkZXJl
ZCBieSBvdGhlciBwcm9wb3NhbHMgYmVpbmcgcHV0IGZvcndhcmQsIGVzcGVjaWFsbHkgPGEg
Y2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDovL3dnMjEubGluay9wMDE0
NCI+UDAxNDQ8L2E+LiBXaGlsZSBzb21lIGJyaWVmIHN0YXRlbWVudHMgYXJlIG1hZGUgYXMg
dG8gb3VyIGNob2ljZXMsIHdlIHVyZ2UgdGhlIHJlYWRlciB0byBrZWVwIGluIG1pbmQgdGhh
dCBzeW50YXggc2hvd24gaXMgdXNlZCBpbiB0aGlzIGNvbnRleHQgb25seSBhcyBhIHRvb2wg
dG8gY29tbXVuaWNhdGUgZXhhbXBsZXMgb2YgdGhlIGZ1dHVyZSBmZWF0dXJlIHNwYWNlLCBh
bmQgbm90IHRvIGdldCBodW5nIHVwIG9uIG1pbm9yIHF1aWJibGVzLiBJbiBwYXJ0aWN1bGFy
LCBvdXIgbW9zdCBpbW1lZGlhdGUgY29uY2VybiBpcyBmb3IgdW5pZmljYXRpb24gb2YgaW1w
bGVtZW50YXRpb24gZGV0YWlscyByZWxhdGVkIHRvIHVucGFja2luZyBhbmQgY3VzdG9taXph
dGlvbiBwb2ludHMgb2YgdGhlIHNhbWUuIFdoaWxlIHdlIGZlZWwgYWxzbyB0aGF0IHNpbWls
YXIgY29uc2lkZXJhdGlvbnMgYXJlIGltcG9ydGFudCB3aXRoIHJlc3BlY3QgdG8gcGFyYW1l
dGVyIHBhY2tzLCB0aGF0IGZlYXR1cmUgc3BhY2UgaXMgbGVzcyBtYXR1cmUsIGFuZCBhY2Nv
cmRpbmdseSB0aGUgbmVlZCBmb3IgYSBjb25zb2xpZGF0ZWQgZGlyZWN0aW9uIGlzIGxlc3Mg
dXJnZW50LCBpZiBubyBsZXNzIHJlYWwuPC9wPgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlv
biIgaWQ9ImRlZmluaXRpb25zIj4KPGgxPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0i
I2lkMTEiPkRlZmluaXRpb25zPC9hPjwvaDE+CjxwPkEgJnF1b3Q7dHVwbGUgbGlrZSZxdW90
OyBpcyBhbnkgb2JqZWN0IGNvbnNpc3Rpbmcgb2Ygb25lIG9yICh1c3VhbGx5KSBtb3JlIG9y
dGhvZ29uYWwgdmFsdWVzIChpbiBtYXRoZW1hdGljYWwgbm90YXRpb24sIGEgJnF1b3Q7cHJv
ZHVjdCB0eXBlJnF1b3Q7KS4gVGhlIGNhbm9uaWNhbCBleGFtcGxlIGlzIDxjb2RlIGNsYXNz
PSJjcHAgYysrIj48c3BhbiBjbGFzcz0ibmFtZSI+c3RkPC9zcGFuPjxzcGFuIGNsYXNzPSJv
cGVyYXRvciI+Ojo8L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUiPnR1cGxlPC9zcGFuPjwvY29k
ZT4sIGJ1dCBvdGhlciBleGFtcGxlcyBpbmNsdWRlIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48
c3BhbiBjbGFzcz0ibmFtZSI+c3RkPC9zcGFuPjxzcGFuIGNsYXNzPSJvcGVyYXRvciI+Ojo8
L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUiPmFycmF5PC9zcGFuPjwvY29kZT4gb3Igc2ltaWxh
ciBmaXhlZC1zaXplIHZlY3RvciB0eXBlcyBhbmQgbW9zdCBhZ2dyZWdhdGVzLCBhcyB3ZWxs
IGFzIHNvbWUgbm9uLWFnZ3JlZ2F0ZSB1c2VyIHR5cGVzIGluY2x1ZGluZyBvbmVzIHdpdGgg
bm8gcHVibGljIE5TRE0nczxhIGNsYXNzPSJmb290bm90ZS1yZWZlcmVuY2UiIGhyZWY9IiNw
dCIgaWQ9ImlkMSI+WzFdPC9hPi48L3A+CjxwPiZxdW90O1VucGFja2luZyZxdW90OyByZWZl
cnMgdG8gdGhlIGNvbnZlcnNpb24gb2YgYSB0dXBsZS1saWtlIG9iamVjdCBpbnRvIGl0cyBj
b21wb25lbnQgcGFydHMuIFRoaXMgaW5jbHVkZXMgYm90aCBuYW1lLWJpbmRpbmcgdW5wYWNr
aW5nIChpLmUuIDxhIGNsYXNzPSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93
ZzIxLmxpbmsvcDAxNDQiPlAwMTQ0PC9hPikgYW5kICZxdW90O2dlbmVyYWxpemVkIHVucGFj
a2luZyZxdW90OyB3aGVyZSB0aGUgY29tcG9uZW50cyBhcmUgdXNlZCBpbiBhIG5vbi1iaW5k
aW5nIGNvbnRleHQ7IGZvciBleGFtcGxlLCBhcyB2YWx1ZXMgaW4gYSBmdW5jdGlvbiBwYXJh
bWV0ZXIgbGlzdC4gTmFtZS1iaW5kaW5nIHVucGFja2luZyBpcyBhbHNvIGNhbGxlZCAmcXVv
dDtzdHJ1Y3R1cmVkIGJpbmRpbmcmcXVvdDsgYW5kLCBoaXN0b3JpY2FsbHksICZxdW90O2Fz
c2lnbm1lbnQgdW5wYWNraW5nJnF1b3Q7LiBXZSBwcmVmZXIgdGhlIHRlcm0gJnF1b3Q7bmFt
ZS1iaW5kaW5nIHVucGFja2luZyZxdW90OyBhcyBpdCBkb2VzIG5vdCBjYWxsIGludG8gcXVl
c3Rpb24gaXNzdWVzIG9mICZxdW90O3RydWUgYXNzaWdubWVudCZxdW90OyB2ZXJzdXMgYWxp
YXNpbmcgd2hlcmUgPGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDov
L3dnMjEubGluay9wMDE0NCI+UDAxNDQ8L2E+IHNwZWNpZmljYWxseSBkZXNpcmVzIHRvIGF2
b2lkIGNlcnRhaW4gb3ZlcmhlYWRzLCBhbmQgdGhlIHVzZSBvZiAmcXVvdDt1bnBhY2tpbmcm
cXVvdDsgc2VydmVzIHRvIGNvbm5lY3QgdHdvIGNsb3NlbHkgcmVsYXRlZCBjb25jZXB0cy48
L3A+CjwvZGl2Pgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0iYWNjZXNzIj4KPGgxPjxhIGNs
YXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkMTIiPkFjY2VzczwvYT48L2gxPgo8cD5PbmUg
b2YgdGhlIGFjdGl2ZSBxdWVzdGlvbnMgYXJvdW5kIDxhIGNsYXNzPSJyZWZlcmVuY2UgZXh0
ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAxNDQiPlAwMTQ0PC9hPiByZWdhcmRz
IHRoZSBjdXN0b21pemF0aW9uIHBvaW50LiBXZSBmZWVsIHN0cm9uZ2x5IHRoYXQgdGhlIGN1
c3RvbWl6YXRpb24gcG9pbnQgZm9yIG5hbWUtYmluZGluZyB1bnBhY2tpbmcgc2hvdWxkIGJl
IHRoZSBzYW1lIGFzIHVzZWQgYnkgZ2VuZXJhbGl6ZWQgdW5wYWNraW5nIGFuZCBieSBleGlz
dGluZyBhbmQgcHJvcG9zZWQgdXRpbGl0eSBmdW5jdGlvbnMgKGUuZy4gPGNvZGUgY2xhc3M9
ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJuYW1lIj5zdGQ8L3NwYW4+PHNwYW4gY2xhc3M9Im9w
ZXJhdG9yIj46Ojwvc3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+YXBwbHk8L3NwYW4+PC9jb2Rl
PiBhbmQgPGNvZGUgY2xhc3M9ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJuYW1lIj5zdGQ8L3Nw
YW4+PHNwYW4gY2xhc3M9Im9wZXJhdG9yIj46Ojwvc3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+
bWFrZV9mcm9tX3R1cGxlPC9zcGFuPjwvY29kZT4pIHRoYXQgYWN0IG9uIHR1cGxlLWxpa2Ug
b2JqZWN0cy4gVGhpcyBpcyBpbXBvcnRhbnQgZm9yIHRoZSBzYWtlIG9mIGNvbnNpc3RlbmN5
OyB0aGVzZSBvcGVyYXRpb25zIGFyZSBleHRyZW1lbHkgc2ltaWxhciwgYW5kIHVzaW5nIGRp
ZmZlcmVudCBjdXN0b21pemF0aW9uIHBvaW50cyB3aWxsIGxpa2VseSByZXN1bHQgaW4gY29u
ZnVzaW9uIGFuZCB0ZWFjaGluZyBkaWZmaWN1bHR5LjwvcD4KPHA+VGhhdCBzYWlkLCB3ZSBm
ZWVsIGxlc3Mgc3Ryb25nbHkgYWJvdXQgdGhlIGV4YWN0IG5hdHVyZSBvZiB0aG9zZSBjdXN0
b21pemF0aW9uIHBvaW50cywgcHJvdmlkaW5nIHRoYXQgdGhvc2UgcG9pbnRzIHdoaWNoIGFy
ZSBldmVudHVhbGx5IHVzZWQgcHJvdmlkZSBzYXRpc2ZhY3RvcnkgYmFja3dhcmRzIGNvbXBh
dGliaWxpdHkuPC9wPgo8cD5BdCBwcmVzZW50LCB0aGVzZSBjdXN0b21pemF0aW9uIHBvaW50
cyBhcmU6PC9wPgo8ZGwgY2xhc3M9ImRvY3V0aWxzIj4KPGR0Pjxjb2RlIGNsYXNzPSJjcHAg
YysrIj48c3BhbiBjbGFzcz0ibmFtZSI+Z2V0PC9zcGFuPjxzcGFuIGNsYXNzPSJvcGVyYXRv
ciI+Jmx0Ozwvc3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+Tjwvc3Bhbj48c3BhbiBjbGFzcz0i
b3BlcmF0b3IiPiZndDs8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4oPC9zcGFu
PjxzcGFuIGNsYXNzPSJuYW1lIj5UPC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+
KTwvc3Bhbj48L2NvZGU+OjwvZHQ+CjxkZD5BY2Nlc3MgdGhlIE4ndGggdmFsdWUgb2YgdGhl
IHR1cGxlLWxpa2UsIHdoZXJlIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0i
bGl0ZXJhbCBudW1iZXIgaW50ZWdlciI+MDwvc3Bhbj4gPHNwYW4gY2xhc3M9Im9wZXJhdG9y
Ij4mbHQ7PC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+Tjwvc3Bhbj4gPHNwYW4gY2xhc3M9
Im9wZXJhdG9yIj4mbHQ7PC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+dHVwbGVfc2l6ZTwv
c3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPig8L3NwYW4+PHNwYW4gY2xhc3M9Im5h
bWUiPlQ8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4pPC9zcGFuPjwvY29kZT4u
PC9kZD4KPGR0Pjxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0ibmFtZSI+Y29u
c3RleHByPC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+dHVwbGVfc2l6ZTwvc3Bhbj48c3Bh
biBjbGFzcz0icHVuY3R1YXRpb24iPig8L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUiPlQ8L3Nw
YW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4pPC9zcGFuPjwvY29kZT46PC9kdD4KPGRk
PlJldHVybnMgdGhlIHNpemUgb2YgKGkuZS4gbnVtYmVyIG9mIGVsZW1lbnRzIGluKSB0aGUg
dHVwbGUtbGlrZS48L2RkPgo8L2RsPgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0iYW4tb3Bl
cmF0b3ItbGlrZS1hbHRlcm5hdGl2ZSI+CjxoMj48YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhy
ZWY9IiNpZDEzIj5BbiBvcGVyYXRvci1saWtlIGFsdGVybmF0aXZlPC9hPjwvaDI+CjxwPlNv
bWUgY29uY2VybnMgd2VyZSBleHByZXNzZWQgdGhhdCBvdmVybG9hZGluZyBvbiA8Y29kZSBj
bGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9Im5hbWUiPmdldDwvc3Bhbj48c3BhbiBjbGFz
cz0ib3BlcmF0b3IiPiZsdDs8L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUiPk48L3NwYW4+PHNw
YW4gY2xhc3M9Im9wZXJhdG9yIj4mZ3Q7PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlv
biI+KDwvc3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+VDwvc3Bhbj48c3BhbiBjbGFzcz0icHVu
Y3R1YXRpb24iPik8L3NwYW4+PC9jb2RlPiBpcyBub3QgYXBwcm9wcmlhdGUgZHVlIHRvIGl0
cyB1c2UgZm9yIG90aGVyIG9wZXJhdGlvbnMgdGhhdCBhcmUgbm90IHJlbGF0ZWQgdG8gdHVw
bGUtbGlrZSBvYmplY3RzLiBPbmUgYWx0ZXJuYXRpdmUgbWlnaHQgYmUgdG8gaW1wbGVtZW50
IGEgbmV3IG9wZXJhdG9yIHR5cGU6PC9wPgo8cHJlIGNsYXNzPSJjb2RlIGMrKyBsaXRlcmFs
LWJsb2NrIj4KPHNwYW4gY2xhc3M9ImtleXdvcmQiPm9wZXJhdG9yPC9zcGFuPiA8c3BhbiBj
bGFzcz0ibmFtZSBmdW5jdGlvbiI+Z2V0PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlv
biI+KDwvc3Bhbj48c3BhbiBjbGFzcz0ia2V5d29yZCI+YXV0bzwvc3Bhbj48c3BhbiBjbGFz
cz0ib3BlcmF0b3IiPiZhbXA7PC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+dHVwbGU8L3Nw
YW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4sPC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFt
ZSI+Y29uc3RleHByPC9zcGFuPiA8c3BhbiBjbGFzcz0ia2V5d29yZCB0eXBlIj5zaXplX3Q8
L3NwYW4+IDxzcGFuIGNsYXNzPSJuYW1lIj5pPC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVh
dGlvbiI+KTs8L3NwYW4+CjxzcGFuIGNsYXNzPSJuYW1lIj5jb25zdGV4cHI8L3NwYW4+IDxz
cGFuIGNsYXNzPSJrZXl3b3JkIj5vcGVyYXRvcjwvc3Bhbj4gPHNwYW4gY2xhc3M9ImtleXdv
cmQiPnNpemVvZjwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPiZsdDs8L3NwYW4+PHNw
YW4gY2xhc3M9Im5hbWUiPlQ8L3NwYW4+PHNwYW4gY2xhc3M9Im9wZXJhdG9yIj4mZ3Q7PC9z
cGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+KCk7PC9zcGFuPgo8L3ByZT4KPHA+SXQg
bWF5IGJlIHJlYXNvbmFibGUgb3IgZXZlbiBkZXNpcmFibGUgdG8gcmVzdHJpY3QgYWNjZXNz
IG9mIHRoZXNlIG9wZXJhdG9ycyB0byBlaXRoZXIgZXhwbGljaXQgc3BlbGxpbmcgb3IgdXNl
IG9mIGRlZGljYXRlZCBzeW50YXg6PC9wPgo8cHJlIGNsYXNzPSJjb2RlIGMrKyBsaXRlcmFs
LWJsb2NrIj4KPHNwYW4gY2xhc3M9Im5hbWUiPk15VHVwbGVMaWtlPC9zcGFuPiA8c3BhbiBj
bGFzcz0ibmFtZSI+dDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPjs8L3NwYW4+
Cgo8c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPls8L3NwYW4+PHNwYW4gY2xhc3M9ImxpdGVy
YWwgbnVtYmVyIGludGVnZXIiPjA8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj5d
PC9zcGFuPjxzcGFuIGNsYXNzPSJuYW1lIj50PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVh
dGlvbiI+Ozwvc3Bhbj4gPHNwYW4gY2xhc3M9ImNvbW1lbnQgc2luZ2xlIj4vLyBvcGVyYXRv
ciBnZXQKPC9zcGFuPjxzcGFuIGNsYXNzPSJrZXl3b3JkIj5zaXplb2Y8L3NwYW4+PHNwYW4g
Y2xhc3M9InB1bmN0dWF0aW9uIj4uLi4oPC9zcGFuPjxzcGFuIGNsYXNzPSJuYW1lIj50PC9z
cGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+KTs8L3NwYW4+IDxzcGFuIGNsYXNzPSJj
b21tZW50IHNpbmdsZSI+Ly8gb3BlcmF0b3Igc2l6ZW9mCjwvc3Bhbj4KPHNwYW4gY2xhc3M9
ImtleXdvcmQiPmF1dG88L3NwYW4+IDxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+Wzwvc3Bh
bj48c3BhbiBjbGFzcz0ibmFtZSI+eDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24i
Piw8L3NwYW4+IDxzcGFuIGNsYXNzPSJuYW1lIj55PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5j
dHVhdGlvbiI+XTwvc3Bhbj4gPHNwYW4gY2xhc3M9Im9wZXJhdG9yIj49PC9zcGFuPiA8c3Bh
biBjbGFzcz0ibmFtZSI+dDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPjs8L3Nw
YW4+IDxzcGFuIGNsYXNzPSJjb21tZW50IHNpbmdsZSI+Ly8gYm90aCwgdmlhIG5hbWUtYmlu
ZGluZyB1bnBhY2tpbmcsIGNhc2UgMgo8L3NwYW4+CjwvcHJlPgo8cD5XZSBzaG91bGQgbm90
ZSB0aGF0LCB3aGlsZSB0aGVyZSBhcmUgc29tZSBzdHJvbmcgZmVlbGluZ3Mgb24gdGhlc2Ug
dG9waWNzLCB3ZSBkbyBub3QgZmVlbCB0aGF0IGFueSBwYXJ0aWN1bGFyIHJlc29sdXRpb24g
aXMgY3JpdGljYWwgZm9yIGFueSBvZiB0aGUgZGlyZWN0aW9ucyB3ZSBhcmUgZXhwbG9yaW5n
LiBJbiB0aGlzIGFyZWEsIHdlIGZlZWwgb25seSB0aGF0IGEgY29uc2lzdGVudCBhbmQgY2xl
YXIgZGlyZWN0aW9uIGlzIGltcG9ydGFudC48L3A+CjxwPihUeXBlcyBoYXZlIGJlZW4gZWxp
ZGVkIGluIHRoZSBhYm92ZSBleGFtcGxlcywgYXMgdGhleSBhcmUgbm90IGNydWNpYWwgdG8g
dGhlIGRpc2N1c3Npb24uKTwvcD4KPC9kaXY+CjwvZGl2Pgo8ZGl2IGNsYXNzPSJzZWN0aW9u
IiBpZD0iZ2VuZXJhbGl6ZWQtdW5wYWNraW5nIj4KPGgxPjxhIGNsYXNzPSJ0b2MtYmFja3Jl
ZiIgaHJlZj0iI2lkMTQiPkdlbmVyYWxpemVkIFVucGFja2luZzwvYT48L2gxPgo8cD5HZW5l
cmFsaXplZCB1bnBhY2tpbmcgaXMgdGhlIGNvbnZlcnNpb24gb2YgYSB0dXBsZS1saWtlIHRv
IGEgJnF1b3Q7dmFsdWUgc2VxdWVuY2UmcXVvdDssIGluIHRoZSBtYW5uZXIgb2YgUHl0aG9u
J3MgPHR0IGNsYXNzPSJkb2N1dGlscyBsaXRlcmFsIj4qPC90dD4gb3BlcmF0b3IsIHN1Y2gg
dGhhdCB0aGUgcmVzdWx0aW5nIHNlcXVlbmNlIG1heSBiZSB1c2VkIGluIGFueSBwbGFjZSB0
aGF0IGEgY29tbWEgc2VwYXJhdGVkIHNlcXVlbmNlIG1heSBiZSB1c2VkLiBXaGlsZSBmdW5j
dGlvbiBwYXJhbWV0ZXIgbGlzdHMgaXMgdGhlIGNhbm9uaWNhbCBleGFtcGxlLCB0aGlzIHdv
dWxkIGFsc28gaW5jbHVkZSBicmFjZWQgaW5pdGlhbGl6ZXIgbGlzdHMuIEZvbGxvd2luZyBk
aXNjdXNzaW9uIG9uIHRoZSA8dHQgY2xhc3M9ImRvY3V0aWxzIGxpdGVyYWwiPjxzcGFuIGNs
YXNzPSJwcmUiPnN0ZC1wcm9wb3NhbHM8L3NwYW4+PC90dD4gZm9ydW0sIHdlIGJlbGlldmUg
dGhhdCB0aGUgbW9zdCByZWFzb25hYmxlIGFuZCB1c2VmdWwgbWVjaGFuaXNtIG9mIGFjY29t
cGxpc2hpbmcgdGhpcyBpcyB0byBwcm92aWRlIGEgbWVjaGFuaXNtIHdoZXJlYnkgYSB0dXBs
ZS1saWtlIG1heSBiZSBjb252ZXJ0ZWQgaW50byBhIHBhcmFtZXRlciBwYWNrLiBNdWNoIGFz
IGluIHRoZSBuYW1lLWJpbmRpbmcgdW5wYWNraW5nIGNhc2UsIHRoZXJlIGlzIGEgbG9naWNh
bCBjb2RlIHRyYW5zZm9ybWF0aW9uIHRoYXQgY2FuIGJlIGFwcGxpZWQgZm9yIHRoaXMgcHVy
cG9zZSwgYnkgcGxhY2luZyB0aGUgdHVwbGUtbGlrZSBpbnRvIGEgdGVtcG9yYXJ5ICh3aGVy
ZSBuZWNlc3NhcnksIGkuZS4gaWYgdGhlIHR1cGxlLWxpa2UgaXMgYW4gZXhwcmVzc2lvbiBy
YXRoZXIgdGhhbiBhbHJlYWR5IGEgbmFtZWQgdmFyaWFibGUpIGFuZCB0YWtpbmcgdGhlIHBh
cmFtZXRlciBwYWNrIHRvIGJlIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0i
bmFtZSI+Z2V0PC9zcGFuPjxzcGFuIGNsYXNzPSJvcGVyYXRvciI+Jmx0Ozwvc3Bhbj48c3Bh
biBjbGFzcz0ibGl0ZXJhbCBudW1iZXIgaW50ZWdlciI+MDwvc3Bhbj48c3BhbiBjbGFzcz0i
b3BlcmF0b3IiPiZndDs8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4oPC9zcGFu
PjxzcGFuIGNsYXNzPSJrZXl3b3JkIHR5cGUiPl9fdDwvc3Bhbj48c3BhbiBjbGFzcz0icHVu
Y3R1YXRpb24iPiksPC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+Z2V0PC9zcGFuPjxzcGFu
IGNsYXNzPSJvcGVyYXRvciI+Jmx0Ozwvc3Bhbj48c3BhbiBjbGFzcz0ibGl0ZXJhbCBudW1i
ZXIgaW50ZWdlciI+MTwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPiZndDs8L3NwYW4+
PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4oPC9zcGFuPjxzcGFuIGNsYXNzPSJrZXl3b3Jk
IHR5cGUiPl9fdDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPiksPC9zcGFuPiA8
c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPi4uLjwvc3Bhbj48L2NvZGU+LiBUaGlzIGV4dGVu
ZHMgdGhlIHVzYWJsZSBzY29wZSB0byBhbnl3aGVyZSBhIGZvbGQgZXhwcmVzc2lvbiBtYXkg
YmUgdXNlZC48L3A+CjxwPldlIGFyZSBhd2FyZSBvZiBhdCBsZWFzdCB0aHJlZSBwb3NzaWJs
ZSBtZWNoYW5pc21zIGZvciBpbXBsZW1lbnRpbmcgZ2VuZXJhbGl6ZWQgdW5wYWNraW5nLiBP
bmUgb3B0aW9uIGlzIHRvIGVtcGxveSBhIG5ldyBzeW50YXggdG8gcGVyZm9ybSB0aGlzIG9w
ZXJhdGlvbiBkaXJlY3RseS4gQW5vdGhlciBpcyB0byBtYWtlIG11bHRpcGxlIHJldHVybiB2
YWx1ZXMsIHRyZWF0ZWQgYXMgcGFyYW1ldGVyIHBhY2tzLCBmaXJzdCBjbGFzcyBjaXRpemVu
cyBvZiB0aGUgbGFuZ3VhZ2UuIEEgdGhpcmQgaXMgdG8gY3JlYXRlIGEgcGFyYW1ldGVyIHBh
Y2sgJnF1b3Q7Z2VuZXJhdG9yJnF1b3Q7LiBUaGUgbGF0dGVyIHR3byBvcHRpb25zIG1ha2Ug
aXQgcG9zc2libGUgdG8gd3JpdGUgYSBmdW5jdGlvbiAod2hpY2ggbWlnaHQgcmVhc29uYWJs
eSBiZSBuYW1lZCA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9Im5hbWUiPnN0
ZDwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPjo6PC9zcGFuPjxzcGFuIGNsYXNzPSJu
YW1lIj51bnBhY2s8L3NwYW4+PC9jb2RlPikgdGhhdCBpcyBlcXVpdmFsZW50IHRvIHRoZSBm
b3JtZXIuPC9wPgo8cD5TZXZlcmFsIHBvc3NpYmxlIHN5bnRheGVzIGhhdmUgYmVlbiBwcm9w
b3NlZCwgaW5jbHVkaW5nIHBvc3RmaXggb3BlcmF0b3IgPHR0IGNsYXNzPSJkb2N1dGlscyBs
aXRlcmFsIj5+PC90dD4uIE91ciBwcmVmZXJlbmNlLCBob3dldmVyLCBpcyBwcmVmaXggb3Bl
cmF0b3IgPHR0IGNsYXNzPSJkb2N1dGlscyBsaXRlcmFsIj5bOl08L3R0PiAoZm9yIHJlYXNv
bnMgdGhhdCB3aWxsIGJlIOKAlCB2ZXJ5IGJyaWVmbHkg4oCUIHNob3duIGxhdGVyKSwgd2hp
Y2ggd2Ugd2lsbCB1c2UgaGVyZSwgYWx3YXlzIGJlYXJpbmcgaW4gbWluZCB0aGF0IHRoaXMg
aXMgc3RyaWN0bHkgZm9yIGRlbW9uc3RyYXRpdmUgcHVycG9zZXMuIEZvciBleGFtcGxlOjwv
cD4KPHByZSBjbGFzcz0iY29kZSBjKysgbGl0ZXJhbC1ibG9jayI+CjxzcGFuIGNsYXNzPSJr
ZXl3b3JkIj5zdHJ1Y3Q8L3NwYW4+IDxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+ezwvc3Bh
bj4gPHNwYW4gY2xhc3M9ImtleXdvcmQgdHlwZSI+ZG91YmxlPC9zcGFuPiA8c3BhbiBjbGFz
cz0ibmFtZSI+eDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPiw8L3NwYW4+IDxz
cGFuIGNsYXNzPSJuYW1lIj55PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+Ozwv
c3Bhbj4gPHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj59PC9zcGFuPiA8c3BhbiBjbGFzcz0i
bmFtZSI+cG9pbnQ8L3NwYW4+IDxzcGFuIGNsYXNzPSJvcGVyYXRvciI+PTwvc3Bhbj4gPHNw
YW4gY2xhc3M9InB1bmN0dWF0aW9uIj4uLi47PC9zcGFuPgo8c3BhbiBjbGFzcz0ia2V5d29y
ZCI+YXV0bzwvc3Bhbj4gPHNwYW4gY2xhc3M9Im5hbWUiPmg8L3NwYW4+IDxzcGFuIGNsYXNz
PSJvcGVyYXRvciI+PTwvc3Bhbj4gPHNwYW4gY2xhc3M9Im5hbWUiPnN0ZDwvc3Bhbj48c3Bh
biBjbGFzcz0ib3BlcmF0b3IiPjo6PC9zcGFuPjxzcGFuIGNsYXNzPSJuYW1lIj5oeXBvdDwv
c3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPihbPC9zcGFuPjxzcGFuIGNsYXNzPSJv
cGVyYXRvciI+Ojwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPl08L3NwYW4+PHNw
YW4gY2xhc3M9Im5hbWUiPnBvaW50PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+
Li4uKTs8L3NwYW4+CjwvcHJlPgo8cD5UaGUgYWRkaXRpb24gb2Ygc3VjaCBhIGZlYXR1cmUs
IHJlZ2FyZGxlc3Mgb2YgaXRzIGZvcm08YSBjbGFzcz0iZm9vdG5vdGUtcmVmZXJlbmNlIiBo
cmVmPSIjdWYiIGlkPSJpZDIiPlsyXTwvYT4sIHdvdWxkIG9idmlhdGUgbW9zdCAodGhvdWdo
IHBlcmhhcHMgbm90IGFsbCkgdXNlIGNhc2VzIGZvciA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+
PHNwYW4gY2xhc3M9Im5hbWUiPnN0ZDwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPjo6
PC9zcGFuPjxzcGFuIGNsYXNzPSJuYW1lIj5hcHBseTwvc3Bhbj48L2NvZGU+IGFuZCA8Y29k
ZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9Im5hbWUiPnNkPC9zcGFuPjxzcGFuIGNs
YXNzPSJvcGVyYXRvciI+Ojo8L3NwYW4+PHNwYW4gY2xhc3M9Im5hbWUiPm1ha2VfZnJvbV90
dXBsZTwvc3Bhbj48L2NvZGU+LiBJdCB3b3VsZCBhbHNvIHBlcm1pdCB0cml2aWFsIGNvbnZl
cnNpb25zIGJldHdlZW4gZGlmZmVyZW50ICZxdW90O3NpbXBsZSZxdW90OyB0eXBlcyB3aGlj
aCBhcmUgZGlzdGluY3QgYnV0IGxheW91dCBjb21wYXRpYmxlLCBieSB1bnBhY2tpbmcgdGhl
IGZpcnN0IHR5cGUgaW50byBhIGJyYWNlZCBpbml0aWFsaXplciBsaXN0IHVzZWQgdG8gY29u
c3RydWN0IHRoZSBzZWNvbmQuIFdlIGJlbGlldmUgdGhhdCB0aGlzIGZlYXR1cmUgd2lsbCBi
ZSBhdCBsZWFzdCBhcyBpbXBvcnRhbnQgYW5kIHVzZWZ1bCBhcyBuYW1lLWJpbmRpbmcgdW5w
YWNraW5nLjwvcD4KPC9kaXY+CjxkaXYgY2xhc3M9InNlY3Rpb24iIGlkPSJ1bmlmaWNhdGlv
bi1vZi11bnBhY2tpbmciPgo8aDE+PGEgY2xhc3M9InRvYy1iYWNrcmVmIiBocmVmPSIjaWQx
NSI+VW5pZmljYXRpb24gb2YgVW5wYWNraW5nPC9hPjwvaDE+CjxwPlBvc3NpYmx5IHRoZSBt
b3N0IGltcG9ydGFudCBhc3BlY3Qgb2YgPGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIg
aHJlZj0iaHR0cDovL3dnMjEubGluay9wMDE5NyI+UDAxOTc8L2E+IGluIG91ciBvcGluaW9u
IGlzIHRoZSBwcm92aXNpb24gZm9yIGEgc2luZ2xlLCB1bmlmaWVkIG1lY2hhbmlzbSBmb3Ig
dW5wYWNraW5nLCB3aGV0aGVyIGluIHRoZSBuYW1lLWJpbmRpbmcgb3IgZ2VuZXJhbGl6ZWQg
c2Vuc2VzLiBUaGUgY3JpdGljYWwgYXNwZWN0IG9mIDxhIGNsYXNzPSJyZWZlcmVuY2UgZXh0
ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAxOTciPlAwMTk3PC9hPiwgYW5kIHRo
ZSBvbmUgdGhhdCB3ZSBmZWVsIHN0cm9uZ2x5IG5lZWRzIHRvIGJlIGNvbnNpZGVyZWQgYnkg
PGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDovL3dnMjEubGluay9w
MDE0NCI+UDAxNDQ8L2E+LCBpcyBwcm92aWRpbmcgaW1wbGljaXQgZ2VuZXJhbCB0dXBsZS1s
aWtlIGFjY2VzcyB0byBzaW1wbGUgZGF0YSBzdHJ1Y3R1cmVzLiBJbiBwYXJ0aWN1bGFyLCB3
ZSBmZWVsIHRoYXQgaXQgd291bGQgYmUgYSB0cmF2ZXN0eSBmb3IgbmFtZS1iaW5kaW5nIHVu
cGFja2luZyBhbmQgZ2VuZXJhbGl6ZWQgdW5wYWNraW5nIHRvIHVzZSBkaWZmZXJlbnQgY3Vz
dG9taXphdGlvbiBwb2ludHMgb3IgdG8gb3RoZXJ3aXNlIGJlaGF2ZSBkaWZmZXJlbnRseSB3
aGVuIHVzZWQgaW4gd2F5cyB3aGVyZSBpbnR1aXRpb24gc3Ryb25nbHkgZXhwZWN0cyBlcXVp
dmFsZW50IGJlaGF2aW9yLiBJbiBwYXJ0aWN1bGFyLCB3ZSBmZWVsIHN0cm9uZ2x5IHRoYXQs
IGZvciBhIHR1cGxlLWxpa2UgdHlwZSBoYXZpbmcgYSBkZWZhdWx0IGRlc3RydWN0b3IsIHRo
ZSBmb2xsb3dpbmcgc2hvdWxkIGJlIGVxdWl2YWxlbnQgKGFmdGVyIG9wdGltaXphdGlvbnMp
OjwvcD4KPHByZSBjbGFzcz0iY29kZSBjKysgbGl0ZXJhbC1ibG9jayI+CjxzcGFuIGNsYXNz
PSJrZXl3b3JkIj5hdXRvPC9zcGFuPiA8c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPls8L3Nw
YW4+PHNwYW4gY2xhc3M9Im5hbWUiPng8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9u
Ij4sPC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+eTwvc3Bhbj48c3BhbiBjbGFzcz0icHVu
Y3R1YXRpb24iPl08L3NwYW4+IDxzcGFuIGNsYXNzPSJvcGVyYXRvciI+PTwvc3Bhbj4gPHNw
YW4gY2xhc3M9Im5hbWUiPnQ8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj47PC9z
cGFuPgo8c3BhbiBjbGFzcz0ia2V5d29yZCI+YXV0bzwvc3Bhbj4gPHNwYW4gY2xhc3M9InB1
bmN0dWF0aW9uIj5bPC9zcGFuPjxzcGFuIGNsYXNzPSJuYW1lIj54PC9zcGFuPjxzcGFuIGNs
YXNzPSJwdW5jdHVhdGlvbiI+LDwvc3Bhbj4gPHNwYW4gY2xhc3M9Im5hbWUiPnk8L3NwYW4+
PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj5dPC9zcGFuPiA8c3BhbiBjbGFzcz0ib3BlcmF0
b3IiPj08L3NwYW4+IDxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+e1s8L3NwYW4+PHNwYW4g
Y2xhc3M9Im9wZXJhdG9yIj46PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+XTwv
c3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+dDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRp
b24iPi4uLn07PC9zcGFuPgo8L3ByZT4KPHA+KFRoaXMgaWxsdXN0cmF0ZXMgYSBuZWVkIHRv
IGJlIGNhcmVmdWwgd2l0aCBsaWZldGltZSBzZW1hbnRpY3M7IGluIHBhcnRpY3VsYXIsIHVu
cGFja2luZyBzaG91bGQgbGlrZWx5IGVpdGhlciBleHRlbmQgbGlmZXRpbWUgd2hlbiB1c2Vk
IGluIGEgYnJhY2VkIGluaXRpYWxpemVyIGxpc3QsIG9yIHNob3VsZCBleHBsaWNpdGx5IGNy
ZWF0ZSB2YWx1ZSBjb3BpZXMgaW4gc3VjaCBjYXNlLiBUaGUgZm9ybWVyIHdvdWxkIG1ha2Ug
dGhlIGFib3ZlIGVxdWl2YWxlbnQgZm9yIDxlbT5hbnk8L2VtPiB0dXBsZS1saWtlLCB3aGls
ZSB0aGUgbGF0dGVyIG1heSBiZSB1c2VmdWwgZm9yIHNlcGFyYXRpbmcgbGlmZXRpbWUgb2Yg
dGhlIHR1cGxlLWxpa2UgYW5kIGl0cyBjb21wb25lbnRzLiBXZSBkbyBub3QgcmVjb21tZW5k
IGEgZGlyZWN0aW9uIGF0IHRoaXMgdGltZSwgYWx0aG91Z2ggdGhpcyBpcyBsaWtlbHkgdG8g
YmUgb2YgcmVsZXZhbmNlIHdoZW4gY29uc2lkZXJpbmcgYSBsYW5ndWFnZSBzb2x1dGlvbiB2
ZXJzdXMgYSAmcXVvdDtsaWJyYXJ5JnF1b3Q7IHNvbHV0aW9uLik8L3A+CjxwPkl0IHNob3Vs
ZCBiZSBub3RlZCB0aGF0IDxhIGNsYXNzPSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0
dHA6Ly93ZzIxLmxpbmsvcDAxOTciPlAwMTk3PC9hPiB3b3VsZCBwcm92aWRlIGEgbW9kZXN0
IGVuaGFuY2VtZW50IHRvIG5hbWUtYmluZGluZyB1bnBhY2tpbmcuIFdoZXJlIDxhIGNsYXNz
PSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAxNDQiPlAw
MTQ0PC9hPiBsaW1pdHMgaXRzZWxmIHRvICZxdW90O2ZsYXQmcXVvdDsgY2xhc3NlcywgPGEg
Y2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDovL3dnMjEubGluay9wMDE5
NyI+UDAxOTc8L2E+IHdvdWxkIGV4dGVuZCBpbXBsaWNpdCB0dXBsZS1saWtlIGFjY2VzcyB0
byBhbGwgY2xhc3NlcyB3aGljaDo8L3A+CjxibG9ja3F1b3RlPgo8dWwgY2xhc3M9InNpbXBs
ZSI+CjxsaT5Db250YWluIG5vIG5vbi1wdWJsaWMgTlNETSdzPC9saT4KPGxpPkNvbnRhaW4g
bm8gbWVtYmVycyBvZiB1bmlvbiB0eXBlPC9saT4KPGxpPkhhdmUgbm8gdmlydHVhbDxhIGNs
YXNzPSJmb290bm90ZS1yZWZlcmVuY2UiIGhyZWY9IiN2YiIgaWQ9ImlkMyI+WzNdPC9hPiBh
bmQvb3Igbm9uLXB1YmxpYzxhIGNsYXNzPSJmb290bm90ZS1yZWZlcmVuY2UiIGhyZWY9IiNl
YiIgaWQ9ImlkNCI+WzRdPC9hPiBiYXNlIGNsYXNzZXM8L2xpPgo8bGk+SGF2ZSBubyBiYXNl
IGNsYXNzZXMgd2hpY2ggZG8gbm90IGFsc28gbWVldCB0aGUgcHJlY2VkaW5nIGVsaWdpYmls
aXR5IGNyaXRlcmlhPC9saT4KPC91bD4KPC9ibG9ja3F1b3RlPgo8cD5XaGlsZSBpdCB3b3Vs
ZCBub3QgYmUgYSBjYXRhc3Ryb3BoaWMgbG9zcyBpZiBub24tJnF1b3Q7ZmxhdCZxdW90OyBj
bGFzc2VzIHdlcmUgbm90IHN1cHBvcnRlZCwgd2UgZG8gZmVlbCB0aGF0IGl0IHdvdWxkIGJl
IG1vc3QgdW5mb3J0dW5hdGUgaWYgd2UgYXJlIG5vdCBhYmxlIOKAlCBldmVudHVhbGx5IOKA
lCB0byByZWx5IG9uIHRoaXMgaW1wbGljaXQgYWNjZXNzIHRvIGltcGxlbWVudCBuYW1lLWJp
bmRpbmcgdW5wYWNraW5nLCBhbmQgYWNjb3JkaW5nbHkgdG8gZWxpbWluYXRlIDxhIGNsYXNz
PSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAxNDQiPlAw
MTQ0PC9hPiBjYXNlIDMuIEluIGFkZGl0aW9uIHRvIGNvbnNpc3RlbmN5LCB3ZSBmZWVsIHRo
YXQgdGhpcyBpcyBpbXBvcnRhbnQgZm9yIHRoZSBzYWtlIG9mIHNpbXBsaWNpdHksIGFzIGl0
IGVsaW1pbmF0ZXMgYSBzcGVjaWFsIGNhc2UgZnJvbSBuYW1lLWJpbmRpbmcgdW5wYWNraW5n
LiBXZSBhcmUgY29uZmlkZW50IHRoYXQgdGhlIHBlcmZvcm1hbmNlIGlzc3VlcyAodGhhdCBp
cywgdGhlIHVuZGVyc3RhbmRpbmcgdGhhdCBjYXNlIDMgcmVwcmVzZW50cyBuYW1lIGFsaWFz
aW5nIGFuZCBuZWl0aGVyIGNvbnN1bWVzIHN0b3JhZ2UgYmV5b25kIHRoYXQgcmVxdWlyZWQg
Zm9yIHRoZSB0dXBsZS1saWtlIGl0c2VsZiBub3IgYWRkcyBhbnkgYWNjZXNzIGluZGlyZWN0
aW9uKSBjYW4gYmUgc2F0aXNmYWN0b3JpbHkgYWRkcmVzc2VkIHRocm91Z2ggY29tcGlsZXIg
b3B0aW1pemF0aW9uLCBrZWVwaW5nIGluIG1pbmQgb2YgY291cnNlIHRoYXQgdGhlIGltcGxl
bWVudGF0aW9ucyBvZiB0aGUgJnF1b3Q7Z2V0JnF1b3Q7IGZ1bmN0aW9uIChob3dldmVyIHdl
IHVsdGltYXRlbHkgc3BlbGwgaXQpIGFyZSBpbmxpbmUgaW4gdGhlc2UgaW5zdGFuY2VzLjwv
cD4KPHA+VGhlIHByb2JsZW0gdGhhdCBhcmlzZXMgZnJvbSB0aGlzIGFwcHJvYWNoIGlzIGJp
dGZpZWxkIG1lbWJlcnMuIEF0IHRoZSAyMDE2IEphY2tzb252aWxsZSBtZWV0aW5nLCBhdCBs
ZWFzdCBvbmUgaW5kaXZpZHVhbCBleHByZXNzZWQgYSBzdHJvbmcgb3BpbmlvbiB0aGF0IHBy
b3ZpZGluZyByZWFkL3dyaXRlIGFjY2VzcyB0byBiaXRmaWVsZCBtZW1iZXJzIHZpYSBuYW1l
LWJpbmRpbmcgdW5wYWNraW5nIGlzIGEgJnF1b3Q7bXVzdCBoYXZlJnF1b3Q7IGZlYXR1cmUu
IFdlIGVuY291cmFnZSBnaXZpbmcgc2VyaW91cyBjb25zaWRlcmF0aW9uIHRvIHRoZSB0cnVl
IGltcG9ydGFuY2Ugb2YgdGhpcyBmZWF0dXJlLCBhbmQgdG8gd2F5cyB0aGF0IHRoaXMgY291
bGQgYmUgYWRkcmVzc2VkIGluIGEgd2F5IHRoYXQgZG9lcyBub3QgcmVxdWlyZSBzcGVjaWFs
IGNhc2luZy4gKEluIHBhcnRpY3VsYXIsIHdlIG5vdGUgdGhhdCB0aGUgZ2VuZXJhbCBhYmls
aXR5IHRvIGhhdmUgYSByZWZlcmVuY2UgdG8gYSBiaXRmaWVsZCDigJQgbGlrZWx5IHRocm91
Z2ggc29tZSBuZXcgbGlicmFyeSB0eXBlIOKAlCBzZWVtcyBhdCBsZWFzdCBhcyBpbnRlcmVz
dGluZyBhcyBiZWluZyBhYmxlIHRvIG5hbWUtYmluZCB0byBhIGNvbXBvbmVudCBvZiBzdWNo
IHR5cGUgb2YgYSB0dXBsZS1saWtlLik8L3A+CjwvZGl2Pgo8ZGl2IGNsYXNzPSJzZWN0aW9u
IiBpZD0ic2xpY2luZyI+CjxoMT48YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhyZWY9IiNpZDE2
Ij5TbGljaW5nPC9hPjwvaDE+CjxwPkluIG91ciBlYXJsaWVyIGRpc2N1c3Npb24gb24gPGEg
Y2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0iI2FjY2VzcyI+QWNjZXNzPC9hPiwg
d2UgbWVudGlvbmVkIHN5bnRheCBmb3IgYWNjZXNzaW5nIHNwZWNpZmljIGVsZW1lbnRzIG9m
IGEgdHVwbGUtbGlrZS4gV2hpbGUgdGhlIG5lZWQgdG8gYWNjZXNzIGluZGl2aWR1YWwgZWxl
bWVudHMgaXMgb2J2aW91cyBhbmQgY2xlYXJseSBkb2VzIG5vdCByZXF1aXJlIGEgc3ludGFj
dGljIHNvbHV0aW9uICh3ZSBhbHJlYWR5IGhhdmUgPGNvZGUgY2xhc3M9ImNwcCBjKysiPjxz
cGFuIGNsYXNzPSJuYW1lIj5zdGQ8L3NwYW4+PHNwYW4gY2xhc3M9Im9wZXJhdG9yIj46Ojwv
c3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+Z2V0PC9zcGFuPjxzcGFuIGNsYXNzPSJvcGVyYXRv
ciI+Jmx0Ozwvc3Bhbj48c3BhbiBjbGFzcz0ibmFtZSI+Tjwvc3Bhbj48c3BhbiBjbGFzcz0i
b3BlcmF0b3IiPiZndDs8L3NwYW4+PC9jb2RlPiksIGFub3RoZXIgZGVzaXJlIHRoYXQgY29t
ZXMgdXAgb2Z0ZW4gaXMgdGhlIGFiaWxpdHkgdG8gc2xpY2UgYSB0dXBsZS1saWtlOyBlLmcu
IHRvIHN0cmlwIHRoZSBmaXJzdCBlbGVtZW50IG9yIHRha2Ugb25seSB0aGUgZmlyc3QgTiBl
bGVtZW50cy48L3A+CjxwPldlIGNob3NlIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBj
bGFzcz0icHVuY3R1YXRpb24iPls8L3NwYW4+PHNwYW4gY2xhc3M9Im9wZXJhdG9yIj46PC9z
cGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+XTwvc3Bhbj48L2NvZGU+IGJlY2F1c2Ug
aXQgbmF0dXJhbGx5IGV4dGVuZHMgdG8gc2xpY2luZywgYnV0IHZhcmlvdXMgcG9zc2libGUg
c29sdXRpb25zIGhhdmUgYmVlbiBzdWdnZXN0ZWQsIGluY2x1ZGluZyBwYWNrIGdlbmVyYXRv
cnMgKHdoaWNoIHdvdWxkIG9mZmVyIHNpZ25pZmljYW50IGV4cHJlc3NpdmUgcG93ZXIpLiBN
b3JlIGltcG9ydGFudGx5LCBzaW5jZSB3ZSByZWNvbW1lbmQgdGhhdCBnZW5lcmFsaXplZCB1
bnBhY2tpbmcgY29udmVydCBhIHR1cGxlLWxpa2UgdG8gYSBwYXJhbWV0ZXIgcGFjaywgaXQg
bWFrZXMgc2Vuc2UgdGhhdCBhIHN5bnRheCBmb3Igc2xpY2luZyB0dXBsZS1saWtlcyBzaG91
bGQgYWxzbyB3b3JrIG9uIHBhcmFtZXRlciBwYWNrcyBkaXJlY3RseS4gSW4gYWRkaXRpb24g
dG8gdGhlIGFkdmFudGFnZXMgZm9yIHR1cGxlLWxpa2VzLCB0aGlzIGVuYWJsZXMgc2ltcGxl
IGFuZCBwb3dlcmZ1bCB0cmFuc2Zvcm1hdGlvbnMgZm9yIHZhcmlhZGljIHRlbXBsYXRlcywg
dGh1cyBzYXRpc2Z5aW5nIGFub3RoZXIgaW1wb3J0YW50IGNvbnRlbXBvcmFyeSB1c2UgY2Fz
ZS4gSW4gcGFydGljdWxhciwgd2UgY2FuIG5vdyB3cml0ZSByZWN1cnNpdmUgdmFyaWFkaWMg
dGVtcGxhdGUgZnVuY3Rpb25zIGxpa2U6PC9wPgo8cHJlIGNsYXNzPSJjb2RlIGMrKyBsaXRl
cmFsLWJsb2NrIj4KPHNwYW4gY2xhc3M9ImtleXdvcmQgdHlwZSI+dm9pZDwvc3Bhbj4gPHNw
YW4gY2xhc3M9Im5hbWUgZnVuY3Rpb24iPnByaW50X2VhY2g8L3NwYW4+PHNwYW4gY2xhc3M9
InB1bmN0dWF0aW9uIj4oKTwvc3Bhbj4gPHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj57fTwv
c3Bhbj4gPHNwYW4gY2xhc3M9ImNvbW1lbnQgc2luZ2xlIj4vLyBzZW50aW5lbAo8L3NwYW4+
CjxzcGFuIGNsYXNzPSJrZXl3b3JkIj50ZW1wbGF0ZTwvc3Bhbj4gPHNwYW4gY2xhc3M9Im9w
ZXJhdG9yIj4mbHQ7PC9zcGFuPjxzcGFuIGNsYXNzPSJrZXl3b3JkIj50eXBlbmFtZTwvc3Bh
bj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPi4uLjwvc3Bhbj4gPHNwYW4gY2xhc3M9Im5h
bWUiPlQ8L3NwYW4+PHNwYW4gY2xhc3M9Im9wZXJhdG9yIj4mZ3Q7PC9zcGFuPgo8c3BhbiBj
bGFzcz0ia2V5d29yZCB0eXBlIj52b2lkPC9zcGFuPiA8c3BhbiBjbGFzcz0ibmFtZSI+cHJp
bnRfZWFjaDwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPig8L3NwYW4+PHNwYW4g
Y2xhc3M9Im5hbWUiPlQ8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4uLi48L3Nw
YW4+IDxzcGFuIGNsYXNzPSJuYW1lIj52YWx1ZXM8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0
dWF0aW9uIj4pPC9zcGFuPgo8c3BhbiBjbGFzcz0icHVuY3R1YXRpb24iPns8L3NwYW4+CiAg
PHNwYW4gY2xhc3M9Im5hbWUiPnByaW50X29uZTwvc3Bhbj48c3BhbiBjbGFzcz0icHVuY3R1
YXRpb24iPihbPC9zcGFuPjxzcGFuIGNsYXNzPSJsaXRlcmFsIG51bWJlciBpbnRlZ2VyIj4w
PC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+XTwvc3Bhbj48c3BhbiBjbGFzcz0i
bmFtZSI+dmFsdWVzPC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+KTs8L3NwYW4+
CiAgPHNwYW4gY2xhc3M9Im5hbWUiPnByaW50X2VhY2g8L3NwYW4+PHNwYW4gY2xhc3M9InB1
bmN0dWF0aW9uIj4oWzwvc3Bhbj48c3BhbiBjbGFzcz0ibGl0ZXJhbCBudW1iZXIgaW50ZWdl
ciI+MTwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPjo8L3NwYW4+PHNwYW4gY2xhc3M9
InB1bmN0dWF0aW9uIj5dPC9zcGFuPjxzcGFuIGNsYXNzPSJuYW1lIj52YWx1ZXM8L3NwYW4+
PHNwYW4gY2xhc3M9InB1bmN0dWF0aW9uIj4pOzwvc3Bhbj4KPHNwYW4gY2xhc3M9InB1bmN0
dWF0aW9uIj59PC9zcGFuPgo8L3ByZT4KPHA+VGhpcyBpcyBhIGZhaXJseSB0cml2aWFsIGV4
YW1wbGUgdGhhdCBwcmV2aW91c2x5IGNvdWxkIGJlIHdyaXR0ZW4gYnkgYnJlYWtpbmcgdGhl
IGNvbXBsZXRlIHBhY2sgaW50byBhIHNlcGFyYXRlbHkgbmFtZWQgaGVhZCBhcmd1bWVudCBh
bmQgdGFpbCBwYWNrLiBUaGlzLCBob3dldmVyLCBtZXJlbHkgc2NyYXRjaGVzIHRoZSBzdXJm
YWNlLiBPbmUgY291bGQgaW1hZ2luZSBpbXBsZW1lbnRpbmcgYSA8Y29kZSBjbGFzcz0iY3Bw
IGMrKyI+PHNwYW4gY2xhc3M9Im5hbWUiPmNvbnN0ZXhwcjwvc3Bhbj48L2NvZGU+IGRpdmlk
ZS1hbmQtY29ucXVlciBzb3J0IGFsZ29yaXRobSB1c2luZyBzbGljaW5nIHRvIHRyaXZpYWxs
eSBzcGxpdCB0aGUgaW5jb21pbmcgcGFyYW1ldGVyIHBhY2sgaW4gaGFsZi4gTWFueSBvdGhl
ciBleGFtcGxlcyB3aGljaCBjYW4gYmUgcmVhZGlseSBpbXBsZW1lbnRlZCB3aXRoIHNsaWNp
bmcgYnV0IHdvdWxkIGJlIGRpZmZpY3VsdCBhbmQvb3IgZXhwZW5zaXZlIHRvIGltcGxlbWVu
dCBvdGhlcndpc2UgY2FuIGJlIGltYWdpbmVkLjwvcD4KPC9kaXY+CjxkaXYgY2xhc3M9InNl
Y3Rpb24iIGlkPSJwYWNrLWdlbmVyYXRpb24tcmV2aXNpdGVkIj4KPGgxPjxhIGNsYXNzPSJ0
b2MtYmFja3JlZiIgaHJlZj0iI2lkMTciPlBhY2sgR2VuZXJhdGlvbiwgUmV2aXNpdGVkPC9h
PjwvaDE+CjxwPlBhcmFtZXRlciBwYWNrIGdlbmVyYXRpb24gaXMsIGluIGdlbmVyYWwsIGFu
IGludGVyZXN0aW5nIGZlYXR1cmUuIFN1Z2dlc3RlZCBleGFtcGxlIHVzZXMgaW5jbHVkZSBn
ZW5lcmF0aW5nIGFuIGludGVnZXIgbGlzdDxhIGNsYXNzPSJmb290bm90ZS1yZWZlcmVuY2Ui
IGhyZWY9IiNpbCIgaWQ9ImlkNSI+WzVdPC9hPiwgYSB0eXBlIGxpc3QsIGFuZCBwZXJmb3Jt
aW5nIHZhcmlvdXMgbWFuaXB1bGF0aW9ucyBvbiBwYXJhbWV0ZXIgcGFja3MuIFdoaWxlIHN1
Y2ggbWFuaXB1bGF0aW9ucyBjb3VsZCBpbmNsdWRlIHNsaWNpbmcgYW5kIHJldmVyc2luZywg
d2Ugbm90ZSB0aGF0IHRoZXNlIG9wZXJhdGlvbnMgYXBwZWFyIHRvIHJlbHkgb24gYSBzeW50
YWN0aWMgbWVjaGFuaXNtIGZvciBleHRyYWN0aW5nIGEgc2luZ2xlIGVsZW1lbnQgZnJvbSBh
IHBhY2sgKHJlZmVyZW5jZSBpcyBtYWRlIHRvIDxhIGNsYXNzPSJyZWZlcmVuY2UgZXh0ZXJu
YWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvbjQyMzUiPk40MjM1PC9hPikuIFdlIGFsc28g
d29uZGVyIGlmIHNsaWNpbmcgb3BlcmF0aW9ucyBpbXBsZW1lbnRlZCBpbiB0aGlzIG1hbm5l
ciB3b3VsZCBwZXJmb3JtIHNhdGlzZmFjdG9yaWx5IGNvbXBhcmVkIHRvIHN5bnRhY3RpYyBz
bGljaW5nLjwvcD4KPHA+Q29uc2VxdWVudGx5LCB3ZSBzdGlsbCBuZWVkIGEgc3ludGF4IGZv
ciBpbmRleGVkIGFjY2VzcyBvZiBwYXJhbWV0ZXIgcGFjayBlbGVtZW50cy4gVGhpcyBpbiB0
dXJuIGFsbG93cyB1cyB0byBhcHBseSB0aGUgcHJldmlvdXMgYXJndW1lbnQgaW4gcmV2ZXJz
ZTsgbmFtZWx5LCB3aHkgbm90IHNlbGVjdCBhIHN5bnRheCB0aGF0IGlzIG5vbi1hbWJpZ3Vv
dXMsIGVhc2lseSBleHRlbmRlZCB0byBzbGljaW5nLCBhbmQgbWF5IGJlIGFwcGxpZWQgYWxz
byB0byB0dXBsZS1saWtlcz8gVGhpcyBpcyBhIHBvaW50IHRoYXQgd2UgZmVlbCBpcyB3b3J0
aCBzZXJpb3VzIGNvbnNpZGVyYXRpb24gYXMgd2UgY29uc2lkZXIgd2hhdCBkaXJlY3Rpb24g
Z2VuZXJhbGl6ZWQgdW5wYWNraW5nIHNob3VsZCB0YWtlLjwvcD4KPC9kaXY+CjxkaXYgY2xh
c3M9InNlY3Rpb24iIGlkPSJzdW1tYXJ5Ij4KPGgxPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIg
aHJlZj0iI2lkMTgiPlN1bW1hcnk8L2E+PC9oMT4KPHA+UHJldmlvdXMgZGlzY3Vzc2lvbnMg
4oCUIGJvdGggaW4gRVdHIGFuZCBvbiB0aGUgPHR0IGNsYXNzPSJkb2N1dGlscyBsaXRlcmFs
Ij48c3BhbiBjbGFzcz0icHJlIj5zdGQtcHJvcG9zYWxzPC9zcGFuPjwvdHQ+IGZvcnVtIOKA
lCBzdWdnZXN0IGEgc3Ryb25nIGRlc2lyZSBieSB0aGUgQysrIGNvbW11bml0eSB0byBtb3Zl
IHRoZSBsYW5ndWFnZSBpbiBhIGRpcmVjdGlvbiB0aGF0IGJsdXJzIHRoZSBsaW5lIGJldHdl
ZW4gY29udGFpbmVycyBhbmQgdGhlaXIgY29udGFpbmVkIHZhbHVlIHNlcXVlbmNlcywgbWFr
aW5nIGl0IGVhc3kgdG8gbW92ZSBmcm9tIG9uZSB0byB0aGUgb3RoZXIsIGFzIGlzIG9mdGVu
IGZvdW5kIGluIG90aGVyIGxhbmd1YWdlcyAoZS5nLiBQeXRob24pLiBBdCB0aGUgc2FtZSB0
aW1lLCB0aGVyZSBhcmUgYSBudW1iZXIgb2YgcHJvcG9zYWxzIGVpdGhlciBwdWJsaXNoZWQg
b3IgaW4gdGhlIHdvcmtzIHRvIHNpbXBsaWZ5IHdvcmtpbmcgd2l0aCBwYXJhbWV0ZXIgcGFj
a3MuIE1vcmVvdmVyLCBkdWUgdG8gdGhlIHNpZ25pZmljYW50IHV0aWxpdHkgb2YgdW5wYWNr
aW5nIGFuZCBvdGhlcndpc2Ugd29ya2luZyB3aXRoIHR1cGxlLWxpa2Ugb2JqZWN0cyBhcyBw
YXJhbWV0ZXIgcGFja3MsIHRoZXNlIGFyZWFzIGFyZSBjbG9zZWx5IHJlbGF0ZWQgYW5kIHRv
IHNvbWUgZXh0ZW50IG92ZXJsYXAuPC9wPgo8cD5XZSBoYXZlIG9ic2VydmVkIHJlY2VudGx5
IHRoYXQgJnF1b3Q7Y29tcGxleGl0eSZxdW90OyBpcyBhIGZyZXF1ZW50IGNvbXBsYWludCBt
YWRlIGFnYWluc3QgQysrLCBlc3BlY2lhbGx5IHRoYXQgaXQgaXMgJnF1b3Q7aGFyZCB0byB0
ZWFjaCZxdW90Oy4gQXMgd2UgY29uc2lkZXIgZmVhdHVyZXMgdG8gc2ltcGxpZnkgd29ya2lu
ZyB3aXRoIHR1cGxlLWxpa2Ugb2JqZWN0cyBhbmQvb3IgcGFyYW1ldGVyIHBhY2tzLCB3ZSBm
ZWVsIGl0IGlzIG9mIHV0bW9zdCBpbXBvcnRhbmNlIHRvIGVzdGFibGlzaCBhbmQgYWRoZXJl
IHRvIGEgY29uc2lzdGVudCB2aXNpb24gb2YgdGhlc2UgZnVuY3Rpb25zLCBpbiB0ZXJtcyBv
ZiBib3RoIHN5bnRheCBhbmQgZnVuY3Rpb24uIFdlIHNwZWNpZmljYWxseSB1cmdlIHRoYXQg
bmFtZS1iaW5kaW5nIHVucGFja2luZyB3b3VsZCBjYXJlZnVsbHkgY29uc2lkZXIgY3VzdG9t
aXphdGlvbiBwb2ludHM8YSBjbGFzcz0iZm9vdG5vdGUtcmVmZXJlbmNlIiBocmVmPSIjY3Ai
IGlkPSJpZDYiPls2XTwvYT4gYW5kIHRoZSBmdXR1cmUgcG9zc2liaWxpdHkgb2YgaW1wbGlj
aXQgdHVwbGUtbGlrZSBhY2Nlc3MgKHNlZSBlc3BlY2lhbGx5IDxhIGNsYXNzPSJyZWZlcmVu
Y2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAxOTciPlAwMTk3PC9hPikg
YW5kIGdlbmVyYWxpemVkIHVucGFja2luZyBpbiBvcmRlciB0byB3b3JrIHRvd2FyZDxhIGNs
YXNzPSJmb290bm90ZS1yZWZlcmVuY2UiIGhyZWY9IiNmZCIgaWQ9ImlkNyI+WzddPC9hPiBh
IGNvbW1vbiBtZWNoYW5pc20gZm9yIGJvdGggdGhhdCB3b3VsZCBlbGltaW5hdGUgc3BlY2lh
bCBjYXNlIHJ1bGVzIHNwZWNpZmljIHRvIHRoZSBpbmRpdmlkdWFsIGZlYXR1cmVzLiBXZSBh
bHNvIHVyZ2UgdGhlIGNvbW1pdHRlZSB0byBjb25zaWRlciB0aGVzZSBpc3N1ZXMgYW5kIGhv
dyBzdWNoIGZlYXR1cmVzIHJlbGF0ZSAob3IgY2FuIGJlIG1hZGUgdG8gcmVsYXRlKSB0byB0
dXBsZS1saWtlIG9iamVjdHMgaW4gb3JkZXIgdG8gbWF4aW1pemUgY29uc2lzdGVuY3kgb2Yg
b3BlcmF0aW9ucyBvbiBib3RoIG9iamVjdCB0eXBlcywgYW5kIHdlIHVyZ2UgYXV0aG9ycyB3
b3JraW5nIG9uIHN1Y2ggcHJvcG9zYWxzIHRvIGRvIGxpa2V3aXNlLiBGaW5hbGx5LCB3ZSBz
dHJvbmdseSBlbmNvdXJhZ2UgYW55IGF1dGhvcnMgd29ya2luZyBpbiB0aGlzIHJlYWxtIHRv
IG1haW50YWluIGNvbW11bmljYXRpb24gaW4gb3JkZXIgdG8gcmVkdWNlIHRoZSBkYW5nZXJz
IG9mIGNvbXBldGluZywgaW5jb21wYXRpYmxlIHByb3Bvc2FscyBhbmQgdG8gbWF4aW1pemUg
b3VyIGFiaWxpdHkgYXMgYSBjb21tdW5pdHkgdG8gcHVyc3VlIGEgd2VsbCBjb25zaWRlcmVk
LCBjb25zaXN0ZW50LCBhbmQgbWF4aW1hbGx5IGZ1bmN0aW9uYWwgZGlyZWN0aW9uLjwvcD4K
PHA+Qnkgb2ZmZXJpbmcgYSBnbGltcHNlIGF0IHdoZXJlIHdlIG1pZ2h0IGJlIGdvaW5nLCB3
ZSBob3BlIHdlIGhhdmUgZGVtb25zdHJhdGVkIHRoZSBpbXBvcnRhbmNlIG9mIGtlZXBpbmcg
dGhlIGZ1dHVyZSBpbiBtaW5kIHdoaWxlIGRldmVsb3BpbmcgbmV3IGFuZCBleGNpdGluZyBm
ZWF0dXJlcyB0b2RheS4gV2UgZXNwZWNpYWxseSBob3BlIHdlIGhhdmUgZGVtb25zdHJhdGVk
IHRoZSBpbXBvcnRhbmNlIG9mIGNvbnNpZGVyaW5nIHRoZSBkaXJlY3Rpb24gcHJvcG9zZWQg
YnkgPGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDovL3dnMjEubGlu
ay9wMDE5NyI+UDAxOTc8L2E+IChpbXBsaWNpdCB0dXBsZS1saWtlIGFjY2VzcyBmb3IgJnF1
b3Q7c2ltcGxlJnF1b3Q7IHR5cGVzKSBpbiBsaWdodCBvZiA8YSBjbGFzcz0icmVmZXJlbmNl
IGV4dGVybmFsIiBocmVmPSJodHRwOi8vd2cyMS5saW5rL3AwMTQ0Ij5QMDE0NDwvYT4gKG5h
bWUtYmluZGluZyB1bnBhY2tpbmcpIGluIG9yZGVyIHRvIG1haW50YWluIGNvbnNpc3RlbmN5
IGFuZCBzaW1wbGljaXR5IG9mIHNwZWNpZmljYXRpb24gaW4gb3JkZXIgdG8gbWF4aW1pemUg
dGhlIGFiaWxpdHkgb2YgdXNlcnMgdG8gdW5kZXJzdGFuZCB0aGUgb3BlcmF0aW9uIG9mIHRo
ZXNlIGZlYXR1cmVzIGFuZCB0byB1c2UgdGhlbSBpbiBhIHNlbnNpYmxlIG1hbm5lci48L3A+
CjwvZGl2Pgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0iYWNrbm93bGVkZ21lbnRzIj4KPGgx
PjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkMTkiPkFja25vd2xlZGdtZW50czwv
YT48L2gxPgo8cD5XZSB3b3VsZCBsaWtlIHRvIHRoYW5rIHRoZSBhdXRob3JzIG9mIDxhIGNs
YXNzPSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAxNDQi
PlAwMTQ0PC9hPiwgZm9yIG9idmlvdXMgcmVhc29ucy4gV2Ugd291bGQgbGlrZSB0byB0aGFu
ayBNaWtlIFNwZXJ0dXMgYW5kIERhdmVlZCBWYW5kZXZvb3JkZSBmb3Igc2hhcmluZyBhICZx
dW90O3ByZXZpZXcmcXVvdDsgb2YgdGhlaXIgcmVzcGVjdGl2ZSB3b3Jrcy1pbi1wcm9ncmVz
cyBpbiB0aGUgYXJlYSBvZiBwYXJhbWV0ZXIgcGFja3MuIFdlIHdvdWxkIGxpa2UgdG8gdGhh
bmtzIERhbmllbCBGcmV5IGZvciBoaXMgb3duIHdvcmsgb24gcGFyYW1ldGVyIHBhY2tzLCB3
aGljaCBhbHNvIGZvcmNlZCB1cyB0byBjb25zaWRlciB0aGUgZGVmZW5zZSBvdXIgb3duIHBy
ZWZlcmVuY2VzIG1vcmUgc3RyZW51b3VzbHkgdGhhbiBoYWQgYmVlbiBkb25lIGJlZm9yZS4g
QXMgYWx3YXlzLCB3ZSB3b3VsZCBhbHNvIGxpa2UgdG8gdGhhbmsgZXZlcnlvbmUgdGhhdCBo
YXMgc2hhcmVkIHRoZWlyIHRob3VnaHRzIGFuZCBpZGVhcyBvbiB0aGVzZSBpc3N1ZXMsIGJv
dGggaW4gcGVyc29uIGF0IHRoZSAyMDE2IEphY2tzb252aWxsZSBtZWV0aW5nIGFuZCBvbiA8
dHQgY2xhc3M9ImRvY3V0aWxzIGxpdGVyYWwiPjxzcGFuIGNsYXNzPSJwcmUiPnN0ZC1wcm9w
b3NhbHM8L3NwYW4+PC90dD4uPC9wPgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9
ImZvb3Rub3RlcyI+CjxoMT48YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhyZWY9IiNpZDIwIj5G
b290bm90ZXM8L2E+PC9oMT4KPHRhYmxlIGNsYXNzPSJkb2N1dGlscyBmb290bm90ZSIgZnJh
bWU9InZvaWQiIGlkPSJwdCIgcnVsZXM9Im5vbmUiPgo8Y29sZ3JvdXA+PGNvbCBjbGFzcz0i
bGFiZWwiIC8+PGNvbCAvPjwvY29sZ3JvdXA+Cjx0Ym9keSB2YWxpZ249InRvcCI+Cjx0cj48
dGQgY2xhc3M9ImxhYmVsIj48YSBjbGFzcz0iZm4tYmFja3JlZiIgaHJlZj0iI2lkMSI+WzFd
PC9hPjwvdGQ+PHRkPjxhIGNsYXNzPSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6
Ly9kb2MucXQuaW8vcXQtNS42L3F2ZWN0b3IzZC5odG1sIj5RVmVjdG9yM0Q8L2E+IGNvbWVz
IHRvIG1pbmQgYXMgYW4gZXhhbXBsZSBvZiBhIHVzZXIgdHlwZSB3aGljaCBpcyDigJQgb3Ig
YXQgbGVhc3QsIG91Z2h0IHRvIGJlIOKAlCB0dXBsZS1saWtlIGJ1dCBoYXMgbm8gcHVibGlj
IGRhdGEgbWVtYmVycy48L3RkPjwvdHI+CjwvdGJvZHk+CjwvdGFibGU+Cjx0YWJsZSBjbGFz
cz0iZG9jdXRpbHMgZm9vdG5vdGUiIGZyYW1lPSJ2b2lkIiBpZD0idWYiIHJ1bGVzPSJub25l
Ij4KPGNvbGdyb3VwPjxjb2wgY2xhc3M9ImxhYmVsIiAvPjxjb2wgLz48L2NvbGdyb3VwPgo8
dGJvZHkgdmFsaWduPSJ0b3AiPgo8dHI+PHRkIGNsYXNzPSJsYWJlbCI+PGEgY2xhc3M9ImZu
LWJhY2tyZWYiIGhyZWY9IiNpZDIiPlsyXTwvYT48L3RkPjx0ZD5UaGUgZm9ybSB0aGF0IHVu
cGFja2luZyB0YWtlcyBpcyBub3QgZW50aXJlbHkgdW5pbnRlcmVzdGluZywgaG93ZXZlciBz
dWNoIGRpc2N1c3Npb24gaXMgbm90IGluIHNjb3BlIGZvciB0aGlzIHBhcGVyLjwvdGQ+PC90
cj4KPC90Ym9keT4KPC90YWJsZT4KPHRhYmxlIGNsYXNzPSJkb2N1dGlscyBmb290bm90ZSIg
ZnJhbWU9InZvaWQiIGlkPSJ2YiIgcnVsZXM9Im5vbmUiPgo8Y29sZ3JvdXA+PGNvbCBjbGFz
cz0ibGFiZWwiIC8+PGNvbCAvPjwvY29sZ3JvdXA+Cjx0Ym9keSB2YWxpZ249InRvcCI+Cjx0
cj48dGQgY2xhc3M9ImxhYmVsIj48YSBjbGFzcz0iZm4tYmFja3JlZiIgaHJlZj0iI2lkMyI+
WzNdPC9hPjwvdGQ+PHRkPldoaWxlIHByZXNlbnQgaW4gdGhlIGluaXRpYWwgcmV2aXNpb24g
b2YgPGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDovL3dnMjEubGlu
ay9wMDE5NyI+UDAxOTc8L2E+LCB0aGlzIHJlc3RyaWN0aW9uIGlzIG5vdCBzZWVuIGluIDxh
IGNsYXNzPSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAx
NDQiPlAwMTQ0PC9hPiwgYW5kIHVwb24gZnVydGhlciBjb25zaWRlcmF0aW9uLCBtYXkgYmUg
dW5uZWNlc3NhcnkuPC90ZD48L3RyPgo8L3Rib2R5Pgo8L3RhYmxlPgo8dGFibGUgY2xhc3M9
ImRvY3V0aWxzIGZvb3Rub3RlIiBmcmFtZT0idm9pZCIgaWQ9ImViIiBydWxlcz0ibm9uZSI+
Cjxjb2xncm91cD48Y29sIGNsYXNzPSJsYWJlbCIgLz48Y29sIC8+PC9jb2xncm91cD4KPHRi
b2R5IHZhbGlnbj0idG9wIj4KPHRyPjx0ZCBjbGFzcz0ibGFiZWwiPjxhIGNsYXNzPSJmbi1i
YWNrcmVmIiBocmVmPSIjaWQ0Ij5bNF08L2E+PC90ZD48dGQ+VGhpcyBjb3VsZCBwcm9iYWJs
eSBiZSByZWxheGVkIHRvIG5vbi1wdWJsaWMgPGVtPmFuZCBub24tZW1wdHk8L2VtPiBiYXNl
IGNsYXNzZXMsIGlmIGRlc2lyZWQuPC90ZD48L3RyPgo8L3Rib2R5Pgo8L3RhYmxlPgo8dGFi
bGUgY2xhc3M9ImRvY3V0aWxzIGZvb3Rub3RlIiBmcmFtZT0idm9pZCIgaWQ9ImlsIiBydWxl
cz0ibm9uZSI+Cjxjb2xncm91cD48Y29sIGNsYXNzPSJsYWJlbCIgLz48Y29sIC8+PC9jb2xn
cm91cD4KPHRib2R5IHZhbGlnbj0idG9wIj4KPHRyPjx0ZCBjbGFzcz0ibGFiZWwiPjxhIGNs
YXNzPSJmbi1iYWNrcmVmIiBocmVmPSIjaWQ1Ij5bNV08L2E+PC90ZD48dGQ+VGhlIHB1cmVs
eSB0ZW1wbGF0ZSBpbXBsZW1lbnRhdGlvbiBvZiA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNw
YW4gY2xhc3M9Im5hbWUiPnN0ZDwvc3Bhbj48c3BhbiBjbGFzcz0ib3BlcmF0b3IiPjo6PC9z
cGFuPjxzcGFuIGNsYXNzPSJuYW1lIj5pbnRlZ2VyX3NlcXVlbmNlPC9zcGFuPjwvY29kZT4g
aXMgZXh0cmVtZWx5IGV4cGVuc2l2ZSwgdG8gdGhlIHBvaW50IHRoYXQgbWFueSBjb21waWxl
cnMgYXJlIHByb3ZpZGluZyBpbXBsZW1lbnRhdGlvbnMgYmFzZWQgb24gY29tcGlsZXIgaW50
cmluc2ljcy4gUGFyYW1ldGVyIHBhY2sgZ2VuZXJhdG9ycyBoYXZlIHRoZSBwb3RlbnRpYWwg
dG8gcHJvdmlkZSBhIHNhdGlzZmFjdG9yeSBpbXBsZW1lbnRhdGlvbiB3aXRob3V0IHN1Y2gg
aW50cmluc2ljcy48L3RkPjwvdHI+CjwvdGJvZHk+CjwvdGFibGU+Cjx0YWJsZSBjbGFzcz0i
ZG9jdXRpbHMgZm9vdG5vdGUiIGZyYW1lPSJ2b2lkIiBpZD0iY3AiIHJ1bGVzPSJub25lIj4K
PGNvbGdyb3VwPjxjb2wgY2xhc3M9ImxhYmVsIiAvPjxjb2wgLz48L2NvbGdyb3VwPgo8dGJv
ZHkgdmFsaWduPSJ0b3AiPgo8dHI+PHRkIGNsYXNzPSJsYWJlbCI+PGEgY2xhc3M9ImZuLWJh
Y2tyZWYiIGhyZWY9IiNpZDYiPls2XTwvYT48L3RkPjx0ZD5JdCBpcyBvdXIgdW5kZXJzdGFu
ZGluZyB0aGF0IHRoZSBjb21taXR0ZWUgYW5kIHRoZSBhdXRob3JzIG9mIDxhIGNsYXNzPSJy
ZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvcDAxNDQiPlAwMTQ0
PC9hPiBhcmUgd2VsbCBhd2FyZSBvZiB0aGUgc3Ryb25nIGZlZWxpbmdzIHN1cnJvdW5kaW5n
IGN1c3RvbWl6YXRpb24gcG9pbnRzIGFuZCA8ZW0+YXJlPC9lbT4gZ2l2aW5nIHRoZW0gc2Vy
aW91cyBjb25zaWRlcmF0aW9uLiBXZSB3aXNoIHRvIHRha2UgdGhpcyBvcHBvcnR1bml0eSB0
byB0aGFuayBhbmQgY29tbWVuZCB0aGVtIGZvciB0aGVzZSBlZmZvcnRzLjwvdGQ+PC90cj4K
PC90Ym9keT4KPC90YWJsZT4KPHRhYmxlIGNsYXNzPSJkb2N1dGlscyBmb290bm90ZSIgZnJh
bWU9InZvaWQiIGlkPSJmZCIgcnVsZXM9Im5vbmUiPgo8Y29sZ3JvdXA+PGNvbCBjbGFzcz0i
bGFiZWwiIC8+PGNvbCAvPjwvY29sZ3JvdXA+Cjx0Ym9keSB2YWxpZ249InRvcCI+Cjx0cj48
dGQgY2xhc3M9ImxhYmVsIj48YSBjbGFzcz0iZm4tYmFja3JlZiIgaHJlZj0iI2lkNyI+Wzdd
PC9hPjwvdGQ+PHRkPldlIHdvdWxkIGxpa2UgdG8gcmVpdGVyYXRlIHRoYXQgd2UgaGF2ZSBu
byBvYmplY3Rpb24gdG8gc3BlY2lhbCBjYXNlIGhhbmRsaW5nIG9mICZxdW90O2ltcGxpY2l0
bHkgdHVwbGUtbGlrZSZxdW90OyB0eXBlcyBpbiB0aGUgc2hvcnQgdGVybSwgZXNwZWNpYWxs
eSBpZiBpdCBtZWFucyBuYW1lLWJpbmRpbmcgdW5wYWNraW5nIGlzIGF2YWlsYWJsZSBpbiBD
KysxNywgPGVtPnByb3ZpZGVkPC9lbT4gdGhlcmUgaXMgYSBsb25nIHRlcm0gbWlncmF0aW9u
IHJvdXRlIHRoYXQgd291bGQgYWxsb3cgdGhpcyBzcGVjaWFsIGNhc2UgdG8gYmUgcmVwbGFj
ZWQgd2l0aCBtb3JlIGdlbmVyYWxpemVkIGZ1bmN0aW9uYWxpdHkuPC90ZD48L3RyPgo8L3Ri
b2R5Pgo8L3RhYmxlPgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9InJlZmVyZW5j
ZXMiPgo8aDE+PGEgY2xhc3M9InRvYy1iYWNrcmVmIiBocmVmPSIjaWQyMSI+UmVmZXJlbmNl
czwvYT48L2gxPgo8dWw+CjxsaT48cCBjbGFzcz0iZmlyc3QiPjxhIGNsYXNzPSJyZWZlcmVu
Y2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvbjQyMzUiPk40MjM1PC9hPiBT
ZWxlY3RpbmcgZnJvbSBQYXJhbWV0ZXIgUGFja3M8L3A+CjxwPjxhIGNsYXNzPSJyZWZlcmVu
Y2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxpbmsvbjQyMzUiPmh0dHA6Ly93ZzIx
LmxpbmsvbjQyMzU8L2E+PC9wPgo8L2xpPgo8L3VsPgo8dWw+CjxsaT48cCBjbGFzcz0iZmly
c3QiPjxhIGNsYXNzPSJyZWZlcmVuY2UgZXh0ZXJuYWwiIGhyZWY9Imh0dHA6Ly93ZzIxLmxp
bmsvcDAxNDQiPlAwMTQ0PC9hPiBTdHJ1Y3R1cmVkIEJpbmRpbmdzPC9wPgo8cD48YSBjbGFz
cz0icmVmZXJlbmNlIGV4dGVybmFsIiBocmVmPSJodHRwOi8vd2cyMS5saW5rL3AwMTQ0Ij5o
dHRwOi8vd2cyMS5saW5rL3AwMTQ0PC9hPjwvcD4KPC9saT4KPC91bD4KPHVsPgo8bGk+PHAg
Y2xhc3M9ImZpcnN0Ij48YSBjbGFzcz0icmVmZXJlbmNlIGV4dGVybmFsIiBocmVmPSJodHRw
Oi8vd2cyMS5saW5rL3AwMTk3Ij5QMDE5NzwvYT4gRGVmYXVsdCBUdXBsZS1saWtlIEFjY2Vz
czwvcD4KPHA+PGEgY2xhc3M9InJlZmVyZW5jZSBleHRlcm5hbCIgaHJlZj0iaHR0cDovL3dn
MjEubGluay9wMDE5NyI+aHR0cDovL3dnMjEubGluay9wMDE5NzwvYT48L3A+CjwvbGk+Cjwv
dWw+CjwhLS0gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4g
Li4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLS0+CjwhLS0ga2F0ZTogaGwgcmVTdHJ1
Y3R1cmVkVGV4dCAtLT4KPC9kaXY+CjwvZGl2Pgo8L2JvZHk+CjwvaHRtbD4K
--------------060305020907090604080801
Content-Type: text/prs.fallenstein.rst;
name="dxxxx-tuple-like-unified-vision.rst"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="dxxxx-tuple-like-unified-vision.rst"
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D
A Unified Vision for Manipulating Tuple-like Objects
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D
:Document: DXXXXR0 (TBD)
:Date: 2016-03-18
:Project: ISO/IEC JTC1 SC22 WG21 Programming Language C++
:Audience: Evolution Working Group
:Author: Matthew Woehlke (mwoehlke.floss@gmail.com)
=2E. raw:: html
<style>
html { color: black; background: white; }
table.docinfo { margin: 2em 0; }
</style>
=2E. role:: cpp(code)
:language: c++
Abstract
=3D=3D=3D=3D=3D=3D=3D=3D
There is much activity and discussion surrounding tuple-like objects, wit=
h many features being requested and many papers submitted or planned. It =
is important that we establish a plan for where we are going that takes i=
nto account future directions in order to avoid overcomplicating the lang=
uage or painting ourselves into a corner of incompatible features.
=2E. contents::
Background
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
At the 2016 Jacksonville meeting, P0144_ was discussed for the second tim=
e. Reception was generally positive, but some issues remained to be addre=
ssed. It seems quite clear that this is a desired direction for C++. Unfo=
rtunately, P0197_, which was scheduled for presentation and has some impa=
ct on the direction which P0144_ is following, was skipped due to time co=
nstraints.
Discussion on the ``std-proposals`` forum often brings up the desire to e=
xtend use of "tuple-like" objects to contexts other than name binding (i.=
e. P0144_). There is also significant and related discussion on improving=
the usability of parameter packs. We feel that several of these areas ar=
e closely related and warrant the formation of a concrete and unified vis=
ion for future direction.
Preface
=3D=3D=3D=3D=3D=3D=3D
We present several suggestions in this paper, along with accompanying syn=
tax. We must stress *emphatically* that this paper is not intended to pro=
pose any features in and of itself (that will come later). Rather, we wis=
h to outline several areas of anticipated future development which we fee=
l need to be explored and, in particular, considered by other proposals b=
eing put forward, especially P0144_. While some brief statements are made=
as to our choices, we urge the reader to keep in mind that syntax shown =
is used in this context only as a tool to communicate examples of the fut=
ure feature space, and not to get hung up on minor quibbles. In particula=
r, our most immediate concern is for unification of implementation detail=
s related to unpacking and customization points of the same. While we fee=
l also that similar considerations are important with respect to paramete=
r packs, that feature space is less mature, and accordingly the need for =
a consolidated direction is less urgent, if no less real.
Definitions
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
A "tuple like" is any object consisting of one or (usually) more orthogon=
al values (in mathematical notation, a "product type"). The canonical exa=
mple is :cpp:`std::tuple`, but other examples include :cpp:`std::array` o=
r similar fixed-size vector types and most aggregates, as well as some no=
n-aggregate user types including ones with no public NSDM's\ [#pt]_.
"Unpacking" refers to the conversion of a tuple-like object into its comp=
onent parts. This includes both name-binding unpacking (i.e. P0144_) and =
"generalized unpacking" where the components are used in a non-binding co=
ntext; for example, as values in a function parameter list. Name-binding =
unpacking is also called "structured binding" and, historically, "assignm=
ent unpacking". We prefer the term "name-binding unpacking" as it does no=
t call into question issues of "true assignment" versus aliasing where P0=
144_ specifically desires to avoid certain overheads, and the use of "unp=
acking" serves to connect two closely related concepts.
Access
=3D=3D=3D=3D=3D=3D
One of the active questions around P0144_ regards the customization point=
=2E We feel strongly that the customization point for name-binding unpack=
ing should be the same as used by generalized unpacking and by existing a=
nd proposed utility functions (e.g. :cpp:`std::apply` and :cpp:`std::make=
_from_tuple`) that act on tuple-like objects. This is important for the s=
ake of consistency; these operations are extremely similar, and using dif=
ferent customization points will likely result in confusion and teaching =
difficulty.
That said, we feel less strongly about the exact nature of those customiz=
ation points, providing that those points which are eventually used provi=
de satisfactory backwards compatibility.
At present, these customization points are:
:cpp:`get<N>(T)`:
Access the N'th value of the tuple-like, where :cpp:`0 < N < tuple_si=
ze(T)`.
:cpp:`constexpr tuple_size(T)`:
Returns the size of (i.e. number of elements in) the tuple-like.
An operator-like alternative
----------------------------
Some concerns were expressed that overloading on :cpp:`get<N>(T)` is not =
appropriate due to its use for other operations that are not related to t=
uple-like objects. One alternative might be to implement a new operator t=
ype:
=2E. code:: c++
operator get(auto& tuple, constexpr size_t i);
constexpr operator sizeof<T>();
It may be reasonable or even desirable to restrict access of these operat=
ors to either explicit spelling or use of dedicated syntax:
=2E. code:: c++
MyTupleLike t;
[0]t; // operator get
sizeof...(t); // operator sizeof
auto [x, y] =3D t; // both, via name-binding unpacking, case 2
We should note that, while there are some strong feelings on these topics=
, we do not feel that any particular resolution is critical for any of th=
e directions we are exploring. In this area, we feel only that a consiste=
nt and clear direction is important.
(Types have been elided in the above examples, as they are not crucial to=
the discussion.)
Generalized Unpacking
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Generalized unpacking is the conversion of a tuple-like to a "value seque=
nce", in the manner of Python's ``*`` operator, such that the resulting s=
equence may be used in any place that a comma separated sequence may be u=
sed. While function parameter lists is the canonical example, this would =
also include braced initializer lists. Following discussion on the ``std-=
proposals`` forum, we believe that the most reasonable and useful mechani=
sm of accomplishing this is to provide a mechanism whereby a tuple-like m=
ay be converted into a parameter pack. Much as in the name-binding unpack=
ing case, there is a logical code transformation that can be applied for =
this purpose, by placing the tuple-like into a temporary (where necessary=
, i.e. if the tuple-like is an expression rather than already a named var=
iable) and taking the parameter pack to be :cpp:`get<0>(__t), get<1>(__t)=
, ...`. This extends the usable scope to anywhere a fold expression may b=
e used.
We are aware of at least three possible mechanisms for implementing gener=
alized unpacking. One option is to employ a new syntax to perform this op=
eration directly. Another is to make multiple return values, treated as p=
arameter packs, first class citizens of the language. A third is to creat=
e a parameter pack "generator". The latter two options make it possible t=
o write a function (which might reasonably be named :cpp:`std::unpack`) t=
hat is equivalent to the former.
Several possible syntaxes have been proposed, including postfix operator =
``~``. Our preference, however, is prefix operator ``[:]`` (for reasons t=
hat will be |--| very briefly |--| shown later), which we will use here, =
always bearing in mind that this is strictly for demonstrative purposes. =
For example:
=2E. code:: c++
struct { double x, y; } point =3D ...;
auto h =3D std::hypot([:]point...);
The addition of such a feature, regardless of its form\ [#uf]_, would obv=
iate most (though perhaps not all) use cases for :cpp:`std::apply` and :c=
pp:`sd::make_from_tuple`. It would also permit trivial conversions betwee=
n different "simple" types which are distinct but layout compatible, by u=
npacking the first type into a braced initializer list used to construct =
the second. We believe that this feature will be at least as important an=
d useful as name-binding unpacking.
Unification of Unpacking
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Possibly the most important aspect of P0197_ in our opinion is the provis=
ion for a single, unified mechanism for unpacking, whether in the name-bi=
nding or generalized senses. The critical aspect of P0197_, and the one t=
hat we feel strongly needs to be considered by P0144_, is providing impli=
cit general tuple-like access to simple data structures. In particular, w=
e feel that it would be a travesty for name-binding unpacking and general=
ized unpacking to use different customization points or to otherwise beha=
ve differently when used in ways where intuition strongly expects equival=
ent behavior. In particular, we feel strongly that, for a tuple-like type=
having a default destructor, the following should be equivalent (after o=
ptimizations):
=2E. code:: c++
auto [x, y] =3D t;
auto [x, y] =3D {[:]t...};
(This illustrates a need to be careful with lifetime semantics; in partic=
ular, unpacking should likely either extend lifetime when used in a brace=
d initializer list, or should explicitly create value copies in such case=
=2E The former would make the above equivalent for *any* tuple-like, whil=
e the latter may be useful for separating lifetime of the tuple-like and =
its components. We do not recommend a direction at this time, although th=
is is likely to be of relevance when considering a language solution vers=
us a "library" solution.)
It should be noted that P0197_ would provide a modest enhancement to name=
-binding unpacking. Where P0144_ limits itself to "flat" classes, P0197_ =
would extend implicit tuple-like access to all classes which:
* Contain no non-public NSDM's
* Contain no members of union type
* Have no virtual\ [#vb]_ and/or non-public\ [#eb]_ base classes
* Have no base classes which do not also meet the preceding eligibility=
criteria
While it would not be a catastrophic loss if non-"flat" classes were not =
supported, we do feel that it would be most unfortunate if we are not abl=
e |--| eventually |--| to rely on this implicit access to implement name-=
binding unpacking, and accordingly to eliminate P0144_ case 3. In additio=
n to consistency, we feel that this is important for the sake of simplici=
ty, as it eliminates a special case from name-binding unpacking. We are c=
onfident that the performance issues (that is, the understanding that cas=
e 3 represents name aliasing and neither consumes storage beyond that req=
uired for the tuple-like itself nor adds any access indirection) can be s=
atisfactorily addressed through compiler optimization, keeping in mind of=
course that the implementations of the "get" function (however we ultima=
tely spell it) are inline in these instances.
The problem that arises from this approach is bitfield members. At the 20=
16 Jacksonville meeting, at least one individual expressed a strong opini=
on that providing read/write access to bitfield members via name-binding =
unpacking is a "must have" feature. We encourage giving serious considera=
tion to the true importance of this feature, and to ways that this could =
be addressed in a way that does not require special casing. (In particula=
r, we note that the general ability to have a reference to a bitfield |--=
| likely through some new library type |--| seems at least as interesting=
as being able to name-bind to a component of such type of a tuple-like.)=
Slicing
=3D=3D=3D=3D=3D=3D=3D
In our earlier discussion on `Access`_, we mentioned syntax for accessing=
specific elements of a tuple-like. While the need to access individual e=
lements is obvious and clearly does not require a syntactic solution (we =
already have :cpp:`std::get<N>`), another desire that comes up often is t=
he ability to slice a tuple-like; e.g. to strip the first element or take=
only the first N elements.
We chose :cpp:`[:]` because it naturally extends to slicing, but various =
possible solutions have been suggested, including pack generators (which =
would offer significant expressive power). More importantly, since we rec=
ommend that generalized unpacking convert a tuple-like to a parameter pac=
k, it makes sense that a syntax for slicing tuple-likes should also work =
on parameter packs directly. In addition to the advantages for tuple-like=
s, this enables simple and powerful transformations for variadic template=
s, thus satisfying another important contemporary use case. In particular=
, we can now write recursive variadic template functions like:
=2E. code:: c++
void print_each() {} // sentinel
template <typename... T>
void print_each(T... values)
{
print_one([0]values);
print_each([1:]values);
}
This is a fairly trivial example that previously could be written by brea=
king the complete pack into a separately named head argument and tail pac=
k. This, however, merely scratches the surface. One could imagine impleme=
nting a :cpp:`constexpr` divide-and-conquer sort algorithm using slicing =
to trivially split the incoming parameter pack in half. Many other exampl=
es which can be readily implemented with slicing but would be difficult a=
nd/or expensive to implement otherwise can be imagined.
Pack Generation, Revisited
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D
Parameter pack generation is, in general, an interesting feature. Suggest=
ed example uses include generating an integer list\ [#il]_, a type list, =
and performing various manipulations on parameter packs. While such manip=
ulations could include slicing and reversing, we note that these operatio=
ns appear to rely on a syntactic mechanism for extracting a single elemen=
t from a pack (reference is made to N4235_). We also wonder if slicing op=
erations implemented in this manner would perform satisfactorily compared=
to syntactic slicing.
Consequently, we still need a syntax for indexed access of parameter pack=
elements. This in turn allows us to apply the previous argument in rever=
se; namely, why not select a syntax that is non-ambiguous, easily extende=
d to slicing, and may be applied also to tuple-likes? This is a point tha=
t we feel is worth serious consideration as we consider what direction ge=
neralized unpacking should take.
Summary
=3D=3D=3D=3D=3D=3D=3D
Previous discussions |--| both in EWG and on the ``std-proposals`` forum =
|--| suggest a strong desire by the C++ community to move the language in=
a direction that blurs the line between containers and their contained v=
alue sequences, making it easy to move from one to the other, as is often=
found in other languages (e.g. Python). At the same time, there are a nu=
mber of proposals either published or in the works to simplify working wi=
th parameter packs. Moreover, due to the significant utility of unpacking=
and otherwise working with tuple-like objects as parameter packs, these =
areas are closely related and to some extent overlap.
We have observed recently that "complexity" is a frequent complaint made =
against C++, especially that it is "hard to teach". As we consider featur=
es to simplify working with tuple-like objects and/or parameter packs, we=
feel it is of utmost importance to establish and adhere to a consistent =
vision of these functions, in terms of both syntax and function. We speci=
fically urge that name-binding unpacking would carefully consider customi=
zation points\ [#cp]_ and the future possibility of implicit tuple-like a=
ccess (see especially P0197_) and generalized unpacking in order to work =
toward\ [#fd]_ a common mechanism for both that would eliminate special c=
ase rules specific to the individual features. We also urge the committee=
to consider these issues and how such features relate (or can be made to=
relate) to tuple-like objects in order to maximize consistency of operat=
ions on both object types, and we urge authors working on such proposals =
to do likewise. Finally, we strongly encourage any authors working in thi=
s realm to maintain communication in order to reduce the dangers of compe=
ting, incompatible proposals and to maximize our ability as a community t=
o pursue a well considered, consistent, and maximally functional directio=
n.
By offering a glimpse at where we might be going, we hope we have demonst=
rated the importance of keeping the future in mind while developing new a=
nd exciting features today. We especially hope we have demonstrated the i=
mportance of considering the direction proposed by P0197_ (implicit tuple=
-like access for "simple" types) in light of P0144_ (name-binding unpacki=
ng) in order to maintain consistency and simplicity of specification in o=
rder to maximize the ability of users to understand the operation of thes=
e features and to use them in a sensible manner.
Acknowledgments
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
We would like to thank the authors of P0144_, for obvious reasons. We wou=
ld like to thank Mike Spertus and Daveed Vandevoorde for sharing a "previ=
ew" of their respective works-in-progress in the area of parameter packs.=
We would like to thanks Daniel Frey for his own work on parameter packs,=
which also forced us to consider the defense our own preferences more st=
renuously than had been done before. As always, we would also like to tha=
nk everyone that has shared their thoughts and ideas on these issues, bot=
h in person at the 2016 Jacksonville meeting and on ``std-proposals``.
Footnotes
=3D=3D=3D=3D=3D=3D=3D=3D=3D
=2E. [#pt] `QVector3D <http://doc.qt.io/qt-5.6/qvector3d.html>`_ comes to=
mind as an example of a user type which is |--| or at least, ought to be=
|--| tuple-like but has no public data members.
=2E. [#uf] The form that unpacking takes is not entirely uninteresting, h=
owever such discussion is not in scope for this paper.
=2E. [#vb] While present in the initial revision of P0197_, this restrict=
ion is not seen in P0144_, and upon further consideration, may be unneces=
sary.
=2E. [#eb] This could probably be relaxed to non-public *and non-empty* b=
ase classes, if desired.
=2E. [#il] The purely template implementation of :cpp:`std::integer_seque=
nce` is extremely expensive, to the point that many compilers are providi=
ng implementations based on compiler intrinsics. Parameter pack generator=
s have the potential to provide a satisfactory implementation without suc=
h intrinsics.
=2E. [#cp] It is our understanding that the committee and the authors of =
P0144_ are well aware of the strong feelings surrounding customization po=
ints and *are* giving them serious consideration. We wish to take this op=
portunity to thank and commend them for these efforts.
=2E. [#fd] We would like to reiterate that we have no objection to specia=
l case handling of "implicitly tuple-like" types in the short term, espec=
ially if it means name-binding unpacking is available in C++17, *provided=
* there is a long term migration route that would allow this special case=
to be replaced with more generalized functionality.
References
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=2E. _N4235: http://wg21.link/n4235
* N4235_ Selecting from Parameter Packs
http://wg21.link/n4235
=2E. _P0144: http://wg21.link/p0144
* P0144_ Structured Bindings
http://wg21.link/p0144
=2E. _P0197: http://wg21.link/p0197
* P0197_ Default Tuple-like Access
http://wg21.link/p0197
=2E. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..=
.. ..
=2E. |--| unicode:: U+02014 .. em dash
=2E. kate: hl reStructuredText
--------------060305020907090604080801--
.
Author: Daniel Frey <d.frey@gmx.de>
Date: Sat, 19 Mar 2016 11:53:06 +0100
Raw View
--Apple-Mail=_82C2F0AE-C5A7-4825-966B-7014C8947F2E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 18.03.2016, at 16:51, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote=
:
>=20
> I was hoping to include this in the next mailing... apparently the
> deadline for the same got decided only a handful of days before the
> deadline itself.
>=20
> Anyway... I'm asking for comments, as always. The attached paper is
> *not* a proposal, but a discussion of ongoing work related to tuple-like
> objects and parameter packs, and a call to consider a "big picture" as
> far as where we are going and how we can bring features in this area to
> C++ while maintaining consistency.
I don't have enough time for a proper, detailed answer yet, so I'll just of=
fer some initial feedback in the form of bullet points. I hope to have more=
time in the next week, but feel free to comment on my bullet points if you=
(or anyone else) would like to.
* I prefer to keep enhancements "local" to a small area of the language and=
provide the necessary fundamentals for efficient and straight-forward use.
* I don't see slices as the only thing we want
- We also want arbitrary lists of indices (2, 4, 7, 12, 3)
- We also want reversed slices/ranges
- We want slices of different types (std::size_t, int, enum?, ...)
- Generating slices could be done from begin_index, end_index (half-open =
interval or closed interval?) or from begin_index, size
* I think using a new syntax for this is not the right choice, as the synta=
x does not have a name.
* I therefore think that library facilities are preferable for this area, e=
xamples (don't get too hung up on the syntax I proposed, just get the gener=
al idea):
- using... Is =3D std::make_index_range<2,5>::values; // 2, 3, 4 - half-o=
pen interval [2,5)
- using... Is =3D std::make_integer_slice<int,2,5>::values; // 2, 3, 4, 5=
, 6 - starting with 2, 5 elements
* We are more flexible that way and adding more generators/transformers is =
possible
- using... Is =3D my_pow2_gen<2, 5>::values; // 2, 4, 8, 16, 32
* For local transformations:
- size_t... Is =3D ...5; // 0, 1, 2, 3, 4
- size_t... Js =3D < 2 * Is + 1... >; // 1, 3, 5, 7, 9
* BTW:
- size_t... Is =3D <>; // empty
* The above shows that generating integer sequences should be separated fro=
m applying them to extract parts from other packs or from tuple(-like) obje=
cts.
* The first is addressed by my proposal though composition with existing la=
nguage facilities:
- std::tuple< int, double, std::shared_ptr<int>, unsigned, int > t =3D /*=
whatever*/;
- using... Ts =3D t::types; // direct, if support is added to std::tuple;=
otherwise:
- using... Ts =3D std::tuple_elements<decltype>(t)>::types; // indirect, =
via customization point std::tuple_elements (with an 's' at the end)
- std::size_t... Is =3D <2, 4, 0, 1>; // explicitly specified: 2, 4, 0, 1
- typename... Us =3D < Ts...[Is]... >; // extract several elements into a=
new type pack
* With a library interface, the same would be possible for tuple(-like) obj=
ects:
- auto t2 =3D std::tuple_elements<Is...>(t);
- auto t3 =3D std::tie_elements<Is...>(t);
* Again, more explicit syntax (via library functions) might help. I am awar=
e that this is requested by new programmers, but in this case explicit vs. =
implicit should not be an issue as the kind of code using those facilities =
shows up in not too many places.
* Extracting a single element from a pack (or even better: expanding a sing=
le pattern):
- More powerful than a library based interface (e.g., type_at_t, value_at=
):
. pattern may contain several packs of different size
. not all expansions of a pattern must yield valid expressions, only th=
ose requested by selection
. this can be used for better SFINAE
- fundamental for efficient implementation of tuple(-like) classes
* Extracting a single element from a tuple(-like) object already has a synt=
ax: std::get<I>(t)
- Not great, but OK
- The implementation of std::get<I> can benefit from my proposal
* Maybe not ideal, maybe you want a better syntax: t[I]
- The syntax already exists (we could add operator[])
- The problem is the semantics (it currently does not work that way as th=
e return type does not depend on a parameter's value)
- The solution is to allow overloading based on constexpr
- Improves/enables other use-cases, by allowing to overload a method for =
constexpr with an implementation that is limited by what a constexpr can do=
, and a non-constexpr run-time implementation which can use all the usual c=
ode to provide an efficient run-time implementation.
* The fundamentals I proposed allow tuple(-like) classes and several other =
use-cases to be
- more efficient wrt compiler resources (time, memory usage)
(than today, not necessarily more efficient than a specialized proposal=
for some explicit use-cases)
- better, shorter, more direct code
- still explicit code wrt more advanced functionality, some standardized =
STL functions could be considered later on
* I'm really running out of time for now, sorry :)
* Feedback welcome
-- Daniel
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1FCE896E-001A-4F56-8866-FB201ABF3391%40gmx.de.
--Apple-Mail=_82C2F0AE-C5A7-4825-966B-7014C8947F2E
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename=signature.asc
Content-Type: application/pgp-signature;
name=signature.asc
Content-Description: Message signed with OpenPGP using GPGMail
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - https://gpgtools.org
iEYEARECAAYFAlbtL5IACgkQAUxJbew56yGHQwCfb1VxV8kt7M196cX9nMIzhBhc
xo4AoM3oT5ntMOQ7JWcYpTeBELrHtJts
=Ylws
-----END PGP SIGNATURE-----
--Apple-Mail=_82C2F0AE-C5A7-4825-966B-7014C8947F2E--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 19 Mar 2016 11:58:31 +0100
Raw View
This is a multi-part message in MIME format.
--------------050007080402000702080606
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 18/03/2016 16:51, Matthew Woehlke a =C3=A9crit :
> I was hoping to include this in the next mailing... apparently the
> deadline for the same got decided only a handful of days before the
> deadline itself.
>
> Anyway... I'm asking for comments, as always. The attached paper is
> *not* a proposal, but a discussion of ongoing work related to tuple-like
> objects and parameter packs, and a call to consider a "big picture" as
> far as where we are going and how we can bring features in this area to
> C++ while maintaining consistency.
>
> I know the acknowledgments section is not yet written. The plan is to
> fill it in partly based on what feedback I get.
>
> I'll probably be submitting this Sunday afternoon (U.S. time).
>
Hi Matthew,
IIUC your paper is a request for direction. I believe this merit to be=20
more explicit.
I believe that the papers presumes that the people are aware of some=20
discussion on this ML. I suggest you to describe them a little bit more=20
(you could also point to those discussions).
Concerning P0197R0, I have some questions about the conditions enabling=20
the default generation of get.
unions are not supported, but I don't see why member of union types=20
should not be supported. Could you clarify?
You say
"
Have no virtual[3] and/or non-public[4] base classes
[3] While present in the initial revision of P0197, this restriction=20
is not seen in P0144, and upon further consideration, may be unnecessary.
[4] This could probably be relaxed to non-public and non-empty base=20
classes, if desired.
"
I agree with [4]. [3] is less intuitive to me.
I have some todo's on a future revision of P0197
A * refine the conditions under which the generation is allowed (see above)=
,
B * introduce an alternative to default conversions to `std::tuple` and=20
`std::pair`,
C * adapt the text to the fact that [P0091R0] has been accepted,
D * take in account C-arrays,
E * add rationale about why `std::array` is not supported,
F * add rationale about why `std::tuple` couldn't be supported if we=20
don't add some additional requirements.
G * more on interactions of P0017, P0144 and P0197
B - P0197 proposes to generate conversion from a Tuple-like to tuple or=20
pair. Maybe it is better to define these conversions in tuple and pair.
C- there is no more need of to_tuple/to_pairs
D- get<I> is not defined for C-arrays, but AS structured binding takes=20
them in account it seems that I need to support them also.
E- std::array<T,N> should have a single member T data[N], and so by=20
default it will be see as a tuple of size one.
F- currently std::tuple has no requirements about how the members are=20
stored. The proposal could be applied only if the standard requires that=20
the members are stored in the same order and that those are the single=20
members of the storage.
G- With P0017 we will be able to
struct base1 { int b1, b2; };
struct base2 {
int b3;
};
struct derived : base1, base2 {
int d;
};
derived d1{{1, 2}, {3}, 4}; // full initialization
P0197 see derived as a tuple-like type with 4 elements. The intent was to s=
upport std::tuple, but it needs some possibly breaking changes in std::tupl=
e I don't want to propose.
I don't see yet what P0144 proposes in this case
auto {b12, b3, d} =3D d1;
or
auto {b1, b2, b3, d} =3D d1;
If the first, I believe that we need to adapt P0197.
What do you think?
Vicente
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/56ED30D7.5090304%40wanadoo.fr.
--------------050007080402000702080606
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body text=3D"#000000" bgcolor=3D"#FFFFFF">
<div class=3D"moz-cite-prefix">Le 18/03/2016 16:51, Matthew Woehlke a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote cite=3D"mid:nch85i$8ob$1@ger.gmane.org" type=3D"cite">
<pre wrap=3D"">I was hoping to include this in the next mailing... ap=
parently the
deadline for the same got decided only a handful of days before the
deadline itself.
Anyway... I'm asking for comments, as always. The attached paper is
*not* a proposal, but a discussion of ongoing work related to tuple-like
objects and parameter packs, and a call to consider a "big picture" as
far as where we are going and how we can bring features in this area to
C++ while maintaining consistency.
I know the acknowledgments section is not yet written. The plan is to
fill it in partly based on what feedback I get.
I'll probably be submitting this Sunday afternoon (U.S. time).
</pre>
</blockquote>
<font size=3D"+1">Hi Matthew,<br>
<br>
IIUC your paper is a request for direction. I believe this merit
to be more explicit.<br>
<br>
I believe that the papers presumes that the people are aware of
some discussion on this ML. I suggest you to describe them a
little bit more (you could also point to those discussions).<br>
<br>
Concerning </font><font size=3D"+1"><font size=3D"+1">P0197R0</font>,
I have some questions about the conditions enabling the default
generation of get.<br>
<br>
unions are not supported, but I don't see why member of union
types should not be supported. Could you clarify?<br>
<br>
</font>You say<br>
"<br>
Have no virtual[3] and/or non-public[4] base classes<br>
[3]=C2=A0=C2=A0=C2=A0 While present in the initial revision of P0197, t=
his
restriction is not seen in P0144, and upon further consideration,
may be unnecessary.<br>
[4]=C2=A0=C2=A0=C2=A0 This could probably be relaxed to non-public and =
non-empty
base classes, if desired.<br>
"<br>
I agree with [4]. [3] is less intuitive to me. <br>
<br>
I have some todo's on a future revision of P0197<br>
<br>
A * refine the conditions under which the generation is allowed (see
above),<br>
B * introduce an alternative to default conversions to `std::tuple`
and `std::pair`,<br>
C * adapt the text to the fact that [P0091R0] has been accepted,<br>
D * take in account C-arrays,<br>
E * add rationale about why `std::array` is not supported,<br>
F * add rationale about why `std::tuple` couldn't be supported if we
don't add some additional requirements.<br>
G * more on interactions of P0017, P0144 and P0197 <br>
<br>
B - P0197 proposes to generate conversion from a Tuple-like to tuple
or pair. Maybe it is better to define these conversions in tuple and
pair.<br>
<br>
C- there is no more need of to_tuple/to_pairs<br>
<br>
D- get<I> is not defined for C-arrays, but AS structured
binding takes them in account it seems that I need to support them
also.<br>
<br>
E- std::array<T,N> should have a single member T data[N], and
so by default it will be see as a tuple of size one.<br>
<br>
F- currently std::tuple has no requirements about how the members
are stored. The proposal could be applied only if the standard
requires that the members are stored in the same order and that
those are the single members of the storage. <br>
<br>
G- With P0017 we will be able to<br>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
<pre>struct base1 { int b1, b2; };
struct base2 {=20
int b3;
};
struct derived : base1, base2 {
int d;
};
derived d1{{1, 2}, {3}, 4}; // full initialization
P0197 see derived as a tuple-like type with 4 elements. The intent was to s=
upport std::tuple, but it needs some possibly breaking changes in std::tupl=
e I don't want to propose.
I don't see yet what P0144 proposes in this case
auto {b12, b3, d} =3D d1;
or=20
auto {b1, b2, b3, d} =3D d1;
If the first, I believe that we need to adapt P0197.
</pre>
=C2=A0<br>
What do you think?<br>
<br>
Vicente<br>
=C2=A0<br>
<br>
=C2=A0=C2=A0 <br>
</body>
</html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/56ED30D7.5090304%40wanadoo.fr?utm_med=
ium=3Demail&utm_source=3Dfooter">https://groups.google.com/a/isocpp.org/d/m=
sgid/std-proposals/56ED30D7.5090304%40wanadoo.fr</a>.<br />
--------------050007080402000702080606--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 19 Mar 2016 12:24:59 +0100
Raw View
This is a multi-part message in MIME format.
--------------030203030707030000030809
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 19/03/2016 11:58, Vicente J. Botet Escriba a =C3=A9crit :
> Le 18/03/2016 16:51, Matthew Woehlke a =C3=A9crit :
>
> I have some todo's on a future revision of P0197
>
> A * refine the conditions under which the generation is allowed (see=20
> above),
> B * introduce an alternative to default conversions to `std::tuple`=20
> and `std::pair`,
> C * adapt the text to the fact that [P0091R0] has been accepted,
> D * take in account C-arrays,
> E * add rationale about why `std::array` is not supported,
> F * add rationale about why `std::tuple` couldn't be supported if we=20
> don't add some additional requirements.
> G * more on interactions of P0017, P0144 and P0197
>
>
>
> C- there is no more need of to_tuple/to_pairs
I was wrong here. More later.
Vicente
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/56ED370B.40108%40wanadoo.fr.
--------------030203030707030000030809
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body text=3D"#000000" bgcolor=3D"#FFFFFF">
<div class=3D"moz-cite-prefix">Le 19/03/2016 11:58, Vicente J. Botet
Escriba a =C3=A9crit=C2=A0:<br>
</div>
<blockquote cite=3D"mid:56ED30D7.5090304@wanadoo.fr" type=3D"cite">
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Ty=
pe">
<div class=3D"moz-cite-prefix">Le 18/03/2016 16:51, Matthew Woehlke
a =C3=A9crit=C2=A0:<br>
</div>
<br>
I have some todo's on a future revision of P0197<br>
<br>
A * refine the conditions under which the generation is allowed
(see above),<br>
B * introduce an alternative to default conversions to
`std::tuple` and `std::pair`,<br>
C * adapt the text to the fact that [P0091R0] has been accepted,<br>
D * take in account C-arrays,<br>
E * add rationale about why `std::array` is not supported,<br>
F * add rationale about why `std::tuple` couldn't be supported if
we don't add some additional requirements.<br>
G * more on interactions of P0017, P0144 and P0197 <br>
<br>
<br>
<br>
C- there is no more need of to_tuple/to_pairs<br>
</blockquote>
I was wrong here. More later.<br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/56ED370B.40108%40wanadoo.fr?utm_mediu=
m=3Demail&utm_source=3Dfooter">https://groups.google.com/a/isocpp.org/d/msg=
id/std-proposals/56ED370B.40108%40wanadoo.fr</a>.<br />
--------------030203030707030000030809--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 19 Mar 2016 18:59:34 +0100
Raw View
This is a multi-part message in MIME format.
--------------000200090105080102020700
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 19/03/2016 11:58, Vicente J. Botet Escriba a =C3=A9crit :
> Le 18/03/2016 16:51, Matthew Woehlke a =C3=A9crit :
>
> You say
> "
> Have no virtual[3] and/or non-public[4] base classes
> [3] While present in the initial revision of P0197, this=20
> restriction is not seen in P0144, and upon further consideration, may=20
> be unnecessary.
> [4] This could probably be relaxed to non-public and non-empty base=20
> classes, if desired.
> "
> I agree with [4]. [3] is less intuitive to me.
>
BTW, P0197 added this constraint as P0017.
# no virtual, private or protected base classes (10.1).
If don't think that we should generate a tuple-like access for a case=20
aggregation is forbidding.
Vicente
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/56ED9386.3060202%40wanadoo.fr.
--------------000200090105080102020700
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body text=3D"#000000" bgcolor=3D"#FFFFFF">
<div class=3D"moz-cite-prefix">Le 19/03/2016 11:58, Vicente J. Botet
Escriba a =C3=A9crit=C2=A0:<br>
</div>
<blockquote cite=3D"mid:56ED30D7.5090304@wanadoo.fr" type=3D"cite">
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Ty=
pe">
<div class=3D"moz-cite-prefix">Le 18/03/2016 16:51, Matthew Woehlke
a =C3=A9crit=C2=A0:<br>
</div>
<font size=3D"+1"><br>
</font>You say<br>
"<br>
Have no virtual[3] and/or non-public[4] base classes<br>
[3]=C2=A0=C2=A0=C2=A0 While present in the initial revision of P0197,=
this
restriction is not seen in P0144, and upon further consideration,
may be unnecessary.<br>
[4]=C2=A0=C2=A0=C2=A0 This could probably be relaxed to non-public an=
d non-empty
base classes, if desired.<br>
"<br>
I agree with [4]. [3] is less intuitive to me. <br>
<br>
</blockquote>
BTW, P0197 added this constraint as P0017. <br>
<br>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
<li><ins>no virtual, private or protected base classes (10.1).</ins>
</li>
<br>
If don't think that we should generate a tuple-like access for a
case aggregation is forbidding.<br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/56ED9386.3060202%40wanadoo.fr?utm_med=
ium=3Demail&utm_source=3Dfooter">https://groups.google.com/a/isocpp.org/d/m=
sgid/std-proposals/56ED9386.3060202%40wanadoo.fr</a>.<br />
--------------000200090105080102020700--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Sat, 19 Mar 2016 15:15:23 -0400
Raw View
On 2016-03-19 06:53, Daniel Frey wrote:
> On 18.03.2016, at 16:51, Matthew Woehlke wrote:
>> [paper]
I'm going to try to keep this brief as it is turning into a discussion
on your proposal vs. mine, which really isn't the topic. (Parameter pack
stuff in general is really only partly on topic; the main topic should
be P0197.)
> * I prefer to keep enhancements "local" to a small area of the language and provide the necessary fundamentals for efficient and straight-forward use.
I still contend that at minimum basic unpacking qualifies (especially
for your "efficient and straight forward" points) :-).
As previously stated, I am strongly opposed to a library-only solution
for the simple unpacking case, as it is effectively useless for my main
use case.
> * I don't see slices as the only thing we want
> - We also want arbitrary lists of indices (2, 4, 7, 12, 3)
> - We also want reversed slices/ranges
Agreed. Pack generation will be able to do these, though. My feeling is
that they are obscure enough that extra syntax (i.e. "library" solution)
is okay. In that respect, your proposal and Daveed's are equally simple,
but Daveed's can do a lot that your proposal can't.
> - We want slices of different types (std::size_t, int, enum?, ...)
Do you mean as indices? These should Just Work with syntactic slicing,
and making them work with library slicing isn't hard.
> * Extracting a single element from a tuple(-like) object already has a syntax: std::get<I>(t)
There was discussion at Jacksonville if that's really the syntax we
want. Compile-time indexing would offer an obvious alternative (as
presented in the section "An operator-like alternative"). More to the
point, though, it seems silly for slicing to operate on both tuple-likes
and parameter packs but to restrict single-value extraction to the
latter. IOW, there is no syntactic cost and there is a benefit in
consistency.
--
Matthew
--
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/nck8gb%249kp%241%40ger.gmane.org.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Sat, 19 Mar 2016 15:38:20 -0400
Raw View
On 2016-03-19 06:58, Vicente J. Botet Escriba wrote:
> Le 18/03/2016 16:51, Matthew Woehlke a =C3=A9crit :
>> [paper]
>=20
> I believe that the papers presumes that the people are aware of some
> discussion on this ML. I suggest you to describe them a little bit more
> (you could also point to those discussions).
Good point. I don't really have time to do any serious revision, and I'm
not convinced getting into to much detail in the body of the paper is
necessarily valuable. However, I'll include some links to relevant
discussions. Thanks for the suggestion.
> Concerning P0197R0, I have some questions about the conditions enabling
> the default generation of get.
>=20
> unions are not supported, but I don't see why member of union types
> should not be supported. Could you clarify?
Hmm... I was going to say 'how would you know what member is engaged'?
But then, I suppose you would just get back the whole union. This may be
a silly restriction; I mostly added it because it seems present in
P0144. It should probably be present in both or neither. This is a
nitpicking detail, however, beyond the scope of this paper.
Same comments re: other base classes. Let's either not go into this here
or else start a new thread; it's off topic.
> I have some todo's on a future revision of P0197
>=20
> G * more on interactions of P0017, P0144 and P0197
Now this is *very* on topic :-). The objective of D0311 is primarily to
bring attention to this exact issue. (In particular, I really want to
kill P0144 Case 3. Maybe not in C++17, but definitely in C++19/20.)
> D- get<I> is not defined for C-arrays, but AS structured binding takes
> them in account it seems that I need to support them also.
Hmm... yes, that probably would not be a bad thing. I'd like both types
of unpacking to be consistent here as in other areas.
> E- std::array<T,N> should have a single member T data[N], and so by
> default it will be see as a tuple of size one.
I expect std::array will provide its own tuple-like access, so P0197
would not apply. That shouldn't be a problem. (Similar for std::tuple.)
> G- With P0017 we will be able to
>=20
> struct base1 { int b1, b2; };
> struct base2 {
> int b3;
> };
> struct derived : base1, base2 {
> int d;
> };
>=20
> derived d1{{1, 2}, {3}, 4}; // full initialization
>=20
> P0197 see derived as a tuple-like type with 4 elements. The intent was
> to support std::tuple, but it needs some possibly breaking changes in
> std::tuple I don't want to propose.
I thought we agreed on bases being seen as a single member? Anyway, off
topic to D0311 :-).
> I don't see yet what P0144 proposes in this case
AFAIUI, P0144 only permits classes where all data members are in 'the
same level'. P0197 would, by superseding P0144 Case 3, lift that
restriction.
> If the first, I believe that we need to adapt P0197.
I believe we need to adopt P0197 and kill P0144 Case 3. That's partly
the point that D0311 is trying to make :-).
--=20
Matthew
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/nck9rc%24qiv%241%40ger.gmane.org.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 19 Mar 2016 12:58:20 -0700 (PDT)
Raw View
------=_Part_2723_1187776930.1458417500877
Content-Type: multipart/alternative;
boundary="----=_Part_2724_1703648650.1458417500878"
------=_Part_2724_1703648650.1458417500878
Content-Type: text/plain; charset=UTF-8
It is a mistake to add slicing to this idea. The primary reason is that, by
avoiding slicing, you ward off the "Let's do it in a library instead!"
folks.
If it's a focused language feature, like "turn tuples into parameter
packs", then it's very difficult to argue that it shouldn't be in the
language. Criticism from that direction can be easily thwarted by simply
showing the syntactic differences for very simple things. The library
solution will always be more verbose, more impenetrable, require lambdas,
and therefore less likely to be used by the common C++ programmer. The
language solution looks clean and obvious.
Once you start removing the focus, it becomes much easier to deconstruct
the idea. For example, slicing sub-sets. Your proposal talks about adding a
bunch of changes to constexpr functions, lambdas, and other things to allow
computing of subsets.
Well, we already have a perfectly functional means to do that right now.
It's called "template metaprogramming". Right now, we can write code that
generates these subsets. It's just not something that is in a form that
could be fed into your sub-set-of-tuple range feature. So your alternative
has to build up a bunch of language sub-features to make it work, a whole
different way of doing such computations.
That seems decidedly unnecessary.
Here is what code would have to look like to select every odd numbered
element from a tuple, under your method:
[std::odd_elements(tpl):]tpl...
Note that you have to pass the `tpl` twice, since `count_odd_elements`
needs to know how many are in the tuple. Or worse, `tuple_count(tpl)`.
Here is what it would look like with a library solution, one that is
coupled with tuple pack expansion:
[:](std::forward_odd_elements(tpl))...
I think the latter one is much more clear as to what's going on. You
generate a (forward) tuple that contains the odd numbered elements, then
expand it.
Notice how, in the first case, the "expand tuple into pack" part becomes
invisiable, syntactically speaking. The `std::odd_elements` part dominates
the syntax, making it hard to tell that tuple-to-pack conversion is
happening. It also looks too much like lambda syntax.
Tuple expansion needs to be a language feature because the equivalent
library code looks Godawful. Tuple element subselection does not need to be
a language feature, because the equivalent library code looks just fine.
Focus on *whole* tuple expansion; leave the subsetting to libraries.
--
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/d96ddb89-d93c-42ba-b727-554b22f79166%40isocpp.org.
------=_Part_2724_1703648650.1458417500878
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">It is a mistake to add slicing to this idea. The primary r=
eason is that, by avoiding slicing, you ward off the "Let's do it =
in a library instead!" folks.<br><br>If it's a focused language fe=
ature, like "turn tuples into parameter packs", then it's ver=
y difficult to argue that it shouldn't be in the language. Criticism fr=
om that direction can be easily thwarted by simply showing the syntactic di=
fferences for very simple things. The library solution will always be more =
verbose, more impenetrable, require lambdas, and therefore less likely to b=
e used by the common C++ programmer. The language solution looks clean and =
obvious.<br><br>Once you start removing the focus, it becomes much easier t=
o deconstruct the idea. For example, slicing sub-sets. Your proposal talks =
about adding a bunch of changes to constexpr functions, lambdas, and other =
things to allow computing of subsets.<br><br>Well, we already have a perfec=
tly functional means to do that right now. It's called "template m=
etaprogramming". Right now, we can write code that generates these sub=
sets. It's just not something that is in a form that could be fed into =
your sub-set-of-tuple range feature. So your alternative has to build up a =
bunch of language sub-features to make it work, a whole different way of do=
ing such computations.<br><br>That seems decidedly unnecessary.<br><br>Here=
is what code would have to look like to select every odd numbered element =
from a tuple, under your method:<br><br><div class=3D"prettyprint" style=3D=
"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bo=
rder-style: solid; border-width: 1px; word-wrap: break-word;"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #660;"=
class=3D"styled-by-prettify">[</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">odd_elements</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">t=
pl</span><span style=3D"color: #660;" class=3D"styled-by-prettify">):]</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">tpl</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">...</span></div></code=
></div><br>Note that you have to pass the `tpl` twice, since `count_odd_ele=
ments` needs to know how many are in the tuple. Or worse, `tuple_count(tpl)=
`.<br><br>Here is what it would look like with a library solution, one that=
is coupled with tuple pack expansion:<br><br><div class=3D"prettyprint" st=
yle=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 18=
7); border-style: solid; border-width: 1px; word-wrap: break-word;"><code c=
lass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">[:](</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify">forward_odd_elements</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">tpl</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">))...</span></div></code></div><br>I think the latter one is much m=
ore clear as to what's going on. You generate a (forward) tuple that co=
ntains the odd numbered elements, then expand it.<br><br>Notice how, in the=
first case, the "expand tuple into pack" part becomes invisiable=
, syntactically speaking. The `std::odd_elements` part dominates the syntax=
, making it hard to tell that tuple-to-pack conversion is happening. It als=
o looks too much like lambda syntax.<br><br>Tuple expansion needs to be a l=
anguage feature because the equivalent library code looks Godawful. Tuple e=
lement subselection does not need to be a language feature, because the equ=
ivalent library code looks just fine.<br><br>Focus on <i>whole</i> tuple ex=
pansion; leave the subsetting to libraries.<br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d96ddb89-d93c-42ba-b727-554b22f79166%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d96ddb89-d93c-42ba-b727-554b22f79166=
%40isocpp.org</a>.<br />
------=_Part_2724_1703648650.1458417500878--
------=_Part_2723_1187776930.1458417500877--
.
Author: Daniel Frey <d.frey@gmx.de>
Date: Sun, 20 Mar 2016 09:21:15 +0100
Raw View
--Apple-Mail=_55FBBF7D-88F4-4C11-9AD8-045B607E9F8A
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 19.03.2016, at 20:15, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote=
:
>=20
> On 2016-03-19 06:53, Daniel Frey wrote:
>> On 18.03.2016, at 16:51, Matthew Woehlke wrote:
>>> [paper]
>=20
> I'm going to try to keep this brief as it is turning into a discussion
> on your proposal vs. mine, which really isn't the topic. (Parameter pack
> stuff in general is really only partly on topic; the main topic should
> be P0197.)
In a way, it is the topic. We are both trying to solve problem in a similar=
domain, coming from different directions and with different ideas about ho=
w to solve those problems. I appreciate these discussions as they are forci=
ng both of us to look further, do more. This is a constructive way of makin=
g progress and by that, I do see value in discussing your proposal vs. mine=
.. I adapt and enhance mine as good as I can, trying to see your use-cases a=
nd provide solutions for them. I hope you can also see similar value in the=
discussion for your proposal. It might end with both of us (and others) jo=
ining forces into a single proposal, but for now I am keeping my proposal a=
s a separate paper as I can not simply merge my ideas with yours on a synta=
ctic level.
>> * I prefer to keep enhancements "local" to a small area of the language =
and provide the necessary fundamentals for efficient and straight-forward u=
se.
>=20
> I still contend that at minimum basic unpacking qualifies (especially
> for your "efficient and straight forward" points) :-).
>=20
> As previously stated, I am strongly opposed to a library-only solution
> for the simple unpacking case, as it is effectively useless for my main
> use case.
I can agree to that, I am about to add an "operator..." to unpack tuple(-li=
ke) classes to my proposal. I think it can combine very nicely with the oth=
er enhancements I proposing.
>> * I don't see slices as the only thing we want
>> - We also want arbitrary lists of indices (2, 4, 7, 12, 3)
>> - We also want reversed slices/ranges
>=20
> Agreed. Pack generation will be able to do these, though. My feeling is
> that they are obscure enough that extra syntax (i.e. "library" solution)
> is okay. In that respect, your proposal and Daveed's are equally simple,
> but Daveed's can do a lot that your proposal can't.
The syntax I've chosen allows for more ways to generate sequences to be add=
ed, as the left-hand side (int... Is) is an anchor, so the possible express=
ions on the right-hand side (...4) can be extended by further options witho=
ut interaction with the rest of the language. Example:
int... Is =3D 2*(...4)+1; // allow an expression with exactly one generat=
ed sequence
I am currently not proposing anything specific in this area, as I'm not sur=
e how important this use-case is. If others feel it should be addressed, I'=
ll think of something.
>> - We want slices of different types (std::size_t, int, enum?, ...)
>=20
> Do you mean as indices? These should Just Work with syntactic slicing,
> and making them work with library slicing isn't hard.
"slices" wasn't the best word in the above sentence I wrote. Maybe "sequenc=
es" would be a better fit. The point is: We currently have (via deduction) =
sequences of different integral types. If we have sequence generators, we s=
hould also be able to control the type. [2:5] would generate a sequence of =
what? std::size_t? Then how do you generate a sequence of int...?
>> * Extracting a single element from a tuple(-like) object already has a s=
yntax: std::get<I>(t)
>=20
> There was discussion at Jacksonville if that's really the syntax we
> want. Compile-time indexing would offer an obvious alternative (as
> presented in the section "An operator-like alternative"). More to the
> point, though, it seems silly for slicing to operate on both tuple-likes
> and parameter packs but to restrict single-value extraction to the
> latter. IOW, there is no syntactic cost and there is a benefit in
> consistency.
I think you are mixing two different things which should (or even need to) =
be distinguished properly:
* Slicing (or other forms of multi-index access) generates another pack (or=
parameter list)
* Single elements are not packs
This is a very important difference. I don't want consistency here, I want =
to explicitly know which case I am working with. A pack of size 1 is still =
a pack that needs to be expanded, the other is simply a single type or a va=
lue (or a single expression).
-- Daniel
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/6605C1A6-7DB7-4CDF-9B36-BEE95D90CAED%40gmx.de.
--Apple-Mail=_55FBBF7D-88F4-4C11-9AD8-045B607E9F8A
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename=signature.asc
Content-Type: application/pgp-signature;
name=signature.asc
Content-Description: Message signed with OpenPGP using GPGMail
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - https://gpgtools.org
iEYEARECAAYFAlbuXXsACgkQAUxJbew56yEZ6wCfesooxgAEojAAPp+goRgovd7T
tj0AoMxisJfZRnXN5z/JLtmuKrzUsGym
=CJwo
-----END PGP SIGNATURE-----
--Apple-Mail=_55FBBF7D-88F4-4C11-9AD8-045B607E9F8A--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Sun, 20 Mar 2016 13:44:34 -0400
Raw View
On 2016-03-20 04:21, Daniel Frey wrote:
> On 19.03.2016, at 20:15, Matthew Woehlke wrote:
>> On 2016-03-19 06:53, Daniel Frey wrote:
>>> On 18.03.2016, at 16:51, Matthew Woehlke wrote:
>>>> [paper]
>>
>> I'm going to try to keep this brief as it is turning into a discussion
>> on your proposal vs. mine, which really isn't the topic. (Parameter pack
>> stuff in general is really only partly on topic; the main topic should
>> be P0197.)
>=20
> In a way, it is the topic. We are both trying to solve problem in a=20
> similar domain, coming from different directions and with different=20
> ideas about how to solve those problems.
Well... okay, yes :-). I do go into this direction, and it is a topic
that I think needs to be resolved. Eventually. The reason I urgently
wanted the paper in the next mailing however is for the sake of P0197,
P0144 and their respective interactions. The issues around parameter
packs are meant (in the context of D0311) more to serve as an
illustration of where we are (probably) headed and why it's important to
considering these interactions, especially where they touch on P0144 and
therefore are of urgent import, as P0144 may yet go into C++17. (I tend
to hope that it does, though if it doesn't, we'll have more chance to
"get it right" with respect to the larger issues.)
> I appreciate these discussions as they are forcing both of us to look
> further, do more. This is a constructive way of making progress and
> by that, I do see value in discussing your proposal vs. mine.
Indeed. You may notice in the latest draft (which includes the
acknowledgments section) that I credited you for exactly this :-).
For the record, I'll reiterate here: thank *you* for making *me* defend
my position more seriously :-).
> It might end with both of us (and others) joining forces into a
> single proposal
That would be awesome :-).
p.s. You might want to ask Daveed if he'll share his pack generation
paper; it might give you a different perspective on some of your ideas.
> I can agree to that, I am about to add an "operator..." to unpack
> tuple(-like) classes to my proposal.
Hmm... I'll try to reserve judgment until I see an example, but my
offhand reaction is that unpacking and fold expansion need to have
different syntax.
>>> * I don't see slices as the only thing we want
>>> - We also want arbitrary lists of indices (2, 4, 7, 12, 3)
>>> - We also want reversed slices/ranges
>>
>> Agreed. Pack generation will be able to do these, though. My feeling is
>> that they are obscure enough that extra syntax (i.e. "library" solution)
>> is okay. In that respect, your proposal and Daveed's are equally simple,
>> but Daveed's can do a lot that your proposal can't.
>=20
> The syntax I've chosen allows for more ways to generate sequences to be a=
dded, as the left-hand side (int... Is) is an anchor, so the possible expre=
ssions on the right-hand side (...4) can be extended by further options wit=
hout interaction with the rest of the language. Example:
>=20
> int... Is =3D 2*(...4)+1; // allow an expression with exactly one gener=
ated sequence
>=20
> I am currently not proposing anything specific in this area, as I'm not s=
ure how important this use-case is. If others feel it should be addressed, =
I'll think of something.
You *really* should read Daveed's paper :-). I have some reservations as
far as implementation complexity (which, in the interest of full
disclosure, he doesn't share); other than that, it's *really* cool.
>>> - We want slices of different types (std::size_t, int, enum?, ...)
>>
>> Do you mean as indices? These should Just Work with syntactic slicing,
>> and making them work with library slicing isn't hard.
>=20
> "slices" wasn't the best word in the above sentence I wrote. Maybe
> "sequences" would be a better fit. The point is: We currently have
> (via deduction) sequences of different integral types. If we have
> sequence generators, we should also be able to control the type.
> [2:5] would generate a sequence of what? std::size_t?
It would generate the parameter pack `[2]__t, [3]__t, [4]__t`. The type
of the indices is not greatly important, since it gets immediately
stuffed into the single-value indexing operator. (Note also that
`[N]__t` isn't fully expanded either; it would actually be `get<N>(__t)`
or whatever we decide we like for tuple-like indexed access.)
> Then how do you generate a sequence of int...?
Using something other than my proposal :-). The scope I am addressing is
more narrow than the scope you are addressing, which is more narrow than
the scope Daveed is addressing. I'm pretty sure I said this elsewhere,
but my approach is to focus on the easy/common cases and also provide
the function (indexed access into parameter packs) that seems to be a
prerequisite for any of the more advanced approaches. It would help if
you don't view your proposal as directly competing with mine; parts of
it would be rather an addition. My main "complaint" against your
proposal in that respect is that I don't see it solving anything that
Daveed's proposal doesn't.
>>> * Extracting a single element from a tuple(-like) object already has a =
syntax: std::get<I>(t)
>>
>> There was discussion at Jacksonville if that's really the syntax we
>> want. Compile-time indexing would offer an obvious alternative (as
>> presented in the section "An operator-like alternative"). More to the
>> point, though, it seems silly for slicing to operate on both tuple-likes
>> and parameter packs but to restrict single-value extraction to the
>> latter. IOW, there is no syntactic cost and there is a benefit in
>> consistency.
>=20
> I think you are mixing two different things which should (or even need to=
) be distinguished properly:
>=20
> * Slicing (or other forms of multi-index access) generates another pack (=
or parameter list)
> * Single elements are not packs
>=20
> This is a very important difference. I don't want consistency here,
> I want to explicitly know which case I am working with. A pack of
> size 1 is still a pack that needs to be expanded, the other is simply
> a single type or a value (or a single expression).
Isn't this a point I was making in an earlier message?
This is a pack: `[4:5]p;`
This is a single element: `[4]p`
This is the same as the previous example: `([4:5]p...)`
The "clear" (okay, we can argue on just *how* clear) differentiation
point is that a single index always gives you a value=C2=B9, whereas the on=
ly
way you get a pack is if there is a `:` in the index-expression;
conversely, you *always* get a pack if there is a `:`, even if the pack
has only one element.
(=C2=B9 *If* we allow packs as indices, the effect would be the same as
`foo[pack]...`, i.e. the indexing expression is "outside" pack
expansion, the same as a call to `bar` is "outside" pack expansion in
e.g. `0 + ... + bar(pack)`.)
Yes, I am lumping those into one syntax (prefix `[]`). I am doing so
because they both are in the "compile time indexing" basket, because we
*need* parameter pack indexing (and I don't see undecorated postfix `[]`
as a feasible solution for that), because I feel very strongly that we
need a short syntax for the common tuple-like unpacking case, and
because the grammar cost of combining these is lower versus having two
different new syntaxes.
--=20
Matthew
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ncmni2%24ir6%241%40ger.gmane.org.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Sun, 20 Mar 2016 14:15:12 -0400
Raw View
On 2016-03-19 15:58, Nicol Bolas wrote:
> It is a mistake to add slicing to this idea. The primary reason is that, by
> avoiding slicing, you ward off the "Let's do it in a library instead!"
> folks.
I took that approach with P0222 / P0224, and... it didn't work out :-).
While I wasn't able to present those papers, I did receive feedback from
a few people that separating the ideas was a mistake. When and if I
resubmit them, it will be combined.
It's probably a good idea to downplay slicing and focus on
default-indexed unpacking and parameter pack indexing for at least the
initial version of a paper. However, the impression I got of EWG is that
it's important to provide as much supporting evidence as possible for
why particular choices were made and why the feature is potentially
worthwhile. To that effect, I think it's important to emphasize first
that we *need* parameter pack indexing, and that short-form common case
tuple-like unpacking is important, but then to take the next step of
presenting the complete case for using a unified syntax (and for `[:]`
in particular) for the two.
That said... I note that once again we're discussing something in the
future and not the goals of D0311 :-).
> Your proposal talks about adding a bunch of changes to constexpr
> functions, lambdas, and other things to allow computing of subsets.
Uh... it does? (Are you talking about the pack generation stuff?)
> So your alternative has to build up a bunch of language sub-features
> to make it work, a whole different way of doing such computations.
I think we're either not on the same page, or you seriously overestimate
the complexity. Default-indexed unpacking already needs to build a pack
of index access operations. Slicing just constrains what indices are
used in that process in a fairly trivial manner.
> Here is what code would have to look like to select every odd numbered
> element from a tuple, under your method:
>
> [std::odd_elements(tpl):]tpl...
Ah... no. That's not legal (in fact, it's syntactic garbage); the
initial-index in that example is not an integer value. The indices
*must* be constexpr integer values. The compiler already knows how to
evaluate constexpr functions, so nothing new is added there.
I trust that the compiler can also manage a for loop with user-provided
boundary conditions; this really isn't difficult. In fact, it is the
difference between:
// default-indexed only
k = tuple_size(__t);
for (auto i = 0; i < k; ++i)
emit("get<" + to_string(i) + ">(__t)");
// sliced
auto k = tuple_size(__t);
auto l = lower_expr < 0 ? max(0, k + lower_expr) : lower_expr;
auto u = upper_expr < 0 ? k + upper_expr : min(k, upper_expr);
for (auto i = l; i < u; ++i)
emit("get<" + to_string(i) + ">(__t)");
(Even showing how to handle negative indices, it adds... two lines of
code, besides evaluating the index expressions which compilers surely
know how to do already.)
> Note that you have to pass the `tpl` twice, since `count_odd_elements`
> needs to know how many are in the tuple. Or worse, `tuple_count(tpl)`.
I can't think of a practical example where you wouldn't just use a
negative index. And all of this stuff is purely at compile time, so who
cares anyway?
> Here is what it would look like with a library solution, one that is
> coupled with tuple pack expansion:
>
> [:](std::forward_odd_elements(tpl))...
*That* would be legal :-). Daveed's proposal can possibly do this more
efficiently, however. Note that I *like* Daveed's proposal.
> Focus on *whole* tuple expansion; leave the subsetting to libraries.
I've at least hinted at this before, but I really don't expect slicing
to get more complicated than `[1:]t` or `[:-1]t` in most use cases. I
still think for such simple examples, it's useful. I'd even be okay
limiting the indices to actual literals (and requiring a "library"
solution otherwise); I just feel like that's a silly and unnecessary
restriction.
(It's worth noting that I've generally changed my mind about allowing
more than one index-expression.)
--
Matthew
--
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/ncmpbg%24i60%241%40ger.gmane.org.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 20 Mar 2016 12:42:08 -0700 (PDT)
Raw View
------=_Part_330_1290636507.1458502929035
Content-Type: multipart/alternative;
boundary="----=_Part_331_455272116.1458502929036"
------=_Part_331_455272116.1458502929036
Content-Type: text/plain; charset=UTF-8
On Sunday, March 20, 2016 at 2:15:23 PM UTC-4, Matthew Woehlke wrote:
>
> On 2016-03-19 15:58, Nicol Bolas wrote:
> > It is a mistake to add slicing to this idea. The primary reason is that,
> by
> > avoiding slicing, you ward off the "Let's do it in a library instead!"
> > folks.
>
> I took that approach with P0222 / P0224, and... it didn't work out :-).
> While I wasn't able to present those papers, I did receive feedback from
> a few people that separating the ideas was a mistake. When and if I
> resubmit them, it will be combined.
>
I'm not suggesting that you separate anything. I'm suggesting that you
*never* propose slicing at all. Don't even talk about it.
The feature is "turn a tuple into a parameter pack". Full Stop. Anything
more than that is something more than that. That's how you justify your
design: the feature is X.
It's probably a good idea to downplay slicing and focus on
> default-indexed unpacking and parameter pack indexing for at least the
> initial version of a paper. However, the impression I got of EWG is that
> it's important to provide as much supporting evidence as possible for
> why particular choices were made and why the feature is potentially
> worthwhile. To that effect, I think it's important to emphasize first
> that we *need* parameter pack indexing,
I don't agree that we need that. And your insistence on emphasizing that
will only lead to bad things.
Oh, I'd like to be able to do `pack[3]` and get a type/value from it. But
*need*? No. *Especially* when we're discussing tuples, where the answer is
just `get<3>(tpl)`.
Selecting a single element from a tuple (or a pack) is something that a
library can handle adequately. It's simple, trivial, doesn't make the code
harder to follow, and so forth. It's slightly more verbose than the direct
approach. But it's *functional*.
So what's the point of a language solution? It doesn't make the code
prettier, cleaner, or better in any objective way.
and that short-form common case
> tuple-like unpacking is important,
To me, the biggest justification for tuple-to-parameter-pack conversion is
how dysfunctional the library solutions are. Hana, and Boost.Fusion before
it, are perfect examples of the nightmare of code you have to write to do
simple things. The existence of two such libraries proves that there is a
genuine need, but the fact that the libraries create unreadable code proves
that there needs to be a language feature to simplify it.
but then to take the next step of
> presenting the complete case for using a unified syntax (and for `[:]`
> in particular) for the two.
>
But it's only "complete" in the sense that it does a bunch of stuff. From
the perspective of "turn a tuple into a parameter pack", what you're
proposing is overdesigned.
> That said... I note that once again we're discussing something in the
> future and not the goals of D0311 :-).
>
> > Your proposal talks about adding a bunch of changes to constexpr
> > functions, lambdas, and other things to allow computing of subsets.
>
> Uh... it does? (Are you talking about the pack generation stuff?)
>
> > So your alternative has to build up a bunch of language sub-features
> > to make it work, a whole different way of doing such computations.
>
> I think we're either not on the same page, or you seriously overestimate
> the complexity. Default-indexed unpacking already needs to build a pack
> of index access operations.
No, it doesn't. It will do whatever it is that it does to accomplish that.
You're specifying behavior, not *implementation*. And since this is a
language feature, the compiler should be allowed to do whatever it wants.
It doesn't actually have to call `std::get<#>` for aggregates that don't
have user-defined overloads. In those case, the compiler can generate far
more optimal code, since it knows exactly where the data members are.
With whole tuple-to-pack, the unpack expression `[:]agg + ...` can be
turned into `agg.x + agg.y + agg.z`, assuming `agg` has x, y, and z members.
Slicing needlessly complicates such simple code-generation functionality.
> Here is what code would have to look like to select every odd numbered
> > element from a tuple, under your method:
> >
> > [std::odd_elements(tpl):]tpl...
>
> Ah... no. That's not legal (in fact, it's syntactic garbage); the
> initial-index in that example is not an integer value. The indices
> *must* be constexpr integer values. The compiler already knows how to
> evaluate constexpr functions, so nothing new is added there.
>
You said:
> Moreover, the syntax can be readily extended to accept multiple values,
perhaps even :cpp:`constexpr` parameter packs, which would permit
discarding of specific elements, or even more complicated operations such
as selecting every other element in reverse order.
There is no such thing as "`constexpr` parameter packs". So the only way to
implement a constexpr function that could do that would be through some new
feature.
> Note that you have to pass the `tpl` twice, since `count_odd_elements`
> > needs to know how many are in the tuple. Or worse, `tuple_count(tpl)`.
>
> I can't think of a practical example where you wouldn't just use a
> negative index.
How would using a negative index equate to slicing a tuple of the odd
elements from another tuple?
And all of this stuff is purely at compile time, so who
> cares anyway?
>
I care about having to write the same variable name twice.
> > Here is what it would look like with a library solution, one that is
> > coupled with tuple pack expansion:
> >
> > [:](std::forward_odd_elements(tpl))...
>
> *That* would be legal :-). Daveed's proposal can possibly do this more
> efficiently, however. Note that I *like* Daveed's proposal.
>
What is "Daveed's proposal"? Your proposal doesn't mention it, and there is
nothing from this year or last year from anyone named Daveed with regard to
tuples and pack expansions. If we're talking about Daveed Vandevoorde, his
name has been formally attached to two proposal in the last 15 months: some
await-style continuations wording and working with lambda capture of
`*this` by value.
--
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/7a6256c3-9a42-4788-a8ac-ffdd5d95db6d%40isocpp.org.
------=_Part_331_455272116.1458502929036
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, March 20, 2016 at 2:15:23 PM UTC-4, Matthew Woe=
hlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-03-19 15:58=
, Nicol Bolas wrote:
<br>> It is a mistake to add slicing to this idea. The primary reason is=
that, by=20
<br>> avoiding slicing, you ward off the "Let's do it in a libr=
ary instead!"=20
<br>> folks.
<br>
<br>I took that approach with P0222 / P0224, and... it didn't work out =
:-).
<br>While I wasn't able to present those papers, I did receive feedback=
from
<br>a few people that separating the ideas was a mistake. When and if I
<br>resubmit them, it will be combined.<br></blockquote><div><br>I'm no=
t suggesting that you separate anything. I'm suggesting that you <i>nev=
er</i> propose slicing at all. Don't even talk about it.<br><br>The fea=
ture is "turn a tuple into a parameter pack". Full Stop. Anything=
more than that is something more than that. That's how you justify you=
r design: the feature is X.<br><br></div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;">
It's probably a good idea to downplay slicing and focus on
<br>default-indexed unpacking and parameter pack indexing for at least the
<br>initial version of a paper. However, the impression I got of EWG is tha=
t
<br>it's important to provide as much supporting evidence as possible f=
or
<br>why particular choices were made and why the feature is potentially
<br>worthwhile. To that effect, I think it's important to emphasize fir=
st
<br>that we *need* parameter pack indexing,</blockquote><div><br>I don'=
t agree that we need that. And your insistence on emphasizing that will onl=
y lead to bad things.<br><br>Oh, I'd like to be able to do `pack[3]` an=
d get a type/value from it. But <i>need</i>? No. <i>Especially</i> when we&=
#39;re discussing tuples, where the answer is just `get<3>(tpl)`.<br>=
<br>Selecting a single element from a tuple (or a pack) is something that a=
library can handle adequately. It's simple, trivial, doesn't make =
the code harder to follow, and so forth. It's slightly more verbose tha=
n the direct approach. But it's <i>functional</i>.<br><br>So what's=
the point of a language solution? It doesn't make the code prettier, c=
leaner, or better in any objective way.<br><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;">and that short-form common case
<br>tuple-like unpacking is important,</blockquote><div><br>To me, the bigg=
est justification for tuple-to-parameter-pack conversion=20
is how dysfunctional the library solutions are. Hana, and Boost.Fusion=20
before it, are perfect examples of the nightmare of code you have to=20
write to do simple things. The existence of two such libraries proves=20
that there is a genuine need, but the fact that the libraries create=20
unreadable code proves that there needs to be a language feature to=20
simplify it.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"> but=
then to take the next step of
<br>presenting the complete case for using a unified syntax (and for `[:]`
<br>in particular) for the two.<br></blockquote><div><br>But it's only =
"complete" in the sense that it does a bunch of stuff. From the p=
erspective of "turn a tuple into a parameter pack", what you'=
re proposing is overdesigned.<br>=C2=A0</div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;">
That said... I note that once again we're discussing something in the
<br>future and not the goals of D0311 :-).
<br>
<br>> Your proposal talks about adding a bunch of changes to constexpr
<br>> functions, lambdas, and other things to allow computing of subsets=
..
<br>
<br>Uh... it does? (Are you talking about the pack generation stuff?)
<br>
<br>> So your alternative has to build up a bunch of language sub-featur=
es
<br>> to make it work, a whole different way of doing such computations.
<br>
<br>I think we're either not on the same page, or you seriously overest=
imate
<br>the complexity. Default-indexed unpacking already needs to build a pack
<br>of index access operations.</blockquote><div><br>No, it doesn't. It=
will do whatever it is that it does to accomplish that. You're specify=
ing behavior, not <i>implementation</i>. And since this is a language featu=
re, the compiler should be allowed to do whatever it wants. It doesn't =
actually have to call `std::get<#>` for aggregates that don't hav=
e user-defined overloads. In those case, the compiler can generate far more=
optimal code, since it knows exactly where the data members are.<br><br>Wi=
th whole tuple-to-pack, the unpack expression `[:]agg + ...` can be turned =
into `agg.x + agg.y + agg.z`, assuming `agg` has x, y, and z members.<br><b=
r>Slicing needlessly complicates such simple code-generation functionality.=
<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
> Here is what code would have to look like to select every odd numbered=
=20
<br>> element from a tuple, under your method:
<br>>=20
<br>> [std::odd_elements(tpl):]tpl..<wbr>.
<br>
<br>Ah... no. That's not legal (in fact, it's syntactic garbage); t=
he
<br>initial-index in that example is not an integer value. The indices
<br>*must* be constexpr integer values. The compiler already knows how to
<br>evaluate constexpr functions, so nothing new is added there.
<br></blockquote><div><br>You said:<br><br>> Moreover, the syntax can be=
readily extended to accept multiple values, perhaps even :cpp:`constexpr` =
parameter packs, which would permit discarding of specific elements, or eve=
n more complicated operations such as selecting every other element in reve=
rse order.<br><br>There is no such thing as "`constexpr` parameter pac=
ks". So the only way to implement a constexpr function that could do t=
hat would be through some new feature.<br><br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;">
> Note that you have to pass the `tpl` twice, since `count_odd_elements`=
=20
<br>> needs to know how many are in the tuple. Or worse, `tuple_count(tp=
l)`.
<br>
<br>I can't think of a practical example where you wouldn't just us=
e a
<br>negative index.</blockquote><div><br>How would using a negative index e=
quate to slicing a tuple of the odd elements from another tuple?<br><br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;">And all of this stuff is pu=
rely at compile time, so who
<br>cares anyway?
<br></blockquote><div><br>I care about having to write the same variable na=
me twice.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
> Here is what it would look like with a library solution, one that is=
=20
<br>> coupled with tuple pack expansion:
<br>>=20
<br>> [:](std::forward_odd_elements(<wbr>tpl))...
<br>
<br>*That* would be legal :-). Daveed's proposal can possibly do this m=
ore
<br>efficiently, however. Note that I *like* Daveed's proposal.<br></bl=
ockquote><div><br>What is "Daveed's proposal"? Your proposal =
doesn't mention it, and there is nothing from this year or last year fr=
om anyone named Daveed with regard to tuples and pack expansions. If we'=
;re talking about Daveed Vandevoorde, his name has been formally attached t=
o two proposal in the last 15 months: some await-style continuations wordin=
g and working with lambda capture of `*this` by value.<br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7a6256c3-9a42-4788-a8ac-ffdd5d95db6d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7a6256c3-9a42-4788-a8ac-ffdd5d95db6d=
%40isocpp.org</a>.<br />
------=_Part_331_455272116.1458502929036--
------=_Part_330_1290636507.1458502929035--
.
Author: Larry Evans <cppljevans@suddenlink.net>
Date: Mon, 21 Mar 2016 02:15:05 -0500
Raw View
On 03/20/2016 10:21 PM, Tony V E wrote:
> Could the member access syntax actually be s[N] for some struct or class s?
>
> ie just extend operator[] to allow the return type to be different for different constexpr inputs.
>
I like this idea. I like it because it reflects that structs are
dependent product types, as described here:
https://en.wikipedia.org/wiki/Dependent_type
In the above, there's a type function B(x) which returns
a type, given and index, x. In the case of std::array,
that type function is constant, IOW, it doesn't vary with x.
IOW, for std::array<T,N>, B<I>::type for I=0...N-1, would be T.
(where, of course, B<I>::type is the type function, in C++ terms,
mentioned in the above web page).
--
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/nco71q%24l0p%241%40ger.gmane.org.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 21 Mar 2016 12:15:14 -0400
Raw View
On 2016-03-20 15:42, Nicol Bolas wrote:
> I'm not suggesting that you separate anything. I'm suggesting that you=20
> *never* propose slicing at all. Don't even talk about it.
>=20
> The feature is "turn a tuple into a parameter pack". Full Stop. Anything=
=20
> more than that is something more than that. That's how you justify your=
=20
> design: the feature is X.
That way lies... postfix `~`. Ick. Which... is the entire point=C2=B9 of
P0311 and the reason I've been debating syntax with Daniel; to *avoid*
having 2-3 new syntaxes where one would suffice.
(=C2=B9 Secondary point, anyway.)
> On Sunday, March 20, 2016 at 2:15:23 PM UTC-4, Matthew Woehlke wrote:
>> [...] I think it's important to emphasize first that we *need*
>> parameter pack indexing,
>=20
> I don't agree that we need that. And your insistence on emphasizing that=
=20
> will only lead to bad things.
I'd like to see you convince Daniel and/or Daveed of this.
>> and that short-form common case tuple-like unpacking is important,
>=20
> To me, the biggest justification for tuple-to-parameter-pack conversion i=
s=20
> how dysfunctional the library solutions are. Hana, and Boost.Fusion befor=
e=20
> it, are perfect examples of the nightmare of code you have to write to do=
=20
> simple things. The existence of two such libraries proves that there is a=
=20
> genuine need, but the fact that the libraries create unreadable code prov=
es=20
> that there needs to be a language feature to simplify it.
Again, my *main* use case (i.e. the one where I would use this feature
most) is where spelling out each element is annoyingly repetitive. If we
have some solution to this that takes half again as much typing as *just
writing the darn thing out the old way*, that makes the feature useless.
I can't and won't advocate that.
>> On 2016-03-19 15:58, Nicol Bolas wrote:=20
>>> So your alternative has to build up a bunch of language sub-features=20
>>> to make it work, a whole different way of doing such computations.=20
>>
>> I think we're either not on the same page, or you seriously overestimate=
=20
>> the complexity. Default-indexed unpacking already needs to build a pack=
=20
>> of index access operations.
>=20
> No, it doesn't. It will do whatever it is that it does to accomplish that=
..=20
> You're specifying behavior, not *implementation*.
Yes, and the *behavior* is that it constructs the parameter pack which
looks like `get<0>(__t), get<1>(__t), ...`. At least for some types.
(And even that's not true; considering P0197, this *is* how I would
specify the behavior, *full stop*. Doing otherwise just overcomplicates
things.)
> And since this is a language feature, the compiler should be allowed
> to do whatever it wants. It doesn't actually have to call
> `std::get<#>` for aggregates that don't have user-defined overloads.
> In those case, the compiler can generate far more optimal code, since
> it knows exactly where the data members are.
See previous comment. It can do this *under as-if*. I have no desire or
intention to *specify* the behavior this way.
> With whole tuple-to-pack, the unpack expression `[:]agg + ...` can be=20
> turned into `agg.x + agg.y + agg.z`, assuming `agg` has x, y, and z membe=
rs.
Yes... *after optimization*.
> Slicing needlessly complicates such simple code-generation functionality.
It doesn't. It *modifies the bounds* used to generate the pack. (Even
without going through indexed access, I would be surprised if this is as
hard for the compiler to accomplish as you are insinuating!)
>> Here is what code would have to look like to select every odd numbered=
=20
>>> element from a tuple, under your method:=20
>>>
>>> [std::odd_elements(tpl):]tpl...=20
>>
>> Ah... no. That's not legal (in fact, it's syntactic garbage); the=20
>> initial-index in that example is not an integer value. The indices=20
>> *must* be constexpr integer values. The compiler already knows how to=20
>> evaluate constexpr functions, so nothing new is added there.
>=20
> You said:
>> Moreover, the syntax can be readily extended to accept multiple values,=
=20
>> perhaps even :cpp:`constexpr` parameter packs, which would permit=20
>> discarding of specific elements, or even more complicated operations suc=
h=20
>> as selecting every other element in reverse order.
I said "can", *not "should"*. I also said (re-adding the part where you
take that out of context) "this may be an area that parameter pack
generators would serve better", and "there are complications with how to
implement expansion if a parameter pack is allowed as an index". As in
*I don't intend to propose this*. (on top of all that... this text isn't
in the final version of P0311. It's not even in the updated draft I
posted *prior* to your previous message.)
At best, `std::odd_elements` is a pack generator, and fold expressions
on CTI=C2=B2 are allowed. In that case... your example *might* be legal, bu=
t
it's almost certainly not what you intended:
[1:]tpl, [3:]tpl, [5:]tpl, ...
(...which is a list of parameter packs that still need to be expanded.
Which... I'm not actually sure is legal, or if it is, how you would use
it... At best, you're running afoul of the packs-of-packs problems.)
(=C2=B2 Compile-Time Indexing)
> There is no such thing as "`constexpr` parameter packs".
Parameter packs whose values are constexpr. If they aren't, you can't
use them for compile-time indexing.
>>> Note that you have to pass the `tpl` twice, since `count_odd_elements`=
=20
>>> needs to know how many are in the tuple. Or worse, `tuple_count(tpl)`.=
=20
>>
>> I can't think of a practical example where you wouldn't just use a=20
>> negative index.
>=20
> How would using a negative index equate to slicing a tuple of the odd=20
> elements from another tuple?
Because that doesn't work the way you think it does. I strongly question
the value of using packs as indices (see also following comment), and if
you aren't doing that, that leaves expressions like:
[3:tuple_size(t)]t;
[3:tuple_size(t) - 2]t;
....which are better written:
[3:]t;
[3:-2]t;
If you can show an example that *isn't* better written as a
tail-relative index or as a pure pack generator, that would be
interesting. So far, I haven't seen one.
>> And all of this stuff is purely at compile time, so who=20
>> cares anyway?=20
>=20
> I care about having to write the same variable name twice.
So... don't:
// ugly, maybe even illegal
[std::odd_indices(tpl)]tpl...
// better
std::odd_elements(tpl)...
>>> Here is what it would look like with a library solution, one that is=20
>>> coupled with tuple pack expansion:=20
>>>
>>> [:](std::forward_odd_elements(tpl))...=20
>>
>> *That* would be legal :-). Daveed's proposal can possibly do this more=
=20
>> efficiently, however. Note that I *like* Daveed's proposal.
>=20
> What is "Daveed's proposal"? Your proposal doesn't mention it,
- "A third is to create a parameter pack 'generator'."
- "various possible solutions have been suggested, including pack
generators"
- The entire "Pack Generation, Revisited" section.
- Many posts in this thread and Daniel's proposal thread.
> and there is nothing from this year or last year from anyone named
> Daveed with regard to tuples and pack expansions. If we're talking
> about Daveed Vandevoorde,
Yes, *that* Daveed. ("The" Daveed, AFAICT; see e.g. Tony's reply in this
thread :-).) Unless it's in the upcoming mailing, I don't believe he's
published it yet. I encouraged him to share with std-proposals, but so
far he hasn't commented on those requests.
--=20
Matthew
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ncp6mo%24258%241%40ger.gmane.org.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 21 Mar 2016 12:53:32 -0400
Raw View
On 2016-03-20 23:21, Tony V E wrote:
> Could the member access syntax actually be s[N] for some struct or class =
s?
>=20
> ie just extend operator[] to allow the return type to be different for di=
fferent constexpr inputs.=20
I think that way lies madness... too easy to confuse CTI=C2=B9 with RTI=C2=
=B2.
Using a separate syntax makes it clear which is happening, and doesn't
run into overload resolution problems for e.g. std::array that needs
both. Also...
(=C2=B9 Compile-Time Indexing)
(=C2=B2 Run-Time Indexing, obviously)
> Then arrays (and vectors, etc) 'just work'.
....I see this as a misfeature at best. CTI *shouldn't* work on vectors,
strings, or any dynamically sized object. In many contexts (both forms
of unpacking, for instance), it *can't* work because code generation is
dependent on the tuple size. Which... is another reason to use a
different syntax. Only a few types will implement both. (But a few types
*will* implement both; see also next comment.)
> I think it is safe to assume that any class that overrides
> operator[] wants to be array-like and doesn't want its members
> exposed as a tuple.
I disagree; an array (at least, a fixed-size array) *is* a tuple.
Specifically, an array is a subset of a tuple for which the elements all
have the same type.
--=20
Matthew
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ncp8uh%248ou%241%40ger.gmane.org.
.
Author: barry.revzin@gmail.com
Date: Mon, 21 Mar 2016 10:16:25 -0700 (PDT)
Raw View
------=_Part_1839_584254327.1458580585661
Content-Type: multipart/alternative;
boundary="----=_Part_1840_728806112.1458580585662"
------=_Part_1840_728806112.1458580585662
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Monday, March 21, 2016 at 11:53:52 AM UTC-5, Matthew Woehlke wrote:
>
> On 2016-03-20 23:21, Tony V E wrote:=20
> > Could the member access syntax actually be s[N] for some struct or clas=
s=20
> s?=20
> >=20
> > ie just extend operator[] to allow the return type to be different for=
=20
> different constexpr inputs.=20
>
> I think that way lies madness... too easy to confuse CTI=C2=B9 with RTI=
=C2=B2.=20
> Using a separate syntax makes it clear which is happening, and doesn't=20
> run into overload resolution problems for e.g. std::array that needs=20
> both. Also...=20
>
> (=C2=B9 Compile-Time Indexing)=20
> (=C2=B2 Run-Time Indexing, obviously)=20
>
Madness? This is C++!
Anyway, we basically have three categories: tuple (CTI only ever), vector=
=20
(RTI only ever), and array (both - which do the same thing really, except=
=20
CTI gives some nice safety mechanisms). We have std::get<I> for CTI, but=
=20
that's because it was created as a library to support tuple, right? Is=20
there a conceptual reason why we wouldn't want tuple[0] to work and do=20
something like call tuple.operator[](integral_constant<size_t, 0> ) (or=20
std::get<0>(tuple) or something else along these lines)?=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/5544dac2-1449-4039-89b9-e72e98a3db36%40isocpp.or=
g.
------=_Part_1840_728806112.1458580585662
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, March 21, 2016 at 11:53:52 AM UTC-5, Ma=
tthew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-03=
-20 23:21, Tony V E wrote:
<br>> Could the member access syntax actually be s[N] for some struct or=
class s?
<br>>=20
<br>> ie just extend operator[] to allow the return type to be different=
for different constexpr inputs.=20
<br>
<br>I think that way lies madness... too easy to confuse CTI=C2=B9 with RTI=
=C2=B2.
<br>Using a separate syntax makes it clear which is happening, and doesn=
9;t
<br>run into overload resolution problems for e.g. std::array that needs
<br>both. Also...
<br>
<br>(=C2=B9 Compile-Time Indexing)
<br>(=C2=B2 Run-Time Indexing, obviously)
<br></blockquote><div><br></div><div>Madness? This is C++!</div><div><br></=
div><div>Anyway, we basically have three categories: tuple (CTI only ever),=
vector (RTI only ever), and array (both - which do the same thing really, =
except CTI gives some nice safety mechanisms). =C2=A0We have std::get<I&=
gt; for CTI, but that's because it was created as a library to support =
tuple, right? Is there a conceptual reason why we wouldn't want tuple[0=
] to work and do something like call tuple.operator[](integral_constant<=
size_t, 0> ) (or std::get<0>(tuple) or something else along these =
lines)?=C2=A0</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5544dac2-1449-4039-89b9-e72e98a3db36%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5544dac2-1449-4039-89b9-e72e98a3db36=
%40isocpp.org</a>.<br />
------=_Part_1840_728806112.1458580585662--
------=_Part_1839_584254327.1458580585661--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 21 Mar 2016 13:26:07 -0400
Raw View
On 2016-03-21 13:16, barry.revzin@gmail.com wrote:
> On Monday, March 21, 2016 at 11:53:52 AM UTC-5, Matthew Woehlke wrote:
>> On 2016-03-20 23:21, Tony V E wrote:=20
>>> ie just extend operator[] to allow the return type to be different for=
=20
>>> different constexpr inputs.=20
>>
>> I think that way lies madness... too easy to confuse CTI=C2=B9 with RTI=
=C2=B2.=20
>> Using a separate syntax makes it clear which is happening, and doesn't=
=20
>> run into overload resolution problems for e.g. std::array that needs=20
>> both.
>=20
> Madness? This is C++!
Hah! :-)
"We're all mad here. I'm mad. You're mad."
"How do you know I'm mad?"
"You must be, or you wouldn't write C++..."
(With apologies to Lewis Carroll.)
> Anyway, we basically have three categories: tuple (CTI only ever), vector=
=20
> (RTI only ever), and array (both - which do the same thing really, except=
=20
> CTI gives some nice safety mechanisms). We have std::get<I> for CTI, but
> that's because it was created as a library to support tuple, right? Is=20
> there a conceptual reason why we wouldn't want tuple[0] to work and do=20
> something like call tuple.operator[](integral_constant<size_t, 0> ) (or=
=20
> std::get<0>(tuple) or something else along these lines)?=20
I could conceive of std::tuple at some point getting RTI `std::any
operator[]`. Or at least, some user type that is otherwise most like
std::tuple having something of that nature. This way lies the madness of
which I spoke. (Which one you call suddenly depends on if the index
expression is constexpr or not. Yuck.)
Even without that, I don't think suddenly allowing one syntax to mean
two non-trivially different things is a good idea.
--=20
Matthew
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ncparh%2499g%241%40ger.gmane.org.
.
Author: Daniel Frey <d.frey@gmx.de>
Date: Mon, 21 Mar 2016 18:46:07 +0100
Raw View
> On 21.03.2016, at 18:26, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote:
>
> I could conceive of std::tuple at some point getting RTI `std::any
> operator[]`. Or at least, some user type that is otherwise most like
> std::tuple having something of that nature. This way lies the madness of
> which I spoke. (Which one you call suddenly depends on if the index
> expression is constexpr or not. Yuck.)
No one would want to return `std::any`. The idea is:
template<size_t N>
auto tuple::operator[]( std::integral_constant<size_t,N> )
{
return get<N>(*this);
}
being callable with just
tuple<...> t;
t[0]; // automatically uses above tuple::operator[] with deduced N
Even if not via templated ctors and instead using some explicit overloading on constexpr, we want to return type to depend on N, not some wrapper like std::any.
-- Daniel
--
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/8F16843C-EC5D-46CA-B8C7-6FD07508CE80%40gmx.de.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 21 Mar 2016 13:56:24 -0400
Raw View
On 2016-03-21 13:36, Daniel Frey wrote:
> I fail to see why "confusing" CTI and RTI is a problem. If you misuse
> overloading or basically any other feature you will get confusing
> syntax or semantics. But that doesn't mean that it's bad if used for
> the right use-cases and to me, this is one of the obvious use-cases.
> Provide access to a tuple's elements via tuple::operator[].
Given a hypothetical (*RTI*) `std::any std::tuple::operator[]`:
auto t = std::tuple<int, float>{};
auto x = tuple[foo()];
....what is decltype(x)? int/float? std::any? I need to inspect `foo()`
to try to determine if the value is constexpr or not.
Even worse:
constexpr inline auto foo(auto tuple, int x)
{
return tuple[x];
}
foo(t, 0); // CTI? RTI?
foo(t, opaque()); // RTI
I'm not sure the above could even be legal (at best, it would have to
never use CTI even though it could). Compare:
constexpr inline auto foo(auto tuple, int x)
{
return [x]tuple; // error if x isn't constexpr
}
constexpr int i = ...;
foo(t, 0); // okay
foo(t, i); // okay
foo(t, opaque()); // error
CTI != RTI. They shouldn't use the same syntax.
On 2016-03-21 13:46, Daniel Frey wrote:
> No one would want to return `std::any`.
How do you know? (Note I'm talking about *RTI* here... the return value
*cannot* depend on the index, and so you *must* use something like
std::any. The question is if you would want RTI, and I assert you can't
just declare that "no one ever will", especially not for all user types.)
--
Matthew
--
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/ncpck9%247pe%241%40ger.gmane.org.
.
Author: barry.revzin@gmail.com
Date: Mon, 21 Mar 2016 11:10:07 -0700 (PDT)
Raw View
------=_Part_247_435261156.1458583807185
Content-Type: multipart/alternative;
boundary="----=_Part_248_2051905124.1458583807185"
------=_Part_248_2051905124.1458583807185
Content-Type: text/plain; charset=UTF-8
>
> Given a hypothetical (*RTI*) `std::any std::tuple::operator[]`:
>
> [...]
>
That sounds like a really good argument for not having CTI and RTI, where
both supported, do entirely different things. And, by extension, sounds
like a really good argument for not having RTI for tuple. And if somebody
wants to implement that for their own type... well, fine, there's already
all sorts of places in the language where people can choose to write things
that are really confusing. I can already write a container where non-const
find() actually inserts 10,000 elements, sends me an email, and returns the
3982374th digit of pi and const find() actually does a lookup and gives me
an iterator. That... would be comically awful, but it's just an instance of
bad design... not really against supporting it as a language feature.
It doesn't address why not CTI operator[] for tuple though.
--
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/ef753ff7-07f1-448d-9772-cc8c9b6bb7b8%40isocpp.org.
------=_Part_248_2051905124.1458583807185
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Given a hypot=
hetical (*RTI*) `std::any std::tuple::operator[]`:
<br>
<br>=C2=A0 [...]<br></blockquote><div><br></div><div>That sounds like a rea=
lly good argument for not having CTI and RTI, where both supported, do enti=
rely different things. And, by extension, sounds like a really good argumen=
t for not having RTI for tuple. And if somebody wants to implement that for=
their own type... well, fine, there's already all sorts of places in t=
he language where people can choose to write things that are really confusi=
ng. I can already write a container where non-const find() actually inserts=
10,000 elements, sends me an email, and returns the 3982374th digit of pi =
and const find() actually does a lookup and gives me an iterator. That... w=
ould be comically awful, but it's just an instance of bad design... not=
really against supporting it as a language feature.=C2=A0</div><div><br></=
div><div>It doesn't address why not CTI operator[] for tuple though.=C2=
=A0</div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ef753ff7-07f1-448d-9772-cc8c9b6bb7b8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ef753ff7-07f1-448d-9772-cc8c9b6bb7b8=
%40isocpp.org</a>.<br />
------=_Part_248_2051905124.1458583807185--
------=_Part_247_435261156.1458583807185--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 21 Mar 2016 14:27:48 -0400
Raw View
On 2016-03-21 14:10, barry.revzin@gmail.com wrote:
>> Given a hypothetical (*RTI*) `std::any std::tuple::operator[]`:
>>
>> [...]
>
> That [...] sounds
> like a really good argument for not having RTI for tuple.
No; not having something because it would be confusing *because we
insisted on shoehorning two different features into the same syntax*
sounds like a terrible argument. It sounds like a case of "what were you
thinking when you made that design decision?".
> It doesn't address why not CTI operator[] for tuple though.
I really, honestly, genuinely don't understand why people want to abuse
RTI syntax for something that *is not RTI*.
CTI != RTI. Quit trying to pretend otherwise. It's not worth it.
(I also don't understand why people seem to think that prefix [] is the
end of the world...)
I want to access the N'th element of 'foo'
-> Use []'s
-> Do you want the access to happen at compile time or run time?
-> Compile time -> [N]foo
-> Run time -> foo[N]
Why is this so hard?
--
Matthew
--
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/ncpef4%245eo%241%40ger.gmane.org.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 21 Mar 2016 14:44:56 -0400
Raw View
On 2016-03-21 14:20, Daniel Frey wrote:
> On 21.03.2016, at 18:56, Matthew Woehlke wrote:
>> Given a hypothetical (*RTI*) `std::any std::tuple::operator[]`:
>
> Are you misreading what I said? tuple::operator[] is CTI only, there
> is no confusion with RTI because tuple::operator[] is not a use-case for
> overloading both.
I'm not misreading; *you* are *ignoring* what I am trying to say, which
is that this is a pointless, unnecessary, and potentially undesirable
*artifically* limitation that is imposed by your design choice.
> Only if a use-case has "obvious", non-confusing semantics, one would overload both.
Even here, the code intent becomes less clear. For example:
auto fifth(Vector& array)
{
return array[5];
}
Let `Vector` be a Concept that requires array-like semantics. In
particular, let's say that both std::array and std::vector satisfy the
Concept. Can `fifth` throw? Is the array access run-time or compile-time?
You're mixing two non-trivially different options in a way that
potentially makes it unclear which one is being used.
>> auto t = std::tuple<int, float>{};
>> auto x = tuple[foo()];
>
> I assume the second line is "auto x = t[foo()];".
Ack, yes :-).
> Anyways, if t is a tuple, foo() *must* return a constexpr.
Again, that's an artificial limitation that *you* have imposed.
> Again, tuple should not have RTI operator[].
Why not? Give me a good reason that has nothing to do with your desire
to hijack the syntax (because that's a poor reason, and also a circular
argument).
This isn't irrelevant. Your proposal will have reprecussions, namely,
limiting expressiveness by making it impossible, or at least very, very
ugly, to provide both CTI and RTI for heterogeneous product types. If
you're going to do that, the onus should be on you to show why having
both would always be a bad thing, and therefore is an acceptable cost of
your proposal (without simply arguing in circles).
--
Matthew
--
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/ncpff9%24m26%241%40ger.gmane.org.
.
Author: Daniel Frey <d.frey@gmx.de>
Date: Mon, 21 Mar 2016 19:46:56 +0100
Raw View
> On 21.03.2016, at 19:27, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote=
:
>=20
> On 2016-03-21 14:10, barry.revzin@gmail.com wrote:
>>> Given a hypothetical (*RTI*) `std::any std::tuple::operator[]`:=20
>>>=20
>>> [...]
>>=20
>> That [...] sounds=20
>> like a really good argument for not having RTI for tuple.
>=20
> No; not having something because it would be confusing *because we
> insisted on shoehorning two different features into the same syntax*
> sounds like a terrible argument. It sounds like a case of "what were you
> thinking when you made that design decision?".
>=20
>> It doesn't address why not CTI operator[] for tuple though.
>=20
> I really, honestly, genuinely don't understand why people want to abuse
> RTI syntax for something that *is not RTI*.
>=20
> CTI !=3D RTI. Quit trying to pretend otherwise. It's not worth it.
....
> (I also don't understand why people seem to think that prefix [] is the
> end of the world...)
>=20
> I want to access the N'th element of 'foo'
> -> Use []'s
> -> Do you want the access to happen at compile time or run time?
> -> Compile time -> [N]foo
> -> Run time -> foo[N]
>=20
> Why is this so hard?
Because some people feel the exact opposite. What is so hard about using t[=
N]? I don't see *anything* wrong with it, the context makes it completely o=
bvious and straight-forward to me. Should I add phrases like: Open your min=
d and quit pretending there's a problem. Why is this so hard? It's not wort=
h it. :)
Also, it makes the whole discussion really hard as I feel that you are not =
even considering "the other side". You are convinced that your way is the r=
ight way and your wording does not show any openness towards other people's=
opinions. At least myself, I find prefix indexing an abomination, I have n=
ever seen any language that has anything similar (e.g. on http://rigaux.org=
/language-study/syntax-across-languages/).
In fact, I think that your prefix operator[] is as inconsistent as choosing=
/mixing CTI/RTI on postfix operator[], just in a different dimension. You s=
ay it's prefix if it's CTI, postfix if RTI. Consistent in this dimension, b=
ut considering that you are using it for both packs and non-packs, you are =
inconsistent in that. For what I am proposing, you have CTI operator[] for =
non-packs and ...[] for packs (implicitly CTI only). Your suggestion is not=
purely better, it is trading one advantage with one disadvantage (syntax-w=
ise).
-- Daniel
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/AC60D68D-7006-453F-8708-4E5476FFCB3E%40gmx.de.
.
Author: Daniel Frey <d.frey@gmx.de>
Date: Mon, 21 Mar 2016 19:54:50 +0100
Raw View
--Apple-Mail=_10AEE1E6-3A0A-4F41-AAD1-6B56CB875318
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 21.03.2016, at 19:44, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote=
:
>=20
> On 2016-03-21 14:20, Daniel Frey wrote:
>> On 21.03.2016, at 18:56, Matthew Woehlke wrote:
>>> Given a hypothetical (*RTI*) `std::any std::tuple::operator[]`:
>>=20
>> Are you misreading what I said? tuple::operator[] is CTI only, there
>> is no confusion with RTI because tuple::operator[] is not a use-case for
>> overloading both.
>=20
> I'm not misreading; *you* are *ignoring* what I am trying to say, which
> is that this is a pointless, unnecessary, and potentially undesirable
> *artifically* limitation that is imposed by your design choice.
And I feel *you* are ignoring what *I* am saying. I'm tired of discussing t=
his, so whatever, you "win". Congrats, you've simply demotivated me enough.=
I don't give up because I think you have the better arguments, I just give=
up because it's pointless and I think you are simply not open to other peo=
ple's views, options and arguments.
-- Daniel
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CD7868FF-D3D6-462C-B65E-C9CCA7F8B012%40gmx.de.
--Apple-Mail=_10AEE1E6-3A0A-4F41-AAD1-6B56CB875318
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename=signature.asc
Content-Type: application/pgp-signature;
name=signature.asc
Content-Description: Message signed with OpenPGP using GPGMail
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - https://gpgtools.org
iEYEARECAAYFAlbwQ3oACgkQAUxJbew56yHGjwCgqpx+umQJhNf7Kc5IPS9F3qD7
GVQAoMY7NsgDSamb7sP6CVh0V6HDUd2t
=52ql
-----END PGP SIGNATURE-----
--Apple-Mail=_10AEE1E6-3A0A-4F41-AAD1-6B56CB875318--
.
Author: Jim Porter <jvp4846@g.rit.edu>
Date: Mon, 21 Mar 2016 15:08:53 -0500
Raw View
On 3/21/2016 1:44 PM, Matthew Woehlke wrote:
> auto fifth(Vector& array)
> {
> return array[5];
> }
>
> Let `Vector` be a Concept that requires array-like semantics. In
> particular, let's say that both std::array and std::vector satisfy the
> Concept. Can `fifth` throw? Is the array access run-time or compile-time?
Even with your proposed prefix-[] (and modifying `fifth` to use it), you
still can't answer either of your questions. The only way you can know
if it will throw is to know the implementation of the underlying type.
Even constexpr functions are allowed to throw, since they may be
evaluated at runtime according to how they're used. (constexpr functions
can also "throw" at compile time in which case the program is ill-formed
and you get a compiler error, but that's beside the point.[1])
Unless I'm mistaken, the array access here is always at run-time because
`fifth` isn't marked constexpr. However, assuming it were, there's still
no guarantee because `array` may not be a constexpr value. Again, you'd
have to examine the point-of-use to answer this question.
However, I'm assuming that the real reason you'd want CTI for std::array
is to get compile-time *bounds checking*. As I'm sure you know, this
isn't possible today with function parameter (hence why std::get uses a
non-type template parameter instead), hence why your proposal contains
the following syntax:
operator get(auto& tuple, constexpr size_t i);
Note especially the `constexpr`. Your paper doesn't elaborate on the
semantics of applying constexpr to a function parameter (and I didn't
see it earlier in the thread, but I may have just missed it), so I'll
assume that it means "this argument *must* be constexpr". Then you'd
just do the same thing std::get does, and presto, compile-time bounds
checking!
Of course, this feature would be useful for other things than CTI, so I
would expect it to be usable by any function (e.g. a printf clone?).
With such a feature it's possible, though not necessarily recommended,
to implement CTI using the current operator[].
Leading from this, one question is: should it be possible to overload a
function based on the constexpr-ness of its parameters? If no, then
you'd need different syntaxes for CTI and RTI. If yes, there's no
technical need for prefix-[], and I'd just as soon avoid adding it.
- Jim
[1] Note that GCC 5 has a bug preventing throw expressions in
unevaluated contexts in C++14 generalized constexpr:
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67371>.
--
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/ncpkcr%24848%241%40ger.gmane.org.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 21 Mar 2016 16:47:47 -0400
Raw View
On 2016-03-21 16:08, Jim Porter wrote:
> On 3/21/2016 1:44 PM, Matthew Woehlke wrote:
>> auto fifth(Vector& array)
>> {
>> return array[5];
>> }
>>
>> Let `Vector` be a Concept that requires array-like semantics. In
>> particular, let's say that both std::array and std::vector satisfy the
>> Concept. Can `fifth` throw? Is the array access run-time or compile-time?
>
> Even with your proposed prefix-[] (and modifying `fifth` to use it), you
> still can't answer either of your questions.
Hmm... okay, I agree that the actual type might throw for some other
reason. However, I can be sure that range checking occurs at compile
time, because I have explicitly used a compile-time operation.
> Unless I'm mistaken, the array access here is always at run-time because
> `fifth` isn't marked constexpr.
Define "access"? The "body" of `fifth`, if using CTI, will be something
like `return *(array.data + 5);`. In the sense that accessing `array`
happens at run-time, that's correct. The code to access the fifth
element is guaranteed to be literal, however. (At worst, it will call
the mangled form of `get<5>(array)`.)
> hence why your proposal contains the following syntax:
>
> operator get(auto& tuple, constexpr size_t i);
>
> Your paper doesn't elaborate on the semantics of applying constexpr
> to a function parameter
....because that's entirely beside the point. There are *no proposed
features* in P0311. Don't read too much into this. This was just an
off-the-cuff thought what the customization point for tuple-likes
*might* look like if it isn't `get<>`.
> (and I didn't see it earlier in the thread, but I may have just
> missed it), so I'll assume that it means "this argument *must* be
> constexpr". Then you'd just do the same thing std::get does, and
> presto, compile-time bounds checking!
Something like that. More to the point, the operator would be forcibly
inlined (because the return type is variable) and the body would likely
have a bunch of `if constexpr (i == ...)`.
--
Matthew
--
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/ncpmlj%24bra%241%40ger.gmane.org.
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Mon, 21 Mar 2016 22:12:25 +0100
Raw View
Le 21/03/2016 19:46, Daniel Frey a =C3=A9crit :
>> On 21.03.2016, at 19:27, Matthew Woehlke <mwoehlke.floss@gmail.com> wrot=
e:
>>
>> On 2016-03-21 14:10, barry.revzin@gmail.com wrote:
>>>> Given a hypothetical (*RTI*) `std::any std::tuple::operator[]`:
>>>>
>>>> [...]
>>> That [...] sounds
>>> like a really good argument for not having RTI for tuple.
>> No; not having something because it would be confusing *because we
>> insisted on shoehorning two different features into the same syntax*
>> sounds like a terrible argument. It sounds like a case of "what were you
>> thinking when you made that design decision?".
>>
>>> It doesn't address why not CTI operator[] for tuple though.
>> I really, honestly, genuinely don't understand why people want to abuse
>> RTI syntax for something that *is not RTI*.
>>
>> CTI !=3D RTI. Quit trying to pretend otherwise. It's not worth it.
> ...
>
>> (I also don't understand why people seem to think that prefix [] is the
>> end of the world...)
>>
>> I want to access the N'th element of 'foo'
>> -> Use []'s
>> -> Do you want the access to happen at compile time or run time?
>> -> Compile time -> [N]foo
>> -> Run time -> foo[N]
>>
>> Why is this so hard?
> Because some people feel the exact opposite. What is so hard about using =
t[N]? I don't see *anything* wrong with it, the context makes it completely=
obvious and straight-forward to me. Should I add phrases like: Open your m=
ind and quit pretending there's a problem. Why is this so hard? It's not wo=
rth it. :)
>
> Also, it makes the whole discussion really hard as I feel that you are no=
t even considering "the other side". You are convinced that your way is the=
right way and your wording does not show any openness towards other people=
's opinions. At least myself, I find prefix indexing an abomination, I have=
never seen any language that has anything similar (e.g. on http://rigaux.o=
rg/language-study/syntax-across-languages/).
>
> In fact, I think that your prefix operator[] is as inconsistent as choosi=
ng/mixing CTI/RTI on postfix operator[], just in a different dimension. You=
say it's prefix if it's CTI, postfix if RTI. Consistent in this dimension,=
but considering that you are using it for both packs and non-packs, you ar=
e inconsistent in that. For what I am proposing, you have CTI operator[] fo=
r non-packs and ...[] for packs (implicitly CTI only). Your suggestion is n=
ot purely better, it is trading one advantage with one disadvantage (syntax=
-wise).
>
>
I don't like [N]t neither. I would like also t[N], but reusing the=20
operator[](unsigned) will need some additional changes in the languages=20
that we don't have yet (that is Dependent types as Larry Evans pointed=20
out). This is a quite complex subject and I will prefer to stay on=20
something that is already available, like=20
operator[](integral_constant<unsigned, N>). It is not as elegant but=20
using User defined literals it could be acceptable.
auto x =3D t[1_c];
Maybe we could consider different syntax for the customization point and=20
the user interface, I don't know.
Vicente
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/56F063B9.4080201%40wanadoo.fr.
.
Author: Jim Porter <jvp4846@g.rit.edu>
Date: Mon, 21 Mar 2016 17:52:46 -0500
Raw View
On 3/21/2016 4:24 PM, Vicente J. Botet Escriba wrote:
> Not with the current standard. We can not qualify a parameter with
> constexpr. Well, I believe that there was no adopted proposal for that yet.
Correct. But I imagine that a feature like this proposal would use
constexpr function parameters, and the implementation details of that
would have a significant impact on this proposal's interface.
- Jim
--
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/ncpu05%244ef%241%40ger.gmane.org.
.
Author: Larry Evans <cppljevans@suddenlink.net>
Date: Tue, 22 Mar 2016 04:31:40 -0500
Raw View
On 03/21/2016 12:56 PM, Matthew Woehlke wrote:
> On 2016-03-21 13:36, Daniel Frey wrote:
>> I fail to see why "confusing" CTI and RTI is a problem. If you misuse
>> overloading or basically any other feature you will get confusing
>> syntax or semantics. But that doesn't mean that it's bad if used for
>> the right use-cases and to me, this is one of the obvious use-cases.
>> Provide access to a tuple's elements via tuple::operator[].
>
> Given a hypothetical (*RTI*) `std::any std::tuple::operator[]`:
>
> auto t = std::tuple<int, float>{};
> auto x = tuple[foo()];
I assume you meant:
auto x = t[foo()]
where foo is declared as:
int foo();
or:
constexpr int foo();
>
> ...what is decltype(x)? int/float? std::any?
The return type should be:
std::variant<int, float>
or:
constexpr std::variant<int, float>
depending on how foo() was declared.
> I need to inspect `foo()`
> to try to determine if the value is constexpr or not.
>
> Even worse:
>
> constexpr inline auto foo(auto tuple, int x)
> {
> return tuple[x];
> }
>
> foo(t, 0); // CTI? RTI?
> foo(t, opaque()); // RTI
>
> I'm not sure the above could even be legal (at best, it would have to
> never use CTI even though it could). Compare:
>
> constexpr inline auto foo(auto tuple, int x)
> {
> return [x]tuple; // error if x isn't constexpr
> }
>
> constexpr int i = ...;
> foo(t, 0); // okay
> foo(t, i); // okay
> foo(t, opaque()); // error
>
> CTI != RTI. They shouldn't use the same syntax.
>
OK. I see your point. But maybe something similar:
operator[]
for RTI, but:
operator.[]
for CTI. This, being similar syntax, suggests to the programmer,
the similarity between the operations. Also, the . part of the
operator suggests struct member access and that's essentially
what get<I>(tuple) is doing. So, the .[] combination would seem
more intuitive to present day programmers.
-regards,
Larry
--
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/ncr3ds%24v5n%241%40ger.gmane.org.
.
Author: Larry Evans <cppljevans@suddenlink.net>
Date: Fri, 1 Apr 2016 03:53:07 -0500
Raw View
On 03/31/2016 11:51 PM, Tony V E wrote:
>> =E2=80=8E Nobody has proposed yet the field syntax s.N.
>=20
>> This will allow to have a constexpr index access a.N and a runtime one=
=20
> a[n] for std::array.
>=20
> =E2=80=8EWorks well for a.5, not so well for a.someConstant. =20
>=20
> But a.<5> and a.<someConstant> might work.
As might:
unsigned const I=3D0;
a.[I]+a.[I+1]
which was proposed elsewhere:
https://groups.google.com/a/isocpp.org/d/msg/std-proposals/5oJkfjjqEdY/Wm4e=
mriFCgAJ
>=20
> Sent from my BlackBerry portable Babbage Device
> Original Message =20
> From: Vicente J. Botet Escriba
> Sent: Thursday, March 31, 2016 6:50 PM
> To: std-proposals@isocpp.org
> Reply To: std-proposals@isocpp.org
> Subject: Re: [std-proposals] Re: [RFC] Call for considering "the big pict=
ure" re: tuples and parameter packs
>=20
> Le 21/03/2016 04:21, Tony V E a =C3=A9crit :
>> Could the member access syntax actually be s[N] for some struct or class=
s?
>>
>> ie just extend operator[] to allow the return type to be different for d=
ifferent constexpr inputs.
>>
>> Then arrays (and vectors, etc) 'just work'. This assumes you never want =
to access the actual members of vector (ie v._ptr and v._size or whatever t=
he vector implementation uses). I think it is safe to assume that any class=
that overrides operator[] wants to be array-like and doesn't want its memb=
ers exposed as a tuple.
>>
>> ?
>=20
> Nobody has proposed yet the field syntax s.N.
>=20
> This will allow to have a constexpr index access a.N and a runtime one=20
> a[n] for std::array.
>=20
[snip]
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ndlctj%24d50%241%40ger.gmane.org.
.