Topic: [RFC] #pragma once... yes, really... (concrete proposal)


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 27 Oct 2016 12:34:21 -0400
Raw View
This is a multi-part message in MIME format.
--------------010703060306050003000205
Content-Type: text/plain; charset=UTF-8

After the recent thread rehashing this yet again, I'm sure some folks
will be surprised to see me on the other side of the issue. However, all
the noise got me to thinking how we might actually do this correctly...

This is *not* a proposal for *unqualified* `#pragma once` (it is
mentioned in the paper, but remains explicitly implementation defined).
Instead, it proposes a *qualified* `#pragma once(identifier)` which
solves the problems of unqualified `#pragma once` (by being semantically
equivalent to correctly used traditional guards). The problem of
choosing the correct identifier is addressed by making the identifier a
qualified C++ identifier, such that it is easy for static analysis tools
to enforce that the (final part of the) identifier matches the header
file name (ideally this would be a compiler warning that many projects
would promote to an error by default). A versioning system is also
proposed to catch errors where multiple (possibly incompatible) versions
of the same header are referenced.

Draft proposal attached. Please let me know what you think!

--
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/58122C8D.9060205%40gmail.com.

--------------010703060306050003000205
Content-Type: text/html; charset=UTF-8;
 name="dxxxx-pragma-once.html"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="dxxxx-pragma-once.html"

PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjwhRE9DVFlQRSBodG1s
IFBVQkxJQyAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFRyYW5zaXRpb25hbC8vRU4iICJodHRw
Oi8vd3d3LnczLm9yZy9UUi94aHRtbDEvRFREL3hodG1sMS10cmFuc2l0aW9uYWwuZHRkIj4K
PGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHhtbDpsYW5nPSJl
biIgbGFuZz0iZW4iPgo8aGVhZD4KPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBj
b250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiIC8+CjxtZXRhIG5hbWU9ImdlbmVy
YXRvciIgY29udGVudD0iRG9jdXRpbHMgMC4xMjogaHR0cDovL2RvY3V0aWxzLnNvdXJjZWZv
cmdlLm5ldC8iIC8+Cjx0aXRsZT5RdWFsaWZpZWQgI3ByYWdtYSBvbmNlPC90aXRsZT4KPG1l
dGEgbmFtZT0iZGF0ZSIgY29udGVudD0iMjAxNi0xMC0yNyIgLz4KPG1ldGEgbmFtZT0iYXV0
aG9yIiBjb250ZW50PSJNYXR0aGV3IFdvZWhsa2UgKG13b2VobGtlLmZsb3NzJiM2NDtnbWFp
bC5jb20pIiAvPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoKLyoKOkF1dGhvcjogRGF2aWQg
R29vZGdlciAoZ29vZGdlckBweXRob24ub3JnKQo6SWQ6ICRJZDogaHRtbDRjc3MxLmNzcyA3
NjE0IDIwMTMtMDItMjEgMTU6NTU6NTFaIG1pbGRlICQKOkNvcHlyaWdodDogVGhpcyBzdHls
ZXNoZWV0IGhhcyBiZWVuIHBsYWNlZCBpbiB0aGUgcHVibGljIGRvbWFpbi4KCkRlZmF1bHQg
Y2FzY2FkaW5nIHN0eWxlIHNoZWV0IGZvciB0aGUgSFRNTCBvdXRwdXQgb2YgRG9jdXRpbHMu
CgpTZWUgaHR0cDovL2RvY3V0aWxzLnNmLm5ldC9kb2NzL2hvd3RvL2h0bWwtc3R5bGVzaGVl
dHMuaHRtbCBmb3IgaG93IHRvCmN1c3RvbWl6ZSB0aGlzIHN0eWxlIHNoZWV0LgoqLwoKLyog
dXNlZCB0byByZW1vdmUgYm9yZGVycyBmcm9tIHRhYmxlcyBhbmQgaW1hZ2VzICovCi5ib3Jk
ZXJsZXNzLCB0YWJsZS5ib3JkZXJsZXNzIHRkLCB0YWJsZS5ib3JkZXJsZXNzIHRoIHsKICBi
b3JkZXI6IDAgfQoKdGFibGUuYm9yZGVybGVzcyB0ZCwgdGFibGUuYm9yZGVybGVzcyB0aCB7
CiAgLyogT3ZlcnJpZGUgcGFkZGluZyBmb3IgInRhYmxlLmRvY3V0aWxzIHRkIiB3aXRoICIh
IGltcG9ydGFudCIuCiAgICAgVGhlIHJpZ2h0IHBhZGRpbmcgc2VwYXJhdGVzIHRoZSB0YWJs
ZSBjZWxscy4gKi8KICBwYWRkaW5nOiAwIDAuNWVtIDAgMCAhIGltcG9ydGFudCB9CgouZmly
c3QgewogIC8qIE92ZXJyaWRlIG1vcmUgc3BlY2lmaWMgbWFyZ2luIHN0eWxlcyB3aXRoICIh
IGltcG9ydGFudCIuICovCiAgbWFyZ2luLXRvcDogMCAhIGltcG9ydGFudCB9CgoubGFzdCwg
LndpdGgtc3VidGl0bGUgewogIG1hcmdpbi1ib3R0b206IDAgISBpbXBvcnRhbnQgfQoKLmhp
ZGRlbiB7CiAgZGlzcGxheTogbm9uZSB9CgphLnRvYy1iYWNrcmVmIHsKICB0ZXh0LWRlY29y
YXRpb246IG5vbmUgOwogIGNvbG9yOiBibGFjayB9CgpibG9ja3F1b3RlLmVwaWdyYXBoIHsK
ICBtYXJnaW46IDJlbSA1ZW0gOyB9CgpkbC5kb2N1dGlscyBkZCB7CiAgbWFyZ2luLWJvdHRv
bTogMC41ZW0gfQoKb2JqZWN0W3R5cGU9ImltYWdlL3N2Zyt4bWwiXSwgb2JqZWN0W3R5cGU9
ImFwcGxpY2F0aW9uL3gtc2hvY2t3YXZlLWZsYXNoIl0gewogIG92ZXJmbG93OiBoaWRkZW47
Cn0KCi8qIFVuY29tbWVudCAoYW5kIHJlbW92ZSB0aGlzIHRleHQhKSB0byBnZXQgYm9sZC1m
YWNlZCBkZWZpbml0aW9uIGxpc3QgdGVybXMKZGwuZG9jdXRpbHMgZHQgewogIGZvbnQtd2Vp
Z2h0OiBib2xkIH0KKi8KCmRpdi5hYnN0cmFjdCB7CiAgbWFyZ2luOiAyZW0gNWVtIH0KCmRp
di5hYnN0cmFjdCBwLnRvcGljLXRpdGxlIHsKICBmb250LXdlaWdodDogYm9sZCA7CiAgdGV4
dC1hbGlnbjogY2VudGVyIH0KCmRpdi5hZG1vbml0aW9uLCBkaXYuYXR0ZW50aW9uLCBkaXYu
Y2F1dGlvbiwgZGl2LmRhbmdlciwgZGl2LmVycm9yLApkaXYuaGludCwgZGl2LmltcG9ydGFu
dCwgZGl2Lm5vdGUsIGRpdi50aXAsIGRpdi53YXJuaW5nIHsKICBtYXJnaW46IDJlbSA7CiAg
Ym9yZGVyOiBtZWRpdW0gb3V0c2V0IDsKICBwYWRkaW5nOiAxZW0gfQoKZGl2LmFkbW9uaXRp
b24gcC5hZG1vbml0aW9uLXRpdGxlLCBkaXYuaGludCBwLmFkbW9uaXRpb24tdGl0bGUsCmRp
di5pbXBvcnRhbnQgcC5hZG1vbml0aW9uLXRpdGxlLCBkaXYubm90ZSBwLmFkbW9uaXRpb24t
dGl0bGUsCmRpdi50aXAgcC5hZG1vbml0aW9uLXRpdGxlIHsKICBmb250LXdlaWdodDogYm9s
ZCA7CiAgZm9udC1mYW1pbHk6IHNhbnMtc2VyaWYgfQoKZGl2LmF0dGVudGlvbiBwLmFkbW9u
aXRpb24tdGl0bGUsIGRpdi5jYXV0aW9uIHAuYWRtb25pdGlvbi10aXRsZSwKZGl2LmRhbmdl
ciBwLmFkbW9uaXRpb24tdGl0bGUsIGRpdi5lcnJvciBwLmFkbW9uaXRpb24tdGl0bGUsCmRp
di53YXJuaW5nIHAuYWRtb25pdGlvbi10aXRsZSwgLmNvZGUgLmVycm9yIHsKICBjb2xvcjog
cmVkIDsKICBmb250LXdlaWdodDogYm9sZCA7CiAgZm9udC1mYW1pbHk6IHNhbnMtc2VyaWYg
fQoKLyogVW5jb21tZW50IChhbmQgcmVtb3ZlIHRoaXMgdGV4dCEpIHRvIGdldCByZWR1Y2Vk
IHZlcnRpY2FsIHNwYWNlIGluCiAgIGNvbXBvdW5kIHBhcmFncmFwaHMuCmRpdi5jb21wb3Vu
ZCAuY29tcG91bmQtZmlyc3QsIGRpdi5jb21wb3VuZCAuY29tcG91bmQtbWlkZGxlIHsKICBt
YXJnaW4tYm90dG9tOiAwLjVlbSB9CgpkaXYuY29tcG91bmQgLmNvbXBvdW5kLWxhc3QsIGRp
di5jb21wb3VuZCAuY29tcG91bmQtbWlkZGxlIHsKICBtYXJnaW4tdG9wOiAwLjVlbSB9Ciov
CgpkaXYuZGVkaWNhdGlvbiB7CiAgbWFyZ2luOiAyZW0gNWVtIDsKICB0ZXh0LWFsaWduOiBj
ZW50ZXIgOwogIGZvbnQtc3R5bGU6IGl0YWxpYyB9CgpkaXYuZGVkaWNhdGlvbiBwLnRvcGlj
LXRpdGxlIHsKICBmb250LXdlaWdodDogYm9sZCA7CiAgZm9udC1zdHlsZTogbm9ybWFsIH0K
CmRpdi5maWd1cmUgewogIG1hcmdpbi1sZWZ0OiAyZW0gOwogIG1hcmdpbi1yaWdodDogMmVt
IH0KCmRpdi5mb290ZXIsIGRpdi5oZWFkZXIgewogIGNsZWFyOiBib3RoOwogIGZvbnQtc2l6
ZTogc21hbGxlciB9CgpkaXYubGluZS1ibG9jayB7CiAgZGlzcGxheTogYmxvY2sgOwogIG1h
cmdpbi10b3A6IDFlbSA7CiAgbWFyZ2luLWJvdHRvbTogMWVtIH0KCmRpdi5saW5lLWJsb2Nr
IGRpdi5saW5lLWJsb2NrIHsKICBtYXJnaW4tdG9wOiAwIDsKICBtYXJnaW4tYm90dG9tOiAw
IDsKICBtYXJnaW4tbGVmdDogMS41ZW0gfQoKZGl2LnNpZGViYXIgewogIG1hcmdpbjogMCAw
IDAuNWVtIDFlbSA7CiAgYm9yZGVyOiBtZWRpdW0gb3V0c2V0IDsKICBwYWRkaW5nOiAxZW0g
OwogIGJhY2tncm91bmQtY29sb3I6ICNmZmZmZWUgOwogIHdpZHRoOiA0MCUgOwogIGZsb2F0
OiByaWdodCA7CiAgY2xlYXI6IHJpZ2h0IH0KCmRpdi5zaWRlYmFyIHAucnVicmljIHsKICBm
b250LWZhbWlseTogc2Fucy1zZXJpZiA7CiAgZm9udC1zaXplOiBtZWRpdW0gfQoKZGl2LnN5
c3RlbS1tZXNzYWdlcyB7CiAgbWFyZ2luOiA1ZW0gfQoKZGl2LnN5c3RlbS1tZXNzYWdlcyBo
MSB7CiAgY29sb3I6IHJlZCB9CgpkaXYuc3lzdGVtLW1lc3NhZ2UgewogIGJvcmRlcjogbWVk
aXVtIG91dHNldCA7CiAgcGFkZGluZzogMWVtIH0KCmRpdi5zeXN0ZW0tbWVzc2FnZSBwLnN5
c3RlbS1tZXNzYWdlLXRpdGxlIHsKICBjb2xvcjogcmVkIDsKICBmb250LXdlaWdodDogYm9s
ZCB9CgpkaXYudG9waWMgewogIG1hcmdpbjogMmVtIH0KCmgxLnNlY3Rpb24tc3VidGl0bGUs
IGgyLnNlY3Rpb24tc3VidGl0bGUsIGgzLnNlY3Rpb24tc3VidGl0bGUsCmg0LnNlY3Rpb24t
c3VidGl0bGUsIGg1LnNlY3Rpb24tc3VidGl0bGUsIGg2LnNlY3Rpb24tc3VidGl0bGUgewog
IG1hcmdpbi10b3A6IDAuNGVtIH0KCmgxLnRpdGxlIHsKICB0ZXh0LWFsaWduOiBjZW50ZXIg
fQoKaDIuc3VidGl0bGUgewogIHRleHQtYWxpZ246IGNlbnRlciB9Cgpoci5kb2N1dGlscyB7
CiAgd2lkdGg6IDc1JSB9CgppbWcuYWxpZ24tbGVmdCwgLmZpZ3VyZS5hbGlnbi1sZWZ0LCBv
YmplY3QuYWxpZ24tbGVmdCB7CiAgY2xlYXI6IGxlZnQgOwogIGZsb2F0OiBsZWZ0IDsKICBt
YXJnaW4tcmlnaHQ6IDFlbSB9CgppbWcuYWxpZ24tcmlnaHQsIC5maWd1cmUuYWxpZ24tcmln
aHQsIG9iamVjdC5hbGlnbi1yaWdodCB7CiAgY2xlYXI6IHJpZ2h0IDsKICBmbG9hdDogcmln
aHQgOwogIG1hcmdpbi1sZWZ0OiAxZW0gfQoKaW1nLmFsaWduLWNlbnRlciwgLmZpZ3VyZS5h
bGlnbi1jZW50ZXIsIG9iamVjdC5hbGlnbi1jZW50ZXIgewogIGRpc3BsYXk6IGJsb2NrOwog
IG1hcmdpbi1sZWZ0OiBhdXRvOwogIG1hcmdpbi1yaWdodDogYXV0bzsKfQoKLmFsaWduLWxl
ZnQgewogIHRleHQtYWxpZ246IGxlZnQgfQoKLmFsaWduLWNlbnRlciB7CiAgY2xlYXI6IGJv
dGggOwogIHRleHQtYWxpZ246IGNlbnRlciB9CgouYWxpZ24tcmlnaHQgewogIHRleHQtYWxp
Z246IHJpZ2h0IH0KCi8qIHJlc2V0IGlubmVyIGFsaWdubWVudCBpbiBmaWd1cmVzICovCmRp
di5hbGlnbi1yaWdodCB7CiAgdGV4dC1hbGlnbjogaW5oZXJpdCB9CgovKiBkaXYuYWxpZ24t
Y2VudGVyICogeyAqLwovKiAgIHRleHQtYWxpZ246IGxlZnQgfSAqLwoKb2wuc2ltcGxlLCB1
bC5zaW1wbGUgewogIG1hcmdpbi1ib3R0b206IDFlbSB9CgpvbC5hcmFiaWMgewogIGxpc3Qt
c3R5bGU6IGRlY2ltYWwgfQoKb2wubG93ZXJhbHBoYSB7CiAgbGlzdC1zdHlsZTogbG93ZXIt
YWxwaGEgfQoKb2wudXBwZXJhbHBoYSB7CiAgbGlzdC1zdHlsZTogdXBwZXItYWxwaGEgfQoK
b2wubG93ZXJyb21hbiB7CiAgbGlzdC1zdHlsZTogbG93ZXItcm9tYW4gfQoKb2wudXBwZXJy
b21hbiB7CiAgbGlzdC1zdHlsZTogdXBwZXItcm9tYW4gfQoKcC5hdHRyaWJ1dGlvbiB7CiAg
dGV4dC1hbGlnbjogcmlnaHQgOwogIG1hcmdpbi1sZWZ0OiA1MCUgfQoKcC5jYXB0aW9uIHsK
ICBmb250LXN0eWxlOiBpdGFsaWMgfQoKcC5jcmVkaXRzIHsKICBmb250LXN0eWxlOiBpdGFs
aWMgOwogIGZvbnQtc2l6ZTogc21hbGxlciB9CgpwLmxhYmVsIHsKICB3aGl0ZS1zcGFjZTog
bm93cmFwIH0KCnAucnVicmljIHsKICBmb250LXdlaWdodDogYm9sZCA7CiAgZm9udC1zaXpl
OiBsYXJnZXIgOwogIGNvbG9yOiBtYXJvb24gOwogIHRleHQtYWxpZ246IGNlbnRlciB9Cgpw
LnNpZGViYXItdGl0bGUgewogIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmIDsKICBmb250LXdl
aWdodDogYm9sZCA7CiAgZm9udC1zaXplOiBsYXJnZXIgfQoKcC5zaWRlYmFyLXN1YnRpdGxl
IHsKICBmb250LWZhbWlseTogc2Fucy1zZXJpZiA7CiAgZm9udC13ZWlnaHQ6IGJvbGQgfQoK
cC50b3BpYy10aXRsZSB7CiAgZm9udC13ZWlnaHQ6IGJvbGQgfQoKcHJlLmFkZHJlc3Mgewog
IG1hcmdpbi1ib3R0b206IDAgOwogIG1hcmdpbi10b3A6IDAgOwogIGZvbnQ6IGluaGVyaXQg
fQoKcHJlLmxpdGVyYWwtYmxvY2ssIHByZS5kb2N0ZXN0LWJsb2NrLCBwcmUubWF0aCwgcHJl
LmNvZGUgewogIG1hcmdpbi1sZWZ0OiAyZW0gOwogIG1hcmdpbi1yaWdodDogMmVtIH0KCnBy
ZS5jb2RlIC5sbiB7IGNvbG9yOiBncmV5OyB9IC8qIGxpbmUgbnVtYmVycyAqLwpwcmUuY29k
ZSwgY29kZSB7IGJhY2tncm91bmQtY29sb3I6ICNlZWVlZWUgfQpwcmUuY29kZSAuY29tbWVu
dCwgY29kZSAuY29tbWVudCB7IGNvbG9yOiAjNUM2NTc2IH0KcHJlLmNvZGUgLmtleXdvcmQs
IGNvZGUgLmtleXdvcmQgeyBjb2xvcjogIzNCMEQwNjsgZm9udC13ZWlnaHQ6IGJvbGQgfQpw
cmUuY29kZSAubGl0ZXJhbC5zdHJpbmcsIGNvZGUgLmxpdGVyYWwuc3RyaW5nIHsgY29sb3I6
ICMwQzU0MDQgfQpwcmUuY29kZSAubmFtZS5idWlsdGluLCBjb2RlIC5uYW1lLmJ1aWx0aW4g
eyBjb2xvcjogIzM1MkI4NCB9CnByZS5jb2RlIC5kZWxldGVkLCBjb2RlIC5kZWxldGVkIHsg
YmFja2dyb3VuZC1jb2xvcjogI0RFQjBBMX0KcHJlLmNvZGUgLmluc2VydGVkLCBjb2RlIC5p
bnNlcnRlZCB7IGJhY2tncm91bmQtY29sb3I6ICNBM0QyODl9CgpzcGFuLmNsYXNzaWZpZXIg
ewogIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmIDsKICBmb250LXN0eWxlOiBvYmxpcXVlIH0K
CnNwYW4uY2xhc3NpZmllci1kZWxpbWl0ZXIgewogIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlm
IDsKICBmb250LXdlaWdodDogYm9sZCB9CgpzcGFuLmludGVycHJldGVkIHsKICBmb250LWZh
bWlseTogc2Fucy1zZXJpZiB9CgpzcGFuLm9wdGlvbiB7CiAgd2hpdGUtc3BhY2U6IG5vd3Jh
cCB9CgpzcGFuLnByZSB7CiAgd2hpdGUtc3BhY2U6IHByZSB9CgpzcGFuLnByb2JsZW1hdGlj
IHsKICBjb2xvcjogcmVkIH0KCnNwYW4uc2VjdGlvbi1zdWJ0aXRsZSB7CiAgLyogZm9udC1z
aXplIHJlbGF0aXZlIHRvIHBhcmVudCAoaDEuLmg2IGVsZW1lbnQpICovCiAgZm9udC1zaXpl
OiA4MCUgfQoKdGFibGUuY2l0YXRpb24gewogIGJvcmRlci1sZWZ0OiBzb2xpZCAxcHggZ3Jh
eTsKICBtYXJnaW4tbGVmdDogMXB4IH0KCnRhYmxlLmRvY2luZm8gewogIG1hcmdpbjogMmVt
IDRlbSB9Cgp0YWJsZS5kb2N1dGlscyB7CiAgbWFyZ2luLXRvcDogMC41ZW0gOwogIG1hcmdp
bi1ib3R0b206IDAuNWVtIH0KCnRhYmxlLmZvb3Rub3RlIHsKICBib3JkZXItbGVmdDogc29s
aWQgMXB4IGJsYWNrOwogIG1hcmdpbi1sZWZ0OiAxcHggfQoKdGFibGUuZG9jdXRpbHMgdGQs
IHRhYmxlLmRvY3V0aWxzIHRoLAp0YWJsZS5kb2NpbmZvIHRkLCB0YWJsZS5kb2NpbmZvIHRo
IHsKICBwYWRkaW5nLWxlZnQ6IDAuNWVtIDsKICBwYWRkaW5nLXJpZ2h0OiAwLjVlbSA7CiAg
dmVydGljYWwtYWxpZ246IHRvcCB9Cgp0YWJsZS5kb2N1dGlscyB0aC5maWVsZC1uYW1lLCB0
YWJsZS5kb2NpbmZvIHRoLmRvY2luZm8tbmFtZSB7CiAgZm9udC13ZWlnaHQ6IGJvbGQgOwog
IHRleHQtYWxpZ246IGxlZnQgOwogIHdoaXRlLXNwYWNlOiBub3dyYXAgOwogIHBhZGRpbmct
bGVmdDogMCB9CgovKiAiYm9va3RhYnMiIHN0eWxlIChubyB2ZXJ0aWNhbCBsaW5lcykgKi8K
dGFibGUuZG9jdXRpbHMuYm9va3RhYnMgewogIGJvcmRlcjogMHB4OwogIGJvcmRlci10b3A6
IDJweCBzb2xpZDsKICBib3JkZXItYm90dG9tOiAycHggc29saWQ7CiAgYm9yZGVyLWNvbGxh
cHNlOiBjb2xsYXBzZTsKfQp0YWJsZS5kb2N1dGlscy5ib29rdGFicyAqIHsKICBib3JkZXI6
IDBweDsKfQp0YWJsZS5kb2N1dGlscy5ib29rdGFicyB0aCB7CiAgYm9yZGVyLWJvdHRvbTog
dGhpbiBzb2xpZDsKICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgpoMSB0dC5kb2N1dGlscywgaDIg
dHQuZG9jdXRpbHMsIGgzIHR0LmRvY3V0aWxzLApoNCB0dC5kb2N1dGlscywgaDUgdHQuZG9j
dXRpbHMsIGg2IHR0LmRvY3V0aWxzIHsKICBmb250LXNpemU6IDEwMCUgfQoKdWwuYXV0by10
b2MgewogIGxpc3Qtc3R5bGUtdHlwZTogbm9uZSB9Cgo8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5
Pgo8ZGl2IGNsYXNzPSJkb2N1bWVudCIgaWQ9InF1YWxpZmllZC1wcmFnbWEtb25jZSI+Cjxo
MSBjbGFzcz0idGl0bGUiPlF1YWxpZmllZCA8dHQgY2xhc3M9ImRvY3V0aWxzIGxpdGVyYWwi
PiNwcmFnbWEgb25jZTwvdHQ+PC9oMT4KPHRhYmxlIGNsYXNzPSJkb2NpbmZvIiBmcmFtZT0i
dm9pZCIgcnVsZXM9Im5vbmUiPgo8Y29sIGNsYXNzPSJkb2NpbmZvLW5hbWUiIC8+Cjxjb2wg
Y2xhc3M9ImRvY2luZm8tY29udGVudCIgLz4KPHRib2R5IHZhbGlnbj0idG9wIj4KPHRyIGNs
YXNzPSJmaWVsZCI+PHRoIGNsYXNzPSJkb2NpbmZvLW5hbWUiPkRvY3VtZW50OjwvdGg+PHRk
IGNsYXNzPSJmaWVsZC1ib2R5Ij5EeHh4eDwvdGQ+CjwvdHI+Cjx0cj48dGggY2xhc3M9ImRv
Y2luZm8tbmFtZSI+RGF0ZTo8L3RoPgo8dGQ+MjAxNi0xMC0yNzwvdGQ+PC90cj4KPHRyIGNs
YXNzPSJmaWVsZCI+PHRoIGNsYXNzPSJkb2NpbmZvLW5hbWUiPlByb2plY3Q6PC90aD48dGQg
Y2xhc3M9ImZpZWxkLWJvZHkiPklTTy9JRUMgSlRDMSBTQzIyIFdHMjEgUHJvZ3JhbW1pbmcg
TGFuZ3VhZ2UgQysrPC90ZD4KPC90cj4KPHRyIGNsYXNzPSJmaWVsZCI+PHRoIGNsYXNzPSJk
b2NpbmZvLW5hbWUiPkF1ZGllbmNlOjwvdGg+PHRkIGNsYXNzPSJmaWVsZC1ib2R5Ij5Fdm9s
dXRpb24gV29ya2luZyBHcm91cDwvdGQ+CjwvdHI+Cjx0cj48dGggY2xhc3M9ImRvY2luZm8t
bmFtZSI+QXV0aG9yOjwvdGg+Cjx0ZD5NYXR0aGV3IFdvZWhsa2UgKDxhIGNsYXNzPSJyZWZl
cmVuY2UgZXh0ZXJuYWwiIGhyZWY9Im1haWx0bzptd29laGxrZS5mbG9zcyYjNjQ7Z21haWwu
Y29tIj5td29laGxrZS5mbG9zcyYjNjQ7Z21haWwuY29tPC9hPik8L3RkPjwvdHI+CjwvdGJv
ZHk+CjwvdGFibGU+CjxzdHlsZT4KICBodG1sIHsgY29sb3I6IGJsYWNrOyBiYWNrZ3JvdW5k
OiB3aGl0ZTsgfQogIHRhYmxlLmRvY2luZm8geyBtYXJnaW46IDJlbSAwOyB9Cjwvc3R5bGU+
PGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9ImFic3RyYWN0Ij4KPGgxPjxhIGNsYXNzPSJ0b2Mt
YmFja3JlZiIgaHJlZj0iI2lkMSI+QWJzdHJhY3Q8L2E+PC9oMT4KPHA+VGhpcyBwcm9wb3Nh
bCByZWNvbW1lbmRzIHRvIHN0YW5kYXJkaXplIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3Bh
biBjbGFzcz0iY29tbWVudCBwcmVwcm9jIj4jcHJhZ21hIG9uY2UoaWRlbnRpZmllcikKPC9z
cGFuPjwvY29kZT4gYXMgYW4gaW1wcm92ZWQgbWVjaGFuaXNtIGZvciBwcmV2ZW50aW5nIG11
bHRpcGxlIGluY2x1c2lvbiBvZiBhIGhlYWRlciwgYW5kIGEgcmVsYXRlZCBkaXJlY3RpdmUg
PGNvZGUgY2xhc3M9ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJjb21tZW50IHByZXByb2MiPiNw
cmFnbWEgZm9yZ2V0KGlkZW50aWZpZXIpCjwvc3Bhbj48L2NvZGU+LjwvcD4KPGRpdiBjbGFz
cz0iY29udGVudHMgdG9waWMiIGlkPSJjb250ZW50cyI+CjxwIGNsYXNzPSJ0b3BpYy10aXRs
ZSBmaXJzdCI+Q29udGVudHM8L3A+Cjx1bCBjbGFzcz0ic2ltcGxlIj4KPGxpPjxhIGNsYXNz
PSJyZWZlcmVuY2UgaW50ZXJuYWwiIGhyZWY9IiNhYnN0cmFjdCIgaWQ9ImlkMSI+QWJzdHJh
Y3Q8L2E+PC9saT4KPGxpPjxhIGNsYXNzPSJyZWZlcmVuY2UgaW50ZXJuYWwiIGhyZWY9IiNw
cm9ibGVtIiBpZD0iaWQyIj5Qcm9ibGVtPC9hPjwvbGk+CjxsaT48YSBjbGFzcz0icmVmZXJl
bmNlIGludGVybmFsIiBocmVmPSIjcHJvcG9zYWwiIGlkPSJpZDMiPlByb3Bvc2FsPC9hPjx1
bD4KPGxpPjxhIGNsYXNzPSJyZWZlcmVuY2UgaW50ZXJuYWwiIGhyZWY9IiNwcmFnbWEtb25j
ZS1pZGVudGlmaWVyIiBpZD0iaWQ0Ij48Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xh
c3M9ImNvbW1lbnQgcHJlcHJvYyI+I3ByYWdtYSBvbmNlKGlkZW50aWZpZXIpCjwvc3Bhbj48
L2NvZGU+PC9hPjwvbGk+CjxsaT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBocmVm
PSIjcHJhZ21hLWZvcmdldC1pZGVudGlmaWVyIiBpZD0iaWQ1Ij48Y29kZSBjbGFzcz0iY3Bw
IGMrKyI+PHNwYW4gY2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+I3ByYWdtYSBmb3JnZXQoaWRl
bnRpZmllcikKPC9zcGFuPjwvY29kZT48L2E+PC9saT4KPC91bD4KPC9saT4KPGxpPjxhIGNs
YXNzPSJyZWZlcmVuY2UgaW50ZXJuYWwiIGhyZWY9IiNjb21tZW50cyIgaWQ9ImlkNiI+Q29t
bWVudHM8L2E+PHVsPgo8bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0i
I3N0YXRpYy1hbmFseXNpcyIgaWQ9ImlkNyI+U3RhdGljIEFuYWx5c2lzPC9hPjwvbGk+Cjxs
aT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBocmVmPSIjcHJvcGVyLXVzZS1vZi12
ZXJzaW9uaW5nIiBpZD0iaWQ4Ij5Qcm9wZXIgVXNlIG9mIFZlcnNpb25pbmc8L2E+PC9saT4K
PGxpPjxhIGNsYXNzPSJyZWZlcmVuY2UgaW50ZXJuYWwiIGhyZWY9IiNwZXJmb3JtYW5jZSIg
aWQ9ImlkOSI+UGVyZm9ybWFuY2U8L2E+PC9saT4KPC91bD4KPC9saT4KPGxpPjxhIGNsYXNz
PSJyZWZlcmVuY2UgaW50ZXJuYWwiIGhyZWY9IiNkaXNjdXNzaW9uIiBpZD0iaWQxMCI+RGlz
Y3Vzc2lvbjwvYT48dWw+CjxsaT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBocmVm
PSIjd29uLXQtbW9kdWxlcy1tYWtlLXRoaXMtaXJyZWxldmFudCIgaWQ9ImlkMTEiPldvbid0
IG1vZHVsZXMgbWFrZSB0aGlzIGlycmVsZXZhbnQ/PC9hPjwvbGk+CjwvdWw+CjwvbGk+Cjxs
aT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBocmVmPSIjc3VtbWFyeSIgaWQ9Imlk
MTIiPlN1bW1hcnk8L2E+PC9saT4KPC91bD4KPC9kaXY+CjwvZGl2Pgo8ZGl2IGNsYXNzPSJz
ZWN0aW9uIiBpZD0icHJvYmxlbSI+CjxoMT48YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhyZWY9
IiNpZDIiPlByb2JsZW08L2E+PC9oMT4KPHA+SXQgaXMgd2VsbCBrbm93biB0aGF0IHdoZW4g
Y29tcGlsaW5nIGNvZGUgb2Ygbm9uLXRyaXZpYWwgY29tcGxleGl0eSwgdGhlIGNvbXBsZXRl
IHNldCBvZiA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9ImNvbW1lbnQgcHJl
cHJvYyI+I2luY2x1ZGUKPC9zcGFuPjwvY29kZT4gZGlyZWN0aXZlcyBtYXkgcmVmZXJlbmNl
IHRoZSBzYW1lIGhlYWRlciBtb3JlIHRoYW4gb25jZS4gVGhpcyBvZnRlbiBvY2N1cnMgd2hl
biBhIHRyYW5zbGF0aW9uIHVuaXQgdXNlcyBzZXZlcmFsIGRpc3RpbmN0IGNvbXBvbmVudHMg
d2hpY2ggZWFjaCByZWx5IG9uIHRoZSBzYW1lIGJhc2UgY29tcG9uZW50IChlc3BlY2lhbGx5
IGxpYnJhcnkgY29uZmlndXJhdGlvbiBoZWFkZXJzLCBoZWFkZXJzIHRoYXQgcHJvdmlkZSBl
eHBvcnQgZGVjb3JhdGlvbiBzeW1ib2xzLCBhbmQgdGhlIGxpa2UpLiBXaGlsZSB0aGlzIGlz
IGNvcnJlY3QgZm9yIGVhY2ggY29tcG9uZW50IGhlYWRlciBpbiBvcmRlciB0byBhbGxvdyBp
dCB0byBiZSB1c2VkIG9uIGl0cyBvd24sIHRoZSBjb21iaW5hdGlvbiBvZiBtdWx0aXBsZSBj
b21wb25lbnRzIHJlcXVpcmVzIGEgbWVjaGFuaXNtIHRvIHByZXZlbnQgdGhlIGRlZmluaXRp
b25zIGluIGEgaGVhZGVyIGZyb20gYmVpbmcgcGFyc2VkIHR3aWNlLCB3aGljaCB3b3VsZCBs
ZWFkIHRvIGNvbXBpbGUgZXJyb3JzLjwvcD4KPHA+VHJhZGl0aW9uYWxseSwgdGhpcyBpcyBh
Y2NvbXBsaXNoZWQgd2l0aCAmcXVvdDtpbmNsdWRlIGd1YXJkcyZxdW90Oywgd2hpY2ggdGFr
ZSB0aGUgZm9ybTo8L3A+CjxwcmUgY2xhc3M9ImNvZGUgYysrIGxpdGVyYWwtYmxvY2siPgo8
c3BhbiBjbGFzcz0iY29tbWVudCBzaW5nbGUiPi8vIGZvby5oCjwvc3Bhbj48c3BhbiBjbGFz
cz0iY29tbWVudCBwcmVwcm9jIj4jaWZuZGVmIF9NWUxJQl9GT09fSF9JTkNMVURFRAojZGVm
aW5lIF9NWUxJQl9GT09fSF9JTkNMVURFRAo8L3NwYW4+PHNwYW4gY2xhc3M9InB1bmN0dWF0
aW9uIj4uLi48L3NwYW4+CjxzcGFuIGNsYXNzPSJjb21tZW50IHByZXByb2MiPiNlbmRpZiA8
L3NwYW4+PHNwYW4gY2xhc3M9ImNvbW1lbnQgc2luZ2xlIj4vLyBfTVlMSUJfRk9PX0hfSU5D
TFVERUQ8L3NwYW4+CjwvcHJlPgo8cD5BdCBsZWFzdCBvbmUgcHJvYmxlbSB3aXRoIHRoaXMg
aXMgb2J2aW91czsgdGhlIGd1YXJkIHN5bWJvbCBpcyByZXBlYXRlZCBhcyBtYW55IGFzIHRo
cmVlIHRpbWVzICh0aGUgbGFzdCBvY2N1cnJlbmNlIGluIHRoZSBjb21tZW50IGlzIG9wdGlv
bmFsIGFuZCBhdCBsZWFzdCBoYXMgbm8gaW1wYWN0IG9uIGNvbXBpbGluZyBpZiBpdCBpcyBp
bmNvcnJlY3QpLCBsZWFkaW5nIHRvIHRoZSBwb3NzaWJpbGl0eSBvZiBtaXN0YWtlcyB3aGVu
IHJldHlwaW5nIHRoZSBzeW1ib2wgdGhhdCBjYXVzZSB0aGUgZ3VhcmQgdG8gYmUgaW5lZmZl
Y3RpdmUuIExlc3Mgb2J2aW91cywgYnV0IGV2ZW4gbW9yZSBwcm9ibGVtYXRpYywgaXQgaXMg
Y29tbW9uIGZvciBoZWFkZXJzIHRvIGJlIGNvcGllZCwgd2hpY2ggY2FuIGxlYWQgdG8gZGlm
ZmljdWx0IHRvIGRpYWdub3NlIGVycm9ycyBpZiB0aGUgcHJvZ3JhbW1lciBuZWdsZWN0cyB0
byBhZGp1c3QgdGhlIGd1YXJkIHdoZW4gZG9pbmcgc28uPC9wPgo8cD5Tb21lIGNvbXBpbGVy
cyBzdXBwb3J0IDx0dCBjbGFzcz0iZG9jdXRpbHMgbGl0ZXJhbCI+I3ByYWdtYSBvbmNlPC90
dD4gYXMgYW4gYWx0ZXJuYXRlIG1lY2hhbmlzbSBmb3IgcHJldmVudGluZyBtdWx0aXBsZSBp
bmNsdXNpb25zLiBIb3dldmVyLCBtYW55IHByb2JsZW1zIHdpdGggdGhpcyBtZWNoYW5pc20g
YXJlIGtub3duLiBJdCBpcyBkaWZmaWN1bHQgZm9yIGNvbXBpbGVyIGF1dGhvcnMgdG8gaW1w
bGVtZW50IGNvcnJlY3RseSwgZXNwZWNpYWxseSBpbiB0aGUgcHJlc2VuY2Ugb2YgcGF0aG9s
b2dpY2FsIHNvdXJjZSB0cmVlcyAoaW52b2x2aW5nIGNvcGllcyBvZiBoZWFkZXJzLCB3aGV0
aGVyIGJ5IHN5bWxpbmssIG9yIHdvcnNlLCB0aGUgc2FtZSBwaHlzaWNhbCBmaWxlIGFjY2Vz
c2libGUgdmlhIGRpZmZlcmVudCBtb3VudCBwb2ludHMpLiBUaGVyZSBpcyBhbHNvIGEgcXVl
c3Rpb24gb2YgaG93IGRpc3RpbmN0IGhlYWRlcnMgcHJvdmlkaW5nIHNpbWlsYXIgZGVmaW5p
dGlvbnMgc2hvdWxkIGJlIGhhbmRsZWQuIFRoZXNlIHByb2JsZW1zIGFyZSB3ZWxsIGFkZHJl
c3NlZCBieSB0cmFkaXRpb25hbCBpbmNsdWRlIGd1YXJkcy48L3A+CjwvZGl2Pgo8ZGl2IGNs
YXNzPSJzZWN0aW9uIiBpZD0icHJvcG9zYWwiPgo8aDE+PGEgY2xhc3M9InRvYy1iYWNrcmVm
IiBocmVmPSIjaWQzIj5Qcm9wb3NhbDwvYT48L2gxPgo8cD5XZSBwcm9wb3NlIHRvIGludHJv
ZHVjZSB0aHJlZSBuZXcgcHJlcHJvY2Vzc29yIGRpcmVjdGl2ZXMgaW4gYW4gYXR0ZW1wdCB0
byBhZGRyZXNzIHRoaXMgaXNzdWUuPC9wPgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0icHJh
Z21hLW9uY2UtaWRlbnRpZmllciI+CjxoMj48YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhyZWY9
IiNpZDQiPjxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0iY29tbWVudCBwcmVw
cm9jIj4jcHJhZ21hIG9uY2UoaWRlbnRpZmllcikKPC9zcGFuPjwvY29kZT48L2E+PC9oMj4K
PGJsb2NrcXVvdGU+CjxzdHJvbmc+I3ByYWdtYTwvc3Ryb25nPiA8c3Ryb25nPm9uY2U8L3N0
cm9uZz4gPHN0cm9uZz4oPC9zdHJvbmc+IDxlbT5pZGVudGlmaWVyPC9lbT4gWyA8ZW0+dmVy
c2lvbjwvZW0+IF0gPHN0cm9uZz4pPC9zdHJvbmc+PC9ibG9ja3F1b3RlPgo8cD5UaGUgPGVt
PmlkZW50aWZpZXI8L2VtPiBzaGFsbCBmb2xsb3cgdGhlIHJ1bGVzIGZvciBhIHF1YWxpZmll
ZCBDKysgaWRlbnRpZmllci4gVGhlIDxlbT52ZXJzaW9uPC9lbT4sIGlmIHNwZWNpZmllZCwg
c2hhbGwgYmUgYSB0b2tlbiBzdHJpbmcgY29uc2lzdGluZyBvZiBhbHBoYW51bWVyaWMgY2hh
cmFjdGVycyBhbmQvb3IgdGhlIDx0dCBjbGFzcz0iZG9jdXRpbHMgbGl0ZXJhbCI+XzwvdHQ+
LCA8dHQgY2xhc3M9ImRvY3V0aWxzIGxpdGVyYWwiPi08L3R0PiwgPHR0IGNsYXNzPSJkb2N1
dGlscyBsaXRlcmFsIj46PC90dD4gb3IgPHR0IGNsYXNzPSJkb2N1dGlscyBsaXRlcmFsIj4u
PC90dD4gY2hhcmFjdGVycywgYW5kIHNoYWxsIHNldCB0aGUgdmVyc2lvbiBhc3NvY2lhdGVk
IHdpdGggdGhlIHNwZWNpZmllZCA8ZW0+aWRlbnRpZmllcjwvZW0+LiBUaGlzIGRpcmVjdGl2
ZSBtdXN0IGFwcGVhciBhcyB0aGUgZmlyc3Qgbm9uLWNvbW1lbnQsIG5vbi13aGl0ZXNwYWNl
IGNvbnRlbnRzIG9mIGFuIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0iY29t
bWVudCBwcmVwcm9jIj4jaW5jbHVkZQo8L3NwYW4+PC9jb2RlPiB1bml0LjwvcD4KPHA+SWYg
YSBwcmV2aW91cyA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9ImNvbW1lbnQg
cHJlcHJvYyI+I3ByYWdtYSBvbmNlCjwvc3Bhbj48L2NvZGU+IGRpcmVjdGl2ZSBoYXZpbmcg
dGhlIHNhbWUgPGVtPmlkZW50aWZpZXI8L2VtPiBhbmQgPGVtPnZlcnNpb248L2VtPiBoYXMg
YmVlbiBwcmV2aW91c2x5IHNlZW4sIHRoZSBjb21waWxlciBzaGFsbCBpZ25vcmUgdGhlIHJl
bWFpbmRlciBvZiB0aGUgPGNvZGUgY2xhc3M9ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJjb21t
ZW50IHByZXByb2MiPiNpbmNsdWRlCjwvc3Bhbj48L2NvZGU+IHVuaXQuIElmIHRoZSA8ZW0+
aWRlbnRpZmllcjwvZW0+IGlzIGtub3duIGJ1dCB0aGUgPGVtPnZlcnNpb248L2VtPiBkb2Vz
IG5vdCBtYXRjaCwgdGhlIHByb2dyYW0gc2hhbGwgYmUgaWxsLWZvcm1lZC4gKElmIDxlbT52
ZXJzaW9uPC9lbT4gaXMgdW5zcGVjaWZpZWQsIHRoZSB2ZXJzaW9uIHNoYWxsIGJlIHRoZSBl
bXB0eSBzdHJpbmcuKTwvcD4KPC9kaXY+CjxkaXYgY2xhc3M9InNlY3Rpb24iIGlkPSJwcmFn
bWEtZm9yZ2V0LWlkZW50aWZpZXIiPgo8aDI+PGEgY2xhc3M9InRvYy1iYWNrcmVmIiBocmVm
PSIjaWQ1Ij48Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9ImNvbW1lbnQgcHJl
cHJvYyI+I3ByYWdtYSBmb3JnZXQoaWRlbnRpZmllcikKPC9zcGFuPjwvY29kZT48L2E+PC9o
Mj4KPGJsb2NrcXVvdGU+CjxzdHJvbmc+I3ByYWdtYTwvc3Ryb25nPiA8c3Ryb25nPmZvcmdl
dDwvc3Ryb25nPiA8c3Ryb25nPig8L3N0cm9uZz4gPGVtPmlkZW50aWZpZXI8L2VtPiA8c3Ry
b25nPik8L3N0cm9uZz48L2Jsb2NrcXVvdGU+CjxwPlRoZSBjb21waWxlciBzaGFsbCByZW1v
dmUgdGhlIDxlbT5pZGVudGlmaWVyPC9lbT4gZnJvbSBpdHMgY29sbGVjdGlvbiBvZiBwcmV2
aW91c2x5IHNlZW4gaWRlbnRpZmllcnMuIFRoaXMgZGlyZWN0aXZlIHByb3ZpZGVzIGEgbWVj
aGFuaXNtIHRvIGZvcmNlIHRoZSBtdWx0aXBsZSBpbmNsdXNpb24gb2YgYW4gPGNvZGUgY2xh
c3M9ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJjb21tZW50IHByZXByb2MiPiNpbmNsdWRlCjwv
c3Bhbj48L2NvZGU+IHVuaXQgd2hpY2ggdXNlcyA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNw
YW4gY2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+I3ByYWdtYSBvbmNlKGlkZW50aWZpZXIpCjwv
c3Bhbj48L2NvZGU+LjwvcD4KPC9kaXY+CjwvZGl2Pgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBp
ZD0iY29tbWVudHMiPgo8aDE+PGEgY2xhc3M9InRvYy1iYWNrcmVmIiBocmVmPSIjaWQ2Ij5D
b21tZW50czwvYT48L2gxPgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0ic3RhdGljLWFuYWx5
c2lzIj4KPGgyPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkNyI+U3RhdGljIEFu
YWx5c2lzPC9hPjwvaDI+CjxwPkFzIG1lbnRpb25lZCwgb25lIG9mIHRoZSBwcm9ibGVtcyB3
aXRoIHRyYWRpdGlvbmFsIGd1YXJkcyBpcyB0aGF0IHRoZXkgY2FuIGVhc2lseSBnZXQgb3V0
IG9mIHN5bmMgd2l0aCB0aGUgaGVhZGVyIGZpbGUgdGhleSBndWFyZC4gV2hpbGUgaXQgaXMg
cG9zc2libGUgdG8gd3JpdGUgc3RhdGljIGFuYWx5c2lzIHRvb2xzIHRvIGRldGVjdCBzdWNo
IGVycm9ycywgdGhlIHByb2xpZmVyYXRpb24gb2YgZGlmZmVyZW50IHN0eWxlcyBvZiBndWFy
ZHMgbWFrZSBpdCBkaWZmaWN1bHQgdG8gd3JpdGUgYSBzaW5nbGUgaGV1cmlzdGljIHRoYXQg
d29ya3MgYWNyb3NzIGEgYnJvYWQgYmFzZSBvZiBleGlzdGluZyBzb2Z0d2FyZS4gSW4gdHVy
biwgdGhpcyBtZWFucyB0aGF0IHN1Y2ggdG9vbHMgdGVuZCB0byBiZSBwcm9qZWN0IHNwZWNp
ZmljIGFuZCBhcmUgYXQgYmVzdCBydW4gd2hlbiBjb2RlIGlzIGNvbW1pdHRlZCB0byBhIHJl
cG9zaXRvcnkuIEl0IHdvdWxkIGJlIGZhciBiZXR0ZXIgZm9yIHN1Y2ggY2hlY2tzIHRvIGJl
IGludGVncmF0ZWQgaW50byB0aGUgY29tcGlsZXIsIHNvIHRoYXQgdGhleSBydW4gYXQgYnVp
bGQgdGltZSwgYW5kIGNhbiBiZSBwcm9tb3RlZCB0byBlcnJvcnMuPC9wPgo8cD5XZSBhZGRy
ZXNzIHRoaXMgYnkgbWFraW5nIHRoZSBndWFyZCBpZGVudGlmaWVyIGEgcXVhbGlmaWVkIEMr
KyBpZGVudGlmaWVyLiBCZXNpZGVzIGJlaW5nIG1vcmUgY29uc2lzdGVudCB3aXRoIEMrKyBj
b252ZW50aW9ucyAoZm9yIGV4YW1wbGUsIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIGd1YXJkIGNv
dWxkIG1hdGNoIHRoZSBuYW1lc3BhY2Ugb2YgdGhlIHByb2plY3Qgd2hpY2ggb3ducyB0aGUg
aGVhZGVyKSwgdGhpcywgY29tYmluZWQgd2l0aCB0aGUgaW50cm9kdWN0aW9uIG9mIGEgbmV3
IGZlYXR1cmUsIG1ha2VzIGl0IHN0cmFpZ2h0IGZvcndhcmQgdG8gc3RpcHVsYXRlIHRoYXQg
dGhlIHVucXVhbGlmaWVkIHBvcnRpb24gb2YgdGhlIGlkZW50aWZpZXIgc2hhbGwgbWF0Y2gg
dGhlIG5hbWUgb2YgdGhlIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0iY29t
bWVudCBwcmVwcm9jIj4jaW5jbHVkZQo8L3NwYW4+PC9jb2RlPiB1bml0IChleGNsdWRpbmcg
YSBmaWxlIGV4dGVuc2lvbiwgaWYgYW55KS48L3A+CjxwPk1vcmVvdmVyLCBpdCBpcyBub3Qg
aW5jb25jZWl2YWJsZSB0aGF0IHdlIGNvdWxkIGFncmVlIHRoYXQgdGhlIG5hbWVzcGFjZSBw
b3J0aW9uIG9mIHRoZSBxdWFsaWZpZWQgaWRlbnRpZmllciBzaGFsbCBtYXRjaCB0aGUgbmFt
ZXNwYWNlIG9mIHRoZSBkZWZpbml0aW9ucyBwcm92aWRlZCBieSB0aGUgPGNvZGUgY2xhc3M9
ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJjb21tZW50IHByZXByb2MiPiNpbmNsdWRlCjwvc3Bh
bj48L2NvZGU+IHVuaXQgKHNvIHRoYXQgYWxsIHBhcnRzIG9mIHRoZSBndWFyZCBpZGVudGlm
aWVyIGFyZSBjaGVja2VkIGZvciBjb3JyZWN0bmVzcyksIHdpdGggdGhlIGNvbXBpbGVyIGlz
c3VpbmcgYSBkaWFnbm9zdGljIGlmIHRoZSA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4g
Y2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+I2luY2x1ZGUKPC9zcGFuPjwvY29kZT4gdW5pdCBk
b2VzIG5vdCBpbmNsdWRlIGF0IGxlYXN0IG9uZSBkZWNsYXJhdGlvbiBpbiB0aGUgc2FtZSBu
YW1lc3BhY2UuPC9wPgo8cD5TaW5jZSB3ZSBhcmUgdGFsa2luZyBhYm91dCBRb0kgaXNzdWVz
IGhlcmUsIHdlIGZlZWwgdGhhdCBpdCBpcyBub3QgbmVjZXNzYXJ5IHRoYXQgdGhlc2UgY2hl
Y2tzIGJlIG5vcm1hdGl2ZS4gSW5zdGVhZCwgd2Ugd291bGQgcHJlZmVyIHRvIGxldCB0aGUg
Y29tcGlsZXIgY29tbXVuaXR5IGFncmVlIG9uIHdoYXQgY29udmVudGlvbnMgc2hvdWxkIGJl
IGV4cGVjdGVkIGFuZCBkaWFnbm9zZWQuPC9wPgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlv
biIgaWQ9InByb3Blci11c2Utb2YtdmVyc2lvbmluZyI+CjxoMj48YSBjbGFzcz0idG9jLWJh
Y2tyZWYiIGhyZWY9IiNpZDgiPlByb3BlciBVc2Ugb2YgVmVyc2lvbmluZzwvYT48L2gyPgo8
cD5BbHRob3VnaCB0aGUgJnF1b3Q7b2J2aW91cyZxdW90OyB3YXkgdG8gdXNlIHZlcnNpb24g
ZGlyZWN0aXZlcyBpcyB0byBpbmNsdWRlIHRoZSB2ZXJzaW9uIG9mIHRoZSBzb2Z0d2FyZSBw
YWNrYWdlIHRvIHdoaWNoIGEgaGVhZGVyIGJlbG9uZ3MgaW4gZXZlcnkgc2luZ2xlIGhlYWRl
ciwgdGhpcyBsZWFkcyB0byBhbiBvYnZpb3VzIGFuZCBzaWduaWZpY2FudCBtYWludGVuYW5j
ZSBidXJkZW4uIEEgYmV0dGVyIHNvbHV0aW9uIHdoaWNoIHdpbGwgYmUgZXF1YWxseSBhZGVx
dWF0ZSBpbiBhbG1vc3QgZXZlcnkgaW5zdGFuY2UgaXMgdG8gbWFpbnRhaW4gc3VjaCB2ZXJz
aW9uIGluZm9ybWF0aW9uIGluIGEgc2luZ2xlLCBnbG9iYWwgaGVhZGVyIGZpbGUgKGUuZy4g
PHR0IGNsYXNzPSJkb2N1dGlscyBsaXRlcmFsIj52ZXJzaW9uLmg8L3R0PiwgPHR0IGNsYXNz
PSJkb2N1dGlscyBsaXRlcmFsIj5jb25maWcuaDwvdHQ+LCA8dHQgY2xhc3M9ImRvY3V0aWxz
IGxpdGVyYWwiPmV4cG9ydHMuaDwvdHQ+KSB3aGljaCBpcyBhbHdheXMgaW5jbHVkZWQgdmlh
IGFuIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0iY29tbWVudCBwcmVwcm9j
Ij4jaW5jbHVkZQo8L3NwYW4+PC9jb2RlPiBkaXJlY3RpdmUgd2hvc2UgcGF0aCBpcyBtYXJr
ZWQgd2l0aCBxdW90ZXMgKDx0dCBjbGFzcz0iZG9jdXRpbHMgbGl0ZXJhbCI+JnF1b3Q7JnF1
b3Q7PC90dD4pIHJhdGhlciB0aGFuIGFuZ2xlIGJyYWNrZXRzICg8dHQgY2xhc3M9ImRvY3V0
aWxzIGxpdGVyYWwiPiZsdDsmZ3Q7PC90dD4pLiBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgZ2xv
YmFsIGhlYWRlciBpcyBhbHdheXMgZm91bmQgaW4gYSBrbm93biBsb2NhdGlvbiByZWxhdGl2
ZSB0byB0aGUgaGVhZGVyIGJlaW5nIHByb2Nlc3NlZCwgYW5kIHdpbGwgaW4gYWxtb3N0IGFs
bCBjYXNlcyBiZSBzdWZmaWNpZW50IHRvIGNhdGNoIG1pc21hdGNoaW5nIHZlcnNpb25zIG9m
IHRoZSBoZWFkZXIgd2hpY2ggaW5jbHVkZXMgdGhlIGdsb2JhbCBoZWFkZXIuPC9wPgo8cD5B
bm90aGVyIG9wdGlvbiwgd2hpY2ggY2FuIGJlIGVtcGxveWVkIGluIHRhbmRlbSwgaXMgdG8g
dXNlIGEgbW9ub3RvbmljYWxseSBpbmNyZWFzaW5nIHZlcnNpb24gbnVtYmVyIHRoYXQgaXMg
dW5pcXVlIHRvIGVhY2ggaGVhZGVyIGFuZCBpcyBpbmNyZW1lbnRlZCB3aGVuZXZlciB0aGUg
aW50ZXJmYWNlKHMpIGRlZmluZWQgaW4gdGhlIGhlYWRlciBjaGFuZ2UuIEJlY2F1c2UgdGhp
cyBudW1iZXIgaXMgdW5pcXVlIHRvIHRoZSBoZWFkZXIsIGFuZCBvbmx5IGNoYW5nZXMgd2hl
biB0aGUgaGVhZGVyIGNoYW5nZXMgKGFuZCBwb3NzaWJseSBub3QgZXZlbiB0aGF0IGZyZXF1
ZW50bHkpLCB0aGUgbWFpbnRlbmFuY2UgYnVyZGVuIGlzIHNpZ25pZmljYW50bHkgcmVkdWNl
ZC48L3A+CjxwPlRoZSByZWxhdGl2ZWx5IGxpYmVyYWwgc3BlY2lmaWNhdGlvbiBvZiBhbGxv
d2VkIHZlcnNpb24gc3RyaW5ncyB3YXMgY2hvc2VuIHdpdGggdGhlIHNwZWNpZmljIGludGVu
dGlvbiBvZiBlbmNvdXJhZ2luZyB0aGUgdmVyc2lvbiBzdHJpbmcgdG8gYmUgZ2VuZXJhdGVk
IGJ5IHRoZSBidWlsZCBzeXN0ZW0sIGFuZCBpbiBwYXJ0aWN1bGFyIHRvIGFsbG93IHRoZSB2
ZXJzaW9uIHN0cmluZyB0byBpbmNsdWRlIGEgVkNTIGlkZW50aWZpZXIuIEluIHRoaXMgd2F5
LCB3ZSBtYXkgZW5zdXJlIHRoYXQgaGVhZGVycyBmcm9tIGEgZGV2ZWxvcG1lbnQgdmVyc2lv
biBvZiBzb2Z0d2FyZSBhcmUgbm90IG1peGVkIHdpdGggdGhvc2UgZnJvbSBhIHJlbGVhc2Ug
dmVyc2lvbiBvciBkaWZmZXJlbnQgZGV2ZWxvcG1lbnQgdmVyc2lvbiwgZXZlbiBpZiB0aGUg
bm9ybWF0aXZlIHZlcnNpb24gbnVtYmVyIGRvZXMgbm90IGRpZmZlciBiZXR3ZWVuIHN1Y2gg
dmVyc2lvbnMuPC9wPgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9InBlcmZvcm1h
bmNlIj4KPGgyPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkOSI+UGVyZm9ybWFu
Y2U8L2E+PC9oMj4KPHA+T25lIG9mIHRoZSBwb2ludHMgdGhhdCBpcyBmcmVxdWVudGx5IHJh
aXNlZCBpbiBmYXZvciBvZiB1bnF1YWxpZmllZCA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNw
YW4gY2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+I3ByYWdtYSBvbmNlCjwvc3Bhbj48L2NvZGU+
IGlzIHRoYXQgaXQgYWxsb3dzIHRoZSBjb21waWxlciB0byBza2lwIHJlYWRpbmcgYSBmaWxl
IHRoYXQgaXQgaGFzIGFscmVhZHkgaW5jbHVkZWQuIEhvd2V2ZXIsIHRoZSBwcm9ibGVtIHdp
dGggdGhpcyBpcyB0aGF0IGlmIHRoZSBjb21waWxlciBpcyBub3QgYWJsZSB0byBjb3JyZWN0
bHkgZGV0ZXJtaW5lIGlmIGEgaGVhZGVyIGhhcyBhbHJlYWR5IGJlZW4gaW5jbHVkZWQsIGl0
IGlzIGxpa2VseSB0aGF0IHRoZSB0cmFuc2xhdGlvbiB1bml0IHdpbGwgZmFpbCB0byBjb21w
aWxlLjwvcD4KPHA+SW4gZmFjdCwgY29tcGlsZXJzIG1heSBhbmQgZG8gYWxyZWFkeSBpbXBs
ZW1lbnQgc2ltaWxhciBsb2dpYyBmb3IgdHJhZGl0aW9uYWwgaW5jbHVkZSBndWFyZHMuIEJ5
IGVtcGxveWluZyBhIGhldXJpc3RpYywgYSBjb21waWxlciBtYXkgZGV0ZXJtaW5lIHRoYXQg
YSBoZWFkZXIncyBjb250ZW50cyBhcmUgZW50aXJlbHkgZ3VhcmRlZC4gSGF2aW5nIGRvbmUg
c28sIHRoZSBoZWFkZXIgYW5kIGl0cyBndWFyZCBtYXkgYmUgZW50ZXJlZCBpbnRvIGEgbWFw
LCBzdWNoIHRoYXQgdGhlIGNvbXBpbGVyIG1heSBjaG9vc2Ugbm90IHRvIHJlYWQgdGhlIGhl
YWRlciBhIHNlY29uZCB0aW1lIGlmIGl0IG9ic2VydmVzIHRoYXQgYW4gPGNvZGUgY2xhc3M9
ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJjb21tZW50IHByZXByb2MiPiNpbmNsdWRlCjwvc3Bh
bj48L2NvZGU+IGRpcmVjdGl2ZSB3b3VsZCByZWZlcmVuY2UgYSBoZWFkZXIgdGhhdCBoYXMg
YmVlbiBwcmV2aW91c2x5IHByb2Nlc3NlZCBhbmQgd2hvc2UgaW5jbHVkZSBndWFyZCBpcyBk
ZWZpbmVkLiBUaGlzIGlzIHNhZmVyLCBzaW5jZSBpbiBjYXNlIG9mIGEgd3JvbmcgZ3Vlc3Ms
IHRoZSBjb21waWxlciB3aWxsIHJlYWQgdGhlIGhlYWRlciBhbnl3YXkgYW5kIHByb2Nlc3Mg
aXQgYXMgZW1wdHkgZHVlIHRvIHRoZSB0cmFkaXRpb25hbCBndWFyZCwgd2hpY2ggaGFzIGEg
c21hbGwgcGVyZm9ybWFuY2UgcGVuYWx0eSBidXQgZG9lcyBub3QgYWZmZWN0IGNvcnJlY3Ru
ZXNzIG9mIHRoZSBwcm9ncmFtLjwvcD4KPHA+T3VyIG1vZGVsIGZvciA8Y29kZSBjbGFzcz0i
Y3BwIGMrKyI+PHNwYW4gY2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+I3ByYWdtYSBvbmNlKGlk
ZW50aWZpZXIpCjwvc3Bhbj48L2NvZGU+IHByb3ZpZGVzIHRoZXNlIHNhbWUgYmVuZWZpdHMs
IHdoaWxlIG1ha2luZyBleHBsaWNpdCAoYW5kIGVuZm9yY2luZykgdGhhdCB0aGUgZW50aXJl
IGhlYWRlciBtYXkgYmUgc2tpcHBlZCBpZiB0aGUgY29tcGlsZXIgJnF1b3Q7a25vd3MmcXVv
dDsgaXQgaGFzIGJlZW4gaW5jbHVkZWQgYWxyZWFkeS4gVGhlIHByb3Bvc2VkIGRpcmVjdGl2
ZSB0aGVyZWZvcmUgcHJvdmlkZXMgdGhlIHNhbWUgcGVyZm9ybWFuY2UgYmVuZWZpdHMgYXMg
dW5xdWFsaWZpZWQgPGNvZGUgY2xhc3M9ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJjb21tZW50
IHByZXByb2MiPiNwcmFnbWEgb25jZQo8L3NwYW4+PC9jb2RlPiwgYnV0IHdpdGhvdXQgdGhl
IHBvdGVudGlhbCBwaXRmYWxscy48L3A+CjwvZGl2Pgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2Vj
dGlvbiIgaWQ9ImRpc2N1c3Npb24iPgo8aDE+PGEgY2xhc3M9InRvYy1iYWNrcmVmIiBocmVm
PSIjaWQxMCI+RGlzY3Vzc2lvbjwvYT48L2gxPgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0i
d29uLXQtbW9kdWxlcy1tYWtlLXRoaXMtaXJyZWxldmFudCI+CjxoMj48YSBjbGFzcz0idG9j
LWJhY2tyZWYiIGhyZWY9IiNpZDExIj5Xb24ndCBtb2R1bGVzIG1ha2UgdGhpcyBpcnJlbGV2
YW50PzwvYT48L2gyPgo8cD5JdCBpcyBwb3NzaWJsZSB0aGF0IG1vZHVsZXMgd2lsbCBzaWdu
aWZpY2FudGx5IHJlZHVjZSB0aGUgbmVlZCBmb3IgdGhpcyBmZWF0dXJlLCBidXQgbW9kdWxl
cyBhcmVuJ3QgaGVyZSB5ZXQsIGFuZCBpdCBpcyBsaWtlbHkgdGhhdCB3ZSB3aWxsIGNvbnRp
bnVlIHRvIGhhdmUgdHJhZGl0aW9uYWwgaGVhZGVycyBmb3IgYSBsb25nIHRpbWUuIFNpbmNl
IHRoaXMgZmVhdHVyZSBoYXBwZW5zIGVudGlyZWx5IGF0IHRoZSBwcmVwcm9jZXNzb3IgbGV2
ZWwsIGl0IGlzIG91ciBzaW5jZXJlIGhvcGUgdGhhdCBjb21waWxlcnMgd2lsbCBjaG9vc2Ug
dG8gaW1wbGVtZW50IHRoZSBmZWF0dXJlIGVhcmx5LCBhbmQgZW5hYmxlIGl0IHJlZ2FyZGxl
c3Mgb2YgdGhlIGxhbmd1YWdlIGxldmVsIHJlcXVlc3RlZC4gVGhpcyBtZWFucyB0aGF0IGV4
aXN0aW5nIHNvZnR3YXJlIG1heSBiZSBhYmxlIHRvIHRha2UgYWR2YW50YWdlIG9mIHRoZSBm
ZWF0dXJlIG11Y2ggc29vbmVyIHRoYW4gc3VjaCBzb2Z0d2FyZSBjYW4gYmUgcG9ydGVkIHRv
IG1vZHVsZXMgKHdoaWNoIHdpbGwgaW52b2x2ZSBhIG11Y2ggbW9yZSBpbnZhc2l2ZSBjaGFu
Z2UpLjwvcD4KPC9kaXY+CjwvZGl2Pgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0ic3VtbWFy
eSI+CjxoMT48YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhyZWY9IiNpZDEyIj5TdW1tYXJ5PC9h
PjwvaDE+CjxwPldlIGhhdmUgc2hvd24gYSBtZWNoYW5pc20gZm9yIGltcGxlbWVudGluZyBh
IG5leHQgZ2VuZXJhdGlvbiBzeXN0ZW0gZm9yIHByZXZlbnRpbmcgbXVsdGlwbGUgaW5jbHVz
aW9uIG9mIGhlYWRlcnMuIFRoaXMgc3lzdGVtIGlzIHNlbWFudGljYWxseSBlcXVpdmFsZW50
IHRvIHRyYWRpdGlvbmFsIGd1YXJkcywgYW5kIHNvIGF2b2lkcyB0aGUga25vd24gaXNzdWVz
IG9mIHByZXNlbnQgaW1wbGVtZW50YXRpb25zIG9mIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48
c3BhbiBjbGFzcz0iY29tbWVudCBwcmVwcm9jIj4jcHJhZ21hIG9uY2UKPC9zcGFuPjwvY29k
ZT4gKHdpdGhvdXQgYW4gaWRlbnRpZmllcikuIEJ5IGFsc28gcHJvdmlkaW5nIGEgPGNvZGUg
Y2xhc3M9ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJjb21tZW50IHByZXByb2MiPiNwcmFnbWEg
Zm9yZ2V0Cjwvc3Bhbj48L2NvZGU+LCB3ZSBhZGRyZXNzIHRoZSBpc3N1ZSBvZiBob3cgdG8g
Zm9yY2UgbXVsdGlwbGUgaW5jbHVzaW9uIHdoZW4gbmVjZXNzYXJ5IGluIGEgd2F5IHRoYXQg
ZG9lcyBub3QgcmVxdWlyZSBlZGl0aW5nIHRoZSBoZWFkZXIgaW4gcXVlc3Rpb24uIEJ5IHVz
aW5nIGEgcXVhbGlmaWVkIGlkZW50aWZpZXIsIHdlIHByb3ZpZGUgYW4gaW1wcm92ZWQgbWVj
aGFuaXNtIGZvciBhdm9pZGluZyBjb2xsaXNpb25zIHRoYXQgaXMgYWxzbyBhbWVuYWJsZSB0
byB0aGUgdXNlIG9mIHN0YXRpYyBhbmFseXNpcyB0b29scyB0byBkZXRlY3QgdGhlIHNvcnRz
IG9mIGltcHJvcGVyIHVzZSB0aGF0IGFyZSB0aGUgbWFqb3IgY29tcGxhaW50IGFnYWluc3Qg
dHJhZGl0aW9uYWwgZ3VhcmRzLiBCeSBhbHNvIHNwZWNpZnlpbmcgYW4gb3B0aW9uYWwgbWVj
aGFuaXNtIGZvciBwcm92aWRpbmcgdmVyc2lvbiBpbmZvcm1hdGlvbiwgd2UgcHJvdmlkZSBh
IG1lYW5zIHRvIGRpYWdub3NlIGFjY2lkZW50YWwgbWl4aW5nIG9mIGRpZmZlcmVudCB2ZXJz
aW9ucyBvZiBoZWFkZXJzLjwvcD4KPCEtLSAuLiAuLiAuLiAuLiAuLiAuLiAuLiAuLiAuLiAu
LiAuLiAuLiAuLiAuLiAuLiAuLiAuLiAuLiAuLiAuLiAuLiAuLiAuLiAuLiAuLiAtLT4KPCEt
LSBrYXRlOiBobCByZVN0cnVjdHVyZWRUZXh0IC0tPgo8L2Rpdj4KPC9kaXY+CjwvYm9keT4K
PC9odG1sPgo=
--------------010703060306050003000205
Content-Type: text/prs.fallenstein.rst;
 name="dxxxx-pragma-once.rst"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
 filename="dxxxx-pragma-once.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
  Qualified ``#pragma once``
=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:  Dxxxx
:Date:      2016-10-27
: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

This proposal recommends to standardize :cpp:`#pragma once(identifier)` a=
s an improved mechanism for preventing multiple inclusion of a header, an=
d a related directive :cpp:`#pragma forget(identifier)`.

=2E. contents::


Problem
=3D=3D=3D=3D=3D=3D=3D

It is well known that when compiling code of non-trivial complexity, the =
complete set of :cpp:`#include` directives may reference the same header =
more than once. This often occurs when a translation unit uses several di=
stinct components which each rely on the same base component (especially =
library configuration headers, headers that provide export decoration sym=
bols, and the like). While this is correct for each component header in o=
rder to allow it to be used on its own, the combination of multiple compo=
nents requires a mechanism to prevent the definitions in a header from be=
ing parsed twice, which would lead to compile errors.

Traditionally, this is accomplished with "include guards", which take the=
 form:

=2E. code:: c++

  // foo.h
  #ifndef _MYLIB_FOO_H_INCLUDED
  #define _MYLIB_FOO_H_INCLUDED
  ...
  #endif // _MYLIB_FOO_H_INCLUDED

At least one problem with this is obvious; the guard symbol is repeated a=
s many as three times (the last occurrence in the comment is optional and=
 at least has no impact on compiling if it is incorrect), leading to the =
possibility of mistakes when retyping the symbol that cause the guard to =
be ineffective. Less obvious, but even more problematic, it is common for=
 headers to be copied, which can lead to difficult to diagnose errors if =
the programmer neglects to adjust the guard when doing so.

Some compilers support ``#pragma once`` as an alternate mechanism for pre=
venting multiple inclusions. However, many problems with this mechanism a=
re known. It is difficult for compiler authors to implement correctly, es=
pecially in the presence of pathological source trees (involving copies o=
f headers, whether by symlink, or worse, the same physical file accessibl=
e via different mount points). There is also a question of how distinct h=
eaders providing similar definitions should be handled. These problems ar=
e well addressed by traditional include guards.


Proposal
=3D=3D=3D=3D=3D=3D=3D=3D

We propose to introduce three new preprocessor directives in an attempt t=
o address this issue.

:cpp:`#pragma once(identifier)`
-------------------------------

  **#pragma** **once** **(** *identifier* [ *version* ] **)**

The *identifier* shall follow the rules for a qualified C++ identifier. T=
he *version*, if specified, shall be a token string consisting of alphanu=
meric characters and/or the ``_``, ``-``, ``:`` or ``.`` characters, and =
shall set the version associated with the specified *identifier*. This di=
rective must appear as the first non-comment, non-whitespace contents of =
an :cpp:`#include` unit.

If a previous :cpp:`#pragma once` directive having the same *identifier* =
and *version* has been previously seen, the compiler shall ignore the rem=
ainder of the :cpp:`#include` unit. If the *identifier* is known but the =
*version* does not match, the program shall be ill-formed. (If *version* =
is unspecified, the version shall be the empty string.)

:cpp:`#pragma forget(identifier)`
---------------------------------

  **#pragma** **forget** **(** *identifier* **)**

The compiler shall remove the *identifier* from its collection of previou=
sly seen identifiers. This directive provides a mechanism to force the mu=
ltiple inclusion of an :cpp:`#include` unit which uses :cpp:`#pragma once=
(identifier)`.


Comments
=3D=3D=3D=3D=3D=3D=3D=3D

Static Analysis
---------------

As mentioned, one of the problems with traditional guards is that they ca=
n easily get out of sync with the header file they guard. While it is pos=
sible to write static analysis tools to detect such errors, the prolifera=
tion of different styles of guards make it difficult to write a single he=
uristic that works across a broad base of existing software. In turn, thi=
s means that such tools tend to be project specific and are at best run w=
hen code is committed to a repository. It would be far better for such ch=
ecks to be integrated into the compiler, so that they run at build time, =
and can be promoted to errors.

We address this by making the guard identifier a qualified C++ identifier=
=2E Besides being more consistent with C++ conventions (for example, the =
namespace of the guard could match the namespace of the project which own=
s the header), this, combined with the introduction of a new feature, mak=
es it straight forward to stipulate that the unqualified portion of the i=
dentifier shall match the name of the :cpp:`#include` unit (excluding a f=
ile extension, if any).

Moreover, it is not inconceivable that we could agree that the namespace =
portion of the qualified identifier shall match the namespace of the defi=
nitions provided by the :cpp:`#include` unit (so that all parts of the gu=
ard identifier are checked for correctness), with the compiler issuing a =
diagnostic if the :cpp:`#include` unit does not include at least one decl=
aration in the same namespace.

Since we are talking about QoI issues here, we feel that it is not necess=
ary that these checks be normative. Instead, we would prefer to let the c=
ompiler community agree on what conventions should be expected and diagno=
sed.

Proper Use of Versioning
------------------------

Although the "obvious" way to use version directives is to include the ve=
rsion of the software package to which a header belongs in every single h=
eader, this leads to an obvious and significant maintenance burden. A bet=
ter solution which will be equally adequate in almost every instance is t=
o maintain such version information in a single, global header file (e.g.=
 ``version.h``, ``config.h``, ``exports.h``) which is always included via=
 an :cpp:`#include` directive whose path is marked with quotes (\ ``""``\=
 ) rather than angle brackets (\ ``<>``\ ). This ensures that the global =
header is always found in a known location relative to the header being p=
rocessed, and will in almost all cases be sufficient to catch mismatching=
 versions of the header which includes the global header.

Another option, which can be employed in tandem, is to use a monotonicall=
y increasing version number that is unique to each header and is incremen=
ted whenever the interface(s) defined in the header change. Because this =
number is unique to the header, and only changes when the header changes =
(and possibly not even that frequently), the maintenance burden is signif=
icantly reduced.

The relatively liberal specification of allowed version strings was chose=
n with the specific intention of encouraging the version string to be gen=
erated by the build system, and in particular to allow the version string=
 to include a VCS identifier. In this way, we may ensure that headers fro=
m a development version of software are not mixed with those from a relea=
se version or different development version, even if the normative versio=
n number does not differ between such versions.

Performance
-----------

One of the points that is frequently raised in favor of unqualified :cpp:=
`#pragma once` is that it allows the compiler to skip reading a file that=
 it has already included. However, the problem with this is that if the c=
ompiler is not able to correctly determine if a header has already been i=
ncluded, it is likely that the translation unit will fail to compile.

In fact, compilers may and do already implement similar logic for traditi=
onal include guards. By employing a heuristic, a compiler may determine t=
hat a header's contents are entirely guarded. Having done so, the header =
and its guard may be entered into a map, such that the compiler may choos=
e not to read the header a second time if it observes that an :cpp:`#incl=
ude` directive would reference a header that has been previously processe=
d and whose include guard is defined. This is safer, since in case of a w=
rong guess, the compiler will read the header anyway and process it as em=
pty due to the traditional guard, which has a small performance penalty b=
ut does not affect correctness of the program.

Our model for :cpp:`#pragma once(identifier)` provides these same benefit=
s, while making explicit (and enforcing) that the entire header may be sk=
ipped if the compiler "knows" it has been included already. The proposed =
directive therefore provides the same performance benefits as unqualified=
 :cpp:`#pragma once`, but without the potential pitfalls.


Discussion
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

Won't modules make this irrelevant?
-----------------------------------

It is possible that modules will significantly reduce the need for this f=
eature, but modules aren't here yet, and it is likely that we will contin=
ue to have traditional headers for a long time. Since this feature happen=
s entirely at the preprocessor level, it is our sincere hope that compile=
rs will choose to implement the feature early, and enable it regardless o=
f the language level requested. This means that existing software may be =
able to take advantage of the feature much sooner than such software can =
be ported to modules (which will involve a much more invasive change).


Summary
=3D=3D=3D=3D=3D=3D=3D

We have shown a mechanism for implementing a next generation system for p=
reventing multiple inclusion of headers. This system is semantically equi=
valent to traditional guards, and so avoids the known issues of present i=
mplementations of :cpp:`#pragma once` (without an identifier). By also pr=
oviding a :cpp:`#pragma forget`, we address the issue of how to force mul=
tiple inclusion when necessary in a way that does not require editing the=
 header in question. By using a qualified identifier, we provide an impro=
ved mechanism for avoiding collisions that is also amenable to the use of=
 static analysis tools to detect the sorts of improper use that are the m=
ajor complaint against traditional guards. By also specifying an optional=
 mechanism for providing version information, we provide a means to diagn=
ose accidental mixing of different versions of headers.


=2E. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..=
 .. ..

=2E. |--| unicode:: U+02014 .. em dash
=2E. |para| unicode:: U+00B6 .. paragraph sign

=2E. kate: hl reStructuredText

--------------010703060306050003000205--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 27 Oct 2016 09:57:59 -0700 (PDT)
Raw View
------=_Part_335_153473334.1477587479270
Content-Type: multipart/alternative;
 boundary="----=_Part_336_520472733.1477587479270"

------=_Part_336_520472733.1477587479270
Content-Type: text/plain; charset=UTF-8

First, take note of 16.9, [cpp.pragma.op], which specifies that
`_Pragma(whatever)` shall be equivalent to `#pragma whatever`. So using
parentheses for `#pragma once` may not be viable. Instead, it should just
be `#pragma once Identifier version`, where `version` can be optional.

Also, I think it would be better to avoid the whole C++ qualified
identifier thing and just let people provide multiple names:

#pragma once MyLibrary HeaderName Random_SHA_Hash

Two pragmas of this type match if they provide the same identifiers in the
same order. That helps avoid collisions. I think this is much simpler than
the current proposal's use of qualified identifiers and versioning, while
retaining plenty of power.

That being said, I think we should avoid the use of `once`. That already
has a meaning for lots of compilers, and we shouldn't confuse the matter.
So we should come up with a different name for it. Perhaps `singular`.

--
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/0e0bd463-e6a2-44e4-b3e4-eb76a259a3f8%40isocpp.org.

------=_Part_336_520472733.1477587479270
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">First, take note of 16.9, [cpp.pragma.op], which specifies=
 that `_Pragma(whatever)` shall be equivalent to `#pragma whatever`. So usi=
ng parentheses for `#pragma once` may not be viable. Instead, it should jus=
t be `#pragma once Identifier version`, where `version` can be optional.<br=
><br>Also, I think it would be better to avoid the whole C++ qualified iden=
tifier thing and just let people provide multiple names:<br><br><div style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
 border-style: solid; border-width: 1px; overflow-wrap: break-word;" class=
=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #800;" class=3D"styled-by-prettify">#pragma</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> once </span><span s=
tyle=3D"color: #606;" class=3D"styled-by-prettify">MyLibrary</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #606;" class=3D"styled-by-prettify">HeaderName</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606=
;" class=3D"styled-by-prettify">Random_SHA_Hash</span></div></code></div><b=
r>Two pragmas of this type match if they provide the same identifiers in th=
e same order. That helps avoid collisions. I think this is much simpler tha=
n the current proposal&#39;s use of qualified identifiers and versioning, w=
hile retaining plenty of power.<br><br>That being said, I think we should a=
void the use of `once`. That already has a meaning for lots of compilers, a=
nd we shouldn&#39;t confuse the matter. So we should come up with a differe=
nt name for it. Perhaps `singular`.<br></div>

<p></p>

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

------=_Part_336_520472733.1477587479270--

------=_Part_335_153473334.1477587479270--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 27 Oct 2016 13:05:41 -0400
Raw View
--001a1143df746863b1053fdbc093
Content-Type: text/plain; charset=UTF-8

I haven't read it yet, but thanks for putting the time into trying to
formalize an actual solution.

On Thu, Oct 27, 2016 at 12:34 PM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:

> After the recent thread rehashing this yet again, I'm sure some folks
> will be surprised to see me on the other side of the issue. However, all
> the noise got me to thinking how we might actually do this correctly...
>
> This is *not* a proposal for *unqualified* `#pragma once` (it is
> mentioned in the paper, but remains explicitly implementation defined).
> Instead, it proposes a *qualified* `#pragma once(identifier)` which
> solves the problems of unqualified `#pragma once` (by being semantically
> equivalent to correctly used traditional guards). The problem of
> choosing the correct identifier is addressed by making the identifier a
> qualified C++ identifier, such that it is easy for static analysis tools
> to enforce that the (final part of the) identifier matches the header
> file name (ideally this would be a compiler warning that many projects
> would promote to an error by default). A versioning system is also
> proposed to catch errors where multiple (possibly incompatible) versions
> of the same header are referenced.
>
> Draft proposal attached. Please let me know what you think!
>
> --
> 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/58122C8D.9060205%40gmail.com.
>

--
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/CANh8DEm-pwt4jr8teaxOwsKvyB1gLQ8WK7m9W7egA%3DKehoPNMw%40mail.gmail.com.

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

<div dir=3D"ltr">I haven&#39;t read it yet, but thanks for putting the time=
 into trying to formalize an actual solution.</div><div class=3D"gmail_extr=
a"><br><div class=3D"gmail_quote">On Thu, Oct 27, 2016 at 12:34 PM, Matthew=
 Woehlke <span dir=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" =
target=3D"_blank">mwoehlke.floss@gmail.com</a>&gt;</span> wrote:<br><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex">After the recent thread rehashing this yet again, I=
&#39;m sure some folks<br>
will be surprised to see me on the other side of the issue. However, all<br=
>
the noise got me to thinking how we might actually do this correctly...<br>
<br>
This is *not* a proposal for *unqualified* `#pragma once` (it is<br>
mentioned in the paper, but remains explicitly implementation defined).<br>
Instead, it proposes a *qualified* `#pragma once(identifier)` which<br>
solves the problems of unqualified `#pragma once` (by being semantically<br=
>
equivalent to correctly used traditional guards). The problem of<br>
choosing the correct identifier is addressed by making the identifier a<br>
qualified C++ identifier, such that it is easy for static analysis tools<br=
>
to enforce that the (final part of the) identifier matches the header<br>
file name (ideally this would be a compiler warning that many projects<br>
would promote to an error by default). A versioning system is also<br>
proposed to catch errors where multiple (possibly incompatible) versions<br=
>
of the same header are referenced.<br>
<br>
Draft proposal attached. Please let me know what you think!<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br>
--<br>
Matthew<br>
<br>
--<br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-propo=
sals+unsubscribe@<wbr>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/58122C8D.9060205%40gmail.com" rel=3D"=
noreferrer" target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d=
/msgid/std-<wbr>proposals/58122C8D.9060205%<wbr>40gmail.com</a>.<br>
</font></span></blockquote></div><br></div>

<p></p>

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

--001a1143df746863b1053fdbc093--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 27 Oct 2016 20:09:38 +0300
Raw View
On 27 October 2016 at 19:34, Matthew Woehlke <mwoehlke.floss@gmail.com> wrote:
> After the recent thread rehashing this yet again, I'm sure some folks
> will be surprised to see me on the other side of the issue. However, all
> the noise got me to thinking how we might actually do this correctly...
>
> This is *not* a proposal for *unqualified* `#pragma once` (it is
> mentioned in the paper, but remains explicitly implementation defined).
> Instead, it proposes a *qualified* `#pragma once(identifier)` which
> solves the problems of unqualified `#pragma once` (by being semantically
> equivalent to correctly used traditional guards). The problem of
> choosing the correct identifier is addressed by making the identifier a
> qualified C++ identifier, such that it is easy for static analysis tools
> to enforce that the (final part of the) identifier matches the header
> file name (ideally this would be a compiler warning that many projects
> would promote to an error by default). A versioning system is also
> proposed to catch errors where multiple (possibly incompatible) versions
> of the same header are referenced.
>
> Draft proposal attached. Please let me know what you think!


Well, let's cut to the chase, shall we? :) If it's going to be
standardized, it shouldn't
be a #pragma, right? A #pragma is by definition an
implementation-defined facility.

Another big snag that tends to come up with preprocessor improvements
is that some
audiences think C should adopt those improvements as well as C++. Who is going
to fight that fight in WG14?

--
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/CAFk2RUZS5A18KCAUzYpLNbuRd1Ta-9nupTURcKodbbj5m7KDOw%40mail.gmail.com.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 27 Oct 2016 13:17:01 -0400
Raw View
On 2016-10-27 12:57, Nicol Bolas wrote:
> First, take note of 16.9, [cpp.pragma.op], which specifies that
> `_Pragma(whatever)` shall be equivalent to `#pragma whatever`. So using
> parentheses for `#pragma once` may not be viable. Instead, it should just
> be `#pragma once Identifier version`, where `version` can be optional.

  _Pragma(once(hi there))

....not sure there is a problem here?

That said, I used `#pragma once` for obvious reasons, but an entirely
new directive might be better.

> Also, I think it would be better to avoid the whole C++ qualified
> identifier thing and just let people provide multiple names:
>
> #pragma once MyLibrary HeaderName Random_SHA_Hash
>
> Two pragmas of this type match if they provide the same identifiers in the
> same order. That helps avoid collisions. I think this is much simpler than
> the current proposal's use of qualified identifiers and versioning, while
> retaining plenty of power.

If we do that, how do we implement the diagnostic if the wrong guard is
used? The choice of a qualified identifier was specifically so it would
be *very easy* for the compiler to issue a diagnostic for code like:

  // foo.h
  #pragma once(example::bar 0.1) // warning: expected `example::foo`

Plus there is the potential of trying to catch namespace mismatches:

  // tests/foo.h
  #pragma once example::corelib::foo

  namespace example {
  namespace test {
  ...
  }
  }
  // warning: no declarations in namespace `example::corelib` found

I consider at least the first the *core* of the proposal. The whole
point is to do better than traditional guards, the biggest problem of
which is forgetting to change them when an existing header is copied to
create a new header. If we don't solve that, what's the point?

> That being said, I think we should avoid the use of `once`. That already
> has a meaning for lots of compilers, and we shouldn't confuse the matter.
> So we should come up with a different name for it. Perhaps `singular`.

I should probably add a bikeshed section. Per above, a non-pragma such
as `#once`, #singular`, `#guard`, etc. could also be used. (Okay, per
Ville's comments, *should* be used. But then we're into the whole Naming
Things problem...)

--
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/5812368D.8050109%40gmail.com.

.


Author: "T. C." <rs2740@gmail.com>
Date: Thu, 27 Oct 2016 13:37:38 -0700 (PDT)
Raw View
------=_Part_450_703539175.1477600658860
Content-Type: multipart/alternative;
 boundary="----=_Part_451_609994626.1477600658860"

------=_Part_451_609994626.1477600658860
Content-Type: text/plain; charset=UTF-8



On Thursday, October 27, 2016 at 12:57:59 PM UTC-4, Nicol Bolas wrote:
>
> First, take note of 16.9, [cpp.pragma.op], which specifies that
> `_Pragma(whatever)` shall be equivalent to `#pragma whatever`. So using
> parentheses for `#pragma once` may not be viable. Instead, it should just
> be `#pragma once Identifier version`, where `version` can be optional.
>

No, it's `_Pragma("whatever")` vs. `#pragma whatever`. _Pragma always takes
a single string literal.

--
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/a4317df3-2a97-46ba-b8d4-33f27a45d5e5%40isocpp.org.

------=_Part_451_609994626.1477600658860
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, October 27, 2016 at 12:57:59 PM UTC-4=
, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">First, take note of 16.9, [cpp.pragma.op], which specifies that `_=
Pragma(whatever)` shall be equivalent to `#pragma whatever`. So using paren=
theses for `#pragma once` may not be viable. Instead, it should just be `#p=
ragma once Identifier version`, where `version` can be optional.</div></blo=
ckquote><div><br></div><div>No, it&#39;s `_Pragma(&quot;whatever&quot;)` vs=
.. `#pragma whatever`. _Pragma always takes a single string literal.</div><d=
iv><br></div></div>

<p></p>

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

------=_Part_451_609994626.1477600658860--

------=_Part_450_703539175.1477600658860--

.


Author: Erich Keane <erich.keane@verizon.net>
Date: Thu, 27 Oct 2016 15:59:04 -0700 (PDT)
Raw View
------=_Part_860_1793766423.1477609145029
Content-Type: multipart/alternative;
 boundary="----=_Part_861_947457219.1477609145030"

------=_Part_861_947457219.1477609145030
Content-Type: text/plain; charset=UTF-8



On Thursday, October 27, 2016 at 10:09:40 AM UTC-7, Ville Voutilainen wrote:
>
> On 27 October 2016 at 19:34, Matthew Woehlke <mwoehlk...@gmail.com
> <javascript:>> wrote:
> > After the recent thread rehashing this yet again, I'm sure some folks
> > will be surprised to see me on the other side of the issue. However, all
> > the noise got me to thinking how we might actually do this correctly...
> >
> > This is *not* a proposal for *unqualified* `#pragma once` (it is
> > mentioned in the paper, but remains explicitly implementation defined).
> > Instead, it proposes a *qualified* `#pragma once(identifier)` which
> > solves the problems of unqualified `#pragma once` (by being semantically
> > equivalent to correctly used traditional guards). The problem of
> > choosing the correct identifier is addressed by making the identifier a
> > qualified C++ identifier, such that it is easy for static analysis tools
> > to enforce that the (final part of the) identifier matches the header
> > file name (ideally this would be a compiler warning that many projects
> > would promote to an error by default). A versioning system is also
> > proposed to catch errors where multiple (possibly incompatible) versions
> > of the same header are referenced.
> >
> > Draft proposal attached. Please let me know what you think!
>
>
> Well, let's cut to the chase, shall we? :) If it's going to be
> standardized, it shouldn't
> be a #pragma, right? A #pragma is by definition an
> implementation-defined facility.
>
>
In C++ that is the case, however note that the C standard has a number of
#pragma statements in it.

Another big snag that tends to come up with preprocessor improvements
> is that some
> audiences think C should adopt those improvements as well as C++. Who is
> going
> to fight that fight in WG14?
>

I'm not sure that is a universal necessity.   It would be NICE, but C++ and
C preprocessors already diverge if this is to be trusted:
http://stackoverflow.com/questions/21515608/what-are-the-differences-between-the-c-and-c-preprocessors



--
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/9a557427-bede-4987-ab6a-a73b9b53a305%40isocpp.org.

------=_Part_861_947457219.1477609145030
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, October 27, 2016 at 10:09:40 AM UTC-7=
, Ville Voutilainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2=
7 October 2016 at 19:34, Matthew Woehlke &lt;<a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"ctvEvmPPAQAJ" rel=3D"nofollow" onmouse=
down=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.hre=
f=3D&#39;javascript:&#39;;return true;">mwoehlk...@gmail.com</a>&gt; wrote:
<br>&gt; After the recent thread rehashing this yet again, I&#39;m sure som=
e folks
<br>&gt; will be surprised to see me on the other side of the issue. Howeve=
r, all
<br>&gt; the noise got me to thinking how we might actually do this correct=
ly...
<br>&gt;
<br>&gt; This is *not* a proposal for *unqualified* `#pragma once` (it is
<br>&gt; mentioned in the paper, but remains explicitly implementation defi=
ned).
<br>&gt; Instead, it proposes a *qualified* `#pragma once(identifier)` whic=
h
<br>&gt; solves the problems of unqualified `#pragma once` (by being semant=
ically
<br>&gt; equivalent to correctly used traditional guards). The problem of
<br>&gt; choosing the correct identifier is addressed by making the identif=
ier a
<br>&gt; qualified C++ identifier, such that it is easy for static analysis=
 tools
<br>&gt; to enforce that the (final part of the) identifier matches the hea=
der
<br>&gt; file name (ideally this would be a compiler warning that many proj=
ects
<br>&gt; would promote to an error by default). A versioning system is also
<br>&gt; proposed to catch errors where multiple (possibly incompatible) ve=
rsions
<br>&gt; of the same header are referenced.
<br>&gt;
<br>&gt; Draft proposal attached. Please let me know what you think!
<br>
<br>
<br>Well, let&#39;s cut to the chase, shall we? :) If it&#39;s going to be
<br>standardized, it shouldn&#39;t
<br>be a #pragma, right? A #pragma is by definition an
<br>implementation-defined facility.
<br>
<br></blockquote><div><br>In C++ that is the case, however note that the C =
standard has a number of #pragma statements in it.=C2=A0 <br><br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;">Another big snag that tends to com=
e up with preprocessor improvements
<br>is that some
<br>audiences think C should adopt those improvements as well as C++. Who i=
s going
<br>to fight that fight in WG14?
<br></blockquote><div><br>I&#39;m not sure that is a universal necessity. =
=C2=A0 It would be NICE, but C++ and C preprocessors already diverge if thi=
s is to be trusted: http://stackoverflow.com/questions/21515608/what-are-th=
e-differences-between-the-c-and-c-preprocessors<br></div><div>=C2=A0</div><=
div>=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&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9a557427-bede-4987-ab6a-a73b9b53a305%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9a557427-bede-4987-ab6a-a73b9b53a305=
%40isocpp.org</a>.<br />

------=_Part_861_947457219.1477609145030--

------=_Part_860_1793766423.1477609145029--

.


Author: Greg Marr <gregmmarr@gmail.com>
Date: Fri, 28 Oct 2016 05:08:32 -0700 (PDT)
Raw View
------=_Part_869_602980353.1477656512808
Content-Type: multipart/alternative;
 boundary="----=_Part_870_848588375.1477656512808"

------=_Part_870_848588375.1477656512808
Content-Type: text/plain; charset=UTF-8

On Thursday, October 27, 2016 at 12:57:59 PM UTC-4, Nicol Bolas wrote:
>
> First, take note of 16.9, [cpp.pragma.op], which specifies that
> `_Pragma(whatever)` shall be equivalent to `#pragma whatever`. So using
> parentheses for `#pragma once` may not be viable. Instead, it should just
> be `#pragma once Identifier version`, where `version` can be optional.
>

Many of the MSVC pragmas use the `#pragma whatever(stuff)` form:

#pragma warning(push, 4)
#pragma comment(lib, "foo.lib")

--
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/12f0e226-7ded-4140-bc93-8077d3a4c0ee%40isocpp.org.

------=_Part_870_848588375.1477656512808
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, October 27, 2016 at 12:57:59 PM UTC-4, Nicol =
Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">F=
irst, take note of 16.9, [cpp.pragma.op], which specifies that `_Pragma(wha=
tever)` shall be equivalent to `#pragma whatever`. So using parentheses for=
 `#pragma once` may not be viable. Instead, it should just be `#pragma once=
 Identifier version`, where `version` can be optional.<br></div></blockquot=
e><div><br></div><div>Many of the MSVC pragmas use the `#pragma whatever(st=
uff)` form:</div><div><br></div><div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-sty=
le: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #800;" class=3D"=
styled-by-prettify">#pragma</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> warning</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">push</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #066;" class=3D"styled-by-prettify">4</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #80=
0;" class=3D"styled-by-prettify">#pragma</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> comment</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">lib</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;=
foo.lib&quot;</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span></div></code></div><div><br></div></div>

<p></p>

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

------=_Part_870_848588375.1477656512808--

------=_Part_869_602980353.1477656512808--

.


Author: "T. C." <rs2740@gmail.com>
Date: Fri, 28 Oct 2016 12:27:19 -0700 (PDT)
Raw View
------=_Part_679_670549345.1477682839819
Content-Type: multipart/alternative;
 boundary="----=_Part_680_2115281394.1477682839819"

------=_Part_680_2115281394.1477682839819
Content-Type: text/plain; charset=UTF-8

The technical specification needs reworking, and having some examples would
be nice to illustrate what is and isn't proposed to be permitted.

For example, the *identifier *production has an existing meaning and is
always "unqualified". If "a qualified C++ identifier" means a *qualified-id,
*it doesn't work because that relies on things that don't exist during
preprocessing (*type-name*, *namespace-name, template-**name *etc.), and I
don't think it makes much sense to allow a *decltype-specifier* etc. in
there anyway.

You seem to want something like

*once-guard* :
    *identifier*
*    once-guard *::* identifier*

*version'*s actual production is unclear, and as described it seems to
result in ambiguities as to where the "identifier" ends and where "version"
begins.  Might be more reasonable to require it to be wrapped into a string
literal or separated by a comma.

--
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/65c2ed7c-e47e-46cb-af9d-d692f0fc2b47%40isocpp.org.

------=_Part_680_2115281394.1477682839819
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>The technical specification needs reworking, and havi=
ng some examples would be nice to illustrate what is and isn&#39;t proposed=
 to be permitted.<br></div><div><br></div><div>For example, the <i>identifi=
er </i>production has an existing meaning and is always &quot;unqualified&q=
uot;. If &quot;a qualified C++ identifier&quot; means a <i>qualified-id, </=
i>it doesn&#39;t work because that relies on things that don&#39;t exist du=
ring preprocessing (<i>type-name</i>, <i>namespace-name, template-</i><i>na=
me </i>etc.), and I don&#39;t think it makes much sense to allow a <i>declt=
ype-specifier</i>=C2=A0etc. in there anyway.</div><div><br></div><div>You s=
eem to want something like</div><div><br></div><div><i>once-guard</i>=C2=A0=
:</div><div>=C2=A0 =C2=A0 <i>identifier</i></div><div><i>=C2=A0 =C2=A0 once=
-guard </i>::<i> identifier</i></div><div><br></div><div><i>version&#39;</i=
>s actual production is unclear, and as described it seems to result in amb=
iguities as to where the &quot;identifier&quot; ends and where &quot;versio=
n&quot; begins. =C2=A0Might be more reasonable to require it to be wrapped =
into a string literal or separated by a comma.</div></div>

<p></p>

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

------=_Part_680_2115281394.1477682839819--

------=_Part_679_670549345.1477682839819--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 28 Oct 2016 15:58:10 -0400
Raw View
On 2016-10-28 15:27, T. C. wrote:
> The technical specification needs reworking, and having some examples would
> be nice to illustrate what is and isn't proposed to be permitted.
> [details]

Okay, I think I see what you're saying. I'll add some examples.

While I agree having a good initial version is desirable, I hope to not
get too bogged down in details at this time. I think it will be more
useful to see first what the committee's general stance is on adding
such a feature.

> *version'*s actual production is unclear, and as described it seems to
> result in ambiguities as to where the "identifier" ends and where "version"
> begins.

They are separated by whitespace.

I'll post a new version in a bit; there have been a couple changes,
including to address your suggestions (thanks!).

--
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/5813ADD2.5070609%40gmail.com.

.


Author: "T. C." <rs2740@gmail.com>
Date: Fri, 28 Oct 2016 13:01:11 -0700 (PDT)
Raw View
------=_Part_820_1616387777.1477684871269
Content-Type: multipart/alternative;
 boundary="----=_Part_821_611842669.1477684871269"

------=_Part_821_611842669.1477684871269
Content-Type: text/plain; charset=UTF-8


On Friday, October 28, 2016 at 3:58:13 PM UTC-4, Matthew Woehlke wrote:
>
>
> > *version'*s actual production is unclear, and as described it seems to
> > result in ambiguities as to where the "identifier" ends and where
> "version"
> > begins.
>
> They are separated by whitespace.
>
> I'll post a new version in a bit; there have been a couple changes,
> including to address your suggestions (thanks!).
>
> --
> Matthew
>

#pragma once (std :: vector :: foo :: bar :: 1.0).

Where does the "qualified C++ identifier" end and where does "version"
begin? Or are you saying that unlike actual "qualified C++ identifier"s,
you can't have whitespace here?

--
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/46bd0615-dd74-464d-8885-34f52d839fa5%40isocpp.org.

------=_Part_821_611842669.1477684871269
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br>On Friday, October 28, 2016 at 3:58:13 PM UTC-4, Matth=
ew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br>&gt; *ver=
sion&#39;*s actual production is unclear, and as described it seems to=20
<br>&gt; result in ambiguities as to where the &quot;identifier&quot; ends =
and where &quot;version&quot;=20
<br>&gt; begins.
<br>
<br>They are separated by whitespace.
<br>
<br>I&#39;ll post a new version in a bit; there have been a couple changes,
<br>including to address your suggestions (thanks!).
<br>
<br>--=20
<br>Matthew
<br></blockquote><div><br></div><div>#pragma once (std :: vector :: foo :: =
bar :: 1.0).</div><div><br></div><div>Where does the &quot;qualified C++ id=
entifier&quot; end and where does &quot;version&quot; begin? Or are you say=
ing that unlike actual &quot;qualified C++ identifier&quot;s, you can&#39;t=
 have whitespace here?=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&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/46bd0615-dd74-464d-8885-34f52d839fa5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/46bd0615-dd74-464d-8885-34f52d839fa5=
%40isocpp.org</a>.<br />

------=_Part_821_611842669.1477684871269--

------=_Part_820_1616387777.1477684871269--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 28 Oct 2016 16:33:20 -0400
Raw View
On 2016-10-28 16:01, T. C. wrote:
> #pragma once (std :: vector :: foo :: bar :: 1.0).
>
> Where does the "qualified C++ identifier" end and where does "version"
> begin?

Um... I think this would be an error; `1.0` isn't a valid identifier.

> Or are you saying that unlike actual "qualified C++ identifier"s,
> you can't have whitespace here?

I wasn't thinking about whitespace, actually... Okay, I see the problem:

  #once hello ::world

If we allow whitespace between 'parts' of the name, is that 'hello',
version '::world', or 'hello::world' with no version?

That's easy to fix; forbid the version starting with `:`. Maybe the
version doesn't even need `:`; that usually only shows up in
distribution package versions for unusual reasons related to
distribution packaging (that delve into the horribly complicated realm
of version number sorting).

I believe this makes the parsing simple: whitespace followed by
not-a-`:` separates the version from the name. Then we can also allow
(and ignore) whitespace around `::`.

Note: the version may *not* contain whitespace.

--
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/5813B610.10106%40gmail.com.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 28 Oct 2016 16:40:25 -0400
Raw View
This is a multi-part message in MIME format.
--------------040904030303050009050103
Content-Type: text/plain; charset=UTF-8

Here's an updated draft. Added some examples and fixed some issues noted
by T.C. (thanks!).

Also, it is now `#once` - no more `#pragma`s - and the requirement that
`#once` is the first meaningful content has been dropped.

--
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/5813B7B9.1060106%40gmail.com.

--------------040904030303050009050103
Content-Type: text/html; charset=UTF-8;
 name="dxxxx-preprocessor-once.html"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="dxxxx-preprocessor-once.html"

PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjwhRE9DVFlQRSBodG1s
IFBVQkxJQyAiLS8vVzNDLy9EVEQgWEhUTUwgMS4wIFRyYW5zaXRpb25hbC8vRU4iICJodHRw
Oi8vd3d3LnczLm9yZy9UUi94aHRtbDEvRFREL3hodG1sMS10cmFuc2l0aW9uYWwuZHRkIj4K
PGh0bWwgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiIHhtbDpsYW5nPSJl
biIgbGFuZz0iZW4iPgo8aGVhZD4KPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBj
b250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLTgiIC8+CjxtZXRhIG5hbWU9ImdlbmVy
YXRvciIgY29udGVudD0iRG9jdXRpbHMgMC4xMjogaHR0cDovL2RvY3V0aWxzLnNvdXJjZWZv
cmdlLm5ldC8iIC8+Cjx0aXRsZT5BIFF1YWxpZmllZCBSZXBsYWNlbWVudCBmb3IgI3ByYWdt
YSBvbmNlPC90aXRsZT4KPG1ldGEgbmFtZT0iZGF0ZSIgY29udGVudD0iMjAxNi0xMC0yNyIg
Lz4KPG1ldGEgbmFtZT0iYXV0aG9yIiBjb250ZW50PSJNYXR0aGV3IFdvZWhsa2UgKG13b2Vo
bGtlLmZsb3NzJiM2NDtnbWFpbC5jb20pIiAvPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoK
LyoKOkF1dGhvcjogRGF2aWQgR29vZGdlciAoZ29vZGdlckBweXRob24ub3JnKQo6SWQ6ICRJ
ZDogaHRtbDRjc3MxLmNzcyA3NjE0IDIwMTMtMDItMjEgMTU6NTU6NTFaIG1pbGRlICQKOkNv
cHlyaWdodDogVGhpcyBzdHlsZXNoZWV0IGhhcyBiZWVuIHBsYWNlZCBpbiB0aGUgcHVibGlj
IGRvbWFpbi4KCkRlZmF1bHQgY2FzY2FkaW5nIHN0eWxlIHNoZWV0IGZvciB0aGUgSFRNTCBv
dXRwdXQgb2YgRG9jdXRpbHMuCgpTZWUgaHR0cDovL2RvY3V0aWxzLnNmLm5ldC9kb2NzL2hv
d3RvL2h0bWwtc3R5bGVzaGVldHMuaHRtbCBmb3IgaG93IHRvCmN1c3RvbWl6ZSB0aGlzIHN0
eWxlIHNoZWV0LgoqLwoKLyogdXNlZCB0byByZW1vdmUgYm9yZGVycyBmcm9tIHRhYmxlcyBh
bmQgaW1hZ2VzICovCi5ib3JkZXJsZXNzLCB0YWJsZS5ib3JkZXJsZXNzIHRkLCB0YWJsZS5i
b3JkZXJsZXNzIHRoIHsKICBib3JkZXI6IDAgfQoKdGFibGUuYm9yZGVybGVzcyB0ZCwgdGFi
bGUuYm9yZGVybGVzcyB0aCB7CiAgLyogT3ZlcnJpZGUgcGFkZGluZyBmb3IgInRhYmxlLmRv
Y3V0aWxzIHRkIiB3aXRoICIhIGltcG9ydGFudCIuCiAgICAgVGhlIHJpZ2h0IHBhZGRpbmcg
c2VwYXJhdGVzIHRoZSB0YWJsZSBjZWxscy4gKi8KICBwYWRkaW5nOiAwIDAuNWVtIDAgMCAh
IGltcG9ydGFudCB9CgouZmlyc3QgewogIC8qIE92ZXJyaWRlIG1vcmUgc3BlY2lmaWMgbWFy
Z2luIHN0eWxlcyB3aXRoICIhIGltcG9ydGFudCIuICovCiAgbWFyZ2luLXRvcDogMCAhIGlt
cG9ydGFudCB9CgoubGFzdCwgLndpdGgtc3VidGl0bGUgewogIG1hcmdpbi1ib3R0b206IDAg
ISBpbXBvcnRhbnQgfQoKLmhpZGRlbiB7CiAgZGlzcGxheTogbm9uZSB9CgphLnRvYy1iYWNr
cmVmIHsKICB0ZXh0LWRlY29yYXRpb246IG5vbmUgOwogIGNvbG9yOiBibGFjayB9CgpibG9j
a3F1b3RlLmVwaWdyYXBoIHsKICBtYXJnaW46IDJlbSA1ZW0gOyB9CgpkbC5kb2N1dGlscyBk
ZCB7CiAgbWFyZ2luLWJvdHRvbTogMC41ZW0gfQoKb2JqZWN0W3R5cGU9ImltYWdlL3N2Zyt4
bWwiXSwgb2JqZWN0W3R5cGU9ImFwcGxpY2F0aW9uL3gtc2hvY2t3YXZlLWZsYXNoIl0gewog
IG92ZXJmbG93OiBoaWRkZW47Cn0KCi8qIFVuY29tbWVudCAoYW5kIHJlbW92ZSB0aGlzIHRl
eHQhKSB0byBnZXQgYm9sZC1mYWNlZCBkZWZpbml0aW9uIGxpc3QgdGVybXMKZGwuZG9jdXRp
bHMgZHQgewogIGZvbnQtd2VpZ2h0OiBib2xkIH0KKi8KCmRpdi5hYnN0cmFjdCB7CiAgbWFy
Z2luOiAyZW0gNWVtIH0KCmRpdi5hYnN0cmFjdCBwLnRvcGljLXRpdGxlIHsKICBmb250LXdl
aWdodDogYm9sZCA7CiAgdGV4dC1hbGlnbjogY2VudGVyIH0KCmRpdi5hZG1vbml0aW9uLCBk
aXYuYXR0ZW50aW9uLCBkaXYuY2F1dGlvbiwgZGl2LmRhbmdlciwgZGl2LmVycm9yLApkaXYu
aGludCwgZGl2LmltcG9ydGFudCwgZGl2Lm5vdGUsIGRpdi50aXAsIGRpdi53YXJuaW5nIHsK
ICBtYXJnaW46IDJlbSA7CiAgYm9yZGVyOiBtZWRpdW0gb3V0c2V0IDsKICBwYWRkaW5nOiAx
ZW0gfQoKZGl2LmFkbW9uaXRpb24gcC5hZG1vbml0aW9uLXRpdGxlLCBkaXYuaGludCBwLmFk
bW9uaXRpb24tdGl0bGUsCmRpdi5pbXBvcnRhbnQgcC5hZG1vbml0aW9uLXRpdGxlLCBkaXYu
bm90ZSBwLmFkbW9uaXRpb24tdGl0bGUsCmRpdi50aXAgcC5hZG1vbml0aW9uLXRpdGxlIHsK
ICBmb250LXdlaWdodDogYm9sZCA7CiAgZm9udC1mYW1pbHk6IHNhbnMtc2VyaWYgfQoKZGl2
LmF0dGVudGlvbiBwLmFkbW9uaXRpb24tdGl0bGUsIGRpdi5jYXV0aW9uIHAuYWRtb25pdGlv
bi10aXRsZSwKZGl2LmRhbmdlciBwLmFkbW9uaXRpb24tdGl0bGUsIGRpdi5lcnJvciBwLmFk
bW9uaXRpb24tdGl0bGUsCmRpdi53YXJuaW5nIHAuYWRtb25pdGlvbi10aXRsZSwgLmNvZGUg
LmVycm9yIHsKICBjb2xvcjogcmVkIDsKICBmb250LXdlaWdodDogYm9sZCA7CiAgZm9udC1m
YW1pbHk6IHNhbnMtc2VyaWYgfQoKLyogVW5jb21tZW50IChhbmQgcmVtb3ZlIHRoaXMgdGV4
dCEpIHRvIGdldCByZWR1Y2VkIHZlcnRpY2FsIHNwYWNlIGluCiAgIGNvbXBvdW5kIHBhcmFn
cmFwaHMuCmRpdi5jb21wb3VuZCAuY29tcG91bmQtZmlyc3QsIGRpdi5jb21wb3VuZCAuY29t
cG91bmQtbWlkZGxlIHsKICBtYXJnaW4tYm90dG9tOiAwLjVlbSB9CgpkaXYuY29tcG91bmQg
LmNvbXBvdW5kLWxhc3QsIGRpdi5jb21wb3VuZCAuY29tcG91bmQtbWlkZGxlIHsKICBtYXJn
aW4tdG9wOiAwLjVlbSB9CiovCgpkaXYuZGVkaWNhdGlvbiB7CiAgbWFyZ2luOiAyZW0gNWVt
IDsKICB0ZXh0LWFsaWduOiBjZW50ZXIgOwogIGZvbnQtc3R5bGU6IGl0YWxpYyB9CgpkaXYu
ZGVkaWNhdGlvbiBwLnRvcGljLXRpdGxlIHsKICBmb250LXdlaWdodDogYm9sZCA7CiAgZm9u
dC1zdHlsZTogbm9ybWFsIH0KCmRpdi5maWd1cmUgewogIG1hcmdpbi1sZWZ0OiAyZW0gOwog
IG1hcmdpbi1yaWdodDogMmVtIH0KCmRpdi5mb290ZXIsIGRpdi5oZWFkZXIgewogIGNsZWFy
OiBib3RoOwogIGZvbnQtc2l6ZTogc21hbGxlciB9CgpkaXYubGluZS1ibG9jayB7CiAgZGlz
cGxheTogYmxvY2sgOwogIG1hcmdpbi10b3A6IDFlbSA7CiAgbWFyZ2luLWJvdHRvbTogMWVt
IH0KCmRpdi5saW5lLWJsb2NrIGRpdi5saW5lLWJsb2NrIHsKICBtYXJnaW4tdG9wOiAwIDsK
ICBtYXJnaW4tYm90dG9tOiAwIDsKICBtYXJnaW4tbGVmdDogMS41ZW0gfQoKZGl2LnNpZGVi
YXIgewogIG1hcmdpbjogMCAwIDAuNWVtIDFlbSA7CiAgYm9yZGVyOiBtZWRpdW0gb3V0c2V0
IDsKICBwYWRkaW5nOiAxZW0gOwogIGJhY2tncm91bmQtY29sb3I6ICNmZmZmZWUgOwogIHdp
ZHRoOiA0MCUgOwogIGZsb2F0OiByaWdodCA7CiAgY2xlYXI6IHJpZ2h0IH0KCmRpdi5zaWRl
YmFyIHAucnVicmljIHsKICBmb250LWZhbWlseTogc2Fucy1zZXJpZiA7CiAgZm9udC1zaXpl
OiBtZWRpdW0gfQoKZGl2LnN5c3RlbS1tZXNzYWdlcyB7CiAgbWFyZ2luOiA1ZW0gfQoKZGl2
LnN5c3RlbS1tZXNzYWdlcyBoMSB7CiAgY29sb3I6IHJlZCB9CgpkaXYuc3lzdGVtLW1lc3Nh
Z2UgewogIGJvcmRlcjogbWVkaXVtIG91dHNldCA7CiAgcGFkZGluZzogMWVtIH0KCmRpdi5z
eXN0ZW0tbWVzc2FnZSBwLnN5c3RlbS1tZXNzYWdlLXRpdGxlIHsKICBjb2xvcjogcmVkIDsK
ICBmb250LXdlaWdodDogYm9sZCB9CgpkaXYudG9waWMgewogIG1hcmdpbjogMmVtIH0KCmgx
LnNlY3Rpb24tc3VidGl0bGUsIGgyLnNlY3Rpb24tc3VidGl0bGUsIGgzLnNlY3Rpb24tc3Vi
dGl0bGUsCmg0LnNlY3Rpb24tc3VidGl0bGUsIGg1LnNlY3Rpb24tc3VidGl0bGUsIGg2LnNl
Y3Rpb24tc3VidGl0bGUgewogIG1hcmdpbi10b3A6IDAuNGVtIH0KCmgxLnRpdGxlIHsKICB0
ZXh0LWFsaWduOiBjZW50ZXIgfQoKaDIuc3VidGl0bGUgewogIHRleHQtYWxpZ246IGNlbnRl
ciB9Cgpoci5kb2N1dGlscyB7CiAgd2lkdGg6IDc1JSB9CgppbWcuYWxpZ24tbGVmdCwgLmZp
Z3VyZS5hbGlnbi1sZWZ0LCBvYmplY3QuYWxpZ24tbGVmdCB7CiAgY2xlYXI6IGxlZnQgOwog
IGZsb2F0OiBsZWZ0IDsKICBtYXJnaW4tcmlnaHQ6IDFlbSB9CgppbWcuYWxpZ24tcmlnaHQs
IC5maWd1cmUuYWxpZ24tcmlnaHQsIG9iamVjdC5hbGlnbi1yaWdodCB7CiAgY2xlYXI6IHJp
Z2h0IDsKICBmbG9hdDogcmlnaHQgOwogIG1hcmdpbi1sZWZ0OiAxZW0gfQoKaW1nLmFsaWdu
LWNlbnRlciwgLmZpZ3VyZS5hbGlnbi1jZW50ZXIsIG9iamVjdC5hbGlnbi1jZW50ZXIgewog
IGRpc3BsYXk6IGJsb2NrOwogIG1hcmdpbi1sZWZ0OiBhdXRvOwogIG1hcmdpbi1yaWdodDog
YXV0bzsKfQoKLmFsaWduLWxlZnQgewogIHRleHQtYWxpZ246IGxlZnQgfQoKLmFsaWduLWNl
bnRlciB7CiAgY2xlYXI6IGJvdGggOwogIHRleHQtYWxpZ246IGNlbnRlciB9CgouYWxpZ24t
cmlnaHQgewogIHRleHQtYWxpZ246IHJpZ2h0IH0KCi8qIHJlc2V0IGlubmVyIGFsaWdubWVu
dCBpbiBmaWd1cmVzICovCmRpdi5hbGlnbi1yaWdodCB7CiAgdGV4dC1hbGlnbjogaW5oZXJp
dCB9CgovKiBkaXYuYWxpZ24tY2VudGVyICogeyAqLwovKiAgIHRleHQtYWxpZ246IGxlZnQg
fSAqLwoKb2wuc2ltcGxlLCB1bC5zaW1wbGUgewogIG1hcmdpbi1ib3R0b206IDFlbSB9Cgpv
bC5hcmFiaWMgewogIGxpc3Qtc3R5bGU6IGRlY2ltYWwgfQoKb2wubG93ZXJhbHBoYSB7CiAg
bGlzdC1zdHlsZTogbG93ZXItYWxwaGEgfQoKb2wudXBwZXJhbHBoYSB7CiAgbGlzdC1zdHls
ZTogdXBwZXItYWxwaGEgfQoKb2wubG93ZXJyb21hbiB7CiAgbGlzdC1zdHlsZTogbG93ZXIt
cm9tYW4gfQoKb2wudXBwZXJyb21hbiB7CiAgbGlzdC1zdHlsZTogdXBwZXItcm9tYW4gfQoK
cC5hdHRyaWJ1dGlvbiB7CiAgdGV4dC1hbGlnbjogcmlnaHQgOwogIG1hcmdpbi1sZWZ0OiA1
MCUgfQoKcC5jYXB0aW9uIHsKICBmb250LXN0eWxlOiBpdGFsaWMgfQoKcC5jcmVkaXRzIHsK
ICBmb250LXN0eWxlOiBpdGFsaWMgOwogIGZvbnQtc2l6ZTogc21hbGxlciB9CgpwLmxhYmVs
IHsKICB3aGl0ZS1zcGFjZTogbm93cmFwIH0KCnAucnVicmljIHsKICBmb250LXdlaWdodDog
Ym9sZCA7CiAgZm9udC1zaXplOiBsYXJnZXIgOwogIGNvbG9yOiBtYXJvb24gOwogIHRleHQt
YWxpZ246IGNlbnRlciB9CgpwLnNpZGViYXItdGl0bGUgewogIGZvbnQtZmFtaWx5OiBzYW5z
LXNlcmlmIDsKICBmb250LXdlaWdodDogYm9sZCA7CiAgZm9udC1zaXplOiBsYXJnZXIgfQoK
cC5zaWRlYmFyLXN1YnRpdGxlIHsKICBmb250LWZhbWlseTogc2Fucy1zZXJpZiA7CiAgZm9u
dC13ZWlnaHQ6IGJvbGQgfQoKcC50b3BpYy10aXRsZSB7CiAgZm9udC13ZWlnaHQ6IGJvbGQg
fQoKcHJlLmFkZHJlc3MgewogIG1hcmdpbi1ib3R0b206IDAgOwogIG1hcmdpbi10b3A6IDAg
OwogIGZvbnQ6IGluaGVyaXQgfQoKcHJlLmxpdGVyYWwtYmxvY2ssIHByZS5kb2N0ZXN0LWJs
b2NrLCBwcmUubWF0aCwgcHJlLmNvZGUgewogIG1hcmdpbi1sZWZ0OiAyZW0gOwogIG1hcmdp
bi1yaWdodDogMmVtIH0KCnByZS5jb2RlIC5sbiB7IGNvbG9yOiBncmV5OyB9IC8qIGxpbmUg
bnVtYmVycyAqLwpwcmUuY29kZSwgY29kZSB7IGJhY2tncm91bmQtY29sb3I6ICNlZWVlZWUg
fQpwcmUuY29kZSAuY29tbWVudCwgY29kZSAuY29tbWVudCB7IGNvbG9yOiAjNUM2NTc2IH0K
cHJlLmNvZGUgLmtleXdvcmQsIGNvZGUgLmtleXdvcmQgeyBjb2xvcjogIzNCMEQwNjsgZm9u
dC13ZWlnaHQ6IGJvbGQgfQpwcmUuY29kZSAubGl0ZXJhbC5zdHJpbmcsIGNvZGUgLmxpdGVy
YWwuc3RyaW5nIHsgY29sb3I6ICMwQzU0MDQgfQpwcmUuY29kZSAubmFtZS5idWlsdGluLCBj
b2RlIC5uYW1lLmJ1aWx0aW4geyBjb2xvcjogIzM1MkI4NCB9CnByZS5jb2RlIC5kZWxldGVk
LCBjb2RlIC5kZWxldGVkIHsgYmFja2dyb3VuZC1jb2xvcjogI0RFQjBBMX0KcHJlLmNvZGUg
Lmluc2VydGVkLCBjb2RlIC5pbnNlcnRlZCB7IGJhY2tncm91bmQtY29sb3I6ICNBM0QyODl9
CgpzcGFuLmNsYXNzaWZpZXIgewogIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmIDsKICBmb250
LXN0eWxlOiBvYmxpcXVlIH0KCnNwYW4uY2xhc3NpZmllci1kZWxpbWl0ZXIgewogIGZvbnQt
ZmFtaWx5OiBzYW5zLXNlcmlmIDsKICBmb250LXdlaWdodDogYm9sZCB9CgpzcGFuLmludGVy
cHJldGVkIHsKICBmb250LWZhbWlseTogc2Fucy1zZXJpZiB9CgpzcGFuLm9wdGlvbiB7CiAg
d2hpdGUtc3BhY2U6IG5vd3JhcCB9CgpzcGFuLnByZSB7CiAgd2hpdGUtc3BhY2U6IHByZSB9
CgpzcGFuLnByb2JsZW1hdGljIHsKICBjb2xvcjogcmVkIH0KCnNwYW4uc2VjdGlvbi1zdWJ0
aXRsZSB7CiAgLyogZm9udC1zaXplIHJlbGF0aXZlIHRvIHBhcmVudCAoaDEuLmg2IGVsZW1l
bnQpICovCiAgZm9udC1zaXplOiA4MCUgfQoKdGFibGUuY2l0YXRpb24gewogIGJvcmRlci1s
ZWZ0OiBzb2xpZCAxcHggZ3JheTsKICBtYXJnaW4tbGVmdDogMXB4IH0KCnRhYmxlLmRvY2lu
Zm8gewogIG1hcmdpbjogMmVtIDRlbSB9Cgp0YWJsZS5kb2N1dGlscyB7CiAgbWFyZ2luLXRv
cDogMC41ZW0gOwogIG1hcmdpbi1ib3R0b206IDAuNWVtIH0KCnRhYmxlLmZvb3Rub3RlIHsK
ICBib3JkZXItbGVmdDogc29saWQgMXB4IGJsYWNrOwogIG1hcmdpbi1sZWZ0OiAxcHggfQoK
dGFibGUuZG9jdXRpbHMgdGQsIHRhYmxlLmRvY3V0aWxzIHRoLAp0YWJsZS5kb2NpbmZvIHRk
LCB0YWJsZS5kb2NpbmZvIHRoIHsKICBwYWRkaW5nLWxlZnQ6IDAuNWVtIDsKICBwYWRkaW5n
LXJpZ2h0OiAwLjVlbSA7CiAgdmVydGljYWwtYWxpZ246IHRvcCB9Cgp0YWJsZS5kb2N1dGls
cyB0aC5maWVsZC1uYW1lLCB0YWJsZS5kb2NpbmZvIHRoLmRvY2luZm8tbmFtZSB7CiAgZm9u
dC13ZWlnaHQ6IGJvbGQgOwogIHRleHQtYWxpZ246IGxlZnQgOwogIHdoaXRlLXNwYWNlOiBu
b3dyYXAgOwogIHBhZGRpbmctbGVmdDogMCB9CgovKiAiYm9va3RhYnMiIHN0eWxlIChubyB2
ZXJ0aWNhbCBsaW5lcykgKi8KdGFibGUuZG9jdXRpbHMuYm9va3RhYnMgewogIGJvcmRlcjog
MHB4OwogIGJvcmRlci10b3A6IDJweCBzb2xpZDsKICBib3JkZXItYm90dG9tOiAycHggc29s
aWQ7CiAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsKfQp0YWJsZS5kb2N1dGlscy5ib29r
dGFicyAqIHsKICBib3JkZXI6IDBweDsKfQp0YWJsZS5kb2N1dGlscy5ib29rdGFicyB0aCB7
CiAgYm9yZGVyLWJvdHRvbTogdGhpbiBzb2xpZDsKICB0ZXh0LWFsaWduOiBsZWZ0Owp9Cgpo
MSB0dC5kb2N1dGlscywgaDIgdHQuZG9jdXRpbHMsIGgzIHR0LmRvY3V0aWxzLApoNCB0dC5k
b2N1dGlscywgaDUgdHQuZG9jdXRpbHMsIGg2IHR0LmRvY3V0aWxzIHsKICBmb250LXNpemU6
IDEwMCUgfQoKdWwuYXV0by10b2MgewogIGxpc3Qtc3R5bGUtdHlwZTogbm9uZSB9Cgo8L3N0
eWxlPgo8L2hlYWQ+Cjxib2R5Pgo8ZGl2IGNsYXNzPSJkb2N1bWVudCIgaWQ9ImEtcXVhbGlm
aWVkLXJlcGxhY2VtZW50LWZvci1wcmFnbWEtb25jZSI+CjxoMSBjbGFzcz0idGl0bGUiPkEg
UXVhbGlmaWVkIFJlcGxhY2VtZW50IGZvciA8dHQgY2xhc3M9ImRvY3V0aWxzIGxpdGVyYWwi
PiNwcmFnbWEgb25jZTwvdHQ+PC9oMT4KPHRhYmxlIGNsYXNzPSJkb2NpbmZvIiBmcmFtZT0i
dm9pZCIgcnVsZXM9Im5vbmUiPgo8Y29sIGNsYXNzPSJkb2NpbmZvLW5hbWUiIC8+Cjxjb2wg
Y2xhc3M9ImRvY2luZm8tY29udGVudCIgLz4KPHRib2R5IHZhbGlnbj0idG9wIj4KPHRyIGNs
YXNzPSJmaWVsZCI+PHRoIGNsYXNzPSJkb2NpbmZvLW5hbWUiPkRvY3VtZW50OjwvdGg+PHRk
IGNsYXNzPSJmaWVsZC1ib2R5Ij5EeHh4eDwvdGQ+CjwvdHI+Cjx0cj48dGggY2xhc3M9ImRv
Y2luZm8tbmFtZSI+RGF0ZTo8L3RoPgo8dGQ+MjAxNi0xMC0yNzwvdGQ+PC90cj4KPHRyIGNs
YXNzPSJmaWVsZCI+PHRoIGNsYXNzPSJkb2NpbmZvLW5hbWUiPlByb2plY3Q6PC90aD48dGQg
Y2xhc3M9ImZpZWxkLWJvZHkiPklTTy9JRUMgSlRDMSBTQzIyIFdHMjEgUHJvZ3JhbW1pbmcg
TGFuZ3VhZ2UgQysrPC90ZD4KPC90cj4KPHRyIGNsYXNzPSJmaWVsZCI+PHRoIGNsYXNzPSJk
b2NpbmZvLW5hbWUiPkF1ZGllbmNlOjwvdGg+PHRkIGNsYXNzPSJmaWVsZC1ib2R5Ij5Fdm9s
dXRpb24gV29ya2luZyBHcm91cDwvdGQ+CjwvdHI+Cjx0cj48dGggY2xhc3M9ImRvY2luZm8t
bmFtZSI+QXV0aG9yOjwvdGg+Cjx0ZD5NYXR0aGV3IFdvZWhsa2UgKDxhIGNsYXNzPSJyZWZl
cmVuY2UgZXh0ZXJuYWwiIGhyZWY9Im1haWx0bzptd29laGxrZS5mbG9zcyYjNjQ7Z21haWwu
Y29tIj5td29laGxrZS5mbG9zcyYjNjQ7Z21haWwuY29tPC9hPik8L3RkPjwvdHI+CjwvdGJv
ZHk+CjwvdGFibGU+CjxzdHlsZT4KICBodG1sIHsgY29sb3I6IGJsYWNrOyBiYWNrZ3JvdW5k
OiB3aGl0ZTsgfQogIHRhYmxlLmRvY2luZm8geyBtYXJnaW46IDJlbSAwOyB9Cjwvc3R5bGU+
PGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9ImFic3RyYWN0Ij4KPGgxPjxhIGNsYXNzPSJ0b2Mt
YmFja3JlZiIgaHJlZj0iI2lkMiI+QWJzdHJhY3Q8L2E+PC9oMT4KPHA+VGhpcyBwcm9wb3Nh
bCByZWNvbW1lbmRzIHRvIHN0YW5kYXJkaXplIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3Bh
biBjbGFzcz0iY29tbWVudCBwcmVwcm9jIj4jb25jZQo8L3NwYW4+PC9jb2RlPiBhcyBhbiBp
bXByb3ZlZCBtZWNoYW5pc20gZm9yIHByZXZlbnRpbmcgbXVsdGlwbGUgaW5jbHVzaW9uIG9m
IGEgaGVhZGVyLCBhbmQgYSByZWxhdGVkIGRpcmVjdGl2ZSA8Y29kZSBjbGFzcz0iY3BwIGMr
KyI+PHNwYW4gY2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+I2ZvcmdldAo8L3NwYW4+PC9jb2Rl
Pi48L3A+CjxkaXYgY2xhc3M9ImNvbnRlbnRzIHRvcGljIiBpZD0iY29udGVudHMiPgo8cCBj
bGFzcz0idG9waWMtdGl0bGUgZmlyc3QiPkNvbnRlbnRzPC9wPgo8dWwgY2xhc3M9InNpbXBs
ZSI+CjxsaT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBocmVmPSIjYWJzdHJhY3Qi
IGlkPSJpZDIiPkFic3RyYWN0PC9hPjwvbGk+CjxsaT48YSBjbGFzcz0icmVmZXJlbmNlIGlu
dGVybmFsIiBocmVmPSIjcHJvYmxlbSIgaWQ9ImlkMyI+UHJvYmxlbTwvYT48L2xpPgo8bGk+
PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0iI3Byb3Bvc2FsIiBpZD0iaWQ0
Ij5Qcm9wb3NhbDwvYT48dWw+CjxsaT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBo
cmVmPSIjb25jZSIgaWQ9ImlkNSI+PGNvZGUgY2xhc3M9ImNwcCBjKysiPjxzcGFuIGNsYXNz
PSJjb21tZW50IHByZXByb2MiPiNvbmNlCjwvc3Bhbj48L2NvZGU+PC9hPjwvbGk+CjxsaT48
YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBocmVmPSIjZm9yZ2V0IiBpZD0iaWQ2Ij48
Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+I2Zv
cmdldAo8L3NwYW4+PC9jb2RlPjwvYT48L2xpPgo8L3VsPgo8L2xpPgo8bGk+PGEgY2xhc3M9
InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0iI2NvbW1lbnRzLWFuZC1leGFtcGxlcyIgaWQ9
ImlkNyI+Q29tbWVudHMgYW5kIEV4YW1wbGVzPC9hPjx1bD4KPGxpPjxhIGNsYXNzPSJyZWZl
cmVuY2UgaW50ZXJuYWwiIGhyZWY9IiNzdGF0aWMtYW5hbHlzaXMiIGlkPSJpZDgiPlN0YXRp
YyBBbmFseXNpczwvYT48dWw+CjxsaT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBo
cmVmPSIjZXhhbXBsZSIgaWQ9ImlkOSI+RXhhbXBsZTwvYT48L2xpPgo8L3VsPgo8L2xpPgo8
bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0iI3Byb3Blci11c2Utb2Yt
dmVyc2lvbmluZyIgaWQ9ImlkMTAiPlByb3BlciBVc2Ugb2YgVmVyc2lvbmluZzwvYT48dWw+
CjxsaT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBocmVmPSIjaWQxIiBpZD0iaWQx
MSI+RXhhbXBsZTwvYT48L2xpPgo8L3VsPgo8L2xpPgo8bGk+PGEgY2xhc3M9InJlZmVyZW5j
ZSBpbnRlcm5hbCIgaHJlZj0iI3BlcmZvcm1hbmNlIiBpZD0iaWQxMiI+UGVyZm9ybWFuY2U8
L2E+PC9saT4KPC91bD4KPC9saT4KPGxpPjxhIGNsYXNzPSJyZWZlcmVuY2UgaW50ZXJuYWwi
IGhyZWY9IiNkaXNjdXNzaW9uIiBpZD0iaWQxMyI+RGlzY3Vzc2lvbjwvYT48dWw+CjxsaT48
YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFsIiBocmVmPSIjd2h5LW5vdC1yZXVzZS1wcmFn
bWEiIGlkPSJpZDE0Ij5XaHkgbm90IHJldXNlIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3Bh
biBjbGFzcz0iY29tbWVudCBwcmVwcm9jIj4jcHJhZ21hCjwvc3Bhbj48L2NvZGU+PzwvYT48
L2xpPgo8bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0iI3dvbi10LW1v
ZHVsZXMtbWFrZS10aGlzLWlycmVsZXZhbnQiIGlkPSJpZDE1Ij5Xb24ndCBtb2R1bGVzIG1h
a2UgdGhpcyBpcnJlbGV2YW50PzwvYT48L2xpPgo8bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBp
bnRlcm5hbCIgaHJlZj0iI3Nob3VsZG4tdC10aGlzLWdvLXRvLWMtZmlyc3QiIGlkPSJpZDE2
Ij5TaG91bGRuJ3QgdGhpcyBnbyB0byBDIGZpcnN0PzwvYT48L2xpPgo8L3VsPgo8L2xpPgo8
bGk+PGEgY2xhc3M9InJlZmVyZW5jZSBpbnRlcm5hbCIgaHJlZj0iI3N1bW1hcnkiIGlkPSJp
ZDE3Ij5TdW1tYXJ5PC9hPjwvbGk+CjxsaT48YSBjbGFzcz0icmVmZXJlbmNlIGludGVybmFs
IiBocmVmPSIjYWNrbm93bGVkZ21lbnRzIiBpZD0iaWQxOCI+QWNrbm93bGVkZ21lbnRzPC9h
PjwvbGk+CjwvdWw+CjwvZGl2Pgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9InBy
b2JsZW0iPgo8aDE+PGEgY2xhc3M9InRvYy1iYWNrcmVmIiBocmVmPSIjaWQzIj5Qcm9ibGVt
PC9hPjwvaDE+CjxwPkl0IGlzIHdlbGwga25vd24gdGhhdCB3aGVuIGNvbXBpbGluZyBjb2Rl
IG9mIG5vbi10cml2aWFsIGNvbXBsZXhpdHksIHRoZSBjb21wbGV0ZSBzZXQgb2YgPGNvZGUg
Y2xhc3M9ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJjb21tZW50IHByZXByb2MiPiNpbmNsdWRl
Cjwvc3Bhbj48L2NvZGU+IGRpcmVjdGl2ZXMgbWF5IHJlZmVyZW5jZSB0aGUgc2FtZSBoZWFk
ZXIgbW9yZSB0aGFuIG9uY2UuIFRoaXMgb2Z0ZW4gb2NjdXJzIHdoZW4gYSB0cmFuc2xhdGlv
biB1bml0IHVzZXMgc2V2ZXJhbCBkaXN0aW5jdCBjb21wb25lbnRzIHdoaWNoIGVhY2ggcmVs
eSBvbiB0aGUgc2FtZSBiYXNlIGNvbXBvbmVudCAoZXNwZWNpYWxseSBsaWJyYXJ5IGNvbmZp
Z3VyYXRpb24gaGVhZGVycywgaGVhZGVycyB0aGF0IHByb3ZpZGUgZXhwb3J0IGRlY29yYXRp
b24gc3ltYm9scywgYW5kIHRoZSBsaWtlKS4gV2hpbGUgdGhpcyBpcyBjb3JyZWN0IGZvciBl
YWNoIGNvbXBvbmVudCBoZWFkZXIgaW4gb3JkZXIgdG8gYWxsb3cgaXQgdG8gYmUgdXNlZCBv
biBpdHMgb3duLCB0aGUgY29tYmluYXRpb24gb2YgbXVsdGlwbGUgY29tcG9uZW50cyByZXF1
aXJlcyBhIG1lY2hhbmlzbSB0byBwcmV2ZW50IHRoZSBkZWZpbml0aW9ucyBpbiBhIGhlYWRl
ciBmcm9tIGJlaW5nIHBhcnNlZCB0d2ljZSwgd2hpY2ggd291bGQgbGVhZCB0byBjb21waWxl
IGVycm9ycy48L3A+CjxwPlRyYWRpdGlvbmFsbHksIHRoaXMgaXMgYWNjb21wbGlzaGVkIHdp
dGggJnF1b3Q7aW5jbHVkZSBndWFyZHMmcXVvdDssIHdoaWNoIHRha2UgdGhlIGZvcm06PC9w
Pgo8cHJlIGNsYXNzPSJjb2RlIGMrKyBsaXRlcmFsLWJsb2NrIj4KPHNwYW4gY2xhc3M9ImNv
bW1lbnQgc2luZ2xlIj4vLyBmb28uaAo8L3NwYW4+PHNwYW4gY2xhc3M9ImNvbW1lbnQgcHJl
cHJvYyI+I2lmbmRlZiBfTVlMSUJfRk9PX0hfSU5DTFVERUQKI2RlZmluZSBfTVlMSUJfRk9P
X0hfSU5DTFVERUQKPC9zcGFuPjxzcGFuIGNsYXNzPSJwdW5jdHVhdGlvbiI+Li4uPC9zcGFu
Pgo8c3BhbiBjbGFzcz0iY29tbWVudCBwcmVwcm9jIj4jZW5kaWYgPC9zcGFuPjxzcGFuIGNs
YXNzPSJjb21tZW50IHNpbmdsZSI+Ly8gX01ZTElCX0ZPT19IX0lOQ0xVREVEPC9zcGFuPgo8
L3ByZT4KPHA+QXQgbGVhc3Qgb25lIHByb2JsZW0gd2l0aCB0aGlzIGlzIG9idmlvdXM7IHRo
ZSBndWFyZCBzeW1ib2wgaXMgcmVwZWF0ZWQgYXMgbWFueSBhcyB0aHJlZSB0aW1lcyAodGhl
IGxhc3Qgb2NjdXJyZW5jZSBpbiB0aGUgY29tbWVudCBpcyBvcHRpb25hbCBhbmQgYXQgbGVh
c3QgaGFzIG5vIGltcGFjdCBvbiBjb21waWxpbmcgaWYgaXQgaXMgaW5jb3JyZWN0KSwgbGVh
ZGluZyB0byB0aGUgcG9zc2liaWxpdHkgb2YgbWlzdGFrZXMgd2hlbiByZXR5cGluZyB0aGUg
c3ltYm9sIHRoYXQgY2F1c2UgdGhlIGd1YXJkIHRvIGJlIGluZWZmZWN0aXZlLiBMZXNzIG9i
dmlvdXMsIGJ1dCBldmVuIG1vcmUgcHJvYmxlbWF0aWMsIGl0IGlzIGNvbW1vbiBmb3IgaGVh
ZGVycyB0byBiZSBjb3BpZWQsIHdoaWNoIGNhbiBsZWFkIHRvIGRpZmZpY3VsdCB0byBkaWFn
bm9zZSBlcnJvcnMgaWYgdGhlIHByb2dyYW1tZXIgbmVnbGVjdHMgdG8gYWRqdXN0IHRoZSBn
dWFyZCB3aGVuIGRvaW5nIHNvLjwvcD4KPHA+U29tZSBjb21waWxlcnMgc3VwcG9ydCA8dHQg
Y2xhc3M9ImRvY3V0aWxzIGxpdGVyYWwiPiNwcmFnbWEgb25jZTwvdHQ+IGFzIGFuIGFsdGVy
bmF0ZSBtZWNoYW5pc20gZm9yIHByZXZlbnRpbmcgbXVsdGlwbGUgaW5jbHVzaW9ucy4gSG93
ZXZlciwgbWFueSBwcm9ibGVtcyB3aXRoIHRoaXMgbWVjaGFuaXNtIGFyZSBrbm93bi4gSXQg
aXMgZGlmZmljdWx0IGZvciBjb21waWxlciBhdXRob3JzIHRvIGltcGxlbWVudCBjb3JyZWN0
bHksIGVzcGVjaWFsbHkgaW4gdGhlIHByZXNlbmNlIG9mIHBhdGhvbG9naWNhbCBzb3VyY2Ug
dHJlZXMgKGludm9sdmluZyBjb3BpZXMgb2YgaGVhZGVycywgd2hldGhlciBieSBzeW1saW5r
LCBvciB3b3JzZSwgdGhlIHNhbWUgcGh5c2ljYWwgZmlsZSBhY2Nlc3NpYmxlIHZpYSBkaWZm
ZXJlbnQgbW91bnQgcG9pbnRzKS4gVGhlcmUgaXMgYWxzbyBhIHF1ZXN0aW9uIG9mIGhvdyBk
aXN0aW5jdCBoZWFkZXJzIHByb3ZpZGluZyBzaW1pbGFyIGRlZmluaXRpb25zIHNob3VsZCBi
ZSBoYW5kbGVkLiBUaGVzZSBwcm9ibGVtcyBhcmUgd2VsbCBhZGRyZXNzZWQgYnkgdHJhZGl0
aW9uYWwgaW5jbHVkZSBndWFyZHMuPC9wPgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIg
aWQ9InByb3Bvc2FsIj4KPGgxPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkNCI+
UHJvcG9zYWw8L2E+PC9oMT4KPHA+V2UgcHJvcG9zZSB0byBpbnRyb2R1Y2UgdGhyZWUgbmV3
IHByZXByb2Nlc3NvciBkaXJlY3RpdmVzIGluIGFuIGF0dGVtcHQgdG8gYWRkcmVzcyB0aGlz
IGlzc3VlLjwvcD4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9Im9uY2UiPgo8aDI+PGEgY2xh
c3M9InRvYy1iYWNrcmVmIiBocmVmPSIjaWQ1Ij48Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNw
YW4gY2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+I29uY2UKPC9zcGFuPjwvY29kZT48L2E+PC9o
Mj4KPGJsb2NrcXVvdGU+CjxzdHJvbmc+I29uY2U8L3N0cm9uZz4gPGVtPmlkZW50aWZpZXI8
L2VtPiBbIDxlbT4mbHQ7d2hpdGVzcGFjZSZndDs8L2VtPiA8ZW0+dmVyc2lvbjwvZW0+IF08
L2Jsb2NrcXVvdGU+CjxwPlRoZSA8ZW0+aWRlbnRpZmllcjwvZW0+IHNoYWxsIGNvbnNpc3Qg
b2Ygb25lIG9yIG1vcmUgQysrIGlkZW50aWZpZXJzIChzZXF1ZW5jZXMgb2YgYWxwaGFudW1l
cmljIGNoYXJhY3RlcnMgYW5kL29yIDx0dCBjbGFzcz0iZG9jdXRpbHMgbGl0ZXJhbCI+Xzwv
dHQ+LCBub3Qgc3RhcnRpbmcgd2l0aCBhIGRpZ2l0KSBqb2luZWQgYnkgPHR0IGNsYXNzPSJk
b2N1dGlscyBsaXRlcmFsIj46OjwvdHQ+IChoZW5jZWZvcnRoIHJlZmVycmVkIHRvIGFzIGEg
JnF1b3Q7cXVhbGlmaWVkIG5hbWUmcXVvdDspLiBUaGUgPGVtPnZlcnNpb248L2VtPiwgaWYg
c3BlY2lmaWVkLCBzaGFsbCBiZSBhIHRva2VuIHN0cmluZyBjb25zaXN0aW5nIG9mIGFscGhh
bnVtZXJpYyBjaGFyYWN0ZXJzIGFuZC9vciB0aGUgPHR0IGNsYXNzPSJkb2N1dGlscyBsaXRl
cmFsIj5fPC90dD4sIDx0dCBjbGFzcz0iZG9jdXRpbHMgbGl0ZXJhbCI+LTwvdHQ+LCA8dHQg
Y2xhc3M9ImRvY3V0aWxzIGxpdGVyYWwiPjo8L3R0PiBvciA8dHQgY2xhc3M9ImRvY3V0aWxz
IGxpdGVyYWwiPi48L3R0PiBjaGFyYWN0ZXJzLCBub3Qgc3RhcnRpbmcgd2l0aCA8dHQgY2xh
c3M9ImRvY3V0aWxzIGxpdGVyYWwiPjo8L3R0PiwgYW5kIHNoYWxsIHNldCB0aGUgdmVyc2lv
biBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCA8ZW0+aWRlbnRpZmllcjwvZW0+Ljwv
cD4KPHA+SWYgYSBwcmV2aW91cyA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9
ImNvbW1lbnQgcHJlcHJvYyI+I29uY2UKPC9zcGFuPjwvY29kZT4gZGlyZWN0aXZlIGhhdmlu
ZyB0aGUgc2FtZSA8ZW0+aWRlbnRpZmllcjwvZW0+IGFuZCA8ZW0+dmVyc2lvbjwvZW0+IGhh
cyBiZWVuIHByZXZpb3VzbHkgc2VlbiwgdGhlIGNvbXBpbGVyIHNoYWxsIGlnbm9yZSB0aGUg
cmVtYWluZGVyIG9mIHRoZSA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9ImNv
bW1lbnQgcHJlcHJvYyI+I2luY2x1ZGUKPC9zcGFuPjwvY29kZT4gdW5pdC4gSWYgdGhlIDxl
bT5pZGVudGlmaWVyPC9lbT4gaXMga25vd24gYnV0IHRoZSA8ZW0+dmVyc2lvbjwvZW0+IGRv
ZXMgbm90IG1hdGNoLCB0aGUgcHJvZ3JhbSBzaGFsbCBiZSBpbGwtZm9ybWVkLiAoSWYgPGVt
PnZlcnNpb248L2VtPiBpcyB1bnNwZWNpZmllZCwgdGhlIHZlcnNpb24gc2hhbGwgYmUgdGhl
IGVtcHR5IHN0cmluZy4pPC9wPgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9ImZv
cmdldCI+CjxoMj48YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhyZWY9IiNpZDYiPjxjb2RlIGNs
YXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0iY29tbWVudCBwcmVwcm9jIj4jZm9yZ2V0Cjwv
c3Bhbj48L2NvZGU+PC9hPjwvaDI+CjxibG9ja3F1b3RlPgo8c3Ryb25nPiNmb3JnZXQ8L3N0
cm9uZz4gPGVtPmlkZW50aWZpZXI8L2VtPjwvYmxvY2txdW90ZT4KPHA+VGhlIGNvbXBpbGVy
IHNoYWxsIHJlbW92ZSB0aGUgPGVtPmlkZW50aWZpZXI8L2VtPiBmcm9tIGl0cyBjb2xsZWN0
aW9uIG9mIHByZXZpb3VzbHkgc2VlbiBpZGVudGlmaWVycy4gVGhpcyBkaXJlY3RpdmUgcHJv
dmlkZXMgYSBtZWNoYW5pc20gdG8gZm9yY2UgdGhlIG11bHRpcGxlIGluY2x1c2lvbiBvZiBh
biA8Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+
I2luY2x1ZGUKPC9zcGFuPjwvY29kZT4gdW5pdCB3aGljaCB1c2VzIDxjb2RlIGNsYXNzPSJj
cHAgYysrIj48c3BhbiBjbGFzcz0iY29tbWVudCBwcmVwcm9jIj4jb25jZQo8L3NwYW4+PC9j
b2RlPi48L3A+CjwvZGl2Pgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9ImNvbW1l
bnRzLWFuZC1leGFtcGxlcyI+CjxoMT48YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhyZWY9IiNp
ZDciPkNvbW1lbnRzIGFuZCBFeGFtcGxlczwvYT48L2gxPgo8ZGl2IGNsYXNzPSJzZWN0aW9u
IiBpZD0ic3RhdGljLWFuYWx5c2lzIj4KPGgyPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJl
Zj0iI2lkOCI+U3RhdGljIEFuYWx5c2lzPC9hPjwvaDI+CjxwPkFzIG1lbnRpb25lZCwgb25l
IG9mIHRoZSBwcm9ibGVtcyB3aXRoIHRyYWRpdGlvbmFsIGd1YXJkcyBpcyB0aGF0IHRoZXkg
Y2FuIGVhc2lseSBnZXQgb3V0IG9mIHN5bmMgd2l0aCB0aGUgaGVhZGVyIGZpbGUgdGhleSBn
dWFyZC4gV2hpbGUgaXQgaXMgcG9zc2libGUgdG8gd3JpdGUgc3RhdGljIGFuYWx5c2lzIHRv
b2xzIHRvIGRldGVjdCBzdWNoIGVycm9ycywgdGhlIHByb2xpZmVyYXRpb24gb2YgZGlmZmVy
ZW50IHN0eWxlcyBvZiBndWFyZHMgbWFrZSBpdCBkaWZmaWN1bHQgdG8gd3JpdGUgYSBzaW5n
bGUgaGV1cmlzdGljIHRoYXQgd29ya3MgYWNyb3NzIGEgYnJvYWQgYmFzZSBvZiBleGlzdGlu
ZyBzb2Z0d2FyZS4gSW4gdHVybiwgdGhpcyBtZWFucyB0aGF0IHN1Y2ggdG9vbHMgdGVuZCB0
byBiZSBwcm9qZWN0IHNwZWNpZmljIGFuZCBhcmUgYXQgYmVzdCBydW4gd2hlbiBjb2RlIGlz
IGNvbW1pdHRlZCB0byBhIHJlcG9zaXRvcnkuIEl0IHdvdWxkIGJlIGZhciBiZXR0ZXIgZm9y
IHN1Y2ggY2hlY2tzIHRvIGJlIGludGVncmF0ZWQgaW50byB0aGUgY29tcGlsZXIsIHNvIHRo
YXQgdGhleSBydW4gYXQgYnVpbGQgdGltZSwgYW5kIGNhbiBiZSBwcm9tb3RlZCB0byBlcnJv
cnMuPC9wPgo8cD5XZSBhZGRyZXNzIHRoaXMgYnkgbWFraW5nIHRoZSBndWFyZCBpZGVudGlm
aWVyIGEgcXVhbGlmaWVkIG5hbWUuIEJlc2lkZXMgYmVpbmcgbW9yZSBjb25zaXN0ZW50IHdp
dGggQysrIGNvbnZlbnRpb25zIChmb3IgZXhhbXBsZSwgdGhlIG5hbWVzcGFjZSBvZiB0aGUg
Z3VhcmQgY291bGQgbWF0Y2ggdGhlIG5hbWVzcGFjZSBvZiB0aGUgcHJvamVjdCB3aGljaCBv
d25zIHRoZSBoZWFkZXIpLCB0aGlzLCBjb21iaW5lZCB3aXRoIHRoZSBpbnRyb2R1Y3Rpb24g
b2YgYSBuZXcgZmVhdHVyZSwgbWFrZXMgaXQgc3RyYWlnaHQgZm9yd2FyZCB0byBzdGlwdWxh
dGUgdGhhdCB0aGUgdW5xdWFsaWZpZWQgcG9ydGlvbiBvZiB0aGUgaWRlbnRpZmllciBzaGFs
bCBtYXRjaCB0aGUgbmFtZSBvZiB0aGUgPGNvZGUgY2xhc3M9ImNwcCBjKysiPjxzcGFuIGNs
YXNzPSJjb21tZW50IHByZXByb2MiPiNpbmNsdWRlCjwvc3Bhbj48L2NvZGU+IHVuaXQgKGV4
Y2x1ZGluZyBhIGZpbGUgZXh0ZW5zaW9uLCBpZiBhbnkpLjwvcD4KPHA+TW9yZW92ZXIsIGl0
IGlzIG5vdCBpbmNvbmNlaXZhYmxlIHRoYXQgd2UgY291bGQgYWdyZWUgdGhhdCB0aGUgbmFt
ZXNwYWNlIHBvcnRpb24gb2YgdGhlIHF1YWxpZmllZCBpZGVudGlmaWVyIHNoYWxsIG1hdGNo
IHRoZSBuYW1lc3BhY2Ugb2YgdGhlIGRlZmluaXRpb25zIHByb3ZpZGVkIGJ5IHRoZSA8Y29k
ZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+I2luY2x1
ZGUKPC9zcGFuPjwvY29kZT4gdW5pdCAoc28gdGhhdCBhbGwgcGFydHMgb2YgdGhlIGd1YXJk
IGlkZW50aWZpZXIgYXJlIGNoZWNrZWQgZm9yIGNvcnJlY3RuZXNzKSwgd2l0aCB0aGUgY29t
cGlsZXIgaXNzdWluZyBhIGRpYWdub3N0aWMgaWYgdGhlIDxjb2RlIGNsYXNzPSJjcHAgYysr
Ij48c3BhbiBjbGFzcz0iY29tbWVudCBwcmVwcm9jIj4jaW5jbHVkZQo8L3NwYW4+PC9jb2Rl
PiB1bml0IGRvZXMgbm90IGluY2x1ZGUgYXQgbGVhc3Qgb25lIGRlY2xhcmF0aW9uIGluIHRo
ZSBzYW1lIG5hbWVzcGFjZS48L3A+CjxwPlNpbmNlIHdlIGFyZSB0YWxraW5nIGFib3V0IFFv
SSBpc3N1ZXMgaGVyZSwgd2UgZmVlbCB0aGF0IGl0IGlzIG5vdCBuZWNlc3NhcnkgdGhhdCB0
aGVzZSBjaGVja3MgYmUgbm9ybWF0aXZlLiBJbnN0ZWFkLCB3ZSB3b3VsZCBwcmVmZXIgdG8g
bGV0IHRoZSBjb21waWxlciBjb21tdW5pdHkgYWdyZWUgb24gd2hhdCBjb252ZW50aW9ucyBz
aG91bGQgYmUgZXhwZWN0ZWQgYW5kIGRpYWdub3NlZC48L3A+CjxkaXYgY2xhc3M9InNlY3Rp
b24iIGlkPSJleGFtcGxlIj4KPGgzPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lk
OSI+RXhhbXBsZTwvYT48L2gzPgo8cHJlIGNsYXNzPSJjb2RlIGMrKyBsaXRlcmFsLWJsb2Nr
Ij4KPHNwYW4gY2xhc3M9ImNvbW1lbnQgc2luZ2xlIj4vLyBmb28uaAo8L3NwYW4+PHNwYW4g
Y2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+I29uY2UgTXlMaWJyYXJ5OjpiYXIgPC9zcGFuPjxz
cGFuIGNsYXNzPSJjb21tZW50IHNpbmdsZSI+Ly8gd2FybmluZzogZ3VhcmQgc2hvdWxkIGJl
ICdNeUxpYnJhcnk6OmZvbycKPC9zcGFuPgo8c3BhbiBjbGFzcz0iY29tbWVudCBzaW5nbGUi
Pi8vIGJhci5oCjwvc3Bhbj48c3BhbiBjbGFzcz0iY29tbWVudCBwcmVwcm9jIj4jb25jZSBi
YXIgPC9zcGFuPjxzcGFuIGNsYXNzPSJjb21tZW50IHNpbmdsZSI+Ly8gd2FybmluZzogZ3Vh
cmQgc2hvdWxkIGJlIG5hbWVzcGFjZWQKPC9zcGFuPgo8L3ByZT4KPC9kaXY+CjwvZGl2Pgo8
ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0icHJvcGVyLXVzZS1vZi12ZXJzaW9uaW5nIj4KPGgy
PjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkMTAiPlByb3BlciBVc2Ugb2YgVmVy
c2lvbmluZzwvYT48L2gyPgo8cD5BbHRob3VnaCB0aGUgJnF1b3Q7b2J2aW91cyZxdW90OyB3
YXkgdG8gdXNlIHZlcnNpb24gZGlyZWN0aXZlcyBpcyB0byBpbmNsdWRlIHRoZSB2ZXJzaW9u
IG9mIHRoZSBzb2Z0d2FyZSBwYWNrYWdlIHRvIHdoaWNoIGEgaGVhZGVyIGJlbG9uZ3MgaW4g
ZXZlcnkgc2luZ2xlIGhlYWRlciwgdGhpcyBsZWFkcyB0byBhbiBvYnZpb3VzIGFuZCBzaWdu
aWZpY2FudCBtYWludGVuYW5jZSBidXJkZW4uIEEgYmV0dGVyIHNvbHV0aW9uIHdoaWNoIHdp
bGwgYmUgZXF1YWxseSBhZGVxdWF0ZSBpbiBhbG1vc3QgZXZlcnkgaW5zdGFuY2UgaXMgdG8g
bWFpbnRhaW4gc3VjaCB2ZXJzaW9uIGluZm9ybWF0aW9uIGluIGEgc2luZ2xlLCBnbG9iYWwg
aGVhZGVyIGZpbGUgKGUuZy4gPHR0IGNsYXNzPSJkb2N1dGlscyBsaXRlcmFsIj52ZXJzaW9u
Lmg8L3R0PiwgPHR0IGNsYXNzPSJkb2N1dGlscyBsaXRlcmFsIj5jb25maWcuaDwvdHQ+LCA8
dHQgY2xhc3M9ImRvY3V0aWxzIGxpdGVyYWwiPmV4cG9ydHMuaDwvdHQ+KSB3aGljaCBpcyBh
bHdheXMgaW5jbHVkZWQgdmlhIGFuIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFz
cz0iY29tbWVudCBwcmVwcm9jIj4jaW5jbHVkZQo8L3NwYW4+PC9jb2RlPiBkaXJlY3RpdmUg
KHByaW9yIHRvIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0iY29tbWVudCBw
cmVwcm9jIj4jb25jZQo8L3NwYW4+PC9jb2RlPikgd2hvc2UgcGF0aCBpcyBtYXJrZWQgd2l0
aCBxdW90ZXMgKDx0dCBjbGFzcz0iZG9jdXRpbHMgbGl0ZXJhbCI+JnF1b3Q7JnF1b3Q7PC90
dD4pIHJhdGhlciB0aGFuIGFuZ2xlIGJyYWNrZXRzICg8dHQgY2xhc3M9ImRvY3V0aWxzIGxp
dGVyYWwiPiZsdDsmZ3Q7PC90dD4pLiBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgZ2xvYmFsIGhl
YWRlciBpcyBhbHdheXMgZm91bmQgaW4gYSBrbm93biBsb2NhdGlvbiByZWxhdGl2ZSB0byB0
aGUgaGVhZGVyIGJlaW5nIHByb2Nlc3NlZCwgYW5kIHdpbGwgaW4gYWxtb3N0IGFsbCBjYXNl
cyBiZSBzdWZmaWNpZW50IHRvIGNhdGNoIG1pc21hdGNoaW5nIHZlcnNpb25zIG9mIHRoZSBo
ZWFkZXIgd2hpY2ggaW5jbHVkZXMgdGhlIGdsb2JhbCBoZWFkZXIuPC9wPgo8cD5Bbm90aGVy
IG9wdGlvbiwgd2hpY2ggY2FuIGJlIGVtcGxveWVkIGluIHRhbmRlbSwgaXMgdG8gdXNlIGEg
bW9ub3RvbmljYWxseSBpbmNyZWFzaW5nIHZlcnNpb24gbnVtYmVyIHRoYXQgaXMgdW5pcXVl
IHRvIGVhY2ggaGVhZGVyIGFuZCBpcyBpbmNyZW1lbnRlZCB3aGVuZXZlciB0aGUgaW50ZXJm
YWNlKHMpIGRlZmluZWQgaW4gdGhlIGhlYWRlciBjaGFuZ2UuIEJlY2F1c2UgdGhpcyBudW1i
ZXIgaXMgdW5pcXVlIHRvIHRoZSBoZWFkZXIsIGFuZCBvbmx5IGNoYW5nZXMgd2hlbiB0aGUg
aGVhZGVyIGNoYW5nZXMgKGFuZCBwb3NzaWJseSBub3QgZXZlbiB0aGF0IGZyZXF1ZW50bHkp
LCB0aGUgbWFpbnRlbmFuY2UgYnVyZGVuIGlzIHNpZ25pZmljYW50bHkgcmVkdWNlZC48L3A+
CjxwPlRoZSByZWxhdGl2ZWx5IGxpYmVyYWwgc3BlY2lmaWNhdGlvbiBvZiBhbGxvd2VkIHZl
cnNpb24gc3RyaW5ncyB3YXMgY2hvc2VuIHdpdGggdGhlIHNwZWNpZmljIGludGVudGlvbiBv
ZiBlbmNvdXJhZ2luZyB0aGUgdmVyc2lvbiBzdHJpbmcgdG8gYmUgZ2VuZXJhdGVkIGJ5IHRo
ZSBidWlsZCBzeXN0ZW0sIGFuZCBpbiBwYXJ0aWN1bGFyIHRvIGFsbG93IHRoZSB2ZXJzaW9u
IHN0cmluZyB0byBpbmNsdWRlIGEgVkNTIGlkZW50aWZpZXIuIEluIHRoaXMgd2F5LCB3ZSBt
YXkgZW5zdXJlIHRoYXQgaGVhZGVycyBmcm9tIGEgZGV2ZWxvcG1lbnQgdmVyc2lvbiBvZiBz
b2Z0d2FyZSBhcmUgbm90IG1peGVkIHdpdGggdGhvc2UgZnJvbSBhIHJlbGVhc2UgdmVyc2lv
biBvciBkaWZmZXJlbnQgZGV2ZWxvcG1lbnQgdmVyc2lvbiwgZXZlbiBpZiB0aGUgbm9ybWF0
aXZlIHZlcnNpb24gbnVtYmVyIGRvZXMgbm90IGRpZmZlciBiZXR3ZWVuIHN1Y2ggdmVyc2lv
bnMuPC9wPgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0iaWQxIj4KPGgzPjxhIGNsYXNzPSJ0
b2MtYmFja3JlZiIgaHJlZj0iI2lkMTEiPkV4YW1wbGU8L2E+PC9oMz4KPHByZSBjbGFzcz0i
Y29kZSBjKysgbGl0ZXJhbC1ibG9jayI+CjxzcGFuIGNsYXNzPSJjb21tZW50IHNpbmdsZSI+
Ly8gdmVyc2lvbi5oCjwvc3Bhbj48c3BhbiBjbGFzcz0iY29tbWVudCBwcmVwcm9jIj4jb25j
ZSBNeUxpYnJhcnk6OnZlcnNpb24gMC4xLjAgPC9zcGFuPjxzcGFuIGNsYXNzPSJjb21tZW50
IHNpbmdsZSI+Ly8gTXlMaWJyYXJ5IHZlcnNpb24gMC4xLjAKPC9zcGFuPgo8c3BhbiBjbGFz
cz0iY29tbWVudCBzaW5nbGUiPi8vIHdpZGdldC5oCjwvc3Bhbj48c3BhbiBjbGFzcz0iY29t
bWVudCBwcmVwcm9jIj4jaW5jbHVkZSAmcXVvdDt2ZXJzaW9uLmgmcXVvdDsKI29uY2UgTXlM
aWJyYXJ5Ojp3aWRnZXQgMiA8L3NwYW4+PHNwYW4gY2xhc3M9ImNvbW1lbnQgc2luZ2xlIj4v
LyB3aWRnZXQgQVBJIHZlcnNpb24gMgo8L3NwYW4+CjxzcGFuIGNsYXNzPSJjb21tZW50IHNp
bmdsZSI+Ly8gY29tbW9uLmgKPC9zcGFuPjxzcGFuIGNsYXNzPSJjb21tZW50IHByZXByb2Mi
PiNpbmNsdWRlICZxdW90O3ZlcnNpb24uaCZxdW90Owojb25jZSBNeUxpYnJhcnk6OmNvbW1v
biA8L3NwYW4+PHNwYW4gY2xhc3M9ImNvbW1lbnQgc2luZ2xlIj4vLyBubyB2ZXJzaW9uCjwv
c3Bhbj4KPC9wcmU+CjwvZGl2Pgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9InBl
cmZvcm1hbmNlIj4KPGgyPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkMTIiPlBl
cmZvcm1hbmNlPC9hPjwvaDI+CjxwPk9uZSBvZiB0aGUgcG9pbnRzIHRoYXQgaXMgZnJlcXVl
bnRseSByYWlzZWQgaW4gZmF2b3Igb2YgPGNvZGUgY2xhc3M9ImNwcCBjKysiPjxzcGFuIGNs
YXNzPSJjb21tZW50IHByZXByb2MiPiNwcmFnbWEgb25jZQo8L3NwYW4+PC9jb2RlPiBpcyB0
aGF0IGl0IGFsbG93cyB0aGUgY29tcGlsZXIgdG8gc2tpcCByZWFkaW5nIGEgZmlsZSB0aGF0
IGl0IGhhcyBhbHJlYWR5IGluY2x1ZGVkLiBIb3dldmVyLCB0aGUgcHJvYmxlbSB3aXRoIHRo
aXMgaXMgdGhhdCBpZiB0aGUgY29tcGlsZXIgaXMgbm90IGFibGUgdG8gY29ycmVjdGx5IGRl
dGVybWluZSBpZiBhIGhlYWRlciBoYXMgYWxyZWFkeSBiZWVuIGluY2x1ZGVkLCBpdCBpcyBs
aWtlbHkgdGhhdCB0aGUgdHJhbnNsYXRpb24gdW5pdCB3aWxsIGZhaWwgdG8gY29tcGlsZS48
L3A+CjxwPkluIGZhY3QsIGNvbXBpbGVycyBtYXkgYW5kIGRvIGFscmVhZHkgaW1wbGVtZW50
IHNpbWlsYXIgbG9naWMgZm9yIHRyYWRpdGlvbmFsIGluY2x1ZGUgZ3VhcmRzLiBCeSBlbXBs
b3lpbmcgYSBoZXVyaXN0aWMsIGEgY29tcGlsZXIgbWF5IGRldGVybWluZSB0aGF0IGEgaGVh
ZGVyJ3MgY29udGVudHMgYXJlIGVudGlyZWx5IGd1YXJkZWQuIEhhdmluZyBkb25lIHNvLCB0
aGUgaGVhZGVyIGFuZCBpdHMgZ3VhcmQgbWF5IGJlIGVudGVyZWQgaW50byBhIG1hcCwgc3Vj
aCB0aGF0IHRoZSBjb21waWxlciBtYXkgY2hvb3NlIG5vdCB0byByZWFkIHRoZSBoZWFkZXIg
YSBzZWNvbmQgdGltZSBpZiBpdCBvYnNlcnZlcyB0aGF0IGFuIDxjb2RlIGNsYXNzPSJjcHAg
YysrIj48c3BhbiBjbGFzcz0iY29tbWVudCBwcmVwcm9jIj4jaW5jbHVkZQo8L3NwYW4+PC9j
b2RlPiBkaXJlY3RpdmUgd291bGQgcmVmZXJlbmNlIGEgaGVhZGVyIHRoYXQgaGFzIGJlZW4g
cHJldmlvdXNseSBwcm9jZXNzZWQgYW5kIHdob3NlIGluY2x1ZGUgZ3VhcmQgaXMgZGVmaW5l
ZC4gVGhpcyBpcyBzYWZlciwgc2luY2UgaW4gY2FzZSBvZiBhIHdyb25nIGd1ZXNzLCB0aGUg
Y29tcGlsZXIgd2lsbCByZWFkIHRoZSBoZWFkZXIgYW55d2F5IGFuZCBwcm9jZXNzIGl0IGFz
IGVtcHR5IGR1ZSB0byB0aGUgdHJhZGl0aW9uYWwgZ3VhcmQsIHdoaWNoIGhhcyBhIHNtYWxs
IHBlcmZvcm1hbmNlIHBlbmFsdHkgYnV0IGRvZXMgbm90IGFmZmVjdCBjb3JyZWN0bmVzcyBv
ZiB0aGUgcHJvZ3JhbS48L3A+CjxwPk91ciBtb2RlbCBmb3IgPGNvZGUgY2xhc3M9ImNwcCBj
KysiPjxzcGFuIGNsYXNzPSJjb21tZW50IHByZXByb2MiPiNvbmNlCjwvc3Bhbj48L2NvZGU+
IHByb3ZpZGVzIHRoZXNlIHNhbWUgYmVuZWZpdHMsIHdoaWxlIG1ha2luZyBleHBsaWNpdCAo
YW5kIGVuZm9yY2luZykgdGhhdCB0aGUgZW50aXJlIGhlYWRlciBtYXkgYmUgc2tpcHBlZCBp
ZiB0aGUgY29tcGlsZXIgJnF1b3Q7a25vd3MmcXVvdDsgaXQgaGFzIGJlZW4gaW5jbHVkZWQg
YWxyZWFkeS4gVGhlIHByb3Bvc2VkIGRpcmVjdGl2ZSB0aGVyZWZvcmUgcHJvdmlkZXMgdGhl
IHNhbWUgcGVyZm9ybWFuY2UgYmVuZWZpdHMgYXMgPGNvZGUgY2xhc3M9ImNwcCBjKysiPjxz
cGFuIGNsYXNzPSJjb21tZW50IHByZXByb2MiPiNwcmFnbWEgb25jZQo8L3NwYW4+PC9jb2Rl
PiwgYnV0IHdpdGhvdXQgdGhlIHBvdGVudGlhbCBwaXRmYWxscy4gKEluIGNhc2VzIHN1Y2gg
YXMgZGVzY3JpYmVkIGFib3ZlLCB3aGVyZSBvbmUgb3IgbW9yZSA8Y29kZSBjbGFzcz0iY3Bw
IGMrKyI+PHNwYW4gY2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+I2luY2x1ZGUKPC9zcGFuPjwv
Y29kZT4gZGlyZWN0aXZlcyBwcmVjZWRlIDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBj
bGFzcz0iY29tbWVudCBwcmVwcm9jIj4jb25jZQo8L3NwYW4+PC9jb2RlPiwgdGhlIGNvbXBp
bGVyIHdvdWxkIG5lZWQgdG8gdHJhY2sgdGhlIHJlY3Vyc2l2ZSBzZXQgb2YgZ3VhcmRzIHdo
aWNoIG1ha2UgYSBzZWNvbmQgaW5jbHVzaW9uIGEgbm8tb3AuIFdoaWxlIHNvbWV3aGF0IG1v
cmUgY29tcGxpY2F0ZWQsIHRoaXMgc3RpbGwgc2VlbXMgYWNoaWV2YWJsZS4pPC9wPgo8L2Rp
dj4KPC9kaXY+CjxkaXYgY2xhc3M9InNlY3Rpb24iIGlkPSJkaXNjdXNzaW9uIj4KPGgxPjxh
IGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkMTMiPkRpc2N1c3Npb248L2E+PC9oMT4K
PGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9IndoeS1ub3QtcmV1c2UtcHJhZ21hIj4KPGgyPjxh
IGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkMTQiPldoeSBub3QgcmV1c2UgPGNvZGUg
Y2xhc3M9ImNwcCBjKysiPjxzcGFuIGNsYXNzPSJjb21tZW50IHByZXByb2MiPiNwcmFnbWEK
PC9zcGFuPjwvY29kZT4/PC9hPjwvaDI+CjxwPlRoZSBvYnZpb3VzIGFuc3dlciBpcyB0aGF0
IDxjb2RlIGNsYXNzPSJjcHAgYysrIj48c3BhbiBjbGFzcz0iY29tbWVudCBwcmVwcm9jIj4j
cHJhZ21hCjwvc3Bhbj48L2NvZGU+IGFzIGEgd2hvbGUgaXMgaW1wbGVtZW50YXRpb24gZGVm
aW5lZC4gQ2hvb3NpbmcgYW4gZW50aXJlbHkgbmV3IGRpcmVjdGl2ZSBtYWtlcyBpdCBjbGVh
ciB0aGF0IHRoaXMgZmVhdHVyZSBpcyAmcXVvdDtibGVzc2VkJnF1b3Q7IGJ5IHRoZSBzdGFu
ZGFyZCBhbmQgbm90IGFuIGltcGxlbWVudGF0aW9uIGRlZmluZWQgZmVhdHVyZS4gVGhlIGV4
YWN0IG5hbWVzIHVzZWQsIGhvd2V2ZXIsIGFyZSBzdWJqZWN0IHRvIHRoZSB1c3VhbCBiaWtl
c2hlZGRpbmcuIFdlIHdvdWxkIGVuY291cmFnZSB0aGUgY29tbWl0dGVlIHRvIGNvbnNpZGVy
IHRoZSBmZWF0dXJlIGZpcnN0IG9uIGl0cyBtZXJpdHM7IGlmIGl0IHNlZW1zIHVzZWZ1bCwg
d2UgYXJlIGNvbXBsZXRlbHkgb3BlbiB0byBjaG9vc2luZyBzb21lIG90aGVyIG5hbWUgb3Ig
ZXZlbiBzeW50YXggZm9yIHRoZSBkaXJlY3RpdmVzLiAoSXQgbWlnaHQgZXZlbiBtYWtlIHNl
bnNlIHRvIHVzZSBhIHN5bnRheCB0aGF0IGlzIGV2b2NhdGl2ZSBvZiB0aGF0IHVzZWQgYnkg
bW9kdWxlcy4pPC9wPgo8L2Rpdj4KPGRpdiBjbGFzcz0ic2VjdGlvbiIgaWQ9Indvbi10LW1v
ZHVsZXMtbWFrZS10aGlzLWlycmVsZXZhbnQiPgo8aDI+PGEgY2xhc3M9InRvYy1iYWNrcmVm
IiBocmVmPSIjaWQxNSI+V29uJ3QgbW9kdWxlcyBtYWtlIHRoaXMgaXJyZWxldmFudD88L2E+
PC9oMj4KPHA+SXQgaXMgcG9zc2libGUgdGhhdCBtb2R1bGVzIHdpbGwgc2lnbmlmaWNhbnRs
eSByZWR1Y2UgdGhlIG5lZWQgZm9yIHRoaXMgZmVhdHVyZSwgYnV0IG1vZHVsZXMgYXJlbid0
IGhlcmUgeWV0LCBhbmQgaXQgaXMgbGlrZWx5IHRoYXQgd2Ugd2lsbCBjb250aW51ZSB0byBo
YXZlIHRyYWRpdGlvbmFsIGhlYWRlcnMgZm9yIGEgbG9uZyB0aW1lLiBTaW5jZSB0aGlzIGZl
YXR1cmUgaGFwcGVucyBlbnRpcmVseSBhdCB0aGUgcHJlcHJvY2Vzc29yIGxldmVsLCBpdCBp
cyBvdXIgc2luY2VyZSBob3BlIHRoYXQgY29tcGlsZXJzIHdpbGwgY2hvb3NlIHRvIGltcGxl
bWVudCB0aGUgZmVhdHVyZSBlYXJseSwgYW5kIGVuYWJsZSBpdCByZWdhcmRsZXNzIG9mIHRo
ZSBsYW5ndWFnZSBsZXZlbCByZXF1ZXN0ZWQuIFRoaXMgbWVhbnMgdGhhdCBleGlzdGluZyBz
b2Z0d2FyZSBtYXkgYmUgYWJsZSB0byB0YWtlIGFkdmFudGFnZSBvZiB0aGUgZmVhdHVyZSBt
dWNoIHNvb25lciB0aGFuIHN1Y2ggc29mdHdhcmUgY2FuIGJlIHBvcnRlZCB0byBtb2R1bGVz
ICh3aGljaCB3aWxsIGludm9sdmUgYSBtdWNoIG1vcmUgaW52YXNpdmUgY2hhbmdlKS48L3A+
CjwvZGl2Pgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0ic2hvdWxkbi10LXRoaXMtZ28tdG8t
Yy1maXJzdCI+CjxoMj48YSBjbGFzcz0idG9jLWJhY2tyZWYiIGhyZWY9IiNpZDE2Ij5TaG91
bGRuJ3QgdGhpcyBnbyB0byBDIGZpcnN0PzwvYT48L2gyPgo8cD5XaGlsZSB3ZSB3b3VsZCBj
ZXJ0YWlubHkgbG92ZSB0byBzZWUgdGhpcyBmZWF0dXJlIGFkb3B0ZWQgYnkgQyBhcyB3ZWxs
LCB3ZSBkb24ndCB0aGluayBpdCBtYWtlcyBzZW5zZSB0aGF0IHByZXByb2Nlc3NvciBmZWF0
dXJlcyA8ZW0+bXVzdDwvZW0+IGJlIGFkb3B0ZWQgYnkgQyBmaXJzdC4gSW4gcGFydGljdWxh
ciwgd2Ugbm90ZSB0aGF0IHRoZSB1c2Ugb2YgYSBDKysgcXVhbGlmaWVkIGlkZW50aWZpZXIg
Z2l2ZXMgdXMgYSB2ZXJ5IGdvb2QgcmVhc29uIHRvIGFkb3B0IHRoaXMgZmVhdHVyZSBpbiBD
KysgZmlyc3QsIGFzIEMgd2lsbCBoYXZlIHRvIGRlY2lkZSB0byBlaXRoZXIgYWNjZXB0IEMr
KyBxdWFsaWZpZWQgaWRlbnRpZmllcnMgZm9yIHRoaXMgcHVycG9zZSBvciBmaW5kIGFuIGFs
dGVybmF0ZSBzb2x1dGlvbiB0aGF0IHNvbHZlcyB0aGUgc2FtZSBwcm9ibGVtcyB0aGF0IGFy
ZSBhZGRyZXNzZWQgYnkgdGhlIHVzZSBvZiBhIHF1YWxpZmllZCBuYW1lLjwvcD4KPHA+TW9y
ZW92ZXIsIHdlIG5vdGUgdGhhdCBpdCBkb2VzIG5vdCBtYWtlIGEgc2lnbmlmaWNhbnQgZGlm
ZmVyZW5jZSBpbiBwcmFjdGljZSB3aGljaCBsYW5ndWFnZSBhZG9wdHMgYSBwcmVwcm9jZXNz
b3IgZmVhdHVyZSBmaXJzdC4gU2luY2UgbW9zdCBjb21waWxlcnMgc2hhcmUgcHJlcHJvY2Vz
c29yIGZ1bmN0aW9uIGJldHdlZW4gQyBhbmQgQysrIGZyb250LWVuZHMsIGFkb3B0aW9uIG9m
IHRoaXMgZmVhdHVyZSBieSBDKysgd2lsbCBsaWtlbHkgbWFrZSBpdCBhIGRlIGZhY3RvIEMg
c3RhbmRhcmQuPC9wPgo8L2Rpdj4KPC9kaXY+CjxkaXYgY2xhc3M9InNlY3Rpb24iIGlkPSJz
dW1tYXJ5Ij4KPGgxPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkMTciPlN1bW1h
cnk8L2E+PC9oMT4KPHA+V2UgaGF2ZSBzaG93biBhIG1lY2hhbmlzbSBmb3IgaW1wbGVtZW50
aW5nIGEgbmV4dCBnZW5lcmF0aW9uIHN5c3RlbSBmb3IgcHJldmVudGluZyBtdWx0aXBsZSBp
bmNsdXNpb24gb2YgaGVhZGVycy4gVGhpcyBzeXN0ZW0gaXMgc2VtYW50aWNhbGx5IGVxdWl2
YWxlbnQgdG8gdHJhZGl0aW9uYWwgZ3VhcmRzLCBhbmQgc28gYXZvaWRzIHRoZSBrbm93biBp
c3N1ZXMgb2YgcHJlc2VudCBpbXBsZW1lbnRhdGlvbnMgb2YgPGNvZGUgY2xhc3M9ImNwcCBj
KysiPjxzcGFuIGNsYXNzPSJjb21tZW50IHByZXByb2MiPiNwcmFnbWEgb25jZQo8L3NwYW4+
PC9jb2RlPiAod2l0aG91dCBhbiBpZGVudGlmaWVyKS4gQnkgYWxzbyBwcm92aWRpbmcgYSA8
Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9ImNvbW1lbnQgcHJlcHJvYyI+I2Zv
cmdldAo8L3NwYW4+PC9jb2RlPiwgd2UgYWRkcmVzcyB0aGUgaXNzdWUgb2YgaG93IHRvIGZv
cmNlIG11bHRpcGxlIGluY2x1c2lvbiB3aGVuIG5lY2Vzc2FyeSBpbiBhIHdheSB0aGF0IGRv
ZXMgbm90IHJlcXVpcmUgZWRpdGluZyB0aGUgaGVhZGVyIGluIHF1ZXN0aW9uLiBCeSB1c2lu
ZyBhIHF1YWxpZmllZCBpZGVudGlmaWVyLCB3ZSBwcm92aWRlIGFuIGltcHJvdmVkIG1lY2hh
bmlzbSBmb3IgYXZvaWRpbmcgY29sbGlzaW9ucyB0aGF0IGlzIGFsc28gYW1lbmFibGUgdG8g
dGhlIHVzZSBvZiBzdGF0aWMgYW5hbHlzaXMgdG9vbHMgdG8gZGV0ZWN0IHRoZSBzb3J0cyBv
ZiBpbXByb3BlciB1c2UgdGhhdCBhcmUgdGhlIG1ham9yIGNvbXBsYWludCBhZ2FpbnN0IHRy
YWRpdGlvbmFsIGd1YXJkcy4gQnkgYWxzbyBzcGVjaWZ5aW5nIGFuIG9wdGlvbmFsIG1lY2hh
bmlzbSBmb3IgcHJvdmlkaW5nIHZlcnNpb24gaW5mb3JtYXRpb24sIHdlIHByb3ZpZGUgYSBt
ZWFucyB0byBkaWFnbm9zZSBhY2NpZGVudGFsIG1peGluZyBvZiBkaWZmZXJlbnQgdmVyc2lv
bnMgb2YgaGVhZGVycy48L3A+CjwvZGl2Pgo8ZGl2IGNsYXNzPSJzZWN0aW9uIiBpZD0iYWNr
bm93bGVkZ21lbnRzIj4KPGgxPjxhIGNsYXNzPSJ0b2MtYmFja3JlZiIgaHJlZj0iI2lkMTgi
PkFja25vd2xlZGdtZW50czwvYT48L2gxPgo8cD5XZSB3aXNoIHRvIHRoYW5rIEhhbnMgR3Vp
anQgZm9yIGNvbXBsYWluaW5nIGxvdWRseSBlbm91Z2ggYWJvdXQgc3RhbmRhcmRpemluZyA8
Y29kZSBjbGFzcz0iY3BwIGMrKyI+PHNwYW4gY2xhc3M9Im5hbWUiPnByYWdtYTwvc3Bhbj4g
PHNwYW4gY2xhc3M9Im5hbWUiPm9uY2U8L3NwYW4+PC9jb2RlPiB0aGF0IHdlIGRlY2lkZWQg
dG8gYWN0dWFsbHkgd3JpdGUgYSBwcm9wb3NhbCwgVGltIFNvbmcgZm9yIHZhbHVhYmxlIGZl
ZWRiYWNrIG9uIHRoZSBpbml0aWFsIGRyYWZ0LCBhbmQgZXZlcnlvbmUgZWxzZSBvbiB0aGUg
PHR0IGNsYXNzPSJkb2N1dGlscyBsaXRlcmFsIj48c3BhbiBjbGFzcz0icHJlIj5zdGQtcHJv
cG9zYWxzPC9zcGFuPjwvdHQ+IGZvcnVtIHRoYXQgY29udHJpYnV0ZWQgY29tbWVudHMgb24g
dGhpcyB0b3BpYy48L3A+CjwhLS0gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4g
Li4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLi4gLS0+CjwhLS0ga2F0
ZTogaGwgcmVTdHJ1Y3R1cmVkVGV4dCAtLT4KPC9kaXY+CjwvZGl2Pgo8L2JvZHk+CjwvaHRt
bD4K
--------------040904030303050009050103
Content-Type: text/prs.fallenstein.rst;
 name="dxxxx-preprocessor-once.rst"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
 filename="dxxxx-preprocessor-once.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
  A Qualified Replacement for ``#pragma once``
=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:  Dxxxx
:Date:      2016-10-27
: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

This proposal recommends to standardize :cpp:`#once` as an improved mecha=
nism for preventing multiple inclusion of a header, and a related directi=
ve :cpp:`#forget`.

=2E. contents::


Problem
=3D=3D=3D=3D=3D=3D=3D

It is well known that when compiling code of non-trivial complexity, the =
complete set of :cpp:`#include` directives may reference the same header =
more than once. This often occurs when a translation unit uses several di=
stinct components which each rely on the same base component (especially =
library configuration headers, headers that provide export decoration sym=
bols, and the like). While this is correct for each component header in o=
rder to allow it to be used on its own, the combination of multiple compo=
nents requires a mechanism to prevent the definitions in a header from be=
ing parsed twice, which would lead to compile errors.

Traditionally, this is accomplished with "include guards", which take the=
 form:

=2E. code:: c++

  // foo.h
  #ifndef _MYLIB_FOO_H_INCLUDED
  #define _MYLIB_FOO_H_INCLUDED
  ...
  #endif // _MYLIB_FOO_H_INCLUDED

At least one problem with this is obvious; the guard symbol is repeated a=
s many as three times (the last occurrence in the comment is optional and=
 at least has no impact on compiling if it is incorrect), leading to the =
possibility of mistakes when retyping the symbol that cause the guard to =
be ineffective. Less obvious, but even more problematic, it is common for=
 headers to be copied, which can lead to difficult to diagnose errors if =
the programmer neglects to adjust the guard when doing so.

Some compilers support ``#pragma once`` as an alternate mechanism for pre=
venting multiple inclusions. However, many problems with this mechanism a=
re known. It is difficult for compiler authors to implement correctly, es=
pecially in the presence of pathological source trees (involving copies o=
f headers, whether by symlink, or worse, the same physical file accessibl=
e via different mount points). There is also a question of how distinct h=
eaders providing similar definitions should be handled. These problems ar=
e well addressed by traditional include guards.


Proposal
=3D=3D=3D=3D=3D=3D=3D=3D

We propose to introduce three new preprocessor directives in an attempt t=
o address this issue.

:cpp:`#once`
------------

  **#once** *identifier* [ *<whitespace>* *version* ]

The *identifier* shall consist of one or more C++ identifiers (sequences =
of alphanumeric characters and/or ``_``, not starting with a digit) joine=
d by ``::`` (henceforth referred to as a "qualified name"). The *version*=
, if specified, shall be a token string consisting of alphanumeric charac=
ters and/or the ``_``, ``-``, ``:`` or ``.`` characters, not starting wit=
h ``:``, and shall set the version associated with the specified *identif=
ier*.

If a previous :cpp:`#once` directive having the same *identifier* and *ve=
rsion* has been previously seen, the compiler shall ignore the remainder =
of the :cpp:`#include` unit. If the *identifier* is known but the *versio=
n* does not match, the program shall be ill-formed. (If *version* is unsp=
ecified, the version shall be the empty string.)

:cpp:`#forget`
--------------

  **#forget** *identifier*

The compiler shall remove the *identifier* from its collection of previou=
sly seen identifiers. This directive provides a mechanism to force the mu=
ltiple inclusion of an :cpp:`#include` unit which uses :cpp:`#once`.


Comments and Examples
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

Static Analysis
---------------

As mentioned, one of the problems with traditional guards is that they ca=
n easily get out of sync with the header file they guard. While it is pos=
sible to write static analysis tools to detect such errors, the prolifera=
tion of different styles of guards make it difficult to write a single he=
uristic that works across a broad base of existing software. In turn, thi=
s means that such tools tend to be project specific and are at best run w=
hen code is committed to a repository. It would be far better for such ch=
ecks to be integrated into the compiler, so that they run at build time, =
and can be promoted to errors.

We address this by making the guard identifier a qualified name. Besides =
being more consistent with C++ conventions (for example, the namespace of=
 the guard could match the namespace of the project which owns the header=
), this, combined with the introduction of a new feature, makes it straig=
ht forward to stipulate that the unqualified portion of the identifier sh=
all match the name of the :cpp:`#include` unit (excluding a file extensio=
n, if any).

Moreover, it is not inconceivable that we could agree that the namespace =
portion of the qualified identifier shall match the namespace of the defi=
nitions provided by the :cpp:`#include` unit (so that all parts of the gu=
ard identifier are checked for correctness), with the compiler issuing a =
diagnostic if the :cpp:`#include` unit does not include at least one decl=
aration in the same namespace.

Since we are talking about QoI issues here, we feel that it is not necess=
ary that these checks be normative. Instead, we would prefer to let the c=
ompiler community agree on what conventions should be expected and diagno=
sed.

Example
~~~~~~~

=2E. code:: c++

  // foo.h
  #once MyLibrary::bar // warning: guard should be 'MyLibrary::foo'

  // bar.h
  #once bar // warning: guard should be namespaced

Proper Use of Versioning
------------------------

Although the "obvious" way to use version directives is to include the ve=
rsion of the software package to which a header belongs in every single h=
eader, this leads to an obvious and significant maintenance burden. A bet=
ter solution which will be equally adequate in almost every instance is t=
o maintain such version information in a single, global header file (e.g.=
 ``version.h``, ``config.h``, ``exports.h``) which is always included via=
 an :cpp:`#include` directive (prior to :cpp:`#once`) whose path is marke=
d with quotes (\ ``""``\ ) rather than angle brackets (\ ``<>``\ ). This =
ensures that the global header is always found in a known location relati=
ve to the header being processed, and will in almost all cases be suffici=
ent to catch mismatching versions of the header which includes the global=
 header.

Another option, which can be employed in tandem, is to use a monotonicall=
y increasing version number that is unique to each header and is incremen=
ted whenever the interface(s) defined in the header change. Because this =
number is unique to the header, and only changes when the header changes =
(and possibly not even that frequently), the maintenance burden is signif=
icantly reduced.

The relatively liberal specification of allowed version strings was chose=
n with the specific intention of encouraging the version string to be gen=
erated by the build system, and in particular to allow the version string=
 to include a VCS identifier. In this way, we may ensure that headers fro=
m a development version of software are not mixed with those from a relea=
se version or different development version, even if the normative versio=
n number does not differ between such versions.

Example
~~~~~~~

=2E. code:: c++

  // version.h
  #once MyLibrary::version 0.1.0 // MyLibrary version 0.1.0

  // widget.h
  #include "version.h"
  #once MyLibrary::widget 2 // widget API version 2

  // common.h
  #include "version.h"
  #once MyLibrary::common // no version

Performance
-----------

One of the points that is frequently raised in favor of :cpp:`#pragma onc=
e` is that it allows the compiler to skip reading a file that it has alre=
ady included. However, the problem with this is that if the compiler is n=
ot able to correctly determine if a header has already been included, it =
is likely that the translation unit will fail to compile.

In fact, compilers may and do already implement similar logic for traditi=
onal include guards. By employing a heuristic, a compiler may determine t=
hat a header's contents are entirely guarded. Having done so, the header =
and its guard may be entered into a map, such that the compiler may choos=
e not to read the header a second time if it observes that an :cpp:`#incl=
ude` directive would reference a header that has been previously processe=
d and whose include guard is defined. This is safer, since in case of a w=
rong guess, the compiler will read the header anyway and process it as em=
pty due to the traditional guard, which has a small performance penalty b=
ut does not affect correctness of the program.

Our model for :cpp:`#once` provides these same benefits, while making exp=
licit (and enforcing) that the entire header may be skipped if the compil=
er "knows" it has been included already. The proposed directive therefore=
 provides the same performance benefits as :cpp:`#pragma once`, but witho=
ut the potential pitfalls. (In cases such as described above, where one o=
r more :cpp:`#include` directives precede :cpp:`#once`, the compiler woul=
d need to track the recursive set of guards which make a second inclusion=
 a no-op. While somewhat more complicated, this still seems achievable.)


Discussion
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

Why not reuse :cpp:`#pragma`?
-----------------------------

The obvious answer is that :cpp:`#pragma` as a whole is implementation de=
fined. Choosing an entirely new directive makes it clear that this featur=
e is "blessed" by the standard and not an implementation defined feature.=
 The exact names used, however, are subject to the usual bikeshedding. We=
 would encourage the committee to consider the feature first on its merit=
s; if it seems useful, we are completely open to choosing some other name=
 or even syntax for the directives. (It might even make sense to use a sy=
ntax that is evocative of that used by modules.)

Won't modules make this irrelevant?
-----------------------------------

It is possible that modules will significantly reduce the need for this f=
eature, but modules aren't here yet, and it is likely that we will contin=
ue to have traditional headers for a long time. Since this feature happen=
s entirely at the preprocessor level, it is our sincere hope that compile=
rs will choose to implement the feature early, and enable it regardless o=
f the language level requested. This means that existing software may be =
able to take advantage of the feature much sooner than such software can =
be ported to modules (which will involve a much more invasive change).

Shouldn't this go to C first?
-----------------------------

While we would certainly love to see this feature adopted by C as well, w=
e don't think it makes sense that preprocessor features *must* be adopted=
 by C first. In particular, we note that the use of a C++ qualified ident=
ifier gives us a very good reason to adopt this feature in C++ first, as =
C will have to decide to either accept C++ qualified identifiers for this=
 purpose or find an alternate solution that solves the same problems that=
 are addressed by the use of a qualified name.

Moreover, we note that it does not make a significant difference in pract=
ice which language adopts a preprocessor feature first. Since most compil=
ers share preprocessor function between C and C++ front-ends, adoption of=
 this feature by C++ will likely make it a de facto C standard.


Summary
=3D=3D=3D=3D=3D=3D=3D

We have shown a mechanism for implementing a next generation system for p=
reventing multiple inclusion of headers. This system is semantically equi=
valent to traditional guards, and so avoids the known issues of present i=
mplementations of :cpp:`#pragma once` (without an identifier). By also pr=
oviding a :cpp:`#forget`, we address the issue of how to force multiple i=
nclusion when necessary in a way that does not require editing the header=
 in question. By using a qualified identifier, we provide an improved mec=
hanism for avoiding collisions that is also amenable to the use of static=
 analysis tools to detect the sorts of improper use that are the major co=
mplaint against traditional guards. By also specifying an optional mechan=
ism for providing version information, we provide a means to diagnose acc=
idental mixing of different versions of headers.


Acknowledgments
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

We wish to thank Hans Guijt for complaining loudly enough about standardi=
zing :cpp:`pragma once` that we decided to actually write a proposal, Tim=
 Song for valuable feedback on the initial draft, and everyone else on th=
e ``std-proposals`` forum that contributed comments on this topic.


=2E. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..=
 .. ..

=2E. kate: hl reStructuredText

--------------040904030303050009050103--

.


Author: "T. C." <rs2740@gmail.com>
Date: Fri, 28 Oct 2016 13:46:39 -0700 (PDT)
Raw View
------=_Part_566_950601767.1477687599598
Content-Type: multipart/alternative;
 boundary="----=_Part_567_522816657.1477687599598"

------=_Part_567_522816657.1477687599598
Content-Type: text/plain; charset=UTF-8



On Friday, October 28, 2016 at 4:33:23 PM UTC-4, Matthew Woehlke wrote:On
2016-10-28 16:01, T. C. wrote:
>
> > #pragma once (std :: vector :: foo :: bar :: 1.0).
> >
> > Where does the "qualified C++ identifier" end and where does "version"
> > begin?
>
> Um... I think this would be an error; `1.0` isn't a valid identifier.
>


> Or are you saying that unlike actual "qualified C++ identifier"s,
> > you can't have whitespace here?
>
> I wasn't thinking about whitespace, actually... Okay, I see the problem:
>
>   #once hello ::world
>
> If we allow whitespace between 'parts' of the name, is that 'hello',
> version '::world', or 'hello::world' with no version?
>
> That's easy to fix; forbid the version starting with `:`. Maybe the
> version doesn't even need `:`; that usually only shows up in
> distribution package versions for unusual reasons related to
> distribution packaging (that delve into the horribly complicated realm
> of version number sorting).
>
> I believe this makes the parsing simple: whitespace followed by
> not-a-`:` separates the version from the name. Then we can also allow
> (and ignore) whitespace around `::`.
>
> Note: the version may *not* contain whitespace.
>

That may work, but "version" as described can be several preprocessing
tokens (1.0.1-1 is three: "1.0.1", "-", "1"), so you either need a special
rule that says there can't be whitespace between those pp-tokens (unlike
most other cases), or introduce a new type of preprocessing token formed
only in #once, like header-names. Neither approach sounds particularly
appealing to me compared to just using a string-literal.

--
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/28223b1b-dd80-4055-acb0-aef52b6a228d%40isocpp.org.

------=_Part_567_522816657.1477687599598
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, October 28, 2016 at 4:33:23 PM UTC-4, M=
atthew Woehlke wrote:On 2016-10-28 16:01, T. C. wrote:=C2=A0<blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;">&gt; #pragma once (std :: vector :: foo :: ba=
r :: 1.0).
<br>&gt;=20
<br>&gt; Where does the &quot;qualified C++ identifier&quot; end and where =
does &quot;version&quot;=20
<br>&gt; begin?
<br>
<br>Um... I think this would be an error; `1.0` isn&#39;t a valid identifie=
r.=C2=A0<br></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:=
 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left=
: 1ex;">=C2=A0</blockquote><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&gt=
; Or are you saying that unlike actual &quot;qualified C++ identifier&quot;=
s,=20
<br>&gt; you can&#39;t have whitespace here?=20
<br>
<br>I wasn&#39;t thinking about whitespace, actually... Okay, I see the pro=
blem:
<br>
<br>=C2=A0 #once hello ::world
<br>
<br>If we allow whitespace between &#39;parts&#39; of the name, is that &#3=
9;hello&#39;,
<br>version &#39;::world&#39;, or &#39;hello::world&#39; with no version?
<br>
<br>That&#39;s easy to fix; forbid the version starting with `:`. Maybe the
<br>version doesn&#39;t even need `:`; that usually only shows up in
<br>distribution package versions for unusual reasons related to
<br>distribution packaging (that delve into the horribly complicated realm
<br>of version number sorting).
<br>
<br>I believe this makes the parsing simple: whitespace followed by
<br>not-a-`:` separates the version from the name. Then we can also allow
<br>(and ignore) whitespace around `::`.
<br>
<br>Note: the version may *not* contain whitespace.
<br></blockquote><div><br></div><div>That may work, but &quot;version&quot;=
 as described can be several preprocessing tokens (1.0.1-1 is three: &quot;=
1.0.1&quot;, &quot;-&quot;, &quot;1&quot;), so you either need a special ru=
le that says there can&#39;t be whitespace between those pp-tokens (unlike =
most other cases), or introduce a new type of preprocessing token formed on=
ly in #once, like header-names. Neither approach sounds particularly appeal=
ing to me compared to just using a string-literal.</div></div>

<p></p>

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

------=_Part_567_522816657.1477687599598--

------=_Part_566_950601767.1477687599598--

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Fri, 28 Oct 2016 14:52:20 -0700 (PDT)
Raw View
------=_Part_831_938266935.1477691541047
Content-Type: multipart/alternative;
 boundary="----=_Part_832_1592102597.1477691541047"

------=_Part_832_1592102597.1477691541047
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thursday, October 27, 2016 at 9:34:25 AM UTC-7, Matthew Woehlke wrote:
>
> After the recent thread rehashing this yet again, I'm sure some folks=20
> will be surprised to see me on the other side of the issue. However, all=
=20
> the noise got me to thinking how we might actually do this correctly...=
=20
>
> This is *not* a proposal for *unqualified* `#pragma once` [...]=20
>

I'm not a Committee member, but if I were, I would strongly oppose any=20
proposal that tried to solve the "#pragma once" problem in any way other=20
than:
(1) Standardizing existing vendor practice, i.e., #pragma once; or
(2) Helping to move the Modules proposal more quickly toward=20
standardization.

Remember, ordinary programmers (such as myself) can already use "#pragma=20
once" with every C or C++ compiler we encounter in daily practice. Relying=
=20
on "#pragma once" is no weirder than relying on ,##__VA_ARGS__=20
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2023.pdf>[a] or system=20
include paths or __builtin_unreachable() or -Wall -Werror or any of the=20
other things we use in our daily practice that have been "standardized"=20
only by vendors, not by ISO.

Include-guards and #pragma once were originally invented to solve a problem=
=20
(breakage from double-inclusion) that in the medium term here will be=20
solved by the Modules proposal, rendering the two existing solutions=20
obsolete. I strongly encourage anyone currently dealing with=20
double-inclusion problems to either:[b]
(1) Adopt the existing ISO Standard solution (include guards); or
(2) Adopt the existing solution documented by your compiler vendor (#pragma=
=20
once); or
(3) Adopt and/or pitch in and/or wait eagerly for the=20
soon-to-be-ISO-Standard solution (the Modules draft TS=20
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4610.pdf>).

Creating a *third* *legacy* solution to the double-inclusion problem=20
doesn't help anyone, least of all the ordinary programmers who are just=20
trying to figure out the best practice and use it to do their daily work.[c=
]

=E2=80=93Arthur

[a] My kudos to Thomas K=C3=B6ppe for attempting to standardize existing=20
practice in N2023=20
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2023.pdf> instead of=20
inventing a new thing.
[b] If you use any third-party headers, you have already done either (1) or=
=20
(2) anyway, whether you know it or not. (And you've probably done *both*.)
[c] As usual, there is an XKCD for this. <https://xkcd.com/927/>

--=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/8422f73d-e04f-49e4-aede-0399cd4d01db%40isocpp.or=
g.

------=_Part_832_1592102597.1477691541047
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, October 27, 2016 at 9:34:25 AM UTC-7, Matthew=
 Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">After the recen=
t thread rehashing this yet again, I&#39;m sure some folks
<br>will be surprised to see me on the other side of the issue. However, al=
l
<br>the noise got me to thinking how we might actually do this correctly...
<br>
<br>This is *not* a proposal for *unqualified* `#pragma once` [...]=C2=A0<b=
r></blockquote><div><br></div><div>I&#39;m not a Committee member, but if I=
 were, I would strongly oppose any proposal that tried to solve the &quot;#=
pragma once&quot; problem in any way other than:</div><div>(1) Standardizin=
g existing vendor practice, i.e., #pragma once; or</div><div>(2) Helping to=
 move the Modules proposal more quickly toward standardization.</div><div><=
br></div><div>Remember, ordinary programmers (such as myself) can already u=
se &quot;#pragma once&quot; with every C or C++ compiler we encounter in da=
ily practice. Relying on &quot;#pragma once&quot; is no weirder than relyin=
g on <font face=3D"courier new, monospace"><a href=3D"http://www.open-std.o=
rg/jtc1/sc22/wg14/www/docs/n2023.pdf">,##__VA_ARGS__</a></font><font size=
=3D"1">[a]</font> or system include paths or <font face=3D"courier new, mon=
ospace">__builtin_unreachable()</font> or <font face=3D"courier new, monosp=
ace">-Wall -Werror</font> or any of the other things we use in our daily pr=
actice that have been &quot;standardized&quot; only by vendors, not by ISO.=
</div><div><br></div><div>Include-guards and #pragma once were originally i=
nvented to solve a problem (breakage from double-inclusion) that in the med=
ium term here will be solved by the Modules proposal, rendering the two exi=
sting solutions obsolete. I strongly encourage anyone currently dealing wit=
h double-inclusion problems to either:<font size=3D"1">[b]</font></div><div=
>(1) Adopt the existing ISO Standard solution (include guards); or</div><di=
v>(2) Adopt the existing solution documented by your compiler vendor (#prag=
ma once); or</div><div>(3) Adopt and/or pitch in and/or wait eagerly for th=
e soon-to-be-ISO-Standard solution (<a href=3D"http://www.open-std.org/jtc1=
/sc22/wg21/docs/papers/2016/n4610.pdf">the Modules draft TS</a>).</div><div=
><br></div><div>Creating a <b>third</b>=C2=A0<i>legacy</i> solution to the =
double-inclusion problem doesn&#39;t help anyone, least of all the ordinary=
 programmers who are just trying to figure out the best practice and use it=
 to do their daily work.<font size=3D"1">[c]</font></div><div><br></div><di=
v>=E2=80=93Arthur</div><div><br></div><div>[a] My kudos to Thomas K=C3=B6pp=
e for attempting to standardize existing practice in <a href=3D"http://www.=
open-std.org/jtc1/sc22/wg14/www/docs/n2023.pdf">N2023</a> instead of invent=
ing a new thing.<br></div><div><div>[b] If you use any third-party headers,=
 you have already done either (1) or (2) anyway, whether you know it or not=
.. (And you&#39;ve probably done=C2=A0<i>both</i>.)</div></div><div><div>[c]=
 As usual,=C2=A0<a href=3D"https://xkcd.com/927/">there is an XKCD for this=
..</a></div></div><div><br></div></div>

<p></p>

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

------=_Part_832_1592102597.1477691541047--

------=_Part_831_938266935.1477691541047--

.


Author: =?UTF-8?Q?=27Bernd_L=C3=B6rwald=27_via_ISO_C=2B=2B_Standard_=2D_Future_Proposal?=
Date: Sun, 30 Oct 2016 02:42:27 +0200
Raw View
From a user perspective:

The only cases where classic include guards have been an issue to me have b=
een
=E2=80=A2 I copied a file and forgot to change the guard name
=E2=80=A2 two libraries use the same guard name
=E2=80=A2 a library I want to use in two versions uses guard names without =
a unique prefix, thus not allowing sed s/boost/moost/gi and including twice=
..=20

Qualified pragma once solves none of these, unqualified pragma once solves =
all of these. Qualified pragma once relies on the exact issue one would lik=
e unqualified pragma once for: the compiler knows better.

The main argument against pragma once in the last days has been it being ha=
rd to decide if it is the same file again, most often pipes are named. I do=
n't see how this is true though: unless you're talking about unnamed files =
even pipes have a unique canonicalized filename which they can be identifie=
d by. As soon as you're talking about anonymous files, I don't see how they=
 can be an issue for pragma once to begin with: they can only be the main f=
ile, as an #include could not identify them otherwise.=20

> Am 27.10.2016 um 18:34 schrieb Matthew Woehlke <mwoehlke.floss@gmail.com>=
:
>=20
> After the recent thread rehashing this yet again, I'm sure some folks
> will be surprised to see me on the other side of the issue. However, all
> the noise got me to thinking how we might actually do this correctly...
>=20
> This is *not* a proposal for *unqualified* `#pragma once` (it is
> mentioned in the paper, but remains explicitly implementation defined).
> Instead, it proposes a *qualified* `#pragma once(identifier)` which
> solves the problems of unqualified `#pragma once` (by being semantically
> equivalent to correctly used traditional guards). The problem of
> choosing the correct identifier is addressed by making the identifier a
> qualified C++ identifier, such that it is easy for static analysis tools
> to enforce that the (final part of the) identifier matches the header
> file name (ideally this would be a compiler warning that many projects
> would promote to an error by default). A versioning system is also
> proposed to catch errors where multiple (possibly incompatible) versions
> of the same header are referenced.
>=20
> Draft proposal attached. Please let me know what you think!
>=20
> --=20
> Matthew
>=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=
 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/isoc=
pp.org/d/msgid/std-proposals/58122C8D.9060205%40gmail.com.
> <dxxxx-pragma-once.html>
> <dxxxx-pragma-once.rst>

--=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/D64E93DC-2905-4183-9203-8D0D44181196%40googlemai=
l.com.

.


Author: "D. B." <db0451@gmail.com>
Date: Sun, 30 Oct 2016 07:23:05 +0000
Raw View
--001a114232c867bc6f05400ff67e
Content-Type: text/plain; charset=UTF-8

FWIW, I mostly agree with Arthur. Although it may be technically
interesting in isolation, ultimately these threads just seem like a
disproportionate amount of noise about something that both

   - has a working solution using the preprocessor, already, and
   - would be obsoleted by an upcoming feature that, although long delayed,
   I think is inexorable, namely modules.

--
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/CACGiwhF%2B0_1X9i8p2v5GxWEqsNntFSMAV%2Bsr_AYFKQw-hmdvqw%40mail.gmail.com.

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

<div dir=3D"ltr">FWIW, I mostly agree with Arthur. Although it may be techn=
ically interesting in isolation, ultimately these threads just seem like a =
disproportionate amount of noise about something that both<br><ul><li>has a=
 working solution using the preprocessor, already, and</li><li>would be obs=
oleted by an upcoming feature that, although long delayed, I think is inexo=
rable, namely modules.</li></ul><p><br></p></div>

<p></p>

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

--001a114232c867bc6f05400ff67e--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Sun, 30 Oct 2016 16:05:28 -0700 (PDT)
Raw View
------=_Part_1391_1479608604.1477868728740
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Sunday, 30 October 2016 01:42:31 UTC+1, Bernd L=C3=B6rwald  wrote:
> From a user perspective:
>=20
> The only cases where classic include guards have been an issue to me have=
 been
> =E2=80=A2 I copied a file and forgot to change the guard name
> =E2=80=A2 two libraries use the same guard name
> =E2=80=A2 a library I want to use in two versions uses guard names withou=
t a unique prefix, thus not allowing sed s/boost/moost/gi and including twi=
ce.=20
>=20
> Qualified pragma once solves none of these, unqualified pragma once solve=
s all of these. Qualified pragma once relies on the exact issue one would l=
ike unqualified pragma once for: the compiler knows better.

Tooling could help here, since the compiler knows that a qualified once gua=
rd is in fact intended for that purpose.=20

> The main argument against pragma once in the last days has been it being =
hard to decide if it is the same file again, most often pipes are named. I =
don't see how this is true though: unless you're talking about unnamed file=
s even pipes have a unique canonicalized filename which they can be identif=
ied by. As soon as you're talking about anonymous files, I don't see how th=
ey can be an issue for pragma once to begin with: they can only be the main=
 file, as an #include could not identify them otherwise.=20

I think you're under a misperception there. The main problems are a) symlin=
ks and b) network filesystems.=20

a) means that a file may have more than one name; b)  means that the inform=
ation to determine whether two names denote the same file may not be availa=
ble to the compiler.=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/977b1f3b-e0d7-4a98-b20a-6e99dd27c64d%40isocpp.or=
g.

------=_Part_1391_1479608604.1477868728740--

.


Author: =?UTF-8?Q?=27Bernd_L=C3=B6rwald=27_via_ISO_C=2B=2B_Standard_=2D_Future_Proposal?=
Date: Mon, 31 Oct 2016 01:13:43 +0100
Raw View
> I think you're under a misperception there. The main problems are a) syml=
inks and b) network filesystems.=20
>=20
> a) means that a file may have more than one name

There is a reason for ::filesystem::canonical etc. and it is exactly this.

> b)  means that the information to determine whether two names denote the =
same file may not be available to the compiler.

Network shares should still expose symlinks as such. (And I'd argue that al=
l^tm filesystems properly implement system APIs). Any filesystem could of c=
ourse serve the same content independent on path, but would you call that w=
ell behaved? Do we really want to exclude things from the standard based on=
 "someone may actively work against it and fuck shit up"? Both symlinks and=
 hard links are traceable by posix API, and I'd guess Microsoft isn't that =
insane either.=20

In the end, a sane filesystem will provide a unique identifier, be it st_de=
v+st_ino or some canonical() implementation. Yes, you can actively work aga=
inst it. Yes, it is technically possible to do things. But there are compil=
ers on every system offering the feature for a decade and I would love to s=
ee a real world scenario where it actually breaks. And we only talk about f=
alse-negatives, not false-positives here. Worst case is that it includes tw=
ice which gives an error, not that it includes once where it should include=
 twice.=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/5D3A57F9-7825-403E-81FA-F353F894C2E0%40googlemai=
l.com.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Sun, 30 Oct 2016 20:01:59 -0700
Raw View
On segunda-feira, 31 de outubro de 2016 01:13:43 PDT 'Bernd L=C3=B6rwald' v=
ia ISO C
++ Standard - Future Proposals wrote:
> > I think you're under a misperception there. The main problems are a)
> > symlinks and b) network filesystems.
> >=20
> > a) means that a file may have more than one name
>=20
> There is a reason for ::filesystem::canonical etc. and it is exactly this=
..

That doesn't work for hardlinks, though.

> > b)  means that the information to determine whether two names denote th=
e
> > same file may not be available to the compiler.
> Network shares should still expose symlinks as such. (And I'd argue that
> all^tm filesystems properly implement system APIs). Any filesystem could =
of
> course serve the same content independent on path, but would you call tha=
t
> well behaved? Do we really want to exclude things from the standard based
> on "someone may actively work against it and fuck shit up"? Both symlinks
> and hard links are traceable by posix API, and I'd guess Microsoft isn't
> that insane either.

Yes, we have to figure out all the possible stupid scenarios when dealing w=
ith=20
a standard.

Here's a simple example: what happens if you do a network mount of a local=
=20
filesystem? Can you tell that a file there is the same as the original loca=
l=20
file?

> In the end, a sane filesystem will provide a unique identifier, be it
> st_dev+st_ino or some canonical() implementation. Yes, you can actively
> work against it. Yes, it is technically possible to do things. But there
> are compilers on every system offering the feature for a decade and I wou=
ld
> love to see a real world scenario where it actually breaks. And we only
> talk about false-negatives, not false-positives here. Worst case is that =
it
> includes twice which gives an error, not that it includes once where it
> should include twice.

It's easy to break them. And read my other emails about the transfer of=20
responsibiity.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center

--=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/1863360.BULYCS5ArV%40tjmaciei-mobl1.

.


Author: Tom Honermann <tom@honermann.net>
Date: Mon, 31 Oct 2016 00:32:42 -0400
Raw View
On 10/30/2016 8:13 PM, 'Bernd L=C3=B6rwald' via ISO C++ Standard - Future=
=20
Proposals wrote:
> In the end, a sane filesystem will provide a unique identifier, be it st_=
dev+st_ino or some canonical() implementation. Yes, you can actively work a=
gainst it. Yes, it is technically possible to do things. But there are comp=
ilers on every system offering the feature for a decade and I would love to=
 see a real world scenario where it actually breaks.

I've had to debug issues where the implementations of #pragma once,=20
#import, or of performance optimizations done to recognize subsequent=20
inclusion of the same header with a standard header guard, produced=20
observable differences across compilers.  MSVC, gcc, and clang all=20
differ in how they determine if two included headers resolve to the=20
"same" file.

MSVC does not attempt to resolve headers based on inodes and will not=20
recognize inclusion of the same (identical inode) file by different file=20
name or path.  MSVC relies solely on file path and name.

Gcc also does not attempt to resolve headers based on inodes.  Gcc=20
considers files with the same size, contents, and modification time to=20
be the "same" file.

Clang relies on inode information (st_dev+st_ino,=20
GetFileInformationByHandle(), etc...) to recognize subsequent inclusion=20
of a previously included file.

For both st_dev+st_ino and GetFileInformationByHandle[ex](), it is=20
necessary to keep file handles open to ensure stable identifiers are=20
returned.  Some (network) filesystems dynamically allocate/assign inode=20
identifiers as files are opened/closed.

Also Miscrosoft's GetFileInformationByHandle() and=20
BY_HANDLE_FILE_INFORMATION are no longer sufficient to uniquely identify=20
files on some filesystems.  Some newer filesystems (ReFS) use 128-bit=20
file identifiers and require the use of GetFileInformationByHandleEx()=20
and FILE_ID_INFO to return a unique identifier.

Tom.

--=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/95f4edef-b077-add2-138e-b0761105c734%40honermann=
..net.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 3 Nov 2016 11:32:28 -0400
Raw View
On 2016-10-28 17:00, Andrey Semashev wrote:
> Maybe just make the version an unsigned integer?

I think that is too much work for developers. The idea is that the
version in this context matches the version number of the package. That
will be at least like "1.0", and may well contain a date and/or VCS stamp.

Requiring an unsigned integer, besides making it nearly impossible to
properly version snapshots, requires extra work in that developers now
have to maintain this version number in addition to a more traditional
version number.

--
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/581B588C.8010203%40gmail.com.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 3 Nov 2016 11:39:11 -0400
Raw View
On 2016-10-28 16:46, T. C. wrote:
> That may work, but "version" as described can be several preprocessing
> tokens (1.0.1-1 is three: "1.0.1", "-", "1"), so you either need a special
> rule that says there can't be whitespace between those pp-tokens (unlike
> most other cases), or introduce a new type of preprocessing token formed
> only in #once, like header-names. Neither approach sounds particularly
> appealing to me compared to just using a string-literal.

So, for now I changed it to a string literal. But... would this work?

1. The first token is the guard name
2. ++current_token
3. If the current token is "::":
  - Append the current token to the guard name
  - ++current_token
  - Append the current token to the guard name
  - ++current_token
  - Go to 3
4. While the token buffer is not empty:
  - Append the current token to the version
  - ++current_token

This allows whitespace to be ignored, besides separating tokens. So,
these are equivalent:

  #once foo::bar 1.0-12
  #once foo :: bar 1 . 0 - 12
  #once \
    foo :: \
    bar \
    1 \
    . \
    0 \
    - \
    1 \
    2

--
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/581B5A1F.4040807%40gmail.com.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 3 Nov 2016 11:46:10 -0400
Raw View
On 2016-10-29 20:42, Bernd L=C3=B6rwald wrote:
> From a user perspective:
>=20
> The only cases where classic include guards have been an issue to me have=
 been
> =E2=80=A2 I copied a file and forgot to change the guard name
> =E2=80=A2 two libraries use the same guard name
> =E2=80=A2 a library I want to use in two versions uses guard names withou=
t a unique prefix, thus not allowing sed s/boost/moost/gi and including twi=
ce.=20
>=20
> Qualified pragma once solves none of these, unqualified pragma once solve=
s all of these.

I'm sorry... did you *read the proposal*? It most explicitly *does*
address your first point, and certainly strongly encourages developers
to DTRT to avoid your second and third points.

--=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/581B5BC2.30805%40gmail.com.

.