From b2da84f903030ab37638fe7315e85436bb17a54a Mon Sep 17 00:00:00 2001 From: xiangsilian Date: Sun, 26 Oct 2025 00:13:08 +0800 Subject: [PATCH] save code --- app/src/main/assets/demo0.png | Bin 71202 -> 20859 bytes app/src/main/assets/demo0_ex.png | Bin 84377 -> 24044 bytes app/src/main/assets/shaders/texture.frag | 24 +- app/src/main/assets/shaders/texture.frag.spv | Bin 1792 -> 1732 bytes app/src/main/cpp/main.cpp | 18 + .../java/com/hmwl/face_sdk/FaceActivity.java | 6 + .../assets/底妆/基础上妆/2按压/区域/demo0.png | Bin 0 -> 20795 bytes .../底妆/基础上妆/2按压/区域/demo0_ex.png | Bin 0 -> 24141 bytes .../assets/底妆/基础上妆/2按压/方向/pic0.png | Bin 0 -> 22136 bytes .../底妆/基础上妆/2按压/方向/pic0_thick.png | Bin 0 -> 29944 bytes .../assets/底妆/基础上妆/2按压/方向/pic1.png | Bin 0 -> 24356 bytes .../底妆/基础上妆/2按压/方向/pic1_thick.png | Bin 0 -> 28534 bytes .../assets/底妆/基础上妆/2按压/方向/pic2.png | Bin 0 -> 24278 bytes .../底妆/基础上妆/2按压/方向/pic2_thick.png | Bin 0 -> 32430 bytes vulkan/AppBase.cpp | 6 +- vulkan/AppBase.h | 2 +- vulkan/Application.cpp | 16 +- vulkan/Application.h | 2 + vulkan/FaceApp.cpp | 159 +- vulkan/FaceApp.h | 38 +- vulkan/main.cpp | 28 +- vulkan/nlohmann/adl_serializer.hpp | 55 + .../nlohmann/byte_container_with_subtype.hpp | 103 + vulkan/nlohmann/detail/abi_macros.hpp | 100 + .../nlohmann/detail/conversions/from_json.hpp | 497 ++ .../nlohmann/detail/conversions/to_chars.hpp | 1118 ++++ .../nlohmann/detail/conversions/to_json.hpp | 447 ++ vulkan/nlohmann/detail/exceptions.hpp | 257 + vulkan/nlohmann/detail/hash.hpp | 129 + .../nlohmann/detail/input/binary_reader.hpp | 3009 ++++++++++ .../nlohmann/detail/input/input_adapters.hpp | 492 ++ vulkan/nlohmann/detail/input/json_sax.hpp | 727 +++ vulkan/nlohmann/detail/input/lexer.hpp | 1633 +++++ vulkan/nlohmann/detail/input/parser.hpp | 519 ++ vulkan/nlohmann/detail/input/position_t.hpp | 37 + .../detail/iterators/internal_iterator.hpp | 35 + .../nlohmann/detail/iterators/iter_impl.hpp | 751 +++ .../detail/iterators/iteration_proxy.hpp | 242 + .../detail/iterators/iterator_traits.hpp | 61 + .../iterators/json_reverse_iterator.hpp | 130 + .../detail/iterators/primitive_iterator.hpp | 132 + .../detail/json_custom_base_class.hpp | 39 + vulkan/nlohmann/detail/json_pointer.hpp | 988 ++++ vulkan/nlohmann/detail/json_ref.hpp | 78 + vulkan/nlohmann/detail/macro_scope.hpp | 482 ++ vulkan/nlohmann/detail/macro_unscope.hpp | 45 + .../nlohmann/detail/meta/call_std/begin.hpp | 17 + vulkan/nlohmann/detail/meta/call_std/end.hpp | 17 + vulkan/nlohmann/detail/meta/cpp_future.hpp | 171 + vulkan/nlohmann/detail/meta/detected.hpp | 70 + vulkan/nlohmann/detail/meta/identity_tag.hpp | 21 + vulkan/nlohmann/detail/meta/is_sax.hpp | 159 + vulkan/nlohmann/detail/meta/std_fs.hpp | 29 + vulkan/nlohmann/detail/meta/type_traits.hpp | 795 +++ vulkan/nlohmann/detail/meta/void_t.hpp | 24 + .../nlohmann/detail/output/binary_writer.hpp | 1838 ++++++ .../detail/output/output_adapters.hpp | 147 + vulkan/nlohmann/detail/output/serializer.hpp | 988 ++++ vulkan/nlohmann/detail/string_concat.hpp | 146 + vulkan/nlohmann/detail/string_escape.hpp | 72 + vulkan/nlohmann/detail/value_t.hpp | 118 + vulkan/nlohmann/json.hpp | 5258 +++++++++++++++++ vulkan/nlohmann/json_fwd.hpp | 75 + vulkan/nlohmann/ordered_map.hpp | 359 ++ vulkan/nlohmann/thirdparty/hedley/hedley.hpp | 2045 +++++++ .../thirdparty/hedley/hedley_undef.hpp | 158 + 66 files changed, 24834 insertions(+), 78 deletions(-) create mode 100644 example/src/main/assets/底妆/基础上妆/2按压/区域/demo0.png create mode 100644 example/src/main/assets/底妆/基础上妆/2按压/区域/demo0_ex.png create mode 100644 example/src/main/assets/底妆/基础上妆/2按压/方向/pic0.png create mode 100644 example/src/main/assets/底妆/基础上妆/2按压/方向/pic0_thick.png create mode 100644 example/src/main/assets/底妆/基础上妆/2按压/方向/pic1.png create mode 100644 example/src/main/assets/底妆/基础上妆/2按压/方向/pic1_thick.png create mode 100644 example/src/main/assets/底妆/基础上妆/2按压/方向/pic2.png create mode 100644 example/src/main/assets/底妆/基础上妆/2按压/方向/pic2_thick.png create mode 100644 vulkan/nlohmann/adl_serializer.hpp create mode 100644 vulkan/nlohmann/byte_container_with_subtype.hpp create mode 100644 vulkan/nlohmann/detail/abi_macros.hpp create mode 100644 vulkan/nlohmann/detail/conversions/from_json.hpp create mode 100644 vulkan/nlohmann/detail/conversions/to_chars.hpp create mode 100644 vulkan/nlohmann/detail/conversions/to_json.hpp create mode 100644 vulkan/nlohmann/detail/exceptions.hpp create mode 100644 vulkan/nlohmann/detail/hash.hpp create mode 100644 vulkan/nlohmann/detail/input/binary_reader.hpp create mode 100644 vulkan/nlohmann/detail/input/input_adapters.hpp create mode 100644 vulkan/nlohmann/detail/input/json_sax.hpp create mode 100644 vulkan/nlohmann/detail/input/lexer.hpp create mode 100644 vulkan/nlohmann/detail/input/parser.hpp create mode 100644 vulkan/nlohmann/detail/input/position_t.hpp create mode 100644 vulkan/nlohmann/detail/iterators/internal_iterator.hpp create mode 100644 vulkan/nlohmann/detail/iterators/iter_impl.hpp create mode 100644 vulkan/nlohmann/detail/iterators/iteration_proxy.hpp create mode 100644 vulkan/nlohmann/detail/iterators/iterator_traits.hpp create mode 100644 vulkan/nlohmann/detail/iterators/json_reverse_iterator.hpp create mode 100644 vulkan/nlohmann/detail/iterators/primitive_iterator.hpp create mode 100644 vulkan/nlohmann/detail/json_custom_base_class.hpp create mode 100644 vulkan/nlohmann/detail/json_pointer.hpp create mode 100644 vulkan/nlohmann/detail/json_ref.hpp create mode 100644 vulkan/nlohmann/detail/macro_scope.hpp create mode 100644 vulkan/nlohmann/detail/macro_unscope.hpp create mode 100644 vulkan/nlohmann/detail/meta/call_std/begin.hpp create mode 100644 vulkan/nlohmann/detail/meta/call_std/end.hpp create mode 100644 vulkan/nlohmann/detail/meta/cpp_future.hpp create mode 100644 vulkan/nlohmann/detail/meta/detected.hpp create mode 100644 vulkan/nlohmann/detail/meta/identity_tag.hpp create mode 100644 vulkan/nlohmann/detail/meta/is_sax.hpp create mode 100644 vulkan/nlohmann/detail/meta/std_fs.hpp create mode 100644 vulkan/nlohmann/detail/meta/type_traits.hpp create mode 100644 vulkan/nlohmann/detail/meta/void_t.hpp create mode 100644 vulkan/nlohmann/detail/output/binary_writer.hpp create mode 100644 vulkan/nlohmann/detail/output/output_adapters.hpp create mode 100644 vulkan/nlohmann/detail/output/serializer.hpp create mode 100644 vulkan/nlohmann/detail/string_concat.hpp create mode 100644 vulkan/nlohmann/detail/string_escape.hpp create mode 100644 vulkan/nlohmann/detail/value_t.hpp create mode 100644 vulkan/nlohmann/json.hpp create mode 100644 vulkan/nlohmann/json_fwd.hpp create mode 100644 vulkan/nlohmann/ordered_map.hpp create mode 100644 vulkan/nlohmann/thirdparty/hedley/hedley.hpp create mode 100644 vulkan/nlohmann/thirdparty/hedley/hedley_undef.hpp diff --git a/app/src/main/assets/demo0.png b/app/src/main/assets/demo0.png index d2ea20e409fe3ac6428e75d34af0f7791df628d5..c9e52443f8fcd210ff2bd54ba4460ef55c65e1bd 100644 GIT binary patch literal 20859 zcmeFYhf@?y)Hk|;paLS2ge6DGAUTT?c11uzaug&<&KVX_B*+p}a!?o%$q16e8emb9 zEIF@4m%Nhmo#%bOs#|sI{t4ey&34aB&*|Qt?h}6JocIU&Iy6^UuRtIW8Wd8~5CVaL zRT$(F1z79`4x1=N`|9i^s z6IY)(tpSpIAdJ$~cob~2F%y)_uhn!x@_Id#7Q=<|eZ$7^07?h9$Cj78gB9KkmEtjF zV5By!%&bhfBwToXn6r=!&Xu5~>YWM-L1L8(xowZKRbd*prm6I2kY*%BX- zwpmg7)FQIVys8my7eW3gjVYt<4Y0%~hOm|3bBzVo%1V#jA`8rOpeM*)960Z7+fqAq-0y%^p31KJp8xH78mq_BoN88RCW0M&H&w3>Ot4)*2hN*A-g6O`XTl1k?Pt{G10#GD*VyCmNok{1rK|D(wCsFP24EAjqvk9cDZ6~n?{Bf6 zvG5S9TlXm{A(7lP!Qg4p@PdPK7JFid9l$$W&wbqR4P27ox$qob^#H?=W5$ZqRLDkA(CeSg^YXLE%4!*p7 zlzCf5v4H|xn=c02f$A=eozN(}KWwsjz2Kw=7rh=d4q^VWP_7MOO1S)75GvniZ@6j9 z;Un$FVmG4D)Dps_L{fOq_iM=Of#7d}RlXqh!yyy)1Vt|p?Qc)VGP`Gqx{c4*| zo?IkIr~~KtgOY&{~gkFj^ zh2#Xqdt5pd;b07>8~;2N&Mlq8g;l~v`v_j-s662u7@32tlb0KJWmAt={B2y%1qr~y z z^;WG$VrUC9FP)w@Hg*3@;DG9r+oa7oJ4IX@U`ZCqpL$yfQBy0+!p2aTiNqQ~0|$I+ z1>zHzEYW?w)on0md165q?ak~Nl`(JloynGEOcIV%kQ%s@R zx8rNu{cKx|z))&tAMRi$tV>sgWBg+e@O8@GW}x**)#)xYQ~sad7~ zQdp&(3$!eM1_=h6DzQ|?&HkHjS`WS(8j#TioCZ5Y4ot_*T(X7bTAixqV=4^#D6Us4 zdxt&z7@tU(3Jp0(^tZ_HV*r#>S!=aB{$8?TZDFd+>&c`cCoH9=AA}Mju+Q(05-EsU z$k#10H@VJKG71o>uIs16$XR%+c!n%O2Ahx?*fKj-7#LXfnViQ1y^GB7`*MEBf^R;G zpyyYDS<~}Fcb3L_ErjHVS=-9ztoT)=4zKFq2RbM*63AD{NzSEkF4p$B;w@ACRNPCh z8@+^1hR8GToxN?EHsg*^$}1b=nXwGNki@?~%kPkuxBme00bJ-=$q)DG&foh`EGL?I zCD`ak+WTZ2dAqwL$Ni*V(4#g7#;ArLs)#Pm3iv)-u3i}nrQoIPZp zI9$5aV${}mBw!U9Go7puA2us*GQv=%kCgRCNsoAdF7nvNOiWc)TuhoX; z7sS@&$GwV73f+vY6U4J?-QDKGYaj=n`rF?m86WMX#(ltC7_Zy@9>;Mx(F^^f7*@8u zPVW#l>x#j_)b-deY`IlM*8XZHVk& zAa}*vo_;aAyM%$xIR}dByWk#WuNiV~GC3d2yf#*=<0T7#pX`k`oHZaiX@-$D2_b~8 z^<$~M%>4aaUXwq9_0VuA-;%pcYLt9T@Kg-x)wdK1Rgm1U27ieGult*ndZhH}mPTlp_?QT` zA(3K@)o#VAt5=&MlPny5XsNyoe=|=aeA2Qc-N3guS-t*|&)u@SKo@UrTGKOD+-CKC ziWa%0k!_Lt`{RLd{6IOx>(%hbIm+~3pd63`3;<2LIgk1Nci3m00(Wsq0VB^R;

} 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 literal 84377 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 diff --git a/app/src/main/assets/shaders/texture.frag b/app/src/main/assets/shaders/texture.frag index e7a447d..d703133 100644 --- a/app/src/main/assets/shaders/texture.frag +++ b/app/src/main/assets/shaders/texture.frag @@ -25,13 +25,13 @@ void main() // 重新映射ndot值,让中间2/3部分进行融合 // 当ndot在[0.166, 0.833]范围内时进行混合,两端保持不变 float blendFactor; - if (ndot < 0.266) { - blendFactor = 0.0; // 完全使用color_ex - } else if (ndot > 0.733) { - blendFactor = 1.0; // 完全使用color + if (ndot < 0.0) { + blendFactor = 0.0; // 完全使用color_ex + } else if (ndot > 0.1) { + blendFactor = 1.0; // 完全使用color } else { - // 在中间2/3部分进行平滑过渡 - blendFactor = (ndot - 0.166) / (0.833 - 0.166); + // 在中间2/3部分进行平滑过渡 + blendFactor = (ndot - 0.0) / (1 - 0); } // 使用smoothstep创建中间2/3的融合区域 @@ -40,9 +40,17 @@ void main() //float blendFactor = smoothstep(0.166, 0.833, ndot); - vec4 blendedColor = mix(color_ex, color, blendFactor); + // vec4 blendedColor = mix(color_ex, color, ndot); - outFragColor = blendedColor; + // outFragColor = blendedColor; + + if (ndot < 0.3){ + outFragColor = color_ex; + } + else + { + outFragColor = color; + } // outFragColor = vec4(1, 0, 0, 1); } \ No newline at end of file diff --git a/app/src/main/assets/shaders/texture.frag.spv b/app/src/main/assets/shaders/texture.frag.spv index f93e19b7a41445755dd1cf76276f1a411463f8de..22d7eaec0c2e87b16b84290a273d2fe20f4dd268 100644 GIT binary patch delta 590 zcmYk4yH3ME6h!aF;U#1mLQj+m0_IHu!Hyxc2=M__lzafCBhk=CuFP+wL9{>@z6XMY z#GKeGVQF+9J3Djl%EOiSFbry~1v6*MwrH25@Y!^sGQqSf&||Qts&`WL(eaw}O3kbkMg0FJY~)Q&m1FW! zZE~iZ9?#4si6S4b#aS#|2n{7TZe2H9 z&3dQZxuJ_vXrUbC{tE$PyccftN%KIdbdYC4arE`qnPd26}(?0j;<1 zjA!Fj+Wp6@zfRpcxkIo+R3kfxd?mIL14bREv67$4iIcnI7pJV&fK4JpsJ(ZJZS&Ok zMLET`h#lgCV&WciB$p;W=~KR9%5ix|qZWu1@xT^TV=wY)RMjZ*eY zBHD$D=z?O(u|+E6D$);E4jhupr+p0~-x0a|+L_gqZ=%_qh)R5V5>2EcTB=7Rr)-~m zA+j}TjnFnOn63O{qV^9u3+hZyNeQ;_X~-ur{ZZLJyj~%G0qF)o Aj{pDw diff --git a/app/src/main/cpp/main.cpp b/app/src/main/cpp/main.cpp index b6ac97e..4bd32da 100644 --- a/app/src/main/cpp/main.cpp +++ b/app/src/main/cpp/main.cpp @@ -29,12 +29,16 @@ void handle_cmd(android_app *pApp, int32_t cmd) { } } +const int ArgLen = 128*1024; +char g_InitArgString[ArgLen] = {0}; + void android_main(struct android_app *pApp) { aout << "Welcome to android_main" << std::endl; g_android_app = pApp; g_assetManager = pApp->activity->assetManager; FaceApp application; g_Application = &application; + application.SetInitArg(g_InitArgString); pApp->onAppCmd = handle_cmd; android_app_set_motion_event_filter(pApp, nullptr); @@ -119,4 +123,18 @@ Java_com_hmwl_face_1sdk_FaceActivity_passDataToNative(JNIEnv *env, jobject thiz, // 或者直接将指针传递给Vulkan ReceiveFacePoint(pos, point_count, width, height); +} + +extern "C" +JNIEXPORT void JNICALL +Java_com_hmwl_face_1sdk_FaceActivity_SetCppInitArg(JNIEnv *env, jobject thiz, jstring json) { + // TODO: implement SetCppInitArg() + const char *nativeString = env->GetStringUTFChars(json, nullptr); + jsize len = env->GetStringUTFLength(json); + if(len > ArgLen) + { + aout << "ArgLen to long:" << len << std::endl; + return; + } + memcpy(g_InitArgString, nativeString, len); } \ No newline at end of file diff --git a/app/src/main/java/com/hmwl/face_sdk/FaceActivity.java b/app/src/main/java/com/hmwl/face_sdk/FaceActivity.java index 6acec66..98ae4e6 100644 --- a/app/src/main/java/com/hmwl/face_sdk/FaceActivity.java +++ b/app/src/main/java/com/hmwl/face_sdk/FaceActivity.java @@ -309,6 +309,12 @@ public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.L public native void passDataToNative(ByteBuffer buffer, int pointCount, int width, int height); + protected native void SetCppInitArg(String json); + + protected void SetInitArg(String json) + { + SetCppInitArg(json); + } protected void ChangeState(String json){ Log.i("FaceActivity", "ChangeState:" + json); } diff --git a/example/src/main/assets/底妆/基础上妆/2按压/区域/demo0.png b/example/src/main/assets/底妆/基础上妆/2按压/区域/demo0.png new file mode 100644 index 0000000000000000000000000000000000000000..add9422ab9594363a198a930834c5edbfcfc56db GIT binary patch literal 20795 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 aQZ>b4Pjlv(vg{uTfM*2b0PvI77BP6Pe> zW&i+)kp%%xu`rT@kkJ!H0t_(Iy9=ls6kcZ>Fg?3tdO&!tpP{^!T)pqzh)@{L4Y%i)Q+)xyl48K^Dh|r|2D%5 zK)^rn|DXOp4+StTC9?vU7$p^MC@BE*{!gv{J&`%@|J0Pq$p5#281;hwr=;0Ubw=+0 z-leFZ@ZVK&|JZu?%pFE`4itm?cPv62w`YUlSFHn&_sn^MRjXd!K6ehp^!YUC{+XN4 z6tK(BUn;DtsKTG4RnLDa0KPd}|NGiAAn2^j+hjoWZJ>L8Yv{A!RWj}G+Th$x``MJ{ z;<8d`?i%)4xX1%8s`{QC`<+!_cHpM45XJBha6iyL&{>q@ z53w?A3LxRrGvE+yJP^l=8$xrUk71oiN^Vloq%ci|($41mBTvS}F<_y{t-2+pK-gNcg`Lad+2wMA<5D;?jNF$et z@|R<<0qlmPNq%Ana{;0R26s23??sZ&icf2VChj&=p@t%|*~&4r$}w~sY-!B!k{F~V zcPEL-hky8(WiX-0kQHU3w#lr$LeZ8MPC6`x&(Hz)Nb}dsbZ-MARKB2kvyl>bDHCxjv?ZP8F* z6uVbk(e2gD_Mz>icjq)<{m~|1ayn&>k0UgUH4#|f;{@7bN=zc@mV(ZMqb`~_pw7-K zt~#;PpRj@@07Fc3D{fqJd!GC3xDU3pp>CbhH&tc2w+k<~?(PchN$ujcvF*M?!@ht) z&?6Q{PR$wLNu#KmULX`f9h~V^tkSmx1Sd(9hwEderO_<7e>N9bMfm97Z)$2z2hT_g z_5iPt$Z`5H#D7bjcc%!8V_NUY@2N?Izx4OO0#dyr&{2pkSp~zKc!^m8Ddw6k(Z0VT zs36TLQ6{+r=+h4pMD6hKe$bqy-#h3aDsER^EE1#E zii=@(!x`Eid(O3&N!7a>lxJsc3%LT814cxETfU35z$G^!SNhWxgoV2wiH9H&tp;ZO zwH>%x@lKvKYSr`XeGPM>OOn#QJGT)f5OgQr*MVD z56${wEH36o9fd}}Mm?2vnKK6rw&>W0qoR`0YmSPR$~ znqF^h(Ens7qx4klR{Ne#Ujd;mASkT#I5z5-Rpf8~wFj7Yib6x|skZ&pqt61DOpZ@I zL#CVYm4I=H+85PG7ya&HCOD&z^SFuiIk+*gu4T9($*tZC9M$%a?0uJzfdcfN_`lK92OrwwHfWKwSv_p+Rjj_Igf}{u6-c;NZg3 z;ezLL(yLA~C@Vb;%Rg&Va~xtazkx#cCG(wQft#3bc;+nG~`QcdiI$0&UBXtD_ zG8VU%*R(l(AX>XC%WA~o;s{?p8=(;aaN`@OK+B>)GUo_S{wdc>kfs}V?~+t(PYQSWjw~H7{Ie^Y zbtRrI_I1ytYM{gBgLH7Oy+RlDx~RG@m_w3v2Ap;!$O}19GJgI+mk+4jz7-v=F*=H= zkHimXzrpP47e!h%d}%oS(OoAgOxM{!mTMNL zbaf{c0s=@!&-ci)5Pflf7$zG-37JFOF589OB3n zpQltDVy9JDK@L0d$*J|XV@ElwSwcQrzbJSglJg!UN(iB_b{)fw%D<3@3Vw7AN|U^M zI1j*n1qz;G!Q%MZ#w2}lQVl|&3px43rifNi9_nWq7KRt1pOok6uS-vWSm*?w!};CtO@CG_@$;&lvQ@#dfjCl>+RV-S;&F$qYeVR3ljCH$i1kduy7zulW!0 z&f44Q=OUk_``+W>e|XlG9rd>%;4&WHION)eh#F^a)GNvt)ilJ3?-~96k}vt%?7|!> z*hkYy$r>;eM?Sn4cP4#cO`bpC%`Q_2PB<+ennaF0eFJBuy;PJE3{rY?lHMT-vRYH4 zmb+H>+(W-4?3w0%bb_@+U9J!l(_)^PvR;rT*y55KhhFxd91=`_O1C+oqz9nwRzIhg z1kN~c&4}$t-}nc+*Vg)PS#&AN$aGjxVQZG@Ny&2=K75G0(#v_4lUv!QPv5Dz(Qke! zv<91e2qpg{A5K81C!N`=BzbV$tg9+v=x9nFjt_XdFuE5qfsX!^V}FPI21Sv5gby3U3s=EE=B;h zo@pGN_)U!CuACJjezh(i0_=z$+snwS?c3g7Ut=BuY=}E4mt&?~9Y0k*ANdt|(a#w( zZGs(bqlh`q4`gZjnc&E@QF@q(2ABE}D#J56qlOl*+=a&<{DF)fXREHK?tYSw>%h!pu-RTduw2+nl#p`*GY?-!CaYmd|xnc?9`b#;AT#OP?xU~a`+=mp${eDniMUbqfkf^?tnOcrBEKRmGUc#(B{|(* z)j-er>zrNZbp9>C`C@{b%kS=t?~hgo+fRY4AFazZaG`shEoF7}u`=iVc&o4E81IBC zLQ%v4XbkGno51FClRb9xo#3VS+;daAX{U8r`0zNcvrKfkRj0Uedqu{Z@*FvnQEDuX z3zNNcm1Eo`s~71u7qth3Dyca+Z54Q$(8fXi#A15E)4xKu)7X?33Ig<~fq%=gLJ)R`Nh%Fag|{?MAEUy$ zC}y~#oG5NwIC|aV+atA*em5y7q~iJ?Uo;rj0DyuqALGy2p5boX3&WvcdOh3J&q+JS z#k9(pEv6jK2+oiy`JtPjh`yG4s^Rgs-Q|MLVh4&B>LH+?E+R6L$Jd>WXMFR`no_8( z+M;hA#6>Lk=3&Rc;J9gBjGaWEck~3nq+-K(a4BfW0UfmyMH3Y1-pp>zP&;2^07e4L)tHeh-21F_GGf_; z>~ZUnwd)C351=!k9lpb*h>Eok^^0hQD`kL!6UZ{D+_wf>K+UR$jY2SqU)(zjDJ}e> zx-YnFxGCB>;^=LL!T0Y#muSt>BYv6Np#>bSAJuY+Dd5y4~I?`LHF zuCaUY0l4Eur`qIJ(|{}e2I)7oSGNU3|7ECA<(pVIG-o)XgPNO<8e?U2a38dziZMYr zZU5XD{QFNT*iG>a<5|#0a^A{wCBJ^S6U#^WZH)^JErth8D@DsEhZgZg-dKc4hzJ24l zR53)1#R^!>rLGp?6M-juW;HV!AR6P<_PhX5mPOZLj>tz~dR&nzRRWEAJ4CHhhT7cE z;(!AjnZBHw(J*o{Yg#j*Z6YTE;b#H(Jh-(WS4fy9$4sXy<2`slORThJD(vdyi%2(| z=8ng*_^;f6!=^)O(K=z(U&a)NB0}Gyt+tY_K7OuDwVuUsNTzX~im<{+b6W2+oyOO} zt8ytHphYOh;SM46i==mff_M?g&^%#S@UIBMifnobM(~MY<`{>_u6Qt? z-+hb(C+m#Fms95Gi*D^v`y7%96sNY-b||i3feToj zNA~8HUjyl2ttzCt!LTdrll$^4pqP9+x$oDBNlgg7%j^LSte1{CMu|-7tnz*O3EbK= z1s3RLyq{xFZU#yTTzvfWLE7rc8b!>I@IoT}29Z0&rM0;YYeJ=ofw_o}WrSfoZtXGp zo1l;h_m%Ne`Vl{osACo9+76Eq;Cs-}0VL1x&}79-fs@`)D5T=|vb8x{tt&$8M#z+m z;K3o>_cA5lJqG32lDgCH2s~nqLPW0iTd+M>!2SC(6L_QgpTwr)o?U=;GUV?a6_^Vy z1N-dJjtC*{Hx9USj^lk13+w(3uR4^7z2Sv%X>`EidzLvqf{N|R3wNy}DJ2a_GU*4T zewpt_nDZp&8ujpd=Jx4n0oR!$;aKDtMvlWn>;}Bg?tF&Xs*Q`PJH#B$DNs>U9``dS z=ogbx_`#)tWI;GP!0&rzT1A9q(EjnXzDs@o+MgX6OzZ`IfD(es;~rnzCEcf_S=DQB zY>}eN*>6-}clnsu{>K7r z3dDb+x$jl#nDcfWD*gb~7YoE-E3pXvl?KJ17$0Gt`%f=XeTk%7N@PQQdj;R7FZ=13 z-g1>ZL+!JS$}3?a$yps49Up(nU5iG=g_31C$Qq*+*OYL;1>`P>fvy?N046cDGe-c` zFZ(#jh@MtoteOZad$`H(TszSBz3O9V(KlE_PXWi5bA&_tMw6RMGV*5SE4(UHr?O!$UX{ zf_T>O!zxV>zz4$y+vZ|)u8{kD#dqUm`25uIKzYnOTkY!+bOH=|q@pOoR-Qywz2JA+ z?~xV1&yM@~S5AYPF)WT38jgkV)^lQCrdeiWR@1V8k4~}jbH53Hj+yp_SM1Znn^Uj( zaXXtIMMiMNnllS=+APd>mcb-|72+B8n?;kpd7+3~gaX?v?X7&zgPBI*NP$X2_d`E1pycnPO^+edBmCNT!U8 z(EA*Z(tu8hPO-t9!aM|3PCp*pp}2Hj_VTn2&oGop_{_XsDTjLb@+!AqyB^T{**W67 z26l@bgTU*W8?*11SO*Ve0FT`F6?!oX&jAG5H3e$vfAi-ZkV=CR34_6 z5donb@hZl{=Zn)W<7|tFfOTtt$)EFif&>m~JK6~>w0KndTY$1x33G4y3+Tx>9orYF zvt!Qq{P%G4da<;#XkOt29Z*F!o`9OX+kCF26@eWE6NPTuRtq4lXyE7!04h$S$u=Gm zsj=Jt#xrP)0VGLeY4hv7%nm!_WoCdnJn6V=?>VDhoI}|s0koy`c=$db>iEf`Cceb zy-{^qlmEAX;O2Fd&+a->AWD>W4VDq!-UHUq^kyeMMLlRJ#sVybnc#q2&iO0oY&Y$a zMpf#JZ!Du-o;?L~%JsK=7(n0bW!TY^ZNn!3v?uaa>pKc34vRj!*A~`W>_0ob7D!j5 zJeluh-6W;_eWt~}95hc;cOKk5PaML}$sC)f$b3e9P!c2w=a4klYD1cAhpXf*E{zW11aRRB(E~2~V z1C5t1fHPJca;*#f{%;wC6WNROIu5K8trn;jnFMTYSDfw%5kKC^zf1m3O{PKv|uu@9*UJ zIiG&e6a4Z$Q9FJ?mec77GI9~E;U-cdCp!PK0p89VHAoBATv+wHrcj2OX2s=frlm^5 zjM}6ZC}?h#ytOjRWUdX{G4!p`nPzp!Uhw3h{9HPRk*cPY{CiDY4Nxx;QartXjIaE( z1X)X#0z0lp675?}pxzjyjblk$6?Y?|OobiQJM^)ZHSyFN%<58TyRU77#mhEpo7~BP zA&ut|eId3@BX!K53wt!%BVRQ?2$0J$NeB%e;*uyq*R?u>Wh5p?_p8&_97dI;>Mu3w9o9`X`e&yPJgL#Iz|4Kc5`j%uzgoC zf7t&+5^IPZ-#x?xAHHi#;}K16H6?D}bm1@AP1{!8w*w`Om#6XOs#!aJ=>`%dM~J;}v4H?{9Q^J-r+D;|F!+6zq&Hh0+Md+ph#vT5d2va4Kme_mxr zzHRIpY|?k%=CYY7x?P+j`eC;=WL*nKin`K<=4h1FPIoS*PcP`?a%)QN_*NWC@(&lU z=ch{S`}NTXt!tv>5r?gf$^3xtC$Q;^(~DV3aRu}EiC4GuTF)u`O}PC;yD`Yusc`KQ zv}S&yC1;B3W7-_S?X10roUQ)NtC5RkZQdNLyP&+{y~83c=Q<|~wZkZkJ-8=Shi*D+ z6Q>@pJbrY2Aa{8jQ#btec-v8UFkk3|@3!vhkbU7IY-~P|eSO1dbP$6*?n6sLSe@&o zs(3@HE2+(#|U$0i2E;j$A zo0}UMsQ$iEii7LQ7)W>{t!_ql`}ICCA?g@6V#WM2E!X^>;}79I!=Ke_7fLtcf`%{B z{_J1NeMidrCd)nhe2yJ&oBQ%;kaRyP}g9wF~Q5S*su`e@NE6WD6OP^zDnOZFu-o| zrGdZ)0ad|QH&~&rMjY2U17BnfG?0(&Pk7fpfh9VPm$x*f5Edz{h`7sN8$f#7pBfGi za^*X|D9V$v7FaSoS9#7+T>DDNr-`WPjvBVOuakTurQPyx z{Zabe171a$ML(~3PR$lR?e=p~T~|9wi^0CaBopiXG2QIQ>q-U2F)rELO?KGsuaej9 zWmybaDYaZKOdz3dXi({YJG``4nBm5}5Td8n-+DC^Q#W4on*^f4H~%qwV9G=;4ItTFd;UeF=)K z^sCidbsd&>dWVM*(N`EQ=9F*q0C)s2qp@1XzN&OvCfAfr3N%vhv+gHxNji;714(j33V%|-CZXTz-WS@aNgH>-L^K1Rb$>{^BL zYF&5IjzXUxsemuSeSlKRwYGrY_)iBB-$S31X3|3QWL~cEp8;sZw zlSXH16L+1KUdx$5Nu1wDDD*G6!N~nEBlMKiJSH8{P+8%v_IOzONm~0i1{g!I;k)5g zgR3&9JRwQZ+K{6R_+!2~Zmo+Pycs9w->(I93i5gwrq|_2)k6^Dvbb?^xHgu-(-o@%psZDeo>#)DQ1*+M*}h0i(PVGBx73Z1Ot#^DRf zibJ4Me=}6s@oW+T`_!er;JIba@Xgi%Y37ThVDkbYg3FKx3c!vrZkUycxxqXIJy~P{{5-wpZA&G@|b$kvGU^lJ?#RI zQOt(llWYM7j_6j*9~3kP;`O0w?7byuC z@h0({WGPF{>z(zzZYO(Xsa=*+Y|8Y;OB4parXr7@){c=p3XTLeC?Q8MTMjr4^nzm2 ze0A~j+0kHLhz12xuUGVk{NsHDZwtvQJDVo5YC@GRKWtB-Ew_x=@xA@~%6KSjM9`?> z87=cYwPi9ZXM_3;HH=}W%MHU3{<#_m%HMwqS+LEpN#D=z_=Gp zO{t|2@}@zxtNn*Ef8KKydy{a~l9b&~uYK?7NOGfqLrGxX%brONv?*OC}kDCVS$r_nQ{(RG|Nx@U(s|}17-UhH2U^%nOb@&t7)bd=h z#18wJIm^JzdRQdRif~v*IuAfy*u~4e&i4yQ9Oyt21DmdF%AGe#W3w|}G@o;5?`*kV z+(wqt9WYWG$+2c{t@+$NS?JGEMkNdGc|MP4C1lEAf=GugQ^k)S5#d>~w9Mkg-S1^z zCBI>|YT!N))~>hBr85IAY<(=x9E5pFF&v2@0f+_Wo$}y`ic(g&l1O^KDcj!WtviT9Znj=h zfez>H@47WV=c`#w%eRcdj$NGd-Su*~Q&Tcx11$L>`yX+DP(Zfbosx<27AF($b!j_3 zN+b`2>lH^Ad~!lgx4ljr*l8C!)SPa+TRkvTXF$&`7=LkAh>-rn1(nWWBE&8G`d$e~ z`PImd5xp9PR-uT;+k*5bBT-884)9r=d#{{mc&eS0St{n@cxk!s!wKtqX#-4?=Xo|t z4ftS`MPn%~u=9^$;{jjS_3m0R4r$G;(4f$TnqFy6bH_5L1=2*(s-L`tRpB*FdF92F zBvSn=H+jn1s}Yg?*DqwkZ=F8|xn<1bM@EQ+bu5IU;sQ3&Q<+jM9)-|pcGE>@Pe|CU zz2oZ$=$D-5x3Cfj!E}cT1@xgQZ&%`HcJz1A>6;`{ZHYq5cZHTd-`D2#E#W@DhbBUe zkW7@;xsA1jJIzjcdfdv2y6CAg6GP+EtUjm&SY+TRp!M-`u4LP+I7s^*g4Voa}qO#SHIPuWCAzBTPu!BfLtwaOwJF5`9yh%Q>IY zda*xiVI(9&Sv&7Q(DCDzQlU?W@}xQ^-hKgvG~kYnU+sUR^YhIc*^=_lA|Ng%N0wHQ zq!5q7V~UvQAPd{KXgz6ahv=qN{%4LDqZb}C$$ixp7!ug(3GhuK z6;8o;mhLdooG{kiL-ShQ5rsdbX<-p1d=rmqJk_*5Bt1i(>sHiIuneMx&EeAasfrqC z>D^5;-EP9p(!}rPt#>*BT1Q`H&U|9u16@hDXp|aKk@^ZN%i%s1-b#F!M`;6& z`=09AgpwMqPXkfCJ(T5&V67G|#GpNJ2bh|mQdaRG`wUteZF+mFlW#5ZlSUg>T*b#B^mT_wO15@Nrmbzm-y+33 zQdM3DLD(PO5=T`MBiICJsd)_2nj)Ap=xA~Rj~+&16*~az9%gG6QjbbXY|F@GQ1vO@ zwkiCOy>wVp&Q5VeoaJ?A_g?)y1ErQ*g$9SzznDsHkAMMoK|@(XNRZ_W9J`Ybt8l6S z)M&!kl&0mc?vA9|0200f;Mh+tQ}LPDzYEVi&WIkO#wM8cM-WH2$ik)imZn;7@qEd+ z3UOw-ljgO?QGHY13^>-PZNGj56Q!K={&gntg6)}HEn);!(Jn0}J3vc0L zeQfH15I*+L{d>ie^JY;07mHgJEujHEJphH9zPH+EhVqR!cFWXqMIw0r90?n&jwGZO zu7}aWu6<8Z=El$Z`2rh#G1hv<9zaQZ{Mr@Wyx}vTOT;M+joi#`U*@7n^+%+U;LwkA`n2P5JG$pwlC5#0BIPS@*yIiS4~?0|x@ zU3$HNrzNcfj4J`D7nMsIK6zc3KbxDVlCi)$DqdlIM(HYAiSlkQBG>BV2VC#PN{Eui zwL&dzislsyt_k8@tBax1=vS&&oX6QChfg8Xp9jAHeowA>b9MrpAxMy*<#%`uv(glE z>w2^V?Ot?9ul~D1oW>KbL>Ju68r8Gi{B!5_`c2%Ljo{1~ z%Y9QZKQYS;D2XVJba|L;Cp7e$_7L+-A$MD3QpKx6gMPT(41kS6_zUzN4Vbzlzi1iu z9c-f3tax9k`Pr$lHeI~CHY(YEx+*P7`xr>gg10L;{;Rr{Ps&MO z2k}vOZQXWu2kC(bMIw96{Y~g+a0J?Ur|+wzvUl}2%4E^`GrbHAAtuBEI ze?95Q+qinwHz`H$V4x5MJO~Hz4}YTa4FnKo*F6145Wu-$a-ypm42`JtfQr|Lp|*&^ z%=`HaQeQ5S%}hg}>#b_fEn82BbnE9Pc;EcEOgj3gNzBC1yLAH7zCouunOmLmzR!$a zxyGjL$?4FX|}Xldxs(h)4`BF3ERSi>X1pA2q@%YRX)DstOq~ zT5D6iZB{GA>5-qeJuZkEj(r*Q7}%4A4L}ywL5}vf)}~(ceIT(+x8eG~XSM<1#~=kW zEyw3v0+5zg`8v1X^IXHvx5lt3wwX1EyV!wy8!JPK`2#;5JwRTP&mPQpR1fh4f0xdq zsiw|I3;9Doh?WMyEX6lfs-$fvo@}^x>oK%U*LnaUpnc~)%wbemgBE-gRe1JF!<{ZRmH#<4mvfqrVR6 zc(zS!j8b;jjy}(sq>K9X_(6e0TOK>W3vL^GGhpK#KG?}#8o8T#s9{`!=eq#uXB zc0-^lB$3plwEG<9uK99>1^Pttt}_)7%yujQGk0sh_2RC;ZQB6o-{c`x1;Z?Ik7jkB z*~2h%FVh>3?z5ay0BN2JQS^&%)S67|&LcXv>*}nBHjEs3_2LX_wgN^AxVHa7Y?xb*mio+;w@EvH(*SZ`(A3DVI9mLdlIoN+VKHwFf?_Xyx7 zZckfv@ODf{e~!;$J43qJB-Nh20Tuy#VRm4Pz+`Y|NCAAfD8g{2K~|A71br0}kCpZY zN*ZV$@hea;ayAHXsT$ZQGb5}D*8A0JW`cInR#2btFIlVID71duVg{@pCsz&(_V4+$ zHyrRQu$L#Tn*rMo)&`=RK<)avL{1&8vkAck>pBLzD%KgVbCv8n2NuM#^#*|DN33sV zf^g}IzURIr2OT=#`AaTC+sw?tMNU&k@#Ds(yeYb-6o!*e@JCoA=`bhoL+o3boo85$ zWHZ%{i%sbPe3h&jOwXGv)=UFpTw%8{cH#<0q?G?DSJb4a!-=b7ZBH=kYrxm1w5nb>&*RvNR#i~A0*N^A}? zJLd8Gl9>&G>?$A`{KXnyZ^f``p-_7;&`bW-e4)S#N&DfzO7`1WV_fThPpFrCJe_$r zDrK-36r_^)wx?1sdbIqR4-@>R6wo~?-=Yng9HynrN`lE zMA;Z@s!3IcfYJK51+N?*_J6~J#;&iW00{@h@IT-7GlcfXOV`C^IA?kbN$TJvZiOii zbm@UHwy(x0N6?PhxCD@@lDjR+Q;4E?K+B)YCS^4Po3RJEA4wx)kBeb<(G0n|$jHDJ zh0)O9I}GYZ2%MeMED}bY?`}qJTxiQv^(w%t6D`K9wJSvD zRIk(ZI9DV66i7&W(y}%d6vfm;nAws=JZdtQbFz z9yM^v%@Y_oThx~S`R6ajoa$p)ch&;0jdushYEC{1$S2r?_PT)6zc#;h$Uh>izYDNp zz=K-+5Dvhlh!oAjmOz459r~M32GotOXUjERICwjMpypQ3T~QLNq2+~-YjrmcE0c`d zh8$HSN4!A%{yfZ$c0|YIXRaD6<{l)`{t5Q#g#{a6OU(^!1 zg!M&B;VRk}x84J~;3a}MCY-X<;pXh^D|$m=(T|C@RtjizJJgxu%%OxT1m(C2!vT=L zY9&J$fJzFLt0-FASmLzz^N22qah)SrGp&i7|<*7bGftk^aE zr7t`@nDQl zy{PMHxO+$oUfz_@=T!a%a;`80=$gKAH^9c(t@t1K;^U!ZPO$6gv;$3_i1^Pr)sf2k zf>o~yh3M5)neE+n9&POVN*M-KR|jO4rhfil#CfzcJca&)AK3yd0W-DSUPVty|J+S$ zrKYDTf})2As{Y@&h^B!a&WG5Y@z-N>cQeM7ZA!DnqmeH=v0@GhKus2+Hl7pb=-*<& zPcO9l~KNvcrx<)UDTr{!fNlRp2pg1 zDKwLxj~6S;qu9_QTNr{2Pnxj|INUs`V@QF4Dssu>GOtQ`V&UR&C2g zYL>0-_|sgcd$uULohbcrSax{Muy-KK%#|t^VVaqia54wt4FQy0$Prj+GaH0?jf4)c3=5C;6 zVcXayke_&RmE?6!rgFd_TaSqI;MhH+;{=jDbJ(p#f;9_EMdl)0&0C^WcZ27b zM`EsN%{SJ`4PT}|I%=?b)&2@8t!a{Vx1kfG8miV=|5b(i7N1~Q&3c*|FGOffY0T%s zazCA)@SKLS?0r=k5dXDNs?ea5SX+s7Yt9V(!iMX99ths5wVJS=Ml8PEuZ%Wua_}^= zYgb2HSJ*K*xhL{2e7J?H>d-S{HOyf4v`0RJox5$tQvQ(pG&WaZ!Tk{rLlso6CJjH* zO<_RY$ocob-ZmTExx4?D<_MmbRv}?`KrVVgmrVp98N84T#xH+6E}_`>fIiZty}VmD zrAK=d!t7%Iw^Vq`W)&Fay%I^Ig=s@4ycxYeTZE_ZM_=M$gcM*pvbw~bZ_RK|h$sg= zKe@$sqO9)w%T6}<%G~P)?d`P*^21<;{IYWIB_zSRW^dOyL%zv-PULwRaS!(`N3{ zyXw4wSB*icS=iN4K^%GKfHmeiVTY+IB10=;ET@P0!|dyp@;W=WE3Y&cJinD&1^GRE zo^0&McAoI*cztnZM{TR3zU6}m^qhXdTM24lvtL7aN>uZt1eLn+xJ>lA-AD@i^z7YX z{_1gtEbDVIW~|hXj7BITc;Eg})~@XQCAw_kVAg^v%&5U?v!+wf}l$+}kC>tw=TF+~lM zKlT0JNTi-i-bhIMX+Ku!3cgD9;JUlvT!~*L2bGY%@0aEIb$?tbOvA1Y&{z5XbtgpR z%F7$MW=>xvr^_%$RAfF89WI=Qbw7?xr%tGI{V_h z(GAhoKtkw=nrF5r4^}42os(0hpS3YuQUVagPcUExY{KF@e@>mAxw@KmLioX8%nyIx zUA+Wm4Qq`>MstIIWSSJp>dX%}HI#bEwT(I<+*eU&{=2UeEx+^^v~!MNNL?vNH*b9n zex zw`=Ia1!wdNToC$>|FrP80k4?jXcO6QAgQ$DKqa#A5rKh3d$*pIoWuF&*B?nc8)GC6 z85RlsH_vSOw5{cPuhRXeA~5?fwKHfHw7F}}BeT>2-it~;87E*a5bbXUm#;$zsT(N5 z{N?nQQ^JA`M$}N@Hyuv$l2@hi7NWwT}?TmmF0F*6(7TK3`1J0WWz;6XGG6-_-CavyW$a5-kPwudTeQsvgp)o1lyMo3-i z&BAN=pH<=Yr`GkSu!Sra)xdtDN@NLcrrK_dqZcG8iL_Da&j(Nn&(EZ0zXxh}W3<_X z&ng+nu9VS=Vhs4dmix)Ku>E!>20VNokXXx5S=@ssoNV5$03K7s*}amzrk8w zYht22bB=zsqGRb^d!(eS$(2^!__Zn?ZIv!7c^`cW!#OE*UK zeQlee6%3K0L)z`|nsiFKE_d5|_BZB;%fp(8df>5Wyw~wL{^ZYRu#^gpK+$X6g<|ZO zx9;ZBDh5(!$Hdp-PA3{ef}ZFjByXCmdcNOoU-vzzlq$(Zq<>s$td@+EyjO&FwA^nO^aMk1=BEv#_C;L-m&c8$E86T`4b)o1+f1F}GRuV0RM0H$jaXSI;QVizkL0z%m#LsVDG+XNvTm zmbxjy>KB(e+GAxN)IYfWQ;dbrkPaXNb@1fwM>tuJ$w10Hsc#p>*FlQ!8@@(tyI z4a`wY4onp51`+;s;aR|C{oRNnKTHObJ9N2&4 zl@0S?RA$?tyj#O2Xz$|b#f+A33_$Z6izmJ^6Rc>A+=^;2+G+jnj+;3NCH3o@rmU z#?K4b-pZA7tY<-AP|P>Tas*12wOwSOYiLB)s1;Pp1)?F)H031W&Ic26eSNyz23XxC z!={+oW$JL8S|c;$<*$u062o&@p-uhmt3sChYh7{4qajO4cGw1%#WdFzU z9ULN}{UVOw&DR^&8tx|}BG z4H-7}z3%_wyWg+tvF&quf8MXx>q#vks>8*SM|`$DKc3m2+<^ULc9HY1I$LmMV5TR} zR-KHd)>HCI#S;_H3S$GBDTb1f_oto_=jf*7z$(|0jDt)ZU;@Y*iO48fLLWn7M4N7% z&)sRINwZz%NtaZR+3LO0R4CODjs$yXb?ie}(~p6;$+4UMMXmzW{nhU-62#h2z2ecq z%5ucUc2sZFIOV*Ai)f8#^9nl^Y>@`R^4_|VX9y0|?wV@i?278fm0*7bxhs;ec?D0{ zmY3d2F45S_qx3v5IB5irJjO^{IhOly&f?7(3rftC?(R$fZ7q1cubv^Kw}RjkH;mUo zc$!ptH}j*8BmM!70Mx9yQUSkT=EHUqW5nDJlX(PXJ7|qwP7AF5wttt_vHwfAl|afq zKdt(yve$!3p(a+__htC8YTP5kCgGn>jIsK`VJiW3t?;XXWf#jJFC7jsy;^8{N`>Z` z_%z05i%3j$_7$R4#(oVC+bl6o&Z?s0p);d9&N?d^H8(Koo?Wh$uo|oYevw)YUOGf^ zh1mug#ks@gny))|LY}KPf^MFyVP5M$+7YmVpT8}D-OQRid$1`rI?a{Fe$+bsuvbvC z<>;Vrr>dIL}G?z|+&l+{X_i?sghe^Jz;Xe^vezD24%OugZPb zKjmf*8~>d{OOyUvVsK%^YB%%Ccz;aXCEXG0EO%+PB!JN^=Qz@kUP&e#w`-)!a`3idJcTe*8tT~T%xFpC4uf~anKEX8NkgWp3| zhP@aNBB@FbncPpEJ$&H0D}hJ5_V_zNfbU0|;XG-Rr(AaAwFv$=Q&SyagDJX&7ByHI z^@jxRZO2x(-%q4wK+WZzd4I(mr21nshoecCCAVcrzmI?(OeX;mTq7P^FWuIp*n5@g zPAGxsJ{c(_M;3L=JJ-YE=a;Qu$P>|5P!|YlL^&`Qh@pN45g5i(IhSI z#?gCT9JbzbEf7YsvSHVM8fTmEe5%tZW07V)_lst+Ljkw^h|H=E|V# zy`FVa3%+Gmp#$T|teZDONKXVM>t*z`80if79kIa2$`A4-Hk-9h06?Ug7hBA4~O0zGcb2RUjuR=8M1;b1zL3hNiI4g=}bD%1BXLzL6P<4>v2=4^{5y9glK}BMZQ- zAv`%N2-~3`&=2ThmhhTj*7J|pcVP&zmwZhZ)9=q8@oc6mPP`TVdd)BX&1gRa5X_=B_AN4BWZeOq5d%w=ar^P+dU+GQ_mS1!RAC@uIH^{){t`_$ z5hcPDjxn%JbNufYVmq{lg+`SanONw!ych}>uFxJ^=m6dQW9=%7>w&U2ea7zfxw7ms zD!#i;N~>P+v>-#ov1$t%Cx!6Nxy*v@M__M@i#<4?c=81%!0$Ye?Vu+pi^F#w#tsE-33lSNy&nT_0Wto1~hM(`1%K5-l00DXNIiQoyGV4 zYdT-SBgksnbO{W%CZEc>^o(;2)i}!W+PgSo0WDEZ6AihQv+>z8h+RdMhIc227k(l< z)BkfY!nBb|4_N5w9SoqBcoCO2a7trv`N86BA;3qISHLPsJF69Lx=>O9_YCs1yb9i7 z_XM_Nn2+?kq3riMU-s_9YKVpyVqI(OkbA+3%Y1_l+>%M2xzxsuYoCS|D!&K`iT)ev z2xjowOj43ZihiLoF1=g`yGwJD9-qm7SJ}MS(=up*Xe|vC>2?HuXi_eN`S?`dmyPmZ z6cBm*M)aDAdppcz{4BRA9UM7pkOR&@Sm?e9u z9dY*mhU)I4b?7^ zFdYp#dFEQ=hXi|)tUgYO$<`u=c3Nc}UPbi48 zh<+_F{mo_p4T2rqYE-1l#Co+?Fr2xOMY^;0P8*Et)-!kqz{h!s+on6hTfr!cu>wb! zSdf%9S}PF*v{Yn{aiu6tMx05RHUx9mRQxsYJ>FiCIn!--7m( zedz;MxsK5NeS6s008wG!H8o>NX6^^{07zW0k0oiy`p|VBKdhE-7&iYm}wCo7zE-gVmdNa`$G!s86QRis>*^y|L(KW}KAGftmpq`Sn^$ z)qXd^NS2R(&Cf%&>->-69ne+un`jj%p-{!G%$KlLiCF7Po%2bZ5!m(uj_%bY#>U*+%Ou|eO~>UikspmJ1yPRA5_Xrz93dzNz3f5BS?6J9OH52Q4u4!y||y;^mY=IFDVTfTrk*W=p3 z1fFN)xi1L(Mgx|U5ye8ptd_UDY)x%TLHPrbVng%vp8Ykq1x0`1Rs2roqeFE8hRd&Y zVscYFpkOo|zztS{U>Ey_2>Nic!s->*^a>6kZ7Nd)6kN(BVt(b%A6hTwwWsc|*O>p} zPSrtmlfzAqw85{NOh6ALhUd1&!796>$4geyA^9}wsg?0@u#H9eMW|XwQWV3d>!eE6Gdt zip^e@mhkTE`gihnvQP-HyZa`77%YPWcALJCQq5py#IWq)OBGF=)xWhbXe(U_Duq>X zqy4aUnm=ja9d8xnWc>G9Fv|c2btNlTZ$x}ogSvUe4xkopnC_n9M%HG(lIvCN7NovA zO$*)XeuLFnrkfsvCgcp)(U#hRa~r?X5a4k<5FB@T8m~R{ZfGz4yk@1=kUiPc`jMD5 zKFny@>>qeolAsvgkEUz^uMj{luqL~qh(qi4uXH(9gRIaP|%eHFVIqMk%lyC>I9Z$Jr|j?vP_4`P;ooVMzvZ^$r=EdrMinLiKY?%_ai! z%w7!xM)UB;W6dg+?^#vN`#rH51(bIi!m%I{X|dWX^id8kLJ;q=>8`w*yj^xQmyxOH zDV4Q6){l+xd_{VieHE7a?c;>#R)FW~aKxiTmqo=-wbFOR;I6uVjYWlsrGyt<0L{GLrlk*ns_(Ki zsg>d7`fyRdKI9CQkI6WoowKL0&*qxx{T8pAnUw?qoZoos;PL3bd>6h}j-{_EKZv$E zj}Qk^so%hKYPC_%P#5Y1y?_Cf)}LR_*1gTYOb9 zqa>jwjaN+i8wVFd2tE+CZzWxm^pA8^P_E;9-lFf4NYGSwX0wNR_(sbwcwYZxDH0F> z&V%$0m!qDN%-8sM{uqIjWX_yoYh!_ zHj{d4xpFdsCxpudC%|Q^t$*H@x0r4<1ajOBWG)SN#nsLpEAwrDG@bBlyZdB6{Fm^h`Yq9i%s+Z&#mOnyCSB%1 zQ7&PZ>vs<;A8VgLYOCt&UJoE}+EK}~H8z7j&vuWT8|s#JR+Y1tZPr*(QlkUU_+|)*Oi7)w|a1U_cF-8TYk}RTt4{w3Pg7L}R5d_?M~pRkQ@Vvb+MgR{rh@{_w|*^{Vax z4<;%~{V4A+xiSA-c)RHs{u{j*_ZWguSPy-EbCa_u3D$^KhVH{Jlz6R;HNQT6c4`Rp zK5P7}9hL$^BT2t$?Mju(Ksq532Rya<=9*qq>2XW^FW?g^8GgpGC*L1RmKA$$WtAKD z%}TyAKVQw`_4S@lcIT*9kQ&=r{jlGY?W81(JWdPOw}nu&Jw~nuTv!VNXRhjMs>`f2 zT^a@1KfTd ze0G2Uk6K>I_Oqpqc$EU+1r>Tnhoi9Ynd5IU7vEiXlaJ z4Wn(Y_G1>OA^K7?3R1b-7inq(z1SkK(Wda`Pkd=~e3;PV@c7^&UT)3QP!P3oDnXqk z2{;C04$2yl$zdfY&}qKyQRVF=cPrOn5&gXHB1>z<`$7ky% z>!WlT$y_r^X7^#2)zju)4wU(hE9aTh%;9^63s}POgMRz+SNDX0=g$7#{@OcZ`G8rI zUsx>U|Nk6!T!$85iUBB(j*d zS4HBxYpD^7`T+$BV$bi!PVwk+Oi#d=Y|GfGZ(blAjEPmxO@Gc+T&mFz6-!J!m8dRu zAGf)FB&OkH&2T>2U)K7o;fOYoCnzrq>Wh#Vi61|M2Ikv;pSGb0=f9?zgMah0cWWij zv~SK!EJ4tsqgpE%2lB%fc6B$d$m|LoqgM>#mB^}V8OhsQ=W!;Z7?Z+90;f*)nD{P# zefTKl5h%bIBJeSw_6dtrLD-8$fV@h#b5!LiB!Vk~k4$SnpLkgmzi+Y*=G11Zf)5$3 z^GES5gs{W}(K72-nj!2Y!GS1E@KgjKfCJThod4X+d{9cv2ToF|&|6EVhlyvOioJ-a zBt3OvnC6j~d$hXyk!x3Iq)keBp#7g~K#C@%UyS)4j~g5D8lUB>U_;!T9#9s~k)wEl zQE`5TR;wlRk&3n|=qTnYalJZr>8xj5P)tBZigch@(rV49zR9%+Cz{%y8LOdXfp=tO z#_BmweFyVX&Dj}Y8_VNxw*T#1~Tc)19&*c85|X%yfx?l@cE?)15ibFKq{$8fzy zk#=pSInb>|{8R03)eUdDr(;~5GwNvF8!yxqpFje?W+EjrtrgAognS`xN_4Dx+ zf2seO{9N9J>Zw~5lNYQ==7bt23>J^JZ?M4@cC6ry>~Ck8kL!bUAzo-)aBEDo4R>}W zJs9J607-hzQK%Bef9Q72UMt=f1L-Jtp0_OhNTASdsMCZ@Sl#A^@koXGvp_hyU`s-= z_cEe=BjNqb{vY3`awcev5-FIge7c}WwL&$Fplw*9eRodAte&0>qv((m&ZbT*Q2^c1 zFN9j^?Bw;!IuZHYIwHO3&gq!^I6@{QXk8_u1QN5B8(yt|FUU{U^`7ti&_UC?zll*% z>@}hu(>KxO)Q}eU5|;!FW@|*Ee;;eW2%;u(S-yifb}ZKv@o}sF`OksQR1|NQxXKas zx61i*sf)@Kp7chU|Jr)FdXE4uoaw_8bC{YBXUlkZSgQvQ`kh4z?VJ0k4-N`b!Y@AQ;;vp@0&-caPd^LDufT0cNy-+uB2qp3dHw4+<<<#hMaA1&S01eY z*#|H*-?!=jYSc*W-{!M;tXkNBE7!w%W%2WJ*`P{^A@}QK&z2zn( S>OY`5#N70n$-BQjWB&(wA6J(E literal 0 HcmV?d00001 diff --git a/example/src/main/assets/底妆/基础上妆/2按压/方向/pic0.png b/example/src/main/assets/底妆/基础上妆/2按压/方向/pic0.png new file mode 100644 index 0000000000000000000000000000000000000000..5e96f819fa4992a544ab19ccf0b14f1acc1b6b53 GIT binary patch literal 22136 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 kvc2aH7}+xKJVf5oR-nA%>dy-0lUKl(izb^rhX literal 0 HcmV?d00001 diff --git a/example/src/main/assets/底妆/基础上妆/2按压/方向/pic0_thick.png b/example/src/main/assets/底妆/基础上妆/2按压/方向/pic0_thick.png new file mode 100644 index 0000000000000000000000000000000000000000..3a076ebeb4300477ee6ab6b332ab5eaf28318b7f GIT binary patch literal 29944 zcmeFYhg%cR7e1PVCITWLMXK};A|0vH5~>2yoAl6;AP`!xAiWcMQ36QsEeJ%VNQcmr zE=Y+;uhMe!`QH0H_qq3P`0exTv$LDc%+8rPbI!cyJuy!Ww5e`0-v$5xR1mO+5dZ)p z6hVMnq=d_H(9{Lt0`xc1egdc&WyKM0h+Wn6)c}C{B#NsSB!qi%U$BKg06;Va7f#u)r5DodHi@K)qpN2AU=hq{Sq}v01`?%gp=j}DHFa1AOIx#-}C=IO9BW2+$CHs2`BVD@&BH?6UzS`I`@HqEu#PT z`u}SbK=>({3_whH^Wh`Ohrpu$yVn0&Bq{p8Yf2}S|2sg0dO`nt(@0*9Q2KxVCGqg# zf4}njMYm)vs1d63FN0{PnFQJHECy!rJpbAEtLzoy7Vl=BqyXe4>41FfC-7YpjRRvI zu<28B($@k45MWHKfIMUrY@j=;Ysv8H=V!_8y`*p!kFir&)=u`FqlMXktPhnJ!=te0 z`4x0aW{)KQ&+&gG@P8!m|CPYDnZ?Cx3vK`jq){iw0Ba6u1pi5_9n#LW!B(c)rb=mG z`%^bknyfrSjIcJTyJHQWFE1pAhli^)0hL6VfF!^khy&;YkjFLMQ`vFFHRIP28QztHIN(6IJwLuAuJHp2$de=8;;0rMA>BjDQSnu zb!%2Li~V!^pqHM7nSUEy8`#cXTiE$hBc>_M&9D}!UFqJH-^?Lvya};>H$Qpx)1~BM zR|i~^Q4^_s5VSc~g;$9OdLQyw7cDl_;F^jav1G3Mi0bYS&9qv@-7JX=DSzLQe2?|iA_bBW?fn)LXl9~Pq?f$$AvPeMAu2VD(2~ZuV9t-pOb)mn`dDUKNcLK1Q>-zC z(Pc?5meC+e);=rAMBUM;r6zqv^orCa_t3`01(?NMa2m2EU{7k_r6mFdohI@|p0o*6 z_g7i0TDJ)%j?`niaLQp+=A5%{PFeSb?PFjnk}Rr-`;lG_40ze%xWgQ4N6WYgOvZ$> z%1A=^?H}CeGmishUmeT$7L7e=vJ&$Vxv-E3Kop1{P`f^wA&kBDv_Im(0Ey2FP(Her z&52_-VUWrG;cHjkMG@Sx1+p`1_XilGkZO=b{+f=rnhhVt$ScZ+J29u}#X=()Az^iGx8HmJ7gPGc9b$erQzuBAZ)2e5EsGDN^Z~X&10tFD{Vq|UdG+94GMp+)g)kiA04qQ-LK5p$eaD)`|hBmjDg}#U(s}W zO7ho+(VWZfd)TjE$w+ztG0C>Wt7Jheau2I(pZC7}25;Kw{V}Ia*&4<=bgfX4Li}nZ z-_Q|J>7bkv5FI7{tD%d|kYyX-O4OY|dZhzlDY-l?dh9aIAqX7_^*nG-j^Yx1EhV)$ zW4Hvi`?R`vOwy?Q(BpR_lQ=FP=9qigin8IcVF^}vl_U~1!>QOc$%i=MW#fh#LnKl2 zA^Y*DOr8-w91s%NgGG(G&SX9qVU&E`-}m=|WDUi^3+*$HYJFn;dnx|VC^SqP`#AeJ z_(_@;&}FRQFP;4-R2sMbpSAjXzBO&-!N$E2_}tWjWLORAJ@y>ulEBcvzPG9K~GW*_d|mvye6AE7Jig`ssSgBu}$|zk%MIq zx;?`udA??O-&JC(1)23!yp?rmm|i=`xW)FFuFj<@Sf-H`1;T#4CrKfr_nRu1F^lP2 z^5bJZ;T{D)1F6bp7>BD#z!q;p*f#lfYYd6Nh4d07!L zOLM197)d6UKI1$?SxCFv--H4nypPG87d&gvignGZx0V9&GrKDVxafVQ^* z<~7f!;7V(9n=?X)%C$CD4h!kPKS}E_Fd3JA#Y=S+Anq6{Z)i;8@w>@9Jk$ZbI4lI% zAi1$rznGu;fGNPtU>2aA&8n7naBir^6!vHeFnr=uvvul>9Yj&^`T=cbC{Y{tHA!U< zNbcd2oSbH2`|37w0g_M56e0z?vu@yyOnH7gEd>(XJb0eFn)Vxz>VC}-kqc4jC&qL5 zZ#D~AJUW}+FnKyMGc~H3AxY}+3q!=DKq-xduiJJ|#t0m@96 zuv-I?DGmWKmhWYUE$QnVo$9Y->z+45(9KUQZ{Zf@7?)#rZ?NtE9$}Y`j|OX_SA(H7 zvcH>OQDl3{j5zfDO*!Dv)%bNO)wefUwzTWUQ&$-EpTjR4PcQ3+2bpOxx; zY}2UMmeBrSOAVMW4ajb;3<5CaKJN2@YWUdp{0Wj8?O*2hqCa|hxQSCqM(Qrl&pH%f z_PFpE&jU+fR>?DJNf%MUzAd}q{QYJoI-BUY5>AD(=hgxSUgO3QCx3U61w7mH@4WULpPihjdhsx@rYjDn zda-nKR~Fzyw5hQhnOSVMa)!B$yK(UnUHv=jLG1ga7)^SVY^s5-)FV>%avm?5)me+j zFd``Y4dwTGXLlcUvf0#o9vqwRMSv+2jy=puEF=L#AUgvem}8>qBHc;yXte*~Gt}7T z_XlA>oZUch2#ry?gJw7q_3t% zVzTi5e!HPR6&K6+4^RXnhKh1pGhCTs&3FFM&~ zCLD-lz9|4u^u6sYC^$W;H3WIbo|A>$z+TMY5WJDKCmW?jtSIT?z*-np5OKNT2Iq5H zLwxfO!LVA3!Z`DjKuzKfD@S?VcJphSl-}JxL4U5*-~P=Pt!@J}#S`h1F|XG7Ee^d|gIf^Si6CUl`PW3tlukZ5L9^SI*qH!&lZQX{iq z=;#Ev$bop&l5->x2Hnls=fhs$!ox(dk$c3U6y{=4s$Cp@YOkW(f!dmHzus2VKjf*ixlrEDep77%WEI6R;hLNzuhOSg>&R&y{q$oqh%OlZ9IKvslkNQT zdy}%TP*DQUPML$L40cEQJ5MJcP63j}o4{0v8-ej}TTh&HcA#EZAg^T?l|_>ckT8v_ zz01_o@2HNn#S41hx3Tyd9X_z762Y^dq;io4mWq!^CB%fA^{{PJ){AADui@1~!&uJA z>Z~M@&6=?8%t6JUX2RN~0qdHjU$y|sbLTxkZOQHVPUOOfjoCU*SZJ0$1Oyd=8FD4r{|3$NX| z13g7pQ@qib=yTP1`tf!Wm>;k+wc~!)Q&qg!1M%6vcWJWeR;plDJ`d=V zZ?Zd();fDpwHL&7wlBkkHu-Uv!^EDsxeI0^Oe?ccwrg_S9=pxW=9n_yy1=A4-qJ0B1mB1K*lTUQ{sq&KmxU{MJ+topjg@*;s*o>T0} zYn7~y(y2y;3Pa$eW@ZF$;j!~qX%9!5@;#-MM=Lkcvv||taE?0*OfNz+p@(UB(v(m9 zUMs>GvMHu|+k-@>G57Iyq@!`aSu#QIwd)d|VFGZMRoC?6iX<@OUA`hu2KmNY5;yMF zX6Tetoiivhn$jFip2eh=s>4Ur4=+g#6YCo?joHft$s~zb$7y}c)g^30D4M~`#m?WB7x$B;yt8G&R zJWZ_alvS%GVfS>~k`iJNEE&^^b=6?}IhS9WAVKIP7!jU&63 z`#;Js36V!(zghQhXGPvN=VjFGV33u)M5tXn%kJy6Y?rF$r#`p6h%-Iltkbeg3P=PE z-rgGXqw_V39Q?;wr34Vxz&t`Mm&}I{;r=c(m#+T#=n~BtsUF#_CB9jG;2Ws^*04(v zek(60v?zLjOO}tyN_w;O`K`?iN`F5H0Kdr{OB%lNd8$Y3DQJgS~n(Usb(uMbdLWN~*sc zP&qTtcjU=4-M8I-f#6EsAh;fb^A2y{mrS?c@(D2C-MJ&f*k9#Vq`m?07vgJ&$6+&( z2u;M}kA4w~F5QN){J#Pn{(Y~+6z1fwkV0)xWB=J{)64jePBk{tm z`S@DK_uhCBNa0Zfm9kaQVM0lBp_ab4mL=aKQd+xAgEJ_fJ$U#=93V;5sDWv`4>W|a z-Qu$Tom0>EsxoNKhQwSR-QnYrVX+HV5&KVcN-hM^o!Lnv6=wc~7ddR%Z-&-Hy4!_S~*aEj(4$)UPAsox;6}J`Vwg%7*!r2^LW}Fxjuea+_N0*mx;mnVhI-)(kI+5H=xJ&SS$9+4 zj<_GUYI`LnNJ4X1`Gb9kw#x!wsh|tpj$;5|o+w1xpWNrM;7GEeT_FSba=qr6=yWdA zuZYTauCT)958n?1BSJro^`?0T!cHQX7|#L`aa{dj#>}dy`)PGK&FQl#?m8yK!&H|4|sAD zDUtNVJ)5^Th4Gj2O2HOY7(blEHt~C{A(4vyva8o^^G8N6Mwx-WEeW+ly~e(ik`|mh zR;7`(rgsPfsQDy*n!EDXGJ+04y;^=kx)Nh8w8DYf;{dOI_4UEl%~lk@2hMGg+V8d% z8AjXNx)Q~eU0N)w&x!E~yn#JKcV>T-gVyl^GQugdII=rLLY;$|4AMSiwSyxx}Qr^WaY13rinL?ID>pLNj)_RJzKu7sUqU2I`Go)oFOjiUxXPXDi;XueN9v@MqW%?Y5I!Oqq- z2j~9Z{nriyYi9@*&}_dR{><^EfZtk>4(h3r#72S$6CM91WP8VH2S$_}TfY<#nLX*n zr%C$M0qU#%6|~9em7hzo{~i|7s3Gv%y@1RGvg{!$f&@&jmAZ@&siI2>wz&NB8VgM_iu0j2UQ&*2?P=9_1O0n_XUH(m zaHm~wrG&AKerzGM<-Adjh}z$Ykp-d3JnmjxnM-GwTk~*kUoXYprF)#OFHu943}An* zPV@g3U2j$Q?-x^BUzNp_upSRVKLo04r+bV?%@Fj(YI66_d9IxYv+mXdqRLo=vM8%E zZdepFfo!x1_&SjLKe3|)R5u|qaOiM2zqk70*Sd}@<<6ZSqEP_dM93M=1Kht+<1AXw z#l3O#_s(Bhuih6l_jWEZUsBYa-x2IQDV#Z1v=`)7YHM)gan5|bwN&H!)hUpe&Qgkt z->0v@C0t!R7$LdB#{Oo1M#Lc4_r)Fa(9HC%1_(ClqViL(!!)U*VA>^3w2mEtGr z|H)>XrTxe0o5&G_eq;g{*GhrJT1R=xeDa2-LaQEkA#wmb_TZWw8rf8!1wbZ6T~%ih zpPT3<-p{wvvB1&;-)Qxm@vb4Pa^>0Czl0VHUFW(>a9+z2%qLlx7|8H z%ls`MnDrI5+zc=UHOzbq;okE&aXwAw_!I3LK$&p@6L=fK+`q$>(T!>>)1X z@(EN6_V%l_N?(`m+DdbdkhGs&e05*9U)TAtD`{8$Lh{t=Bol4U$8FiKZ%Mk^%3zp`JxXjhL+11phJHoL<_`_pr(>J@(U%D9T{4`#C zRsu=hOa^eXVU!kep#F7B5&jQ0DK@wRC9yi<9=2-)8;)ko6Hek;?Wj7vS5ysmP^ za7vtQCT0mASc<*;`{qD(oOXz@nvA9&%`Qrp{*k_yZNI(KT0xc*ghMR>P2>7P!Rfu+ zf|GN82ewiLE-pzD*CYt($Rqd!w}cq-V&P66y#$v#JSU+HVX=A{?8tB;@^AJr1XyjO zicgFx1Sxc?I`ZYWRNi{q%w6Yqc(E!G_#0uay}WN*^K$ib_NpszXyY(Uk+l=xzkXI< z(7Swm@f-bYR1FtW{SJWFQ>ho~%AR>)948X264$Y2N0iwcgb%@SG--{20=0R%LRN7V z!l1qQnDuOq{=B!;Yxw@Mj46Ar{r+<{ctGSR$xU_*>>Dj!C1gRb>6-Ev$g&AxAXGH= zk>D^O5`~IN4Ut~YQ(TLjV60WQP~m@oE`ospo_cSzV%R@87SFfcGjxn4wxMx9Z8EoM2;||<<*Itc z>RQ>yvtG>w+PwGkJoVo#4NMI(rhJ+FV`f=S86q2dM(`3(2b2U)@BMbMj%SJJAh>T$ zZ`#}znTK}JsZv#8P=cdj!_4?SjpPT8h_fj4&cx2!Ti6Cin@OmW2%Bsd*!ivUNf@mvrj{Bbsh%AqhWWD69rZ{g_a5w5 zpd!E*#(Y%b*F;Uz znAd*QOhVAoHe^B~o)B3h#5*}k_B>qK0*RhN;)w_dT|m#f8k-)4KhiuSLeMU^g^snJ zC)o2gIfK;W^jO1Xn`{0d|Lk8)2$?f>N9ZPm zIvw^3ZA=m|+E7*Q#|x)TJ7-95Qrp$4lHyo3Ozl!pHa0tKX(9FG!X>tSu_C~7hS;!* z4?*!__nm!Ni@!a>Ey9*9d-NY!AX7dUKytW8-yaa7-D5tojm*8n3+j$D=VmW|vC76H z*r|aLhRd!yUC+5>Y?} zOGQ9@tcU7|ECAfdZDYRC1|DKUabwS{F5~Fwk2G4Q1lzP7SXIJvg^@BCdjd6vsYAdA#iZ(huI`-id2c!cr&KBorX9 z%Kc?0=9jT6u4P(d6J>r~5wx;tj$Bl2J|Ii|p3B0#mP7i5$=l?SLTWiggnhdD8rQKj zYK^;iW&-TWt#sG0x_hfq5m-$Mr9rh0N-ZP^T99I8gxJlF`ew7aJ605FDD0Pxm#6Js zQr(PEY<&e!J{Fwa?>1M>ZP8u0F{Rlw#mNQTf=l;z~PqPgOhMR1w!)%GdAx zC>4{Mz-U8T5#DQ&)9&0=9Y%_jKcVC|vOk+dds0Uo{f8oq*AQWoXBKI_3P0flkZD2$ zd>@;XQlQ1G^!$xU$iG`S?R&0cfjlTqaBIfDMd6H)ZoUchHBV4&Pn3q%-#(4*V!ppy?s4!oN(~p0|T~@yW<1-)M=}Pey z=cf&bluDV)Y z&~|+)#-}e-q9*2?_IIEg5rvXY$iA#(9H${UHmdo8e|Yw`8_ja{hwJ2w^Ivkik{X&z z880i?r}aq)4%9gU-Z5yU)&O7jEI(ALz^=3Wg`(f#i;B_E8uKVAy+7EV3zpKSO@z_`bx&*^S&oq{gZfjcHeEoIMgnSDb;l{X3QbTTRDB2yv$x;b%^ zTa?ZZ6m47XGj*{P34o4deX{m8Z`^s}N`RtYMSEIM5cO-yQ~pru^HL!;058va)_)dI zQY&rNi_eW*=Ja|a6?oxqWuy4w`YtZzQMaAa`U%>bz3bX5D~m&|;?EZ-&O)dtuK1w) zGa}FDvl^F+GDaHLVxouU-Ix$T66Tb*&g9x=%`L8}m(u~1w9>WEd%s8usT=>xGizo-54?T+(W;{W%eLl|$<6k*32q4S&7p$s zGS%WKup!RjnO)*mK2&?%cH61gF@!O8xtKlWRVE0IMi__}?NGQm2VNSo*l(W4dsi`( zapE{DS!wr#|7q+moOt^-Qv(c4kSJLrb&<+F@HJpvp ztv}q<#r%;7{rt?y-TK>opcPp0*X-IMVR3kpBWeoJTVy)Xzt5;kiD&MlX5kvK+Wz6n z-CK3TTYP!^1Z6gK6>?d7&kPuf5p5+z8X{_lZ)nmYZOOc&9~jMQGafyH#{P!WkH40f zS+}`@zCTL!Q!Q28(XQtXB&ba1&-!p{!6<-Z4{KZpqQ8+^{b-=COS;@UGzk}uO2_71?_f08-FuQ88{6ihjIuBGu3Aj*(cwpRSrYS}UDFex zYM=jQ_8`Of@LcnRb-pfc6uEqU;ULKw#{Z~sx>z`Kx_Sc5rGz6(T{4m&ntLo%I(+>A zE1Z=0NGx-tRyeU7$36Y`Nh*V>pLGBPGSqw4Ss;}usn9?w^M{GOR_#sV7`nqSg9qK= zI!H>zO!vWwLZ~!_m4yy6o6*#U(!CIBbOMglt}YM)Xf5%_gKv1eM4&NFXR^GD!Z=At z1ZyE~z^P*zfFp+VZ`i_(u-tyb;+)VyTJhTf9H%p9gDnse3mz&gqvNHD z8{4*pBe^Ti_ zM%MT^@>J(T#tfbrQ-JOy!@Muxs@NL~q)nE$n`{C)NJgL7<^0(NoFv4>;*};rLYm3( zalBqB-onMg%!?{oISb;tmNG`$rHkqi2oJ*Ep#rAb ze)gnExsBUe1fFFGu^Y4W4d64|QhthscV9lIr0KA}>YN>E`1`A=q023Sg#yF|*L@#HOHU-S$O+BW%Sm2dibYiOET(rA_@hydhvftF&$z`$^=Uln z#GgupUmm3*jq2yoj|)sTWBF&vo?A!2{e{EbXom2Vkd9uuub&Tm%<_UHd(#S5y)XW? z9TfcABWUb{;?!zx%Hl?uGwqCh#i*w+V_BJ8rgl3GM9el?dlj|@Mq>qS$X zSsirPisDpuUaAAGl)OKk4K@4~$DO`hg`Cc9odla>#r(K`+tSN-;_Wf%V8M5qREM}O#6Q6ij_SV|`7T<$y z+}jE>o?Dgz=xVd*1`XKd2)&_{k`nNkel^A&1`AZ?#jOWngS4>Un^+`jht0jX|I*3= z#Cy`7i7F>Ixg(vwO;T0!y}q5n#jxRX*Clq0yY^Vh0uB9c$4}6(ZNhLRj!iXe5_p3s zA|AF(=btfzehVx)Ei-ptQdt~mJ?IW|TL4tCN4!62bXfc8L8I!n)JASD)+KiT$aN#B z;Pr=g(oeRFe&6;j^8EKSsJ{tM4DG*E6rn1dS?-!W9(VbX&ksaoqD_bOwgd(O0|wYhhAgQUd%CcrycI(ss7JBg0hu!d- z$EG(^VPY^7H&3Uua&ALe=}*L(gCc%GWT-2R;AJ>CDKgm{&pP!k%P*F}h~`A0LwabX zMORBrLk&*vah<|%@qXc>*^k91J%Vsoxp!^OIX0MYeo4H2SX$seTEz=|_nlZy1nH`n z%Hw@M?K1q{_@VAoOSK+t4ramFO^qBfC=m6Idt}py2H@0wjyCz+1^z2bjb%N!xxeZ# za~DF3)It(DwlCAQJC>#zl3KddfpR_|Oa+S6DYpJO1v~U6cZ>i+g_SGIUH+W$B%aN# zWeKn}vO}w_LA8z8otgU%_xCL^a2kM{qkaE5TB8|YJk!r*WL%=>RgQ0QPzF@m^e`H- z>_Nrfkg}DoN;EsM@@Eol_K&RlW294P&+TXkA&8>6Ag}(|b0Sy9@psQk;YQvq(X?=L zJ<=-3!e=BcEFL>wmLInK+auYBp+xI%PQ>f4kcb(ZQct(lJ=fS0wuNF#uN3MJvC|mmfefGK*2)Du}S{@ zW3!VxGdHUn^{FbrX=GeWlcfu&wLwSMeDHo+u7t;q>tje9N?b+*xt>&<-5|0}8r3J~ z0Zq7mx+07TT)dv0&?)pvYFu_KQH6qj7YxX3Q|^_C^SFF^F|DQRamIqcD(qNxPVR2Y zkX4v_PX!uUF7|!{{jkAGVrWuFlU78MAZTlB1g{N)nrc_F=?fxl(>(bI-K)LQd)%8A zuH`LLKK1M%K8uLxAAkF`0*5Oxml9f&Y~-wbL>!ufGuMc&V0e@A`zAH961TOXSmAQ?u8wJ+#QyRePmkDfXh3#&%(G$(%iNn-Ebb`o4}ZTf zt4!(o;2DOIKM0<_SI6HDl;d11U>vB{vDmdeb;67i4c{GzbcwC?*Z5eMm_ zWJ4gGXI(5#wUEwZ1hZ~)g+C%#e2(prOy=*BE%R)>pP-M+YGtPmhsNkVYCKL{yeWTJ znhAm@9}R40q({*Uvr}968BCNMbn8Oq1b_C^1R!jWO63h6N#vf;0s$1mgQ)Bfs;?J-r!6I8(2;B2iwXsE{#vk zEwgLe4${iR=^)&v_vY8-!fWQqv4U?qhksP506ajM8)&D(k$?$wg*qmkz<$@iDJ}(*LR{u5{mUG`47bdU}x~DCv>%v1_&ZZlPBL2grzMx zyznuy^cI`v4wd;`a~5;59|ErdUSw4iBI&z6*8;L#W|cl=0p=d+3T=9CY|3Gr`Eke4 zY_D})WMmU}orB)4y!2~;5)(ecR_ehfAwjIM1aIJ>Pe@o$PFZaiLS?5E#5k_mHEYys zSW@8{gT}fEQ@jB20kcTs=^d(fw}1(+LK6i1Are-2LboCgrLgM_CvbPr$u8<}_X^UE zm%+qPLsX1&%ZUkEfUobFa)X)PLpIvw)@$GF=kKM$#0HnCrsVWuVZonWxv*NeR~{;u zJj^_lJ9UzZ6*!gi7_~kH^KGqzyE-TUwL*S!WAD$djnQCA+yi|^ogf^&F`uJj`SGhM z>S1d3E)Zd08Q^iLPfOw>dD=~Z)ECom)_gWUNNL*fHLSR~L=56M$>@*f@-v@rDfYUg zrY@mtW>`#V9-agA3M8G_g5Q^CVM@|ZTTJO-xDx*grps%!mAeE2`|pVkUK?&4klw$W zW0w;#nn7PnS2B=)wDD2ZG#wHMK?~jl@}o{tZK|&IYG~zOfmu18zmKV+22k|>Rz{RL ztlF7{hKav!|4eR8?76L>x3x~^tyZ=%2dUoaFqNmX`Jbi9dWl)c%4*FHqEWi5 zm-qh^5IyW?eY4Hl&w}i-7u}(PaA-X&x8wqKJy*OZZ5|MHme3BsN8=X_Quz~dPDt!M zR_20)LLSqCGD4A;>?=N)s{hDj$)h=c$UEUbmCkO0lb3`V4ae3iDhm=-jixEdYF+}8 zPeGKi2bPEm-Q(mLEoP4X{uj7YcP=r^ry#t#3AvzWHAR*%XtbK#lR2{F6+ngSKgP_ zS9)IwBWO2&uTJln*0j@}TNH7u#>&!d*g6ZsH7y*R6vH~2$yUBHv9prt#gcC<9$af< z)S8Ed>q&`7XM>5xNj%eL9IJr@hMv`s)M&<_E7*ho#4~Bi#%1}?d4FZs=&$wPp%4Z)x zJ)EPJju?GI3bC;%Za(PS)0kcQn?e-&Ci-8e{pWBlU*Jm3LgWii<(Om?+P}-SH<-Ar z4=*Ny%W`7$2>aLbbRDKy&VP_4ecRUp{@C=(TgyIt6`oV{-SMf3;bz9rL)5>)spreA zuSHu!<0gs?W5qg!xlhkf(I?kZ4;2C_!+5WQXKdZ6aPh|-a#~ssM031rNwAdQKrN-T ze1T7$8q^q@_M`5+mR+Em2Zk1NEx~tWV%?@2iC9WfRrLWxkhWAgUyWUGU`vdpho^^T z2d5-&;YuG}o>~_KeY6}e{CpN!GFj-c13c&RmE0%rJ8$EP>-5Ei?M{C}R2GqwozRsYXI zi^wOIB51st0{5aVHA+5(JqgVR$Cfw8w)ot0%-e9KId^4S(Oa2KX}!J$nbj`JN+2-J zj-C#G3_zpcg`bkX-^i*7H(T4#wIJ`VS-|ds$2uA$RbD^qr5Su*&3!fVdusXqL>!foyp&y` zR%5OF#FD#OSo{f~``Jb(!E`>;O_w!1zTf7+WpBnRNmfcAY(f7me9o)~CmPIsB;V143O z1lrOy&y4epv~s*Fm-{^GKl9?F-G{M>{E1bl+T*0sx)?G^@I5({Mdg&@xNV+qTq|W- z`RI?XSDflalr|TdOTz^B-9*z~`+J;gb4!bq$QeZ)&n`#=vl&h2(r&9@j#DVN{zc!u zpxtNQXV~{7&a#ptI2GLXiCZ=K6z1X}pcjP*3!PM`>!K6b)nFQ6Cf>?DQZVz}psF#v zM2}4=)3pF+V0C_*kLYAWu#Vv#(54`Etl8adDXY#>!JAnjh6&nYO-%%5oQ8k%xaKy3 zWP*SrtU!bdiMyS*=Lm_&P8ohfRUxdRuN5Ag?f}ZjdEjLme%A3I%`m=K+;~cgIRINe-X8 z*=6PVRhOSwGUIB>nHT@8zd-R$UR0=Aa?NU5b>5rB7gntvGzR7^R07F>%Oo;Mv$6+u z&o*P*)ujWPxxJ8aWaF-1LRR@!+7}Msjq0Sb)OAqB2YQK=jU_#tix^kT0Y;C&j4lMQ zJSYE^gPxDHxwwO!NvU%E6V>{%UBZEQiVBzO{HM|cozh}JU_AO?{+6Lns+WIh!RJ$S zIJXa_l^sv|ojA*%(v`mJ8b*EoY7W731Jd)4cH8E)KiR6No~FxJ4xuZ*OF)NuXN|H+ z2uv3Blvi=H?r=~A-;=zXM^8#isl1yHH=*~<60#?u`Rlq8S9?R?cUz=4ymhyHgLu*v zWYFi~9E*4=0taf!<8oL&5$n3b;41Nx-q&X@fYvXeUr46@U> z!=Ebh_D}IZgFzdLL3yB?xv#+XyYItNw}WIs(&@C)p-gmWEsf-&LV$4To=+elTFN#a zr*%$`atyhYdea2L{_70=6Ttv&Y#N1g?wFMB>NwLz;4cdu6l+cKzh#Fe5^p>|=Ms%9gnS3K-Cwl#%xDlaRG`WV)e5G2AC)x}0l zZ3ddW0yt9vJONdd!yIae7JzBOteMBA6P1!$j>^|%W#iHhl_l{pyJzssh3eNZ2JH7o z0j9!>2a=nH+dB!Lgs<;s3<`g~J{`j{bj8MD2{v8)^;;Uo(;PTSN=?k#*3QzX1ulUJ z-61ZItktj-U2J`}`el_1HPBx8j|Zy;K0;jv3fa361BEmm6j?-O=K<>yddS)w_^SY_ zIbsdzguFe>v{4^-zL_D278UFm^y|;9n4B34-Cz*3pO8%WB&TwBD*~%oUscPlU8XWW z$Fcuzi}R`unT!!)_g@}h)4gV9R){)JRKJiq^EsDt@TyARUA_gT;9`qDUjD7f90emz zedB0x)Vugo5Mx^(x^4J>6?fJTO@8nH-)N+}yQNEzMv2ji0%J%Bf=-a`90n;Zoi7}s zzz6}6o=Ql|P(WJJf%JeeVxOD$FW*1m>redR*&XM;&bgk~^?V$~j4gEDTu=xti&th> z%X|-X^`%mZ1InEigMxG$5o`^{9mKhR=C9mR=D=`|Z=bZZVg6Y?#aW1i#gM2|Bb@mQ*Cn6CK>}x`l!+bH+%*;CS*v||7pHQ@L?5cf z-THyvLW1gdc|kg3Zaa^~@WDMOS3QKFsdCG)k(j*p40$U2%}$EtN0y>MS<~oAC;l=e zL9jJN1Qc8gB|i`-TW>yY?F$Lj{!_(62d6}8X1R4}eq=96XuA8h@1L6-x&YEGsf;^$ z@HX1AI+5|9-9VuXg_w`k7N$zCqd^JE{XCl1M7^CCEWZ0L)-(IyK_J6q| z@L27Ax%2ajdd7M_1&293ZzlbUoHV0FD-}|`8nXA&a#WbER=1}_z{;NV2hHc&JC?T^ zTFP1-Q+rE;8E%aHmA;<5e{riLh6;llKU1??)tMG7!CM&+I55?0{?8)iFG7NzKRGW= zzTsxB#rftnN$SBh1Usmx+~S?q zNA?yE%S0UiRUO@+y`dl|`x0l#YZt}M`kr6$?jDk=a{iv1Hak`unJYZ~qc|gF?=sK) z+=JE+*YxqRb;n5~p7=Op-IOR>EXYsQhUpX8@ahLW0izYM68CyP!1=bRuwRuVp2TGP z?cd+4Oz4^NX?!k%9v^YPw8$P*mTCK2LvSXIVcvV2uzO**#JiM`C+}}ZOBpG4@!R7% z|BH=&Kh>%_@ueeMtpOia77Cx&|J9Xn>bn^KTG%Q0zVNR~`T7zsv@t@KB3;!30<+s5j!G(2u@KNTs*Hn!0s8YPHj zGx0GvRhQloL3Y3A%-*9j*>cCU-@E*I%u(H&`UaOA=rB43a38dy8s-DP(xDkm`b{)! zG0N9y}s^k-Ll!fQwj;=Z7;FL{ni;Yyd4vt%=7uG)c z*KbNNz!={(f^f@X8_hQ@H@89{l@JXrpd#0hd1DyakI*$E1h?HLUj)4EY1m{y?5ypN z@=JkA41H|DL=7g|@19iSal}BCmlx5>TC&UQg7V44K(V?QIpO#Pwy9KS4~!yKr&oS1!v0^J7&k_ z3b&ev`?3XM;-vH+R4T#PB7BtYd$ngFnn}U#MlQZ&;DU;YfPui81ZI3M?kJc;Kei-E zOt18a@%=_to+^2k(1O7q^^A7tgun?dXuf#pdOD_WU1QWtl@Z0)r-lBU$YfBaX0 zyV#bQ{NpVQ*9QuPGxsq)e-~mj;|z9kRD`8RNk&cG!ncLPrMz>R!rD;JbHz|uCL+Sk zyYp4r&71Y=wi>RVzYmhiy=kgLt^oR;r;IN5WgUc@?Hg$9-C1A~bW$_GR!e>uMp^It zC`bhJxvMlHvoH@360A4Ed~_i^$HFAb@|EvNZIfQ!{U)Nkiic1gI`JwCfEd8KAdRl% z2~ij2r8wAI@Om%z`N#f(W;K@u2v?UWl4=ozzgDkUAD2trLgk{d)P>BbL-GLK!u>D@ zZ>$Y!jRpDPqps1lX*M^Ai=#`B%PT69`vK8pjZ_(DPk4Rma2x*6Er$jbPM1fKvhIw< ztg(pAd~>fTYW(9!_2wCE)HfIh=3^`8zvdh>On6md`z2lR<%$02kJR?hFsMeN7}>!V!xZ==M`G<2gBx$$NI$RvV@(kD1I@;_kn+^BH%myM5q7Nd-f!Ilh-WEXInk)qf@i&j2kRRDM58;k`*()rye zRGOIVbEl?qdP$eLlvp{Sl@VFwv%J%7mC0$pmH6;Ki-_677lEcb)3d6;3m4;O)v>Il z4s(l8e%wQV43pw5UV3-viU*~n99&nR59R+Xn%N!7>{6(wQFG-y`**{TuNNt=R{7YE z&5~3L)MJh2Sr+##4vdg>HCgKS`!^3%xKwL8phTj>(lJ!yTy&3Y&%<1}>w6doMytR& zEh!#?qN-ub>R?acDgx}vSK3I7ljN1}hXFZXuLllQ2NqGz#o0dej2T&&R7Lz{cw46} zBqntQXqrmCdYGS?pp1EZc`Q&?=(Ifu&~qR%+k1TBJbHl8dUc7)Hrfhmd%>9Rb_Y`R zj{r-X_|ixGT!eOm^vC_|kE<8b^WKw58dXBCwRY`D&Om2@ceP-LrRShuu9cz&aq|nFsbLpoy@HyUDt+7yB0M# z_QaN|;KkFgnk?mPc60%KmmkrKkVRB1Z{?tm_le4tXAW7tqIEo3MqLHP6X7+gIRAgd z?u-hQF?v}sPK|WW5b&_7!aDA;7}*nV5gd5aveGwA6&|64!ZQ*deoNd3{bpmh#)1FS zKn{+9aO0m|$^-L+6v#_~zugy`O2T_ErO!HU^}Hj;%s|{$@;YwJd!uBPE<4k2u-}vi z-!tTF2I7#3?uYB6CR_FEw+jTYzy9Y)V(eYw(dbIJ0Z9fCf&D{Bz|^SffWK<+mcbk-$V<1g?FQe3({?XDW4VV!Jao zFnEXa!W7Ux?$w-hOA3Rdd9z;h8z{6g#3nKDOg>U<^<0OZb-KQ}DZEnH?hWI_a9s^q z!2@q^D!DI1j*8DRq!UEfG-!~yGzLca7zCozmeo-j2JR>k@$5QA?6-}?GJj9QS)~ze zgGmO2(0n`R)B8WQoI@ggUf~!z-kiyY7iq4mO#|-S zr>1LGaBb~GzfPXmKj=lboLytIL&iV1&>E`gMSBqCyFAHoq53Cn&tRfvFe|{Zxs^~P zbOzQWaZZ$J)FtVnuOS`I>*|M5)jymWwA)v|1KDc0e4)aM?fTy=;kS0Q!YVR6+Q&y@ zsV*BO73{DyAnAd_R2zkRUY1RGL?1Zn?AT3GqmpDiRiCw&GD_Tnfd+F(B!=@T4xpqD0X^99nF@45V} znD-ymZl;oZ{R?-aceV@(icMm9WrG7JJmLp~jxF8yh+iEwDnIGCOHz=YTugCG$M*6}i4- zivEY@Mw_6SfE(};x^VuV7f=yZ$?kV+YGt#Dek)Runso{65*HZpR&cvi^PRk9OQAg} zC>bO{nuWOM-wM_N^A85?zox9Bc+=3Q2fLB8UvXt)6vY(59h(zOV%`SOMT%u1N-Kh( z8_ADcd+z-CaWxj5ew$*5*Dmm_k1(--Hb0T9(r6|k!+99%P13azrvFT|@4VF9;q>|^^R0%yTLh1*n?42Rybs8XWTL{Zl$y2ddIn(y8KQVPN}_z|wh>BBX;#Ca-G@1`Q-mt(*X&tU4t5$aRFs1Bv3V zV8~;bCV#Klg|PP#94Sd=R0n?$vZq4njIR-&&Txu)2Ql~+f+y<&j!&|7F1Ixy9NAYs zwy25laFG%mk>p&*BVv)uF=B&+W7Yc0r2@du z*L7mzJ~+6atj@o$CvVINxDZZA#Q(4v(wOjYQovNGq5}lYi`B!ih>6($DCAs}%befh zgo;Zv*R3pC92S#oZaHFK32xB2Q~(2tBT9{OT2Qfzpzb6SK4TKfoE++RyN$r>q`+?f z@9P%FWWpUgnWXhL{mfzUL0x(K7nbJNigo7~?9$g$_a+T|(361P8v5|h^q*6w+Gb9cH%OVenEyx?xMSZT`c2P%}n!@p*tN`tY z`Rr);RbBKC@GMS+v;I;licarxL?N^MH_)$uwMoYKj8_lw%|DUfh_qCkpL^Rc4y*VbmrcBFCGzT5Rh-6$cCR&!<3h%z!2jPBCN4z|Kpw#6If~r3U z)5&&vPhLy!D%O;^bdWO@#5{mRTW`NoCpw$S;}ac$u5TXFYfLi@{89YOO^!kq@wnu< zS5>&5m|1@@%Gt^^9r=2x4c6|1<yk`OP7_Ro;jIASW2O|8LeSDHABk{HQoih-Td?zh`dCK6v0s@ez=^ru8Z5%7n zg=<&Pd~jZeu71^@+MK?Mv#ol1ZxK3HdN$HX(twSTGl*yZU?C>u%M|8h`ll&FXa-ZD z$3_$vS{Q5qpUb7XygRTl??dWnJ{i$u{?^G8J2-~l-AasUsHx`fh5&n@+;%YMcxg;aBlTm#ZQC!g$)E6-Aq0?i7uOfSgurrGyIuhc_LUM{ z#8sZOl_6)WK@b0gd#u8|*R1jJRx0VS889-3w7yQV{n8tm@odBLu!PhPp)X%JPoUBLf=QEh=EM>8ICGD9>_Dm69wG+4v{ z@FK$Zd+e(3UhyJG=`e$xRQt2{@)K|o$o#9pnbuIOR8LAC2$tP4KlUP!FUl}rH6dyu z^T{|)j2UD%`)0fxVDB|VV^klk)a{+>>VeO|S<8By#k`ziZX$j^z|k6Sgrl&h?s5i4 zIZO}<;iK6{MS)?Dr34ujMCw`U&7<4x8wF)w2U_GG#^o6+3wf6jGrOje5LiUx1Wov8 zI~s#MqsY`LM*N~jXp4=AVRcM2Ap~T} zGp6NKY(xsqZ_;R#?}QOGndnuV6oWtLxER1YIOmwuiQAkce*UIwj>#1(mcjnOtEFZE z*hQ2mN*G%OU>6~aK9jV50g?4cF|kfDEQ^WA3gLd6CEXYj*jddGdwLdLh!xAhD?fW! z$YUk!bLjpKCzD=M2$KIRb0rOVkrak)UwL#U%AM{gS`0Mjj7^----o!Qd;FK zsuN7(ZhuU#;PW6p4$x3M+Dhr}C_3N_TtWjGv4o!B59 zmlgcE&t9JI8ObClny!Y`k7xz5B*}rCsGjler67ggd%XN+^r`E!;Qd0XHz%A5DyV)9 zp1l#^KONBNMI;S$%J*#Gopy@EZO_fK?fuFQV=r~p%)%w38lK-2Dq@q_ zWY`0Eyj<*My66SIA4bgB(Ed4h!uaoFA_wHQOxlK-K$WXJh;;Yg#@CI0ap!wiyKtDa zSIEQ6PW3R_*ko-z%vPp2lBZ@RI|om1=G1Zws9&0u^5Six7M9K`XT0^sG8fhB_m+&7 z%z#A+Cj6%#HLi`%&D+?wB_k)uE6{!hP1FCK`2KRT01<>x*0!B1LC^`mx3h9OR9gHH z#-_&w@Q{wP1DlhuHy*#{T9!8>lp|+FwE=6KTLUpLGtR^Q#&v*=aJR^!+Pr{w{JgCk zf=Oy<+7Yn#Gt|3h_)W(Vu)+13yYvpe9M~sR4mb?gq<}n40mLeA=1xwN1`%tdreL zR4uh4Mnsq$9iHit-sC3kSlHEVkH{C31-MrC_6-z7<(PL(VfvVo%s5~Q#N#?WCT9?A zuF;b$nKzPn&Km$QZtjk!t<7pmmqJ^H6S>o1kaWd3sX&^ZJ|7J{4A~d}&{VS3(qZKe zY|v}!lzEJ1FPsv`_S}~Kgcd`tHQExQ8*O8oZepf{C8rRi!=Q7{X`wiuRPt1kPbMd- zTWl_OYG~^En~OV?K=5{@l*s0T7fmIX6fzVY`O#1|E#^-0$uGj-pSlP~01|o)&WI`Y z^Pc}THP8gRJBMa5i_{%1ZdpN~Fc%}?RT{6xOtHS2Xa=EZ*O~5%OVAI1G4ydQW`xrAySicf(Yb$ z+7I#1nz9zRE;9dpU-f~y^*01Lkn}6}>@B>6P<;aM5;j7`yc;$g77f&Z1xey97;kg%wUVW>$$0V7=)CjI4EQT8r; z9iEYLxTapo|1PiI3k~u>J%k<`1L&rA)C!zF>`N==4cmXa{8B^8iuW>Y*eK8=;|)MJN!D-OeVhO*Fb*YBZ6y8GRzWi8prhFuwRT}kO^aOKz;EGRRDE#0)A0kkOs z(jc2w_dt~Q28nXTS+f$7D}5(1;4xWm*mXWxot9buQU@!FRRaisx}8&%lP=^u+s>UF z-*J^g)BR6HP)6nqlyjEYY$W+24=ayghrKrm;2(S|-=9snzizVH znLD*;>%0dxu9R?I?g&2Da!4eGPEh3;W8_5?@7N7r7Z3>RAmKnq zcH+Is$r8!h(9bp)9QM<-%Y2jeck(w_>eG-H!q^GZOpml4Bk7)#Z_8T&nL6nzLbfb5 zqS!DK3DY*=p^rOF-k$s}$|i#!{~ZJ0;@iCGb#D{r1U5sUFu{Y3F21II2Y_bpB>&Rb zGB~K!6y4sGDVg+lT^?jYE1~6MS7J*^&iV~B#kW1xq8X>Cc1W>`)>nZol318OUe5FoH6MC^?D)pa;hr!UX ze;~=yPyE>;SxvFGk1@n~q*#OqX$fI=ky<*PJH0(^(~wdN}VSg)p<{_xKLA`-l8R>AkWL8K+R^f6a4@P zh%nn4kUHNqFJ8ZfLS5FD1mN~j*W}H{M7xv*51LPALF@_USI;H?b(15^t~#l(qr`h> zkc+e?d(!O)e4JXiu~<2)p^rI=(ZnGB9#hy-I8pLbj;0;1O;B}q-f!!+cSsEU+D%%U zthlC$Xm_1Ea9zrNBFRt5Zne1Ro&IUF_YS%ml3WqgT=lo}gYoQYv5%o&);a84HqEl7 zMH4BO?vxhrkPPz_s8N-_5$EH)Hq5I1G?|3P;LWdW#9C40&tnnkv=EoUpo(uLn&Y;Nz6;l@&d+F|H3B7#F}vy`kS9_nABu zASkij2qCfR&BV@6M2*Zikx6`*a))bgQ^1Xo?L#UDzf8^Cfk&f2>Kj1#a^wQIe?pa9 z=>?3hg`wVv-uf`JW-8%o|w; z+-W(K&-bwm@l1KoLu+1(aVu9K$$oT;^cC*HR?{VHiKCdElLB4{r8gVC+)Z%*@*$7L zW+b4?LWJbEDJ0-hC zYhiM(DtmZ`@L1`UD{!HP(d!tC1iwp;*oKDGbNJFqf{-tD{avi3I(PObeoZ5d=Bo%! z`!?^+2lw8W739ljt>wc!Svnlx=zk3sKr_atM+yHD0!uAPWSA5cO)+!ad}jac3dY~FO<3`s*4 zD`QszZ#VXuuiqBqlfkO?^Vx4nA5Ca~UinNE%Ic-m?*FzmLol z$pwjwuuf-9&E53Q5lAFI)K3PYDwmPYhxG*@fDe{bV8hM(rNm;G9K9-JD%-&oTBzX_=fEVN=C=Tj@+o9L^ZSK~@q|8tv_ zyUmN)Y2_k{q~9<Ad@9Tp! zu_$3IDO)>3NG9$*au?VO+rl1K-_|g}SWQfM`o2Tn{WV6U$UnCDM~mFH$McL0OgL|{a9VkkQ?{XX|cbtP$jO+Ja|Dp$yg@2f{F zqT90AdYPfxK_BHt1JUp58dJZ{{deTriXOX$J)G6o=p4QmExXoX>%dpG{8;TXE9ZBL z8_1xHg;BmnU9%G`EBXu5#A<f!x`YU7 zHU$Tn$1rZZ(%$VQB9ODpVd>Bp4eP%tB#{;w3nP5h&oWlZofPF)aI3JuhXDKkmt=`> zOkvUeX1rUwoZ4-Tw^z@(wYpoFqA%sQ>V8W!S*Yeo3sLkWio+K|%LWxl2za!EJF-PI zkz$Nn-EbRMF)vlJL-1Ja)hU-FdN6*}S!(Z#UHXLdPByX-z#aY}AS zaACr06#b>7cyNmkxgy7vMNHn$3dxW00yH2JhSwZX=bIE7Pcn@-|(e5Gz(CNz6L zlwgcnvT^wX>{p98h1*px7ou{E*x???UwMub4(1R_eP|vNSRq{cuMVJ=_hc2Gp-6U<VGmg;+#*h7?l!9-{8JZ}yp{sX&^B+1K4MY2*4;0N;Xk2x-suMlN@!c%_gZGtZ zGLF+iFDq668p+CVAg(Ov!CNYr4-Tq>W8xOijG&H#BLs6e%~8=rE}L}<3&O)_!_o9 zK`Uu|RqJoTe5#Yq!7PI+>zz^pzcQ290Q{!rA~>3V{z4?SWf>qXUgk`-%sw*PviCOG z41g&2dwL3KztN1-F(L#L7J}LP&$`g8cW=bD#>Ov0iJa=+{p5yWw7y=$Op@9cx!mtd zB0>L(CMT-WKN*Ern7?rH!5YoTp>*ZNRikn)zg))$0Ug<$Pl`r;eh$(g^~Wn1Fxh~^ zpD(k}z!WEl%I|7%1S=c797;3o_t!v@M~d)sPY!l_d&rV}7KXohy3eR!1#FFO!N{Y{QR%_v~bVjXZYGEVLZnZd7iwJY8 zxHAZk7@0AV>6emCt1_Oo_?xIoTp3aUnk|Mf8fJ(Q&%fFO5iC#zpj^nW;7I#yJi!n9 zcT<3)AELwGy9ME!lI$xg^J{f$RT5;4CCf5_oGuPO*lIR#y)h$|GN8Ie`_~2Q!D@q3Kw0*v^;Vxh!yUuucIvS zMAM;L-BYuf6v2De$Wp;)uYLya^CN;>yL#?F{OWe#JdovmKB57Uc^IMneER28;d*zN zow6X%9Il_A9Ds7S2H>OOlYV3K_g<>85uJwmt|yC$aG>?kCy10-0kHGlFmaNJiD&5e z?@v;=1Ts0DKLL`t_SHHjDbSa&U`sATRg}~Ig$T-XWtLHRtR-4R7C6jH39tf|4tp`p z;q&vR|2@kH)(^if*Rv8p4gDUaD^xPWpCZvFAQHs|@aMYj4_|kd>2g*doYNC>{Xt}h z%0`t2_F1?-m^-| z${P+%Ofb8bbm@K4oVrtuqV9N2xUKdD1(X=U&^a-MA!9jwLK&6TT7qk7{ByL`jF%r zPc3aLQe2w$be1Zkx*fq0lL~%HV?&p)JG_hC8oY?D2Skyu^Bbt{ zI)jy%X9R}#%l0mbO>&+BOk2wXc&%NEb+Z#V8@d2}7p|tGP@QF&Z*P`V`6fQIuaRBg z-R}X!f2TyBH=NP$`-jjRS27={+TgyKaDdBD&8sw?P1)F(_3)pg!0{}~p7x5L77Ab9 zW-w6ssvS$?=6GopD>hN8D7!4Rxs1;jaYF^dr^{KzgRBh=vBC*EKx>pYS-JNad{|QwO)1l%){fEM6OQA z=wB`*wxaysOuQ_sDaIBVsCKV|ZXC1qni zI&RbOQPUxcSTT_boS9!y6nDev$Z(A<)BX2qHz}*Q1Wsvfk9&VVB|leJ(qCXQgT!1L z&iZ#aHs^O7iTri!o0)Il>Dr6NGTp+jyv8=emh#=h8s{nwZx{0NX le0;r%^7#M#&-Mk85;!box+~b;^Xm9c6GKab+FLHq{}21$PsRWM literal 0 HcmV?d00001 diff --git a/example/src/main/assets/底妆/基础上妆/2按压/方向/pic1.png b/example/src/main/assets/底妆/基础上妆/2按压/方向/pic1.png new file mode 100644 index 0000000000000000000000000000000000000000..3af6c630fcc822a206f72163f6d15ca6a5459da3 GIT binary patch literal 24356 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

Lyf$MQz?1i)RA~hMFG8fDN|jgM-hvAK0JS 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 literal 0 HcmV?d00001 diff --git a/vulkan/AppBase.cpp b/vulkan/AppBase.cpp index dfdec75..5018ff1 100644 --- a/vulkan/AppBase.cpp +++ b/vulkan/AppBase.cpp @@ -22,11 +22,15 @@ void VK_CHECK(VkResult ret) // return path; //} -std::vector AppBase::readFileEx(const std::string& path) +std::vector AppBase::readFileUnsignedChar(const std::string& path, bool example) { std::vector buffer; #ifdef _WIN32 std::string enginePath = "app/src/main/assets/" + path; + if (example) + { + enginePath = "example/src/main/assets/" + path; + } std::ifstream file{ enginePath, std::ios::ate | std::ios::binary }; if (!file.is_open()) diff --git a/vulkan/AppBase.h b/vulkan/AppBase.h index 11126bc..0ab5c52 100644 --- a/vulkan/AppBase.h +++ b/vulkan/AppBase.h @@ -65,7 +65,7 @@ class AppBase { public: std::vector readFile(const std::string& enginePath); - std::vector readFileEx(const std::string& enginePath); + std::vector readFileUnsignedChar(const std::string& enginePath, bool example); //std::string getPath(const std::string path); VkShaderModule createShaderModule(VkDevice& device, const std::vector& code); const std::vector validationLayers = {"VK_LAYER_KHRONOS_validation"}; diff --git a/vulkan/Application.cpp b/vulkan/Application.cpp index 4749ecf..39e3400 100644 --- a/vulkan/Application.cpp +++ b/vulkan/Application.cpp @@ -20,7 +20,7 @@ void Application::initWindow() glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); - window = glfwCreateWindow(480, 480, "Vulkan", nullptr, nullptr); + window = glfwCreateWindow(480*2, 480*2, "Vulkan", nullptr, nullptr); #else #endif @@ -68,6 +68,7 @@ void Application::initVulkan() createCommandPool(); // 创建命令池 createCommandBuffer(); // 创建命令缓冲区 createSyncObjects(); // 创建同步对象 + _lastDrawFrameTime = getCurrentTimeMillis(); inited = true; } @@ -560,6 +561,7 @@ void Application::drawFrame() // 8. 前进到下一帧 currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT; + _lastDrawFrameTime = } void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator) { @@ -628,7 +630,17 @@ uint32_t Application::findMemoryType(VkPhysicalDevice physicalDevice, uint32_t t Texture Application::loadTexture(std::string path, Texture& tex, bool srgb) { - std::vector data = readFileEx(path); + std::vector data = readFileUnsignedChar(path, false); + std::vector image; + unsigned w, h; + unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8); + processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb); + return tex; +} + +Texture Application::loadTextureExample(std::string path, Texture& tex, bool srgb) +{ + std::vector data = readFileUnsignedChar(path, true); std::vector image; unsigned w, h; unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8); diff --git a/vulkan/Application.h b/vulkan/Application.h index 30ff4be..5f28180 100644 --- a/vulkan/Application.h +++ b/vulkan/Application.h @@ -75,6 +75,7 @@ protected: protected: Texture loadTexture(std::string path, Texture& tex, bool srgb); + Texture loadTextureExample(std::string path, Texture& tex, bool srgb); uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter, VkMemoryPropertyFlags properties); @@ -85,4 +86,5 @@ protected: void transitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout); void destroy_texture(Texture texture); std::mutex mtx; + long long _lastDrawFrameTime; }; \ No newline at end of file diff --git a/vulkan/FaceApp.cpp b/vulkan/FaceApp.cpp index 34cd891..7374b9d 100644 --- a/vulkan/FaceApp.cpp +++ b/vulkan/FaceApp.cpp @@ -4,6 +4,7 @@ + FaceApp* FaceApp::faceIns = nullptr; FaceApp::FaceApp(/* args */) @@ -372,11 +373,11 @@ void FaceApp::setup_descriptor_pool() { VkDescriptorPoolSize descriptor_pool_size{}; descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptor_pool_size.descriptorCount = 6; + descriptor_pool_size.descriptorCount = 2; VkDescriptorPoolSize descriptor_pool_image_size{}; descriptor_pool_image_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptor_pool_image_size.descriptorCount = 6; + descriptor_pool_image_size.descriptorCount = kMaxTexture + 4; std::vector pool_sizes; @@ -388,7 +389,7 @@ void FaceApp::setup_descriptor_pool() descriptor_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; descriptor_pool_info.poolSizeCount = pool_sizes.size(); descriptor_pool_info.pPoolSizes = pool_sizes.data(); - descriptor_pool_info.maxSets = 6; + descriptor_pool_info.maxSets = kMaxTexture + 4 + 2; VK_CHECK(vkCreateDescriptorPool(device, &descriptor_pool_info, nullptr, &descriptor_pool)); } @@ -447,66 +448,71 @@ void FaceApp::setup_descriptor_set_layout() void FaceApp::setup_descriptor_set() { - + m_descriptor_sets.resize(kMaxTexture); + std::vector layouts(kMaxTexture, m_descriptorSetLayout); VkDescriptorSetAllocateInfo alloc_info{}; alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; alloc_info.descriptorPool = descriptor_pool; - alloc_info.pSetLayouts = &m_descriptorSetLayout; - alloc_info.descriptorSetCount = 1; + alloc_info.pSetLayouts = layouts.data(); + alloc_info.descriptorSetCount = m_descriptor_sets.size(); + VK_CHECK(vkAllocateDescriptorSets(device, &alloc_info, m_descriptor_sets.data())); - VK_CHECK(vkAllocateDescriptorSets(device, &alloc_info, &m_descriptor_set)); - - VkDescriptorBufferInfo buffer_descriptor{}; - buffer_descriptor.buffer = uniform_buffer_vs; - buffer_descriptor.range = VK_WHOLE_SIZE; - buffer_descriptor.offset = 0; - - - VkDescriptorImageInfo image_descriptor; - image_descriptor.imageView = tex_demo0.view; - image_descriptor.sampler = tex_demo0.sampler; - image_descriptor.imageLayout = tex_demo0.image_layout; - - // 第二个纹理描述符 - 假设你的第二个纹理变量名为 tex_demo1 - VkDescriptorImageInfo image_descriptor1; - image_descriptor1.imageView = tex_demo0_ex.view; - image_descriptor1.sampler = tex_demo0_ex.sampler; - image_descriptor1.imageLayout = tex_demo0_ex.image_layout; - - VkWriteDescriptorSet write_descriptor_set_uniform{}; - write_descriptor_set_uniform.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor_set_uniform.dstSet = m_descriptor_set; - write_descriptor_set_uniform.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - write_descriptor_set_uniform.dstBinding = 0; - write_descriptor_set_uniform.pBufferInfo = &buffer_descriptor; - write_descriptor_set_uniform.descriptorCount = 1; - - - VkWriteDescriptorSet write_descriptor_set_image{}; - write_descriptor_set_image.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor_set_image.dstSet = m_descriptor_set; - write_descriptor_set_image.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - write_descriptor_set_image.dstBinding = 1; - write_descriptor_set_image.pImageInfo = &image_descriptor; - write_descriptor_set_image.descriptorCount = 1; - - // 添加第二个纹理的写入描述符 - VkWriteDescriptorSet write_descriptor_set_image1{}; - write_descriptor_set_image1.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor_set_image1.dstSet = m_descriptor_set; - write_descriptor_set_image1.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - write_descriptor_set_image1.dstBinding = 2; // 绑定到位置2 - write_descriptor_set_image1.pImageInfo = &image_descriptor1; - write_descriptor_set_image1.descriptorCount = 1; - - std::vector write_descriptor_sets = + for (int i = 0; i < kMaxTexture; ++i) { - write_descriptor_set_uniform, - write_descriptor_set_image, - write_descriptor_set_image1, // 添加第二个纹理 - }; + VkDescriptorBufferInfo buffer_descriptor{}; + buffer_descriptor.buffer = uniform_buffer_vs; + buffer_descriptor.range = VK_WHOLE_SIZE; + buffer_descriptor.offset = 0; - vkUpdateDescriptorSets(device, static_cast(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL); + + VkDescriptorImageInfo image_descriptor; + image_descriptor.imageView = m_texs[i].view; + image_descriptor.sampler = m_texs[i].sampler; + image_descriptor.imageLayout = m_texs[i].image_layout; + + // 第二个纹理描述符 - 假设你的第二个纹理变量名为 tex_demo1 + VkDescriptorImageInfo image_descriptor1; + image_descriptor1.imageView = m_texs_ex[i].view; + image_descriptor1.sampler = m_texs_ex[i].sampler; + image_descriptor1.imageLayout = m_texs_ex[i].image_layout; + + VkWriteDescriptorSet write_descriptor_set_uniform{}; + write_descriptor_set_uniform.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set_uniform.dstSet = m_descriptor_sets[i]; + write_descriptor_set_uniform.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + write_descriptor_set_uniform.dstBinding = 0; + write_descriptor_set_uniform.pBufferInfo = &buffer_descriptor; + write_descriptor_set_uniform.descriptorCount = 1; + + + VkWriteDescriptorSet write_descriptor_set_image{}; + write_descriptor_set_image.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set_image.dstSet = m_descriptor_sets[i]; + write_descriptor_set_image.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + write_descriptor_set_image.dstBinding = 1; + write_descriptor_set_image.pImageInfo = &image_descriptor; + write_descriptor_set_image.descriptorCount = 1; + + // 添加第二个纹理的写入描述符 + VkWriteDescriptorSet write_descriptor_set_image1{}; + write_descriptor_set_image1.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor_set_image1.dstSet = m_descriptor_sets[i]; + write_descriptor_set_image1.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + write_descriptor_set_image1.dstBinding = 2; // 绑定到位置2 + write_descriptor_set_image1.pImageInfo = &image_descriptor1; + write_descriptor_set_image1.descriptorCount = 1; + + std::vector write_descriptor_sets = + { + write_descriptor_set_uniform, + write_descriptor_set_image, + write_descriptor_set_image1, // 添加第二个纹理 + }; + + vkUpdateDescriptorSets(device, static_cast(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL); + } + + } void FaceApp::render(VkCommandBuffer commandBuffer) @@ -521,10 +527,10 @@ void FaceApp::render(VkCommandBuffer commandBuffer) vkCmdPushConstants(commandBuffer, m_pipelineLayout_bg, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float), &myFloatValue); - vkCmdDraw(commandBuffer, 6, 1, 0, 0); + //vkCmdDraw(commandBuffer, 6, 1, 0, 0); - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descriptor_set, 0, NULL); + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descriptor_sets[_curTexIndex], 0, NULL); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline); vkCmdPushConstants(commandBuffer, m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float), &myFloatValue); @@ -575,8 +581,13 @@ void FaceApp::initVulkan() Application::initVulkan(); createVmaAllocator(); LoadOBJ("face_picture_3dmax.obj", obj_vertices, obj_indices); - loadTexture("demo0.png", tex_demo0, true); - loadTexture("demo0_ex.png", tex_demo0_ex, true); + m_texs.resize(kMaxTexture); + m_texs_ex.resize(kMaxTexture); + for (int i = 0; i < kMaxTexture; ++i) + { + loadTexture("demo0.png", m_texs[i], true); + loadTexture("demo0_ex.png", m_texs_ex[i], true); + } loadTexture("out.png", tex_bg, false); createVertexBuffer(); @@ -604,7 +615,7 @@ void FaceApp::initVulkan() floatArray.push_back(std::stof(token)); } - ReceiveFacePoint(floatArray.data(), floatArray.size() / 3, 480, 480); + //ReceiveFacePoint(floatArray.data(), floatArray.size() / 3, 480, 480); #endif } @@ -972,4 +983,28 @@ void FaceApp::cleanup() //vmaDestroyBuffer(allocator, m_stagingBuffer, m_stagingBufferAllocation); vkDestroyDescriptorSetLayout(device, m_descriptorSetLayout, nullptr); Application::cleanup(); +} + + +void FaceApp::SetInitArg(const char* arg) +{ + _initArg = json::parse(arg); + +} + +void FaceApp::changeMotion(Motion& motion) +{ + if (_curMotion.getMotionId() == motion.getMotionId()) + { + return; + } + _curMotion = _initArg.motion; + for (int i = 0; i < _curMotion.png_num; ++i) + { + string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type; + string path_name = path + "/" + _curMotion.png_name + std::to_string(i) + ".png"; + loadTexture(path_name, m_texs[i], true); + string path_name_ex = path + "/" + _curMotion.png_name + std::to_string(i) + "_thick.png"; + loadTexture(path_name, m_texs[i], true); + } } \ No newline at end of file diff --git a/vulkan/FaceApp.h b/vulkan/FaceApp.h index 927b38e..572f625 100644 --- a/vulkan/FaceApp.h +++ b/vulkan/FaceApp.h @@ -7,7 +7,30 @@ #include #include #include +#include "nlohmann/json.hpp" +using namespace std; +using json = nlohmann::json; +struct Motion { + string type; + string technique; + string step; + string show_type; + string png_name; + int png_num; + string getMotionId() { + return type + technique + step + show_type; + } + NLOHMANN_DEFINE_TYPE_INTRUSIVE(Motion, type, technique, step, show_type, png_name, png_num) +}; + +struct InitArg +{ + int action_fps; + float zoom; + Motion motion; + NLOHMANN_DEFINE_TYPE_INTRUSIVE(InitArg, action_fps, zoom) +}; struct PushConstants { @@ -79,7 +102,10 @@ private: VkPipeline m_graphicsPipeline = VK_NULL_HANDLE; VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE; - VkDescriptorSet m_descriptor_set = VK_NULL_HANDLE; + vector m_descriptor_sets; + const int kMaxTexture = 20; + vector m_texs; + vector m_texs_ex; std::vector obj_vertices; @@ -95,8 +121,7 @@ private: void* uniform_buffer_mapped = nullptr; // 映射的内存指针 void createUniformBuffer(); - Texture tex_demo0 = {0}; - Texture tex_demo0_ex = { 0 }; + bool faceAppInited = false; float myFloatValue = 1.5f; @@ -110,6 +135,13 @@ private: VkPipelineLayout m_pipelineLayout_bg = VK_NULL_HANDLE; VkDescriptorSetLayout m_descriptorSetLayout_bg = VK_NULL_HANDLE; VkDescriptorSet m_descriptor_set_bg = VK_NULL_HANDLE; + + void changeMotion(Motion& motion); +public: + InitArg _initArg; + Motion _curMotion; + int _curTexIndex = 0; + void SetInitArg(const char* arg); }; #endif diff --git a/vulkan/main.cpp b/vulkan/main.cpp index 4d098bc..bbd9be6 100644 --- a/vulkan/main.cpp +++ b/vulkan/main.cpp @@ -1,10 +1,36 @@ - + #include "FaceApp.h" int main() { + InitArg init_arg; + Motion motion; + motion.type = "底妆"; + motion.technique = "基础上妆"; + motion.step = "2按压"; + motion.show_type = "方向"; + motion.png_name = "pic"; + motion.png_num = 3; + + init_arg.motion = motion; + + //motion.type = "底妆"; + //motion.technique = "基础上妆"; + //motion.step = "2按压"; + //motion.show_type = "区域"; + //motion.png_name = "pic"; + //motion.png_num = 1; + + //init_arg.motions.push_back(motion); + + init_arg.action_fps = 3; + init_arg.zoom = 1.5f; + + string json_str = json(init_arg).dump(); + FaceApp app; + app.SetInitArg(json_str.c_str()); app.initVulkan(); try { app.mainLoop(); diff --git a/vulkan/nlohmann/adl_serializer.hpp b/vulkan/nlohmann/adl_serializer.hpp new file mode 100644 index 0000000..56a606c --- /dev/null +++ b/vulkan/nlohmann/adl_serializer.hpp @@ -0,0 +1,55 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN + +/// @sa https://json.nlohmann.me/api/adl_serializer/ +template +struct adl_serializer +{ + /// @brief convert a JSON value to any value type + /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/ + template + static auto from_json(BasicJsonType && j, TargetType& val) noexcept( + noexcept(::nlohmann::from_json(std::forward(j), val))) + -> decltype(::nlohmann::from_json(std::forward(j), val), void()) + { + ::nlohmann::from_json(std::forward(j), val); + } + + /// @brief convert a JSON value to any value type + /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/ + template + static auto from_json(BasicJsonType && j) noexcept( + noexcept(::nlohmann::from_json(std::forward(j), detail::identity_tag {}))) + -> decltype(::nlohmann::from_json(std::forward(j), detail::identity_tag {})) + { + return ::nlohmann::from_json(std::forward(j), detail::identity_tag {}); + } + + /// @brief convert any value type to a JSON value + /// @sa https://json.nlohmann.me/api/adl_serializer/to_json/ + template + static auto to_json(BasicJsonType& j, TargetType && val) noexcept( + noexcept(::nlohmann::to_json(j, std::forward(val)))) + -> decltype(::nlohmann::to_json(j, std::forward(val)), void()) + { + ::nlohmann::to_json(j, std::forward(val)); + } +}; + +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/byte_container_with_subtype.hpp b/vulkan/nlohmann/byte_container_with_subtype.hpp new file mode 100644 index 0000000..91382cd --- /dev/null +++ b/vulkan/nlohmann/byte_container_with_subtype.hpp @@ -0,0 +1,103 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // uint8_t, uint64_t +#include // tie +#include // move + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN + +/// @brief an internal type for a backed binary type +/// @sa https://json.nlohmann.me/api/byte_container_with_subtype/ +template +class byte_container_with_subtype : public BinaryType +{ + public: + using container_type = BinaryType; + using subtype_type = std::uint64_t; + + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ + byte_container_with_subtype() noexcept(noexcept(container_type())) + : container_type() + {} + + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ + byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b))) + : container_type(b) + {} + + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ + byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) + : container_type(std::move(b)) + {} + + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ + byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b))) + : container_type(b) + , m_subtype(subtype_) + , m_has_subtype(true) + {} + + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ + byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b)))) + : container_type(std::move(b)) + , m_subtype(subtype_) + , m_has_subtype(true) + {} + + bool operator==(const byte_container_with_subtype& rhs) const + { + return std::tie(static_cast(*this), m_subtype, m_has_subtype) == + std::tie(static_cast(rhs), rhs.m_subtype, rhs.m_has_subtype); + } + + bool operator!=(const byte_container_with_subtype& rhs) const + { + return !(rhs == *this); + } + + /// @brief sets the binary subtype + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/ + void set_subtype(subtype_type subtype_) noexcept + { + m_subtype = subtype_; + m_has_subtype = true; + } + + /// @brief return the binary subtype + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/subtype/ + constexpr subtype_type subtype() const noexcept + { + return m_has_subtype ? m_subtype : static_cast(-1); + } + + /// @brief return whether the value has a subtype + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/ + constexpr bool has_subtype() const noexcept + { + return m_has_subtype; + } + + /// @brief clears the binary subtype + /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/ + void clear_subtype() noexcept + { + m_subtype = 0; + m_has_subtype = false; + } + + private: + subtype_type m_subtype = 0; + bool m_has_subtype = false; +}; + +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/abi_macros.hpp b/vulkan/nlohmann/detail/abi_macros.hpp new file mode 100644 index 0000000..f48b9eb --- /dev/null +++ b/vulkan/nlohmann/detail/abi_macros.hpp @@ -0,0 +1,100 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +// This file contains all macro definitions affecting or depending on the ABI + +#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK + #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) + #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 3 + #warning "Already included a different version of the library!" + #endif + #endif +#endif + +#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_PATCH 3 // NOLINT(modernize-macro-to-enum) + +#ifndef JSON_DIAGNOSTICS + #define JSON_DIAGNOSTICS 0 +#endif + +#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 +#endif + +#if JSON_DIAGNOSTICS + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag +#else + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS +#endif + +#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp +#else + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION + #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 +#endif + +// Construct the namespace ABI tags component +#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b +#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \ + NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) + +#define NLOHMANN_JSON_ABI_TAGS \ + NLOHMANN_JSON_ABI_TAGS_CONCAT( \ + NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ + NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON) + +// Construct the namespace version component +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ + _v ## major ## _ ## minor ## _ ## patch +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) + +#if NLOHMANN_JSON_NAMESPACE_NO_VERSION +#define NLOHMANN_JSON_NAMESPACE_VERSION +#else +#define NLOHMANN_JSON_NAMESPACE_VERSION \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ + NLOHMANN_JSON_VERSION_MINOR, \ + NLOHMANN_JSON_VERSION_PATCH) +#endif + +// Combine namespace components +#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b +#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ + NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) + +#ifndef NLOHMANN_JSON_NAMESPACE +#define NLOHMANN_JSON_NAMESPACE \ + nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN +#define NLOHMANN_JSON_NAMESPACE_BEGIN \ + namespace nlohmann \ + { \ + inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ + NLOHMANN_JSON_ABI_TAGS, \ + NLOHMANN_JSON_NAMESPACE_VERSION) \ + { +#endif + +#ifndef NLOHMANN_JSON_NAMESPACE_END +#define NLOHMANN_JSON_NAMESPACE_END \ + } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ + } // namespace nlohmann +#endif diff --git a/vulkan/nlohmann/detail/conversions/from_json.hpp b/vulkan/nlohmann/detail/conversions/from_json.hpp new file mode 100644 index 0000000..aa2f0cb --- /dev/null +++ b/vulkan/nlohmann/detail/conversions/from_json.hpp @@ -0,0 +1,497 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // transform +#include // array +#include // forward_list +#include // inserter, front_inserter, end +#include // map +#include // string +#include // tuple, make_tuple +#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible +#include // unordered_map +#include // pair, declval +#include // valarray + +#include +#include +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_null())) + { + JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j)); + } + n = nullptr; +} + +// overloads for basic_json template parameters +template < typename BasicJsonType, typename ArithmeticType, + enable_if_t < std::is_arithmetic::value&& + !std::is_same::value, + int > = 0 > +void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) +{ + switch (static_cast(j)) + { + case value_t::number_unsigned: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::number_integer: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::number_float: + { + val = static_cast(*j.template get_ptr()); + break; + } + + case value_t::null: + case value_t::object: + case value_t::array: + case value_t::string: + case value_t::boolean: + case value_t::binary: + case value_t::discarded: + default: + JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j)); + } +} + +template +inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_boolean())) + { + JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j)); + } + b = *j.template get_ptr(); +} + +template +inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_string())) + { + JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j)); + } + s = *j.template get_ptr(); +} + +template < + typename BasicJsonType, typename StringType, + enable_if_t < + std::is_assignable::value + && is_detected_exact::value + && !std::is_same::value + && !is_json_ref::value, int > = 0 > +inline void from_json(const BasicJsonType& j, StringType& s) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_string())) + { + JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j)); + } + + s = *j.template get_ptr(); +} + +template +inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val) +{ + get_arithmetic_value(j, val); +} + +template +inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val) +{ + get_arithmetic_value(j, val); +} + +template +inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val) +{ + get_arithmetic_value(j, val); +} + +#if !JSON_DISABLE_ENUM_SERIALIZATION +template::value, int> = 0> +inline void from_json(const BasicJsonType& j, EnumType& e) +{ + typename std::underlying_type::type val; + get_arithmetic_value(j, val); + e = static_cast(val); +} +#endif // JSON_DISABLE_ENUM_SERIALIZATION + +// forward_list doesn't have an insert method +template::value, int> = 0> +inline void from_json(const BasicJsonType& j, std::forward_list& l) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + l.clear(); + std::transform(j.rbegin(), j.rend(), + std::front_inserter(l), [](const BasicJsonType & i) + { + return i.template get(); + }); +} + +// valarray doesn't have an insert method +template::value, int> = 0> +inline void from_json(const BasicJsonType& j, std::valarray& l) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + l.resize(j.size()); + std::transform(j.begin(), j.end(), std::begin(l), + [](const BasicJsonType & elem) + { + return elem.template get(); + }); +} + +template +auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) +-> decltype(j.template get(), void()) +{ + for (std::size_t i = 0; i < N; ++i) + { + arr[i] = j.at(i).template get(); + } +} + +template +inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/) +{ + arr = *j.template get_ptr(); +} + +template +auto from_json_array_impl(const BasicJsonType& j, std::array& arr, + priority_tag<2> /*unused*/) +-> decltype(j.template get(), void()) +{ + for (std::size_t i = 0; i < N; ++i) + { + arr[i] = j.at(i).template get(); + } +} + +template::value, + int> = 0> +auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/) +-> decltype( + arr.reserve(std::declval()), + j.template get(), + void()) +{ + using std::end; + + ConstructibleArrayType ret; + ret.reserve(j.size()); + std::transform(j.begin(), j.end(), + std::inserter(ret, end(ret)), [](const BasicJsonType & i) + { + // get() returns *this, this won't call a from_json + // method when value_type is BasicJsonType + return i.template get(); + }); + arr = std::move(ret); +} + +template::value, + int> = 0> +inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, + priority_tag<0> /*unused*/) +{ + using std::end; + + ConstructibleArrayType ret; + std::transform( + j.begin(), j.end(), std::inserter(ret, end(ret)), + [](const BasicJsonType & i) + { + // get() returns *this, this won't call a from_json + // method when value_type is BasicJsonType + return i.template get(); + }); + arr = std::move(ret); +} + +template < typename BasicJsonType, typename ConstructibleArrayType, + enable_if_t < + is_constructible_array_type::value&& + !is_constructible_object_type::value&& + !is_constructible_string_type::value&& + !std::is_same::value&& + !is_basic_json::value, + int > = 0 > +auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr) +-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}), +j.template get(), +void()) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + + from_json_array_impl(j, arr, priority_tag<3> {}); +} + +template < typename BasicJsonType, typename T, std::size_t... Idx > +std::array from_json_inplace_array_impl(BasicJsonType&& j, + identity_tag> /*unused*/, index_sequence /*unused*/) +{ + return { { std::forward(j).at(Idx).template get()... } }; +} + +template < typename BasicJsonType, typename T, std::size_t N > +auto from_json(BasicJsonType&& j, identity_tag> tag) +-> decltype(from_json_inplace_array_impl(std::forward(j), tag, make_index_sequence {})) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + + return from_json_inplace_array_impl(std::forward(j), tag, make_index_sequence {}); +} + +template +inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_binary())) + { + JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j)); + } + + bin = *j.template get_ptr(); +} + +template::value, int> = 0> +inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_object())) + { + JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j)); + } + + ConstructibleObjectType ret; + const auto* inner_object = j.template get_ptr(); + using value_type = typename ConstructibleObjectType::value_type; + std::transform( + inner_object->begin(), inner_object->end(), + std::inserter(ret, ret.begin()), + [](typename BasicJsonType::object_t::value_type const & p) + { + return value_type(p.first, p.second.template get()); + }); + obj = std::move(ret); +} + +// overload for arithmetic types, not chosen for basic_json template arguments +// (BooleanType, etc..); note: Is it really necessary to provide explicit +// overloads for boolean_t etc. in case of a custom BooleanType which is not +// an arithmetic type? +template < typename BasicJsonType, typename ArithmeticType, + enable_if_t < + std::is_arithmetic::value&& + !std::is_same::value&& + !std::is_same::value&& + !std::is_same::value&& + !std::is_same::value, + int > = 0 > +inline void from_json(const BasicJsonType& j, ArithmeticType& val) +{ + switch (static_cast(j)) + { + case value_t::number_unsigned: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::number_integer: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::number_float: + { + val = static_cast(*j.template get_ptr()); + break; + } + case value_t::boolean: + { + val = static_cast(*j.template get_ptr()); + break; + } + + case value_t::null: + case value_t::object: + case value_t::array: + case value_t::string: + case value_t::binary: + case value_t::discarded: + default: + JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j)); + } +} + +template +std::tuple from_json_tuple_impl_base(BasicJsonType&& j, index_sequence /*unused*/) +{ + return std::make_tuple(std::forward(j).at(Idx).template get()...); +} + +template < typename BasicJsonType, class A1, class A2 > +std::pair from_json_tuple_impl(BasicJsonType&& j, identity_tag> /*unused*/, priority_tag<0> /*unused*/) +{ + return {std::forward(j).at(0).template get(), + std::forward(j).at(1).template get()}; +} + +template +inline void from_json_tuple_impl(BasicJsonType&& j, std::pair& p, priority_tag<1> /*unused*/) +{ + p = from_json_tuple_impl(std::forward(j), identity_tag> {}, priority_tag<0> {}); +} + +template +std::tuple from_json_tuple_impl(BasicJsonType&& j, identity_tag> /*unused*/, priority_tag<2> /*unused*/) +{ + return from_json_tuple_impl_base(std::forward(j), index_sequence_for {}); +} + +template +inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple& t, priority_tag<3> /*unused*/) +{ + t = from_json_tuple_impl_base(std::forward(j), index_sequence_for {}); +} + +template +auto from_json(BasicJsonType&& j, TupleRelated&& t) +-> decltype(from_json_tuple_impl(std::forward(j), std::forward(t), priority_tag<3> {})) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + + return from_json_tuple_impl(std::forward(j), std::forward(t), priority_tag<3> {}); +} + +template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator, + typename = enable_if_t < !std::is_constructible < + typename BasicJsonType::string_t, Key >::value >> +inline void from_json(const BasicJsonType& j, std::map& m) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + m.clear(); + for (const auto& p : j) + { + if (JSON_HEDLEY_UNLIKELY(!p.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j)); + } + m.emplace(p.at(0).template get(), p.at(1).template get()); + } +} + +template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator, + typename = enable_if_t < !std::is_constructible < + typename BasicJsonType::string_t, Key >::value >> +inline void from_json(const BasicJsonType& j, std::unordered_map& m) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); + } + m.clear(); + for (const auto& p : j) + { + if (JSON_HEDLEY_UNLIKELY(!p.is_array())) + { + JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j)); + } + m.emplace(p.at(0).template get(), p.at(1).template get()); + } +} + +#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM +template +inline void from_json(const BasicJsonType& j, std_fs::path& p) +{ + if (JSON_HEDLEY_UNLIKELY(!j.is_string())) + { + JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j)); + } + p = *j.template get_ptr(); +} +#endif + +struct from_json_fn +{ + template + auto operator()(const BasicJsonType& j, T&& val) const + noexcept(noexcept(from_json(j, std::forward(val)))) + -> decltype(from_json(j, std::forward(val))) + { + return from_json(j, std::forward(val)); + } +}; + +} // namespace detail + +#ifndef JSON_HAS_CPP_17 +/// namespace to hold default `from_json` function +/// to see why this is required: +/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html +namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces) +{ +#endif +JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers) + detail::static_const::value; +#ifndef JSON_HAS_CPP_17 +} // namespace +#endif + +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/conversions/to_chars.hpp b/vulkan/nlohmann/detail/conversions/to_chars.hpp new file mode 100644 index 0000000..e10741c --- /dev/null +++ b/vulkan/nlohmann/detail/conversions/to_chars.hpp @@ -0,0 +1,1118 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2009 Florian Loitsch +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // array +#include // signbit, isfinite +#include // intN_t, uintN_t +#include // memcpy, memmove +#include // numeric_limits +#include // conditional + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/*! +@brief implements the Grisu2 algorithm for binary to decimal floating-point +conversion. + +This implementation is a slightly modified version of the reference +implementation which may be obtained from +http://florian.loitsch.com/publications (bench.tar.gz). + +The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch. + +For a detailed description of the algorithm see: + +[1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with + Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming + Language Design and Implementation, PLDI 2010 +[2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately", + Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language + Design and Implementation, PLDI 1996 +*/ +namespace dtoa_impl +{ + +template +Target reinterpret_bits(const Source source) +{ + static_assert(sizeof(Target) == sizeof(Source), "size mismatch"); + + Target target; + std::memcpy(&target, &source, sizeof(Source)); + return target; +} + +struct diyfp // f * 2^e +{ + static constexpr int kPrecision = 64; // = q + + std::uint64_t f = 0; + int e = 0; + + constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {} + + /*! + @brief returns x - y + @pre x.e == y.e and x.f >= y.f + */ + static diyfp sub(const diyfp& x, const diyfp& y) noexcept + { + JSON_ASSERT(x.e == y.e); + JSON_ASSERT(x.f >= y.f); + + return {x.f - y.f, x.e}; + } + + /*! + @brief returns x * y + @note The result is rounded. (Only the upper q bits are returned.) + */ + static diyfp mul(const diyfp& x, const diyfp& y) noexcept + { + static_assert(kPrecision == 64, "internal error"); + + // Computes: + // f = round((x.f * y.f) / 2^q) + // e = x.e + y.e + q + + // Emulate the 64-bit * 64-bit multiplication: + // + // p = u * v + // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi) + // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi ) + // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 ) + // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 ) + // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3) + // = (p0_lo ) + 2^32 (Q ) + 2^64 (H ) + // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H ) + // + // (Since Q might be larger than 2^32 - 1) + // + // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H) + // + // (Q_hi + H does not overflow a 64-bit int) + // + // = p_lo + 2^64 p_hi + + const std::uint64_t u_lo = x.f & 0xFFFFFFFFu; + const std::uint64_t u_hi = x.f >> 32u; + const std::uint64_t v_lo = y.f & 0xFFFFFFFFu; + const std::uint64_t v_hi = y.f >> 32u; + + const std::uint64_t p0 = u_lo * v_lo; + const std::uint64_t p1 = u_lo * v_hi; + const std::uint64_t p2 = u_hi * v_lo; + const std::uint64_t p3 = u_hi * v_hi; + + const std::uint64_t p0_hi = p0 >> 32u; + const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu; + const std::uint64_t p1_hi = p1 >> 32u; + const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu; + const std::uint64_t p2_hi = p2 >> 32u; + + std::uint64_t Q = p0_hi + p1_lo + p2_lo; + + // The full product might now be computed as + // + // p_hi = p3 + p2_hi + p1_hi + (Q >> 32) + // p_lo = p0_lo + (Q << 32) + // + // But in this particular case here, the full p_lo is not required. + // Effectively we only need to add the highest bit in p_lo to p_hi (and + // Q_hi + 1 does not overflow). + + Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up + + const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u); + + return {h, x.e + y.e + 64}; + } + + /*! + @brief normalize x such that the significand is >= 2^(q-1) + @pre x.f != 0 + */ + static diyfp normalize(diyfp x) noexcept + { + JSON_ASSERT(x.f != 0); + + while ((x.f >> 63u) == 0) + { + x.f <<= 1u; + x.e--; + } + + return x; + } + + /*! + @brief normalize x such that the result has the exponent E + @pre e >= x.e and the upper e - x.e bits of x.f must be zero. + */ + static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept + { + const int delta = x.e - target_exponent; + + JSON_ASSERT(delta >= 0); + JSON_ASSERT(((x.f << delta) >> delta) == x.f); + + return {x.f << delta, target_exponent}; + } +}; + +struct boundaries +{ + diyfp w; + diyfp minus; + diyfp plus; +}; + +/*! +Compute the (normalized) diyfp representing the input number 'value' and its +boundaries. + +@pre value must be finite and positive +*/ +template +boundaries compute_boundaries(FloatType value) +{ + JSON_ASSERT(std::isfinite(value)); + JSON_ASSERT(value > 0); + + // Convert the IEEE representation into a diyfp. + // + // If v is denormal: + // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1)) + // If v is normalized: + // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1)) + + static_assert(std::numeric_limits::is_iec559, + "internal error: dtoa_short requires an IEEE-754 floating-point implementation"); + + constexpr int kPrecision = std::numeric_limits::digits; // = p (includes the hidden bit) + constexpr int kBias = std::numeric_limits::max_exponent - 1 + (kPrecision - 1); + constexpr int kMinExp = 1 - kBias; + constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1) + + using bits_type = typename std::conditional::type; + + const auto bits = static_cast(reinterpret_bits(value)); + const std::uint64_t E = bits >> (kPrecision - 1); + const std::uint64_t F = bits & (kHiddenBit - 1); + + const bool is_denormal = E == 0; + const diyfp v = is_denormal + ? diyfp(F, kMinExp) + : diyfp(F + kHiddenBit, static_cast(E) - kBias); + + // Compute the boundaries m- and m+ of the floating-point value + // v = f * 2^e. + // + // Determine v- and v+, the floating-point predecessor and successor if v, + // respectively. + // + // v- = v - 2^e if f != 2^(p-1) or e == e_min (A) + // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B) + // + // v+ = v + 2^e + // + // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_ + // between m- and m+ round to v, regardless of how the input rounding + // algorithm breaks ties. + // + // ---+-------------+-------------+-------------+-------------+--- (A) + // v- m- v m+ v+ + // + // -----------------+------+------+-------------+-------------+--- (B) + // v- m- v m+ v+ + + const bool lower_boundary_is_closer = F == 0 && E > 1; + const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1); + const diyfp m_minus = lower_boundary_is_closer + ? diyfp(4 * v.f - 1, v.e - 2) // (B) + : diyfp(2 * v.f - 1, v.e - 1); // (A) + + // Determine the normalized w+ = m+. + const diyfp w_plus = diyfp::normalize(m_plus); + + // Determine w- = m- such that e_(w-) = e_(w+). + const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e); + + return {diyfp::normalize(v), w_minus, w_plus}; +} + +// Given normalized diyfp w, Grisu needs to find a (normalized) cached +// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies +// within a certain range [alpha, gamma] (Definition 3.2 from [1]) +// +// alpha <= e = e_c + e_w + q <= gamma +// +// or +// +// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q +// <= f_c * f_w * 2^gamma +// +// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies +// +// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma +// +// or +// +// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma) +// +// The choice of (alpha,gamma) determines the size of the table and the form of +// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well +// in practice: +// +// The idea is to cut the number c * w = f * 2^e into two parts, which can be +// processed independently: An integral part p1, and a fractional part p2: +// +// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e +// = (f div 2^-e) + (f mod 2^-e) * 2^e +// = p1 + p2 * 2^e +// +// The conversion of p1 into decimal form requires a series of divisions and +// modulos by (a power of) 10. These operations are faster for 32-bit than for +// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be +// achieved by choosing +// +// -e >= 32 or e <= -32 := gamma +// +// In order to convert the fractional part +// +// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ... +// +// into decimal form, the fraction is repeatedly multiplied by 10 and the digits +// d[-i] are extracted in order: +// +// (10 * p2) div 2^-e = d[-1] +// (10 * p2) mod 2^-e = d[-2] / 10^1 + ... +// +// The multiplication by 10 must not overflow. It is sufficient to choose +// +// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64. +// +// Since p2 = f mod 2^-e < 2^-e, +// +// -e <= 60 or e >= -60 := alpha + +constexpr int kAlpha = -60; +constexpr int kGamma = -32; + +struct cached_power // c = f * 2^e ~= 10^k +{ + std::uint64_t f; + int e; + int k; +}; + +/*! +For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached +power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c +satisfies (Definition 3.2 from [1]) + + alpha <= e_c + e + q <= gamma. +*/ +inline cached_power get_cached_power_for_binary_exponent(int e) +{ + // Now + // + // alpha <= e_c + e + q <= gamma (1) + // ==> f_c * 2^alpha <= c * 2^e * 2^q + // + // and since the c's are normalized, 2^(q-1) <= f_c, + // + // ==> 2^(q - 1 + alpha) <= c * 2^(e + q) + // ==> 2^(alpha - e - 1) <= c + // + // If c were an exact power of ten, i.e. c = 10^k, one may determine k as + // + // k = ceil( log_10( 2^(alpha - e - 1) ) ) + // = ceil( (alpha - e - 1) * log_10(2) ) + // + // From the paper: + // "In theory the result of the procedure could be wrong since c is rounded, + // and the computation itself is approximated [...]. In practice, however, + // this simple function is sufficient." + // + // For IEEE double precision floating-point numbers converted into + // normalized diyfp's w = f * 2^e, with q = 64, + // + // e >= -1022 (min IEEE exponent) + // -52 (p - 1) + // -52 (p - 1, possibly normalize denormal IEEE numbers) + // -11 (normalize the diyfp) + // = -1137 + // + // and + // + // e <= +1023 (max IEEE exponent) + // -52 (p - 1) + // -11 (normalize the diyfp) + // = 960 + // + // This binary exponent range [-1137,960] results in a decimal exponent + // range [-307,324]. One does not need to store a cached power for each + // k in this range. For each such k it suffices to find a cached power + // such that the exponent of the product lies in [alpha,gamma]. + // This implies that the difference of the decimal exponents of adjacent + // table entries must be less than or equal to + // + // floor( (gamma - alpha) * log_10(2) ) = 8. + // + // (A smaller distance gamma-alpha would require a larger table.) + + // NB: + // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34. + + constexpr int kCachedPowersMinDecExp = -300; + constexpr int kCachedPowersDecStep = 8; + + static constexpr std::array kCachedPowers = + { + { + { 0xAB70FE17C79AC6CA, -1060, -300 }, + { 0xFF77B1FCBEBCDC4F, -1034, -292 }, + { 0xBE5691EF416BD60C, -1007, -284 }, + { 0x8DD01FAD907FFC3C, -980, -276 }, + { 0xD3515C2831559A83, -954, -268 }, + { 0x9D71AC8FADA6C9B5, -927, -260 }, + { 0xEA9C227723EE8BCB, -901, -252 }, + { 0xAECC49914078536D, -874, -244 }, + { 0x823C12795DB6CE57, -847, -236 }, + { 0xC21094364DFB5637, -821, -228 }, + { 0x9096EA6F3848984F, -794, -220 }, + { 0xD77485CB25823AC7, -768, -212 }, + { 0xA086CFCD97BF97F4, -741, -204 }, + { 0xEF340A98172AACE5, -715, -196 }, + { 0xB23867FB2A35B28E, -688, -188 }, + { 0x84C8D4DFD2C63F3B, -661, -180 }, + { 0xC5DD44271AD3CDBA, -635, -172 }, + { 0x936B9FCEBB25C996, -608, -164 }, + { 0xDBAC6C247D62A584, -582, -156 }, + { 0xA3AB66580D5FDAF6, -555, -148 }, + { 0xF3E2F893DEC3F126, -529, -140 }, + { 0xB5B5ADA8AAFF80B8, -502, -132 }, + { 0x87625F056C7C4A8B, -475, -124 }, + { 0xC9BCFF6034C13053, -449, -116 }, + { 0x964E858C91BA2655, -422, -108 }, + { 0xDFF9772470297EBD, -396, -100 }, + { 0xA6DFBD9FB8E5B88F, -369, -92 }, + { 0xF8A95FCF88747D94, -343, -84 }, + { 0xB94470938FA89BCF, -316, -76 }, + { 0x8A08F0F8BF0F156B, -289, -68 }, + { 0xCDB02555653131B6, -263, -60 }, + { 0x993FE2C6D07B7FAC, -236, -52 }, + { 0xE45C10C42A2B3B06, -210, -44 }, + { 0xAA242499697392D3, -183, -36 }, + { 0xFD87B5F28300CA0E, -157, -28 }, + { 0xBCE5086492111AEB, -130, -20 }, + { 0x8CBCCC096F5088CC, -103, -12 }, + { 0xD1B71758E219652C, -77, -4 }, + { 0x9C40000000000000, -50, 4 }, + { 0xE8D4A51000000000, -24, 12 }, + { 0xAD78EBC5AC620000, 3, 20 }, + { 0x813F3978F8940984, 30, 28 }, + { 0xC097CE7BC90715B3, 56, 36 }, + { 0x8F7E32CE7BEA5C70, 83, 44 }, + { 0xD5D238A4ABE98068, 109, 52 }, + { 0x9F4F2726179A2245, 136, 60 }, + { 0xED63A231D4C4FB27, 162, 68 }, + { 0xB0DE65388CC8ADA8, 189, 76 }, + { 0x83C7088E1AAB65DB, 216, 84 }, + { 0xC45D1DF942711D9A, 242, 92 }, + { 0x924D692CA61BE758, 269, 100 }, + { 0xDA01EE641A708DEA, 295, 108 }, + { 0xA26DA3999AEF774A, 322, 116 }, + { 0xF209787BB47D6B85, 348, 124 }, + { 0xB454E4A179DD1877, 375, 132 }, + { 0x865B86925B9BC5C2, 402, 140 }, + { 0xC83553C5C8965D3D, 428, 148 }, + { 0x952AB45CFA97A0B3, 455, 156 }, + { 0xDE469FBD99A05FE3, 481, 164 }, + { 0xA59BC234DB398C25, 508, 172 }, + { 0xF6C69A72A3989F5C, 534, 180 }, + { 0xB7DCBF5354E9BECE, 561, 188 }, + { 0x88FCF317F22241E2, 588, 196 }, + { 0xCC20CE9BD35C78A5, 614, 204 }, + { 0x98165AF37B2153DF, 641, 212 }, + { 0xE2A0B5DC971F303A, 667, 220 }, + { 0xA8D9D1535CE3B396, 694, 228 }, + { 0xFB9B7CD9A4A7443C, 720, 236 }, + { 0xBB764C4CA7A44410, 747, 244 }, + { 0x8BAB8EEFB6409C1A, 774, 252 }, + { 0xD01FEF10A657842C, 800, 260 }, + { 0x9B10A4E5E9913129, 827, 268 }, + { 0xE7109BFBA19C0C9D, 853, 276 }, + { 0xAC2820D9623BF429, 880, 284 }, + { 0x80444B5E7AA7CF85, 907, 292 }, + { 0xBF21E44003ACDD2D, 933, 300 }, + { 0x8E679C2F5E44FF8F, 960, 308 }, + { 0xD433179D9C8CB841, 986, 316 }, + { 0x9E19DB92B4E31BA9, 1013, 324 }, + } + }; + + // This computation gives exactly the same results for k as + // k = ceil((kAlpha - e - 1) * 0.30102999566398114) + // for |e| <= 1500, but doesn't require floating-point operations. + // NB: log_10(2) ~= 78913 / 2^18 + JSON_ASSERT(e >= -1500); + JSON_ASSERT(e <= 1500); + const int f = kAlpha - e - 1; + const int k = (f * 78913) / (1 << 18) + static_cast(f > 0); + + const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep; + JSON_ASSERT(index >= 0); + JSON_ASSERT(static_cast(index) < kCachedPowers.size()); + + const cached_power cached = kCachedPowers[static_cast(index)]; + JSON_ASSERT(kAlpha <= cached.e + e + 64); + JSON_ASSERT(kGamma >= cached.e + e + 64); + + return cached; +} + +/*! +For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k. +For n == 0, returns 1 and sets pow10 := 1. +*/ +inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10) +{ + // LCOV_EXCL_START + if (n >= 1000000000) + { + pow10 = 1000000000; + return 10; + } + // LCOV_EXCL_STOP + if (n >= 100000000) + { + pow10 = 100000000; + return 9; + } + if (n >= 10000000) + { + pow10 = 10000000; + return 8; + } + if (n >= 1000000) + { + pow10 = 1000000; + return 7; + } + if (n >= 100000) + { + pow10 = 100000; + return 6; + } + if (n >= 10000) + { + pow10 = 10000; + return 5; + } + if (n >= 1000) + { + pow10 = 1000; + return 4; + } + if (n >= 100) + { + pow10 = 100; + return 3; + } + if (n >= 10) + { + pow10 = 10; + return 2; + } + + pow10 = 1; + return 1; +} + +inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta, + std::uint64_t rest, std::uint64_t ten_k) +{ + JSON_ASSERT(len >= 1); + JSON_ASSERT(dist <= delta); + JSON_ASSERT(rest <= delta); + JSON_ASSERT(ten_k > 0); + + // <--------------------------- delta ----> + // <---- dist ---------> + // --------------[------------------+-------------------]-------------- + // M- w M+ + // + // ten_k + // <------> + // <---- rest ----> + // --------------[------------------+----+--------------]-------------- + // w V + // = buf * 10^k + // + // ten_k represents a unit-in-the-last-place in the decimal representation + // stored in buf. + // Decrement buf by ten_k while this takes buf closer to w. + + // The tests are written in this order to avoid overflow in unsigned + // integer arithmetic. + + while (rest < dist + && delta - rest >= ten_k + && (rest + ten_k < dist || dist - rest > rest + ten_k - dist)) + { + JSON_ASSERT(buf[len - 1] != '0'); + buf[len - 1]--; + rest += ten_k; + } +} + +/*! +Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+. +M- and M+ must be normalized and share the same exponent -60 <= e <= -32. +*/ +inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent, + diyfp M_minus, diyfp w, diyfp M_plus) +{ + static_assert(kAlpha >= -60, "internal error"); + static_assert(kGamma <= -32, "internal error"); + + // Generates the digits (and the exponent) of a decimal floating-point + // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's + // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma. + // + // <--------------------------- delta ----> + // <---- dist ---------> + // --------------[------------------+-------------------]-------------- + // M- w M+ + // + // Grisu2 generates the digits of M+ from left to right and stops as soon as + // V is in [M-,M+]. + + JSON_ASSERT(M_plus.e >= kAlpha); + JSON_ASSERT(M_plus.e <= kGamma); + + std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e) + std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e) + + // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0): + // + // M+ = f * 2^e + // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e + // = ((p1 ) * 2^-e + (p2 )) * 2^e + // = p1 + p2 * 2^e + + const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e); + + auto p1 = static_cast(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.) + std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e + + // 1) + // + // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0] + + JSON_ASSERT(p1 > 0); + + std::uint32_t pow10{}; + const int k = find_largest_pow10(p1, pow10); + + // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1) + // + // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1)) + // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1)) + // + // M+ = p1 + p2 * 2^e + // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e + // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e + // = d[k-1] * 10^(k-1) + ( rest) * 2^e + // + // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0) + // + // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0] + // + // but stop as soon as + // + // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e + + int n = k; + while (n > 0) + { + // Invariants: + // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k) + // pow10 = 10^(n-1) <= p1 < 10^n + // + const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1) + const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1) + // + // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e + // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e) + // + JSON_ASSERT(d <= 9); + buffer[length++] = static_cast('0' + d); // buffer := buffer * 10 + d + // + // M+ = buffer * 10^(n-1) + (r + p2 * 2^e) + // + p1 = r; + n--; + // + // M+ = buffer * 10^n + (p1 + p2 * 2^e) + // pow10 = 10^n + // + + // Now check if enough digits have been generated. + // Compute + // + // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e + // + // Note: + // Since rest and delta share the same exponent e, it suffices to + // compare the significands. + const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2; + if (rest <= delta) + { + // V = buffer * 10^n, with M- <= V <= M+. + + decimal_exponent += n; + + // We may now just stop. But instead look if the buffer could be + // decremented to bring V closer to w. + // + // pow10 = 10^n is now 1 ulp in the decimal representation V. + // The rounding procedure works with diyfp's with an implicit + // exponent of e. + // + // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e + // + const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e; + grisu2_round(buffer, length, dist, delta, rest, ten_n); + + return; + } + + pow10 /= 10; + // + // pow10 = 10^(n-1) <= p1 < 10^n + // Invariants restored. + } + + // 2) + // + // The digits of the integral part have been generated: + // + // M+ = d[k-1]...d[1]d[0] + p2 * 2^e + // = buffer + p2 * 2^e + // + // Now generate the digits of the fractional part p2 * 2^e. + // + // Note: + // No decimal point is generated: the exponent is adjusted instead. + // + // p2 actually represents the fraction + // + // p2 * 2^e + // = p2 / 2^-e + // = d[-1] / 10^1 + d[-2] / 10^2 + ... + // + // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...) + // + // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m + // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...) + // + // using + // + // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e) + // = ( d) * 2^-e + ( r) + // + // or + // 10^m * p2 * 2^e = d + r * 2^e + // + // i.e. + // + // M+ = buffer + p2 * 2^e + // = buffer + 10^-m * (d + r * 2^e) + // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e + // + // and stop as soon as 10^-m * r * 2^e <= delta * 2^e + + JSON_ASSERT(p2 > delta); + + int m = 0; + for (;;) + { + // Invariant: + // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e + // = buffer * 10^-m + 10^-m * (p2 ) * 2^e + // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e + // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e + // + JSON_ASSERT(p2 <= (std::numeric_limits::max)() / 10); + p2 *= 10; + const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e + const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e + // + // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e + // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e)) + // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e + // + JSON_ASSERT(d <= 9); + buffer[length++] = static_cast('0' + d); // buffer := buffer * 10 + d + // + // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e + // + p2 = r; + m++; + // + // M+ = buffer * 10^-m + 10^-m * p2 * 2^e + // Invariant restored. + + // Check if enough digits have been generated. + // + // 10^-m * p2 * 2^e <= delta * 2^e + // p2 * 2^e <= 10^m * delta * 2^e + // p2 <= 10^m * delta + delta *= 10; + dist *= 10; + if (p2 <= delta) + { + break; + } + } + + // V = buffer * 10^-m, with M- <= V <= M+. + + decimal_exponent -= m; + + // 1 ulp in the decimal representation is now 10^-m. + // Since delta and dist are now scaled by 10^m, we need to do the + // same with ulp in order to keep the units in sync. + // + // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e + // + const std::uint64_t ten_m = one.f; + grisu2_round(buffer, length, dist, delta, p2, ten_m); + + // By construction this algorithm generates the shortest possible decimal + // number (Loitsch, Theorem 6.2) which rounds back to w. + // For an input number of precision p, at least + // + // N = 1 + ceil(p * log_10(2)) + // + // decimal digits are sufficient to identify all binary floating-point + // numbers (Matula, "In-and-Out conversions"). + // This implies that the algorithm does not produce more than N decimal + // digits. + // + // N = 17 for p = 53 (IEEE double precision) + // N = 9 for p = 24 (IEEE single precision) +} + +/*! +v = buf * 10^decimal_exponent +len is the length of the buffer (number of decimal digits) +The buffer must be large enough, i.e. >= max_digits10. +*/ +JSON_HEDLEY_NON_NULL(1) +inline void grisu2(char* buf, int& len, int& decimal_exponent, + diyfp m_minus, diyfp v, diyfp m_plus) +{ + JSON_ASSERT(m_plus.e == m_minus.e); + JSON_ASSERT(m_plus.e == v.e); + + // --------(-----------------------+-----------------------)-------- (A) + // m- v m+ + // + // --------------------(-----------+-----------------------)-------- (B) + // m- v m+ + // + // First scale v (and m- and m+) such that the exponent is in the range + // [alpha, gamma]. + + const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e); + + const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k + + // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma] + const diyfp w = diyfp::mul(v, c_minus_k); + const diyfp w_minus = diyfp::mul(m_minus, c_minus_k); + const diyfp w_plus = diyfp::mul(m_plus, c_minus_k); + + // ----(---+---)---------------(---+---)---------------(---+---)---- + // w- w w+ + // = c*m- = c*v = c*m+ + // + // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and + // w+ are now off by a small amount. + // In fact: + // + // w - v * 10^k < 1 ulp + // + // To account for this inaccuracy, add resp. subtract 1 ulp. + // + // --------+---[---------------(---+---)---------------]---+-------- + // w- M- w M+ w+ + // + // Now any number in [M-, M+] (bounds included) will round to w when input, + // regardless of how the input rounding algorithm breaks ties. + // + // And digit_gen generates the shortest possible such number in [M-, M+]. + // Note that this does not mean that Grisu2 always generates the shortest + // possible number in the interval (m-, m+). + const diyfp M_minus(w_minus.f + 1, w_minus.e); + const diyfp M_plus (w_plus.f - 1, w_plus.e ); + + decimal_exponent = -cached.k; // = -(-k) = k + + grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus); +} + +/*! +v = buf * 10^decimal_exponent +len is the length of the buffer (number of decimal digits) +The buffer must be large enough, i.e. >= max_digits10. +*/ +template +JSON_HEDLEY_NON_NULL(1) +void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value) +{ + static_assert(diyfp::kPrecision >= std::numeric_limits::digits + 3, + "internal error: not enough precision"); + + JSON_ASSERT(std::isfinite(value)); + JSON_ASSERT(value > 0); + + // If the neighbors (and boundaries) of 'value' are always computed for double-precision + // numbers, all float's can be recovered using strtod (and strtof). However, the resulting + // decimal representations are not exactly "short". + // + // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars) + // says "value is converted to a string as if by std::sprintf in the default ("C") locale" + // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars' + // does. + // On the other hand, the documentation for 'std::to_chars' requires that "parsing the + // representation using the corresponding std::from_chars function recovers value exactly". That + // indicates that single precision floating-point numbers should be recovered using + // 'std::strtof'. + // + // NB: If the neighbors are computed for single-precision numbers, there is a single float + // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision + // value is off by 1 ulp. +#if 0 // NOLINT(readability-avoid-unconditional-preprocessor-if) + const boundaries w = compute_boundaries(static_cast(value)); +#else + const boundaries w = compute_boundaries(value); +#endif + + grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus); +} + +/*! +@brief appends a decimal representation of e to buf +@return a pointer to the element following the exponent. +@pre -1000 < e < 1000 +*/ +JSON_HEDLEY_NON_NULL(1) +JSON_HEDLEY_RETURNS_NON_NULL +inline char* append_exponent(char* buf, int e) +{ + JSON_ASSERT(e > -1000); + JSON_ASSERT(e < 1000); + + if (e < 0) + { + e = -e; + *buf++ = '-'; + } + else + { + *buf++ = '+'; + } + + auto k = static_cast(e); + if (k < 10) + { + // Always print at least two digits in the exponent. + // This is for compatibility with printf("%g"). + *buf++ = '0'; + *buf++ = static_cast('0' + k); + } + else if (k < 100) + { + *buf++ = static_cast('0' + k / 10); + k %= 10; + *buf++ = static_cast('0' + k); + } + else + { + *buf++ = static_cast('0' + k / 100); + k %= 100; + *buf++ = static_cast('0' + k / 10); + k %= 10; + *buf++ = static_cast('0' + k); + } + + return buf; +} + +/*! +@brief prettify v = buf * 10^decimal_exponent + +If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point +notation. Otherwise it will be printed in exponential notation. + +@pre min_exp < 0 +@pre max_exp > 0 +*/ +JSON_HEDLEY_NON_NULL(1) +JSON_HEDLEY_RETURNS_NON_NULL +inline char* format_buffer(char* buf, int len, int decimal_exponent, + int min_exp, int max_exp) +{ + JSON_ASSERT(min_exp < 0); + JSON_ASSERT(max_exp > 0); + + const int k = len; + const int n = len + decimal_exponent; + + // v = buf * 10^(n-k) + // k is the length of the buffer (number of decimal digits) + // n is the position of the decimal point relative to the start of the buffer. + + if (k <= n && n <= max_exp) + { + // digits[000] + // len <= max_exp + 2 + + std::memset(buf + k, '0', static_cast(n) - static_cast(k)); + // Make it look like a floating-point number (#362, #378) + buf[n + 0] = '.'; + buf[n + 1] = '0'; + return buf + (static_cast(n) + 2); + } + + if (0 < n && n <= max_exp) + { + // dig.its + // len <= max_digits10 + 1 + + JSON_ASSERT(k > n); + + std::memmove(buf + (static_cast(n) + 1), buf + n, static_cast(k) - static_cast(n)); + buf[n] = '.'; + return buf + (static_cast(k) + 1U); + } + + if (min_exp < n && n <= 0) + { + // 0.[000]digits + // len <= 2 + (-min_exp - 1) + max_digits10 + + std::memmove(buf + (2 + static_cast(-n)), buf, static_cast(k)); + buf[0] = '0'; + buf[1] = '.'; + std::memset(buf + 2, '0', static_cast(-n)); + return buf + (2U + static_cast(-n) + static_cast(k)); + } + + if (k == 1) + { + // dE+123 + // len <= 1 + 5 + + buf += 1; + } + else + { + // d.igitsE+123 + // len <= max_digits10 + 1 + 5 + + std::memmove(buf + 2, buf + 1, static_cast(k) - 1); + buf[1] = '.'; + buf += 1 + static_cast(k); + } + + *buf++ = 'e'; + return append_exponent(buf, n - 1); +} + +} // namespace dtoa_impl + +/*! +@brief generates a decimal representation of the floating-point number value in [first, last). + +The format of the resulting decimal representation is similar to printf's %g +format. Returns an iterator pointing past-the-end of the decimal representation. + +@note The input number must be finite, i.e. NaN's and Inf's are not supported. +@note The buffer must be large enough. +@note The result is NOT null-terminated. +*/ +template +JSON_HEDLEY_NON_NULL(1, 2) +JSON_HEDLEY_RETURNS_NON_NULL +char* to_chars(char* first, const char* last, FloatType value) +{ + static_cast(last); // maybe unused - fix warning + JSON_ASSERT(std::isfinite(value)); + + // Use signbit(value) instead of (value < 0) since signbit works for -0. + if (std::signbit(value)) + { + value = -value; + *first++ = '-'; + } + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (value == 0) // +-0 + { + *first++ = '0'; + // Make it look like a floating-point number (#362, #378) + *first++ = '.'; + *first++ = '0'; + return first; + } +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + + JSON_ASSERT(last - first >= std::numeric_limits::max_digits10); + + // Compute v = buffer * 10^decimal_exponent. + // The decimal digits are stored in the buffer, which needs to be interpreted + // as an unsigned decimal integer. + // len is the length of the buffer, i.e. the number of decimal digits. + int len = 0; + int decimal_exponent = 0; + dtoa_impl::grisu2(first, len, decimal_exponent, value); + + JSON_ASSERT(len <= std::numeric_limits::max_digits10); + + // Format the buffer like printf("%.*g", prec, value) + constexpr int kMinExp = -4; + // Use digits10 here to increase compatibility with version 2. + constexpr int kMaxExp = std::numeric_limits::digits10; + + JSON_ASSERT(last - first >= kMaxExp + 2); + JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits::max_digits10); + JSON_ASSERT(last - first >= std::numeric_limits::max_digits10 + 6); + + return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp); +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/conversions/to_json.hpp b/vulkan/nlohmann/detail/conversions/to_json.hpp new file mode 100644 index 0000000..562089c --- /dev/null +++ b/vulkan/nlohmann/detail/conversions/to_json.hpp @@ -0,0 +1,447 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // copy +#include // begin, end +#include // string +#include // tuple, get +#include // is_same, is_constructible, is_floating_point, is_enum, underlying_type +#include // move, forward, declval, pair +#include // valarray +#include // vector + +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +////////////////// +// constructors // +////////////////// + +/* + * Note all external_constructor<>::construct functions need to call + * j.m_data.m_value.destroy(j.m_data.m_type) to avoid a memory leak in case j contains an + * allocated value (e.g., a string). See bug issue + * https://github.com/nlohmann/json/issues/2865 for more information. + */ + +template struct external_constructor; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::boolean; + j.m_data.m_value = b; + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::string; + j.m_data.m_value = s; + j.assert_invariant(); + } + + template + static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::string; + j.m_data.m_value = std::move(s); + j.assert_invariant(); + } + + template < typename BasicJsonType, typename CompatibleStringType, + enable_if_t < !std::is_same::value, + int > = 0 > + static void construct(BasicJsonType& j, const CompatibleStringType& str) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::string; + j.m_data.m_value.string = j.template create(str); + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::binary; + j.m_data.m_value = typename BasicJsonType::binary_t(b); + j.assert_invariant(); + } + + template + static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::binary; + j.m_data.m_value = typename BasicJsonType::binary_t(std::move(b)); + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::number_float; + j.m_data.m_value = val; + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::number_unsigned; + j.m_data.m_value = val; + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::number_integer; + j.m_data.m_value = val; + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::array; + j.m_data.m_value = arr; + j.set_parents(); + j.assert_invariant(); + } + + template + static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::array; + j.m_data.m_value = std::move(arr); + j.set_parents(); + j.assert_invariant(); + } + + template < typename BasicJsonType, typename CompatibleArrayType, + enable_if_t < !std::is_same::value, + int > = 0 > + static void construct(BasicJsonType& j, const CompatibleArrayType& arr) + { + using std::begin; + using std::end; + + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::array; + j.m_data.m_value.array = j.template create(begin(arr), end(arr)); + j.set_parents(); + j.assert_invariant(); + } + + template + static void construct(BasicJsonType& j, const std::vector& arr) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::array; + j.m_data.m_value = value_t::array; + j.m_data.m_value.array->reserve(arr.size()); + for (const bool x : arr) + { + j.m_data.m_value.array->push_back(x); + j.set_parent(j.m_data.m_value.array->back()); + } + j.assert_invariant(); + } + + template::value, int> = 0> + static void construct(BasicJsonType& j, const std::valarray& arr) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::array; + j.m_data.m_value = value_t::array; + j.m_data.m_value.array->resize(arr.size()); + if (arr.size() > 0) + { + std::copy(std::begin(arr), std::end(arr), j.m_data.m_value.array->begin()); + } + j.set_parents(); + j.assert_invariant(); + } +}; + +template<> +struct external_constructor +{ + template + static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::object; + j.m_data.m_value = obj; + j.set_parents(); + j.assert_invariant(); + } + + template + static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj) + { + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::object; + j.m_data.m_value = std::move(obj); + j.set_parents(); + j.assert_invariant(); + } + + template < typename BasicJsonType, typename CompatibleObjectType, + enable_if_t < !std::is_same::value, int > = 0 > + static void construct(BasicJsonType& j, const CompatibleObjectType& obj) + { + using std::begin; + using std::end; + + j.m_data.m_value.destroy(j.m_data.m_type); + j.m_data.m_type = value_t::object; + j.m_data.m_value.object = j.template create(begin(obj), end(obj)); + j.set_parents(); + j.assert_invariant(); + } +}; + +///////////// +// to_json // +///////////// + +template::value, int> = 0> +inline void to_json(BasicJsonType& j, T b) noexcept +{ + external_constructor::construct(j, b); +} + +template < typename BasicJsonType, typename BoolRef, + enable_if_t < + ((std::is_same::reference, BoolRef>::value + && !std::is_same ::reference, typename BasicJsonType::boolean_t&>::value) + || (std::is_same::const_reference, BoolRef>::value + && !std::is_same ::const_reference>, + typename BasicJsonType::boolean_t >::value)) + && std::is_convertible::value, int > = 0 > +inline void to_json(BasicJsonType& j, const BoolRef& b) noexcept +{ + external_constructor::construct(j, static_cast(b)); +} + +template::value, int> = 0> +inline void to_json(BasicJsonType& j, const CompatibleString& s) +{ + external_constructor::construct(j, s); +} + +template +inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s) +{ + external_constructor::construct(j, std::move(s)); +} + +template::value, int> = 0> +inline void to_json(BasicJsonType& j, FloatType val) noexcept +{ + external_constructor::construct(j, static_cast(val)); +} + +template::value, int> = 0> +inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept +{ + external_constructor::construct(j, static_cast(val)); +} + +template::value, int> = 0> +inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept +{ + external_constructor::construct(j, static_cast(val)); +} + +#if !JSON_DISABLE_ENUM_SERIALIZATION +template::value, int> = 0> +inline void to_json(BasicJsonType& j, EnumType e) noexcept +{ + using underlying_type = typename std::underlying_type::type; + static constexpr value_t integral_value_t = std::is_unsigned::value ? value_t::number_unsigned : value_t::number_integer; + external_constructor::construct(j, static_cast(e)); +} +#endif // JSON_DISABLE_ENUM_SERIALIZATION + +template +inline void to_json(BasicJsonType& j, const std::vector& e) +{ + external_constructor::construct(j, e); +} + +template < typename BasicJsonType, typename CompatibleArrayType, + enable_if_t < is_compatible_array_type::value&& + !is_compatible_object_type::value&& + !is_compatible_string_type::value&& + !std::is_same::value&& + !is_basic_json::value, + int > = 0 > +inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr) +{ + external_constructor::construct(j, arr); +} + +template +inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin) +{ + external_constructor::construct(j, bin); +} + +template::value, int> = 0> +inline void to_json(BasicJsonType& j, const std::valarray& arr) +{ + external_constructor::construct(j, std::move(arr)); +} + +template +inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr) +{ + external_constructor::construct(j, std::move(arr)); +} + +template < typename BasicJsonType, typename CompatibleObjectType, + enable_if_t < is_compatible_object_type::value&& !is_basic_json::value, int > = 0 > +inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj) +{ + external_constructor::construct(j, obj); +} + +template +inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) +{ + external_constructor::construct(j, std::move(obj)); +} + +template < + typename BasicJsonType, typename T, std::size_t N, + enable_if_t < !std::is_constructible::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + int > = 0 > +inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) +{ + external_constructor::construct(j, arr); +} + +template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible::value&& std::is_constructible::value, int > = 0 > +inline void to_json(BasicJsonType& j, const std::pair& p) +{ + j = { p.first, p.second }; +} + +// for https://github.com/nlohmann/json/pull/1134 +template>::value, int> = 0> +inline void to_json(BasicJsonType& j, const T& b) +{ + j = { {b.key(), b.value()} }; +} + +template +inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence /*unused*/) +{ + j = { std::get(t)... }; +} + +template::value, int > = 0> +inline void to_json(BasicJsonType& j, const T& t) +{ + to_json_tuple_impl(j, t, make_index_sequence::value> {}); +} + +#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM +template +inline void to_json(BasicJsonType& j, const std_fs::path& p) +{ + j = p.string(); +} +#endif + +struct to_json_fn +{ + template + auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward(val)))) + -> decltype(to_json(j, std::forward(val)), void()) + { + return to_json(j, std::forward(val)); + } +}; +} // namespace detail + +#ifndef JSON_HAS_CPP_17 +/// namespace to hold default `to_json` function +/// to see why this is required: +/// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html +namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces) +{ +#endif +JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers) + detail::static_const::value; +#ifndef JSON_HAS_CPP_17 +} // namespace +#endif + +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/exceptions.hpp b/vulkan/nlohmann/detail/exceptions.hpp new file mode 100644 index 0000000..5974d7b --- /dev/null +++ b/vulkan/nlohmann/detail/exceptions.hpp @@ -0,0 +1,257 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // nullptr_t +#include // exception +#if JSON_DIAGNOSTICS + #include // accumulate +#endif +#include // runtime_error +#include // to_string +#include // vector + +#include +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +//////////////// +// exceptions // +//////////////// + +/// @brief general exception of the @ref basic_json class +/// @sa https://json.nlohmann.me/api/basic_json/exception/ +class exception : public std::exception +{ + public: + /// returns the explanatory string + const char* what() const noexcept override + { + return m.what(); + } + + /// the id of the exception + const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) + + protected: + JSON_HEDLEY_NON_NULL(3) + exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing) + + static std::string name(const std::string& ename, int id_) + { + return concat("[json.exception.", ename, '.', std::to_string(id_), "] "); + } + + static std::string diagnostics(std::nullptr_t /*leaf_element*/) + { + return ""; + } + + template + static std::string diagnostics(const BasicJsonType* leaf_element) + { +#if JSON_DIAGNOSTICS + std::vector tokens; + for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent) + { + switch (current->m_parent->type()) + { + case value_t::array: + { + for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i) + { + if (¤t->m_parent->m_data.m_value.array->operator[](i) == current) + { + tokens.emplace_back(std::to_string(i)); + break; + } + } + break; + } + + case value_t::object: + { + for (const auto& element : *current->m_parent->m_data.m_value.object) + { + if (&element.second == current) + { + tokens.emplace_back(element.first.c_str()); + break; + } + } + break; + } + + case value_t::null: // LCOV_EXCL_LINE + case value_t::string: // LCOV_EXCL_LINE + case value_t::boolean: // LCOV_EXCL_LINE + case value_t::number_integer: // LCOV_EXCL_LINE + case value_t::number_unsigned: // LCOV_EXCL_LINE + case value_t::number_float: // LCOV_EXCL_LINE + case value_t::binary: // LCOV_EXCL_LINE + case value_t::discarded: // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + break; // LCOV_EXCL_LINE + } + } + + if (tokens.empty()) + { + return ""; + } + + auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{}, + [](const std::string & a, const std::string & b) + { + return concat(a, '/', detail::escape(b)); + }); + return concat('(', str, ") "); +#else + static_cast(leaf_element); + return ""; +#endif + } + + private: + /// an exception object as storage for error messages + std::runtime_error m; +}; + +/// @brief exception indicating a parse error +/// @sa https://json.nlohmann.me/api/basic_json/parse_error/ +class parse_error : public exception +{ + public: + /*! + @brief create a parse error exception + @param[in] id_ the id of the exception + @param[in] pos the position where the error occurred (or with + chars_read_total=0 if the position cannot be + determined) + @param[in] what_arg the explanatory string + @return parse_error object + */ + template::value, int> = 0> + static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context) + { + const std::string w = concat(exception::name("parse_error", id_), "parse error", + position_string(pos), ": ", exception::diagnostics(context), what_arg); + return {id_, pos.chars_read_total, w.c_str()}; + } + + template::value, int> = 0> + static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context) + { + const std::string w = concat(exception::name("parse_error", id_), "parse error", + (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""), + ": ", exception::diagnostics(context), what_arg); + return {id_, byte_, w.c_str()}; + } + + /*! + @brief byte index of the parse error + + The byte index of the last read character in the input file. + + @note For an input with n bytes, 1 is the index of the first character and + n+1 is the index of the terminating null byte or the end of file. + This also holds true when reading a byte vector (CBOR or MessagePack). + */ + const std::size_t byte; + + private: + parse_error(int id_, std::size_t byte_, const char* what_arg) + : exception(id_, what_arg), byte(byte_) {} + + static std::string position_string(const position_t& pos) + { + return concat(" at line ", std::to_string(pos.lines_read + 1), + ", column ", std::to_string(pos.chars_read_current_line)); + } +}; + +/// @brief exception indicating errors with iterators +/// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/ +class invalid_iterator : public exception +{ + public: + template::value, int> = 0> + static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context) + { + const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg); + return {id_, w.c_str()}; + } + + private: + JSON_HEDLEY_NON_NULL(3) + invalid_iterator(int id_, const char* what_arg) + : exception(id_, what_arg) {} +}; + +/// @brief exception indicating executing a member function with a wrong type +/// @sa https://json.nlohmann.me/api/basic_json/type_error/ +class type_error : public exception +{ + public: + template::value, int> = 0> + static type_error create(int id_, const std::string& what_arg, BasicJsonContext context) + { + const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg); + return {id_, w.c_str()}; + } + + private: + JSON_HEDLEY_NON_NULL(3) + type_error(int id_, const char* what_arg) : exception(id_, what_arg) {} +}; + +/// @brief exception indicating access out of the defined range +/// @sa https://json.nlohmann.me/api/basic_json/out_of_range/ +class out_of_range : public exception +{ + public: + template::value, int> = 0> + static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context) + { + const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg); + return {id_, w.c_str()}; + } + + private: + JSON_HEDLEY_NON_NULL(3) + out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {} +}; + +/// @brief exception indicating other library errors +/// @sa https://json.nlohmann.me/api/basic_json/other_error/ +class other_error : public exception +{ + public: + template::value, int> = 0> + static other_error create(int id_, const std::string& what_arg, BasicJsonContext context) + { + const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg); + return {id_, w.c_str()}; + } + + private: + JSON_HEDLEY_NON_NULL(3) + other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/hash.hpp b/vulkan/nlohmann/detail/hash.hpp new file mode 100644 index 0000000..4464e8e --- /dev/null +++ b/vulkan/nlohmann/detail/hash.hpp @@ -0,0 +1,129 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // uint8_t +#include // size_t +#include // hash + +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// boost::hash_combine +inline std::size_t combine(std::size_t seed, std::size_t h) noexcept +{ + seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U); + return seed; +} + +/*! +@brief hash a JSON value + +The hash function tries to rely on std::hash where possible. Furthermore, the +type of the JSON value is taken into account to have different hash values for +null, 0, 0U, and false, etc. + +@tparam BasicJsonType basic_json specialization +@param j JSON value to hash +@return hash value of j +*/ +template +std::size_t hash(const BasicJsonType& j) +{ + using string_t = typename BasicJsonType::string_t; + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + + const auto type = static_cast(j.type()); + switch (j.type()) + { + case BasicJsonType::value_t::null: + case BasicJsonType::value_t::discarded: + { + return combine(type, 0); + } + + case BasicJsonType::value_t::object: + { + auto seed = combine(type, j.size()); + for (const auto& element : j.items()) + { + const auto h = std::hash {}(element.key()); + seed = combine(seed, h); + seed = combine(seed, hash(element.value())); + } + return seed; + } + + case BasicJsonType::value_t::array: + { + auto seed = combine(type, j.size()); + for (const auto& element : j) + { + seed = combine(seed, hash(element)); + } + return seed; + } + + case BasicJsonType::value_t::string: + { + const auto h = std::hash {}(j.template get_ref()); + return combine(type, h); + } + + case BasicJsonType::value_t::boolean: + { + const auto h = std::hash {}(j.template get()); + return combine(type, h); + } + + case BasicJsonType::value_t::number_integer: + { + const auto h = std::hash {}(j.template get()); + return combine(type, h); + } + + case BasicJsonType::value_t::number_unsigned: + { + const auto h = std::hash {}(j.template get()); + return combine(type, h); + } + + case BasicJsonType::value_t::number_float: + { + const auto h = std::hash {}(j.template get()); + return combine(type, h); + } + + case BasicJsonType::value_t::binary: + { + auto seed = combine(type, j.get_binary().size()); + const auto h = std::hash {}(j.get_binary().has_subtype()); + seed = combine(seed, h); + seed = combine(seed, static_cast(j.get_binary().subtype())); + for (const auto byte : j.get_binary()) + { + seed = combine(seed, std::hash {}(byte)); + } + return seed; + } + + default: // LCOV_EXCL_LINE + JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE + return 0; // LCOV_EXCL_LINE + } +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/input/binary_reader.hpp b/vulkan/nlohmann/detail/input/binary_reader.hpp new file mode 100644 index 0000000..a6e100e --- /dev/null +++ b/vulkan/nlohmann/detail/input/binary_reader.hpp @@ -0,0 +1,3009 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // generate_n +#include // array +#include // ldexp +#include // size_t +#include // uint8_t, uint16_t, uint32_t, uint64_t +#include // snprintf +#include // memcpy +#include // back_inserter +#include // numeric_limits +#include // char_traits, string +#include // make_pair, move +#include // vector + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/// how to treat CBOR tags +enum class cbor_tag_handler_t +{ + error, ///< throw a parse_error exception in case of a tag + ignore, ///< ignore tags + store ///< store tags as binary type +}; + +/*! +@brief determine system byte order + +@return true if and only if system's byte order is little endian + +@note from https://stackoverflow.com/a/1001328/266378 +*/ +static inline bool little_endianness(int num = 1) noexcept +{ + return *reinterpret_cast(&num) == 1; +} + +/////////////////// +// binary reader // +/////////////////// + +/*! +@brief deserialization of CBOR, MessagePack, and UBJSON values +*/ +template> +class binary_reader +{ + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + using json_sax_t = SAX; + using char_type = typename InputAdapterType::char_type; + using char_int_type = typename char_traits::int_type; + + public: + /*! + @brief create a binary reader + + @param[in] adapter input adapter to read from + */ + explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format) + { + (void)detail::is_sax_static_asserts {}; + } + + // make class move-only + binary_reader(const binary_reader&) = delete; + binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + binary_reader& operator=(const binary_reader&) = delete; + binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + ~binary_reader() = default; + + /*! + @param[in] format the binary format to parse + @param[in] sax_ a SAX event processor + @param[in] strict whether to expect the input to be consumed completed + @param[in] tag_handler how to treat CBOR tags + + @return whether parsing was successful + */ + JSON_HEDLEY_NON_NULL(3) + bool sax_parse(const input_format_t format, + json_sax_t* sax_, + const bool strict = true, + const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error) + { + sax = sax_; + bool result = false; + + switch (format) + { + case input_format_t::bson: + result = parse_bson_internal(); + break; + + case input_format_t::cbor: + result = parse_cbor_internal(true, tag_handler); + break; + + case input_format_t::msgpack: + result = parse_msgpack_internal(); + break; + + case input_format_t::ubjson: + case input_format_t::bjdata: + result = parse_ubjson_internal(); + break; + + case input_format_t::json: // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE + } + + // strict mode: next byte must be EOF + if (result && strict) + { + if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata) + { + get_ignore_noop(); + } + else + { + get(); + } + + if (JSON_HEDLEY_UNLIKELY(current != char_traits::eof())) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read, + exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr)); + } + } + + return result; + } + + private: + ////////// + // BSON // + ////////// + + /*! + @brief Reads in a BSON-object and passes it to the SAX-parser. + @return whether a valid BSON-value was passed to the SAX parser + */ + bool parse_bson_internal() + { + std::int32_t document_size{}; + get_number(input_format_t::bson, document_size); + + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast(-1)))) + { + return false; + } + + if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false))) + { + return false; + } + + return sax->end_object(); + } + + /*! + @brief Parses a C-style string from the BSON input. + @param[in,out] result A reference to the string variable where the read + string is to be stored. + @return `true` if the \x00-byte indicating the end of the string was + encountered before the EOF; false` indicates an unexpected EOF. + */ + bool get_bson_cstr(string_t& result) + { + auto out = std::back_inserter(result); + while (true) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring"))) + { + return false; + } + if (current == 0x00) + { + return true; + } + *out++ = static_cast(current); + } + } + + /*! + @brief Parses a zero-terminated string of length @a len from the BSON + input. + @param[in] len The length (including the zero-byte at the end) of the + string to be read. + @param[in,out] result A reference to the string variable where the read + string is to be stored. + @tparam NumberType The type of the length @a len + @pre len >= 1 + @return `true` if the string was successfully parsed + */ + template + bool get_bson_string(const NumberType len, string_t& result) + { + if (JSON_HEDLEY_UNLIKELY(len < 1)) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr)); + } + + return get_string(input_format_t::bson, len - static_cast(1), result) && get() != char_traits::eof(); + } + + /*! + @brief Parses a byte array input of length @a len from the BSON input. + @param[in] len The length of the byte array to be read. + @param[in,out] result A reference to the binary variable where the read + array is to be stored. + @tparam NumberType The type of the length @a len + @pre len >= 0 + @return `true` if the byte array was successfully parsed + */ + template + bool get_bson_binary(const NumberType len, binary_t& result) + { + if (JSON_HEDLEY_UNLIKELY(len < 0)) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr)); + } + + // All BSON binary values have a subtype + std::uint8_t subtype{}; + get_number(input_format_t::bson, subtype); + result.set_subtype(subtype); + + return get_binary(input_format_t::bson, len, result); + } + + /*! + @brief Read a BSON document element of the given @a element_type. + @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html + @param[in] element_type_parse_position The position in the input stream, + where the `element_type` was read. + @warning Not all BSON element types are supported yet. An unsupported + @a element_type will give rise to a parse_error.114: + Unsupported BSON record type 0x... + @return whether a valid BSON-object/array was passed to the SAX parser + */ + bool parse_bson_element_internal(const char_int_type element_type, + const std::size_t element_type_parse_position) + { + switch (element_type) + { + case 0x01: // double + { + double number{}; + return get_number(input_format_t::bson, number) && sax->number_float(static_cast(number), ""); + } + + case 0x02: // string + { + std::int32_t len{}; + string_t value; + return get_number(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value); + } + + case 0x03: // object + { + return parse_bson_internal(); + } + + case 0x04: // array + { + return parse_bson_array(); + } + + case 0x05: // binary + { + std::int32_t len{}; + binary_t value; + return get_number(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value); + } + + case 0x08: // boolean + { + return sax->boolean(get() != 0); + } + + case 0x0A: // null + { + return sax->null(); + } + + case 0x10: // int32 + { + std::int32_t value{}; + return get_number(input_format_t::bson, value) && sax->number_integer(value); + } + + case 0x12: // int64 + { + std::int64_t value{}; + return get_number(input_format_t::bson, value) && sax->number_integer(value); + } + + default: // anything else not supported (yet) + { + std::array cr{{}}; + static_cast((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + const std::string cr_str{cr.data()}; + return sax->parse_error(element_type_parse_position, cr_str, + parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr)); + } + } + } + + /*! + @brief Read a BSON element list (as specified in the BSON-spec) + + The same binary layout is used for objects and arrays, hence it must be + indicated with the argument @a is_array which one is expected + (true --> array, false --> object). + + @param[in] is_array Determines if the element list being read is to be + treated as an object (@a is_array == false), or as an + array (@a is_array == true). + @return whether a valid BSON-object/array was passed to the SAX parser + */ + bool parse_bson_element_list(const bool is_array) + { + string_t key; + + while (auto element_type = get()) + { + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list"))) + { + return false; + } + + const std::size_t element_type_parse_position = chars_read; + if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key))) + { + return false; + } + + if (!is_array && !sax->key(key)) + { + return false; + } + + if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position))) + { + return false; + } + + // get_bson_cstr only appends + key.clear(); + } + + return true; + } + + /*! + @brief Reads an array from the BSON input and passes it to the SAX-parser. + @return whether a valid BSON-array was passed to the SAX parser + */ + bool parse_bson_array() + { + std::int32_t document_size{}; + get_number(input_format_t::bson, document_size); + + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast(-1)))) + { + return false; + } + + if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true))) + { + return false; + } + + return sax->end_array(); + } + + ////////// + // CBOR // + ////////// + + /*! + @param[in] get_char whether a new character should be retrieved from the + input (true) or whether the last read character should + be considered instead (false) + @param[in] tag_handler how CBOR tags should be treated + + @return whether a valid CBOR value was passed to the SAX parser + */ + bool parse_cbor_internal(const bool get_char, + const cbor_tag_handler_t tag_handler) + { + switch (get_char ? get() : current) + { + // EOF + case char_traits::eof(): + return unexpect_eof(input_format_t::cbor, "value"); + + // Integer 0x00..0x17 (0..23) + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x0A: + case 0x0B: + case 0x0C: + case 0x0D: + case 0x0E: + case 0x0F: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + return sax->number_unsigned(static_cast(current)); + + case 0x18: // Unsigned integer (one-byte uint8_t follows) + { + std::uint8_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); + } + + case 0x19: // Unsigned integer (two-byte uint16_t follows) + { + std::uint16_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); + } + + case 0x1A: // Unsigned integer (four-byte uint32_t follows) + { + std::uint32_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); + } + + case 0x1B: // Unsigned integer (eight-byte uint64_t follows) + { + std::uint64_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_unsigned(number); + } + + // Negative integer -1-0x00..-1-0x17 (-1..-24) + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + return sax->number_integer(static_cast(0x20 - 1 - current)); + + case 0x38: // Negative integer (one-byte uint8_t follows) + { + std::uint8_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); + } + + case 0x39: // Negative integer -1-n (two-byte uint16_t follows) + { + std::uint16_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); + } + + case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) + { + std::uint32_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) - number); + } + + case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) + { + std::uint64_t number{}; + return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast(-1) + - static_cast(number)); + } + + // Binary data (0x00..0x17 bytes follow) + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4A: + case 0x4B: + case 0x4C: + case 0x4D: + case 0x4E: + case 0x4F: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + case 0x58: // Binary data (one-byte uint8_t for n follows) + case 0x59: // Binary data (two-byte uint16_t for n follow) + case 0x5A: // Binary data (four-byte uint32_t for n follow) + case 0x5B: // Binary data (eight-byte uint64_t for n follow) + case 0x5F: // Binary data (indefinite length) + { + binary_t b; + return get_cbor_binary(b) && sax->binary(b); + } + + // UTF-8 string (0x00..0x17 bytes follow) + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6A: + case 0x6B: + case 0x6C: + case 0x6D: + case 0x6E: + case 0x6F: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + case 0x78: // UTF-8 string (one-byte uint8_t for n follows) + case 0x79: // UTF-8 string (two-byte uint16_t for n follow) + case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) + case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) + case 0x7F: // UTF-8 string (indefinite length) + { + string_t s; + return get_cbor_string(s) && sax->string(s); + } + + // array (0x00..0x17 data items follow) + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8A: + case 0x8B: + case 0x8C: + case 0x8D: + case 0x8E: + case 0x8F: + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + return get_cbor_array( + conditional_static_cast(static_cast(current) & 0x1Fu), tag_handler); + + case 0x98: // array (one-byte uint8_t for n follows) + { + std::uint8_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); + } + + case 0x99: // array (two-byte uint16_t for n follow) + { + std::uint16_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast(len), tag_handler); + } + + case 0x9A: // array (four-byte uint32_t for n follow) + { + std::uint32_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast(len), tag_handler); + } + + case 0x9B: // array (eight-byte uint64_t for n follow) + { + std::uint64_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast(len), tag_handler); + } + + case 0x9F: // array (indefinite length) + return get_cbor_array(static_cast(-1), tag_handler); + + // map (0x00..0x17 pairs of data items follow) + case 0xA0: + case 0xA1: + case 0xA2: + case 0xA3: + case 0xA4: + case 0xA5: + case 0xA6: + case 0xA7: + case 0xA8: + case 0xA9: + case 0xAA: + case 0xAB: + case 0xAC: + case 0xAD: + case 0xAE: + case 0xAF: + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: + return get_cbor_object(conditional_static_cast(static_cast(current) & 0x1Fu), tag_handler); + + case 0xB8: // map (one-byte uint8_t for n follows) + { + std::uint8_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); + } + + case 0xB9: // map (two-byte uint16_t for n follow) + { + std::uint16_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast(len), tag_handler); + } + + case 0xBA: // map (four-byte uint32_t for n follow) + { + std::uint32_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast(len), tag_handler); + } + + case 0xBB: // map (eight-byte uint64_t for n follow) + { + std::uint64_t len{}; + return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast(len), tag_handler); + } + + case 0xBF: // map (indefinite length) + return get_cbor_object(static_cast(-1), tag_handler); + + case 0xC6: // tagged item + case 0xC7: + case 0xC8: + case 0xC9: + case 0xCA: + case 0xCB: + case 0xCC: + case 0xCD: + case 0xCE: + case 0xCF: + case 0xD0: + case 0xD1: + case 0xD2: + case 0xD3: + case 0xD4: + case 0xD8: // tagged item (1 bytes follow) + case 0xD9: // tagged item (2 bytes follow) + case 0xDA: // tagged item (4 bytes follow) + case 0xDB: // tagged item (8 bytes follow) + { + switch (tag_handler) + { + case cbor_tag_handler_t::error: + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr)); + } + + case cbor_tag_handler_t::ignore: + { + // ignore binary subtype + switch (current) + { + case 0xD8: + { + std::uint8_t subtype_to_ignore{}; + get_number(input_format_t::cbor, subtype_to_ignore); + break; + } + case 0xD9: + { + std::uint16_t subtype_to_ignore{}; + get_number(input_format_t::cbor, subtype_to_ignore); + break; + } + case 0xDA: + { + std::uint32_t subtype_to_ignore{}; + get_number(input_format_t::cbor, subtype_to_ignore); + break; + } + case 0xDB: + { + std::uint64_t subtype_to_ignore{}; + get_number(input_format_t::cbor, subtype_to_ignore); + break; + } + default: + break; + } + return parse_cbor_internal(true, tag_handler); + } + + case cbor_tag_handler_t::store: + { + binary_t b; + // use binary subtype and store in binary container + switch (current) + { + case 0xD8: + { + std::uint8_t subtype{}; + get_number(input_format_t::cbor, subtype); + b.set_subtype(detail::conditional_static_cast(subtype)); + break; + } + case 0xD9: + { + std::uint16_t subtype{}; + get_number(input_format_t::cbor, subtype); + b.set_subtype(detail::conditional_static_cast(subtype)); + break; + } + case 0xDA: + { + std::uint32_t subtype{}; + get_number(input_format_t::cbor, subtype); + b.set_subtype(detail::conditional_static_cast(subtype)); + break; + } + case 0xDB: + { + std::uint64_t subtype{}; + get_number(input_format_t::cbor, subtype); + b.set_subtype(detail::conditional_static_cast(subtype)); + break; + } + default: + return parse_cbor_internal(true, tag_handler); + } + get(); + return get_cbor_binary(b) && sax->binary(b); + } + + default: // LCOV_EXCL_LINE + JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE + return false; // LCOV_EXCL_LINE + } + } + + case 0xF4: // false + return sax->boolean(false); + + case 0xF5: // true + return sax->boolean(true); + + case 0xF6: // null + return sax->null(); + + case 0xF9: // Half-Precision Float (two-byte IEEE 754) + { + const auto byte1_raw = get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) + { + return false; + } + const auto byte2_raw = get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number"))) + { + return false; + } + + const auto byte1 = static_cast(byte1_raw); + const auto byte2 = static_cast(byte2_raw); + + // code from RFC 7049, Appendix D, Figure 3: + // As half-precision floating-point numbers were only added + // to IEEE 754 in 2008, today's programming platforms often + // still only have limited support for them. It is very + // easy to include at least decoding support for them even + // without such support. An example of a small decoder for + // half-precision floating-point numbers in the C language + // is shown in Fig. 3. + const auto half = static_cast((byte1 << 8u) + byte2); + const double val = [&half] + { + const int exp = (half >> 10u) & 0x1Fu; + const unsigned int mant = half & 0x3FFu; + JSON_ASSERT(0 <= exp&& exp <= 32); + JSON_ASSERT(mant <= 1024); + switch (exp) + { + case 0: + return std::ldexp(mant, -24); + case 31: + return (mant == 0) + ? std::numeric_limits::infinity() + : std::numeric_limits::quiet_NaN(); + default: + return std::ldexp(mant + 1024, exp - 25); + } + }(); + return sax->number_float((half & 0x8000u) != 0 + ? static_cast(-val) + : static_cast(val), ""); + } + + case 0xFA: // Single-Precision Float (four-byte IEEE 754) + { + float number{}; + return get_number(input_format_t::cbor, number) && sax->number_float(static_cast(number), ""); + } + + case 0xFB: // Double-Precision Float (eight-byte IEEE 754) + { + double number{}; + return get_number(input_format_t::cbor, number) && sax->number_float(static_cast(number), ""); + } + + default: // anything else (0xFF is handled inside the other types) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr)); + } + } + } + + /*! + @brief reads a CBOR string + + This function first reads starting bytes to determine the expected + string length and then copies this number of bytes into a string. + Additionally, CBOR's strings with indefinite lengths are supported. + + @param[out] result created string + + @return whether string creation completed + */ + bool get_cbor_string(string_t& result) + { + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string"))) + { + return false; + } + + switch (current) + { + // UTF-8 string (0x00..0x17 bytes follow) + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6A: + case 0x6B: + case 0x6C: + case 0x6D: + case 0x6E: + case 0x6F: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + { + return get_string(input_format_t::cbor, static_cast(current) & 0x1Fu, result); + } + + case 0x78: // UTF-8 string (one-byte uint8_t for n follows) + { + std::uint8_t len{}; + return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); + } + + case 0x79: // UTF-8 string (two-byte uint16_t for n follow) + { + std::uint16_t len{}; + return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); + } + + case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) + { + std::uint32_t len{}; + return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); + } + + case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) + { + std::uint64_t len{}; + return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result); + } + + case 0x7F: // UTF-8 string (indefinite length) + { + while (get() != 0xFF) + { + string_t chunk; + if (!get_cbor_string(chunk)) + { + return false; + } + result.append(chunk); + } + return true; + } + + default: + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, + exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr)); + } + } + } + + /*! + @brief reads a CBOR byte array + + This function first reads starting bytes to determine the expected + byte array length and then copies this number of bytes into the byte array. + Additionally, CBOR's byte arrays with indefinite lengths are supported. + + @param[out] result created byte array + + @return whether byte array creation completed + */ + bool get_cbor_binary(binary_t& result) + { + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary"))) + { + return false; + } + + switch (current) + { + // Binary data (0x00..0x17 bytes follow) + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4A: + case 0x4B: + case 0x4C: + case 0x4D: + case 0x4E: + case 0x4F: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + { + return get_binary(input_format_t::cbor, static_cast(current) & 0x1Fu, result); + } + + case 0x58: // Binary data (one-byte uint8_t for n follows) + { + std::uint8_t len{}; + return get_number(input_format_t::cbor, len) && + get_binary(input_format_t::cbor, len, result); + } + + case 0x59: // Binary data (two-byte uint16_t for n follow) + { + std::uint16_t len{}; + return get_number(input_format_t::cbor, len) && + get_binary(input_format_t::cbor, len, result); + } + + case 0x5A: // Binary data (four-byte uint32_t for n follow) + { + std::uint32_t len{}; + return get_number(input_format_t::cbor, len) && + get_binary(input_format_t::cbor, len, result); + } + + case 0x5B: // Binary data (eight-byte uint64_t for n follow) + { + std::uint64_t len{}; + return get_number(input_format_t::cbor, len) && + get_binary(input_format_t::cbor, len, result); + } + + case 0x5F: // Binary data (indefinite length) + { + while (get() != 0xFF) + { + binary_t chunk; + if (!get_cbor_binary(chunk)) + { + return false; + } + result.insert(result.end(), chunk.begin(), chunk.end()); + } + return true; + } + + default: + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, + exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr)); + } + } + } + + /*! + @param[in] len the length of the array or static_cast(-1) for an + array of indefinite size + @param[in] tag_handler how CBOR tags should be treated + @return whether array creation completed + */ + bool get_cbor_array(const std::size_t len, + const cbor_tag_handler_t tag_handler) + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) + { + return false; + } + + if (len != static_cast(-1)) + { + for (std::size_t i = 0; i < len; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) + { + return false; + } + } + } + else + { + while (get() != 0xFF) + { + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler))) + { + return false; + } + } + } + + return sax->end_array(); + } + + /*! + @param[in] len the length of the object or static_cast(-1) for an + object of indefinite size + @param[in] tag_handler how CBOR tags should be treated + @return whether object creation completed + */ + bool get_cbor_object(const std::size_t len, + const cbor_tag_handler_t tag_handler) + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) + { + return false; + } + + if (len != 0) + { + string_t key; + if (len != static_cast(-1)) + { + for (std::size_t i = 0; i < len; ++i) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) + { + return false; + } + + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) + { + return false; + } + key.clear(); + } + } + else + { + while (get() != 0xFF) + { + if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key))) + { + return false; + } + + if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler))) + { + return false; + } + key.clear(); + } + } + } + + return sax->end_object(); + } + + ///////////// + // MsgPack // + ///////////// + + /*! + @return whether a valid MessagePack value was passed to the SAX parser + */ + bool parse_msgpack_internal() + { + switch (get()) + { + // EOF + case char_traits::eof(): + return unexpect_eof(input_format_t::msgpack, "value"); + + // positive fixint + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x0A: + case 0x0B: + case 0x0C: + case 0x0D: + case 0x0E: + case 0x0F: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + case 0x1A: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x1E: + case 0x1F: + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3A: + case 0x3B: + case 0x3C: + case 0x3D: + case 0x3E: + case 0x3F: + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4A: + case 0x4B: + case 0x4C: + case 0x4D: + case 0x4E: + case 0x4F: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + case 0x58: + case 0x59: + case 0x5A: + case 0x5B: + case 0x5C: + case 0x5D: + case 0x5E: + case 0x5F: + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6A: + case 0x6B: + case 0x6C: + case 0x6D: + case 0x6E: + case 0x6F: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + case 0x78: + case 0x79: + case 0x7A: + case 0x7B: + case 0x7C: + case 0x7D: + case 0x7E: + case 0x7F: + return sax->number_unsigned(static_cast(current)); + + // fixmap + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8A: + case 0x8B: + case 0x8C: + case 0x8D: + case 0x8E: + case 0x8F: + return get_msgpack_object(conditional_static_cast(static_cast(current) & 0x0Fu)); + + // fixarray + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + case 0x98: + case 0x99: + case 0x9A: + case 0x9B: + case 0x9C: + case 0x9D: + case 0x9E: + case 0x9F: + return get_msgpack_array(conditional_static_cast(static_cast(current) & 0x0Fu)); + + // fixstr + case 0xA0: + case 0xA1: + case 0xA2: + case 0xA3: + case 0xA4: + case 0xA5: + case 0xA6: + case 0xA7: + case 0xA8: + case 0xA9: + case 0xAA: + case 0xAB: + case 0xAC: + case 0xAD: + case 0xAE: + case 0xAF: + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: + case 0xB8: + case 0xB9: + case 0xBA: + case 0xBB: + case 0xBC: + case 0xBD: + case 0xBE: + case 0xBF: + case 0xD9: // str 8 + case 0xDA: // str 16 + case 0xDB: // str 32 + { + string_t s; + return get_msgpack_string(s) && sax->string(s); + } + + case 0xC0: // nil + return sax->null(); + + case 0xC2: // false + return sax->boolean(false); + + case 0xC3: // true + return sax->boolean(true); + + case 0xC4: // bin 8 + case 0xC5: // bin 16 + case 0xC6: // bin 32 + case 0xC7: // ext 8 + case 0xC8: // ext 16 + case 0xC9: // ext 32 + case 0xD4: // fixext 1 + case 0xD5: // fixext 2 + case 0xD6: // fixext 4 + case 0xD7: // fixext 8 + case 0xD8: // fixext 16 + { + binary_t b; + return get_msgpack_binary(b) && sax->binary(b); + } + + case 0xCA: // float 32 + { + float number{}; + return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast(number), ""); + } + + case 0xCB: // float 64 + { + double number{}; + return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast(number), ""); + } + + case 0xCC: // uint 8 + { + std::uint8_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); + } + + case 0xCD: // uint 16 + { + std::uint16_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); + } + + case 0xCE: // uint 32 + { + std::uint32_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); + } + + case 0xCF: // uint 64 + { + std::uint64_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number); + } + + case 0xD0: // int 8 + { + std::int8_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_integer(number); + } + + case 0xD1: // int 16 + { + std::int16_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_integer(number); + } + + case 0xD2: // int 32 + { + std::int32_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_integer(number); + } + + case 0xD3: // int 64 + { + std::int64_t number{}; + return get_number(input_format_t::msgpack, number) && sax->number_integer(number); + } + + case 0xDC: // array 16 + { + std::uint16_t len{}; + return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast(len)); + } + + case 0xDD: // array 32 + { + std::uint32_t len{}; + return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast(len)); + } + + case 0xDE: // map 16 + { + std::uint16_t len{}; + return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast(len)); + } + + case 0xDF: // map 32 + { + std::uint32_t len{}; + return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast(len)); + } + + // negative fixint + case 0xE0: + case 0xE1: + case 0xE2: + case 0xE3: + case 0xE4: + case 0xE5: + case 0xE6: + case 0xE7: + case 0xE8: + case 0xE9: + case 0xEA: + case 0xEB: + case 0xEC: + case 0xED: + case 0xEE: + case 0xEF: + case 0xF0: + case 0xF1: + case 0xF2: + case 0xF3: + case 0xF4: + case 0xF5: + case 0xF6: + case 0xF7: + case 0xF8: + case 0xF9: + case 0xFA: + case 0xFB: + case 0xFC: + case 0xFD: + case 0xFE: + case 0xFF: + return sax->number_integer(static_cast(current)); + + default: // anything else + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr)); + } + } + } + + /*! + @brief reads a MessagePack string + + This function first reads starting bytes to determine the expected + string length and then copies this number of bytes into a string. + + @param[out] result created string + + @return whether string creation completed + */ + bool get_msgpack_string(string_t& result) + { + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string"))) + { + return false; + } + + switch (current) + { + // fixstr + case 0xA0: + case 0xA1: + case 0xA2: + case 0xA3: + case 0xA4: + case 0xA5: + case 0xA6: + case 0xA7: + case 0xA8: + case 0xA9: + case 0xAA: + case 0xAB: + case 0xAC: + case 0xAD: + case 0xAE: + case 0xAF: + case 0xB0: + case 0xB1: + case 0xB2: + case 0xB3: + case 0xB4: + case 0xB5: + case 0xB6: + case 0xB7: + case 0xB8: + case 0xB9: + case 0xBA: + case 0xBB: + case 0xBC: + case 0xBD: + case 0xBE: + case 0xBF: + { + return get_string(input_format_t::msgpack, static_cast(current) & 0x1Fu, result); + } + + case 0xD9: // str 8 + { + std::uint8_t len{}; + return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); + } + + case 0xDA: // str 16 + { + std::uint16_t len{}; + return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); + } + + case 0xDB: // str 32 + { + std::uint32_t len{}; + return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result); + } + + default: + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, + exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr)); + } + } + } + + /*! + @brief reads a MessagePack byte array + + This function first reads starting bytes to determine the expected + byte array length and then copies this number of bytes into a byte array. + + @param[out] result created byte array + + @return whether byte array creation completed + */ + bool get_msgpack_binary(binary_t& result) + { + // helper function to set the subtype + auto assign_and_return_true = [&result](std::int8_t subtype) + { + result.set_subtype(static_cast(subtype)); + return true; + }; + + switch (current) + { + case 0xC4: // bin 8 + { + std::uint8_t len{}; + return get_number(input_format_t::msgpack, len) && + get_binary(input_format_t::msgpack, len, result); + } + + case 0xC5: // bin 16 + { + std::uint16_t len{}; + return get_number(input_format_t::msgpack, len) && + get_binary(input_format_t::msgpack, len, result); + } + + case 0xC6: // bin 32 + { + std::uint32_t len{}; + return get_number(input_format_t::msgpack, len) && + get_binary(input_format_t::msgpack, len, result); + } + + case 0xC7: // ext 8 + { + std::uint8_t len{}; + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, len) && + get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, len, result) && + assign_and_return_true(subtype); + } + + case 0xC8: // ext 16 + { + std::uint16_t len{}; + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, len) && + get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, len, result) && + assign_and_return_true(subtype); + } + + case 0xC9: // ext 32 + { + std::uint32_t len{}; + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, len) && + get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, len, result) && + assign_and_return_true(subtype); + } + + case 0xD4: // fixext 1 + { + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 1, result) && + assign_and_return_true(subtype); + } + + case 0xD5: // fixext 2 + { + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 2, result) && + assign_and_return_true(subtype); + } + + case 0xD6: // fixext 4 + { + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 4, result) && + assign_and_return_true(subtype); + } + + case 0xD7: // fixext 8 + { + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 8, result) && + assign_and_return_true(subtype); + } + + case 0xD8: // fixext 16 + { + std::int8_t subtype{}; + return get_number(input_format_t::msgpack, subtype) && + get_binary(input_format_t::msgpack, 16, result) && + assign_and_return_true(subtype); + } + + default: // LCOV_EXCL_LINE + return false; // LCOV_EXCL_LINE + } + } + + /*! + @param[in] len the length of the array + @return whether array creation completed + */ + bool get_msgpack_array(const std::size_t len) + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len))) + { + return false; + } + + for (std::size_t i = 0; i < len; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) + { + return false; + } + } + + return sax->end_array(); + } + + /*! + @param[in] len the length of the object + @return whether object creation completed + */ + bool get_msgpack_object(const std::size_t len) + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len))) + { + return false; + } + + string_t key; + for (std::size_t i = 0; i < len; ++i) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key))) + { + return false; + } + + if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal())) + { + return false; + } + key.clear(); + } + + return sax->end_object(); + } + + //////////// + // UBJSON // + //////////// + + /*! + @param[in] get_char whether a new character should be retrieved from the + input (true, default) or whether the last read + character should be considered instead + + @return whether a valid UBJSON value was passed to the SAX parser + */ + bool parse_ubjson_internal(const bool get_char = true) + { + return get_ubjson_value(get_char ? get_ignore_noop() : current); + } + + /*! + @brief reads a UBJSON string + + This function is either called after reading the 'S' byte explicitly + indicating a string, or in case of an object key where the 'S' byte can be + left out. + + @param[out] result created string + @param[in] get_char whether a new character should be retrieved from the + input (true, default) or whether the last read + character should be considered instead + + @return whether string creation completed + */ + bool get_ubjson_string(string_t& result, const bool get_char = true) + { + if (get_char) + { + get(); // TODO(niels): may we ignore N here? + } + + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value"))) + { + return false; + } + + switch (current) + { + case 'U': + { + std::uint8_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'i': + { + std::int8_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'I': + { + std::int16_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'l': + { + std::int32_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'L': + { + std::int64_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'u': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint16_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'm': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint32_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + case 'M': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint64_t len{}; + return get_number(input_format, len) && get_string(input_format, len, result); + } + + default: + break; + } + auto last_token = get_token_string(); + std::string message; + + if (input_format != input_format_t::bjdata) + { + message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token; + } + else + { + message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token; + } + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr)); + } + + /*! + @param[out] dim an integer vector storing the ND array dimensions + @return whether reading ND array size vector is successful + */ + bool get_ubjson_ndarray_size(std::vector& dim) + { + std::pair size_and_type; + size_t dimlen = 0; + bool no_ndarray = true; + + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray))) + { + return false; + } + + if (size_and_type.first != npos) + { + if (size_and_type.second != 0) + { + if (size_and_type.second != 'N') + { + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second))) + { + return false; + } + dim.push_back(dimlen); + } + } + } + else + { + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray))) + { + return false; + } + dim.push_back(dimlen); + } + } + } + else + { + while (current != ']') + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current))) + { + return false; + } + dim.push_back(dimlen); + get_ignore_noop(); + } + } + return true; + } + + /*! + @param[out] result determined size + @param[in,out] is_ndarray for input, `true` means already inside an ndarray vector + or ndarray dimension is not allowed; `false` means ndarray + is allowed; for output, `true` means an ndarray is found; + is_ndarray can only return `true` when its initial value + is `false` + @param[in] prefix type marker if already read, otherwise set to 0 + + @return whether size determination completed + */ + bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0) + { + if (prefix == 0) + { + prefix = get_ignore_noop(); + } + + switch (prefix) + { + case 'U': + { + std::uint8_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + result = static_cast(number); + return true; + } + + case 'i': + { + std::int8_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + if (number < 0) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, + exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr)); + } + result = static_cast(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char + return true; + } + + case 'I': + { + std::int16_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + if (number < 0) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, + exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr)); + } + result = static_cast(number); + return true; + } + + case 'l': + { + std::int32_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + if (number < 0) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, + exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr)); + } + result = static_cast(number); + return true; + } + + case 'L': + { + std::int64_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + if (number < 0) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, + exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr)); + } + if (!value_in_range_of(number)) + { + return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, + exception_message(input_format, "integer value overflow", "size"), nullptr)); + } + result = static_cast(number); + return true; + } + + case 'u': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint16_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + result = static_cast(number); + return true; + } + + case 'm': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint32_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + result = conditional_static_cast(number); + return true; + } + + case 'M': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint64_t number{}; + if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number))) + { + return false; + } + if (!value_in_range_of(number)) + { + return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, + exception_message(input_format, "integer value overflow", "size"), nullptr)); + } + result = detail::conditional_static_cast(number); + return true; + } + + case '[': + { + if (input_format != input_format_t::bjdata) + { + break; + } + if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimensional vector is not allowed", "size"), nullptr)); + } + std::vector dim; + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim))) + { + return false; + } + if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector + { + result = dim.at(dim.size() - 1); + return true; + } + if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format + { + for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container + { + if ( i == 0 ) + { + result = 0; + return true; + } + } + + string_t key = "_ArraySize_"; + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size()))) + { + return false; + } + result = 1; + for (auto i : dim) + { + result *= i; + if (result == 0 || result == npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be npos as it is used to initialize size in get_ubjson_size_type() + { + return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr)); + } + if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast(i)))) + { + return false; + } + } + is_ndarray = true; + return sax->end_array(); + } + result = 0; + return true; + } + + default: + break; + } + auto last_token = get_token_string(); + std::string message; + + if (input_format != input_format_t::bjdata) + { + message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token; + } + else + { + message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token; + } + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr)); + } + + /*! + @brief determine the type and size for a container + + In the optimized UBJSON format, a type and a size can be provided to allow + for a more compact representation. + + @param[out] result pair of the size and the type + @param[in] inside_ndarray whether the parser is parsing an ND array dimensional vector + + @return whether pair creation completed + */ + bool get_ubjson_size_type(std::pair& result, bool inside_ndarray = false) + { + result.first = npos; // size + result.second = 0; // type + bool is_ndarray = false; + + get_ignore_noop(); + + if (current == '$') + { + result.second = get(); // must not ignore 'N', because 'N' maybe the type + if (input_format == input_format_t::bjdata + && JSON_HEDLEY_UNLIKELY(std::binary_search(bjd_optimized_type_markers.begin(), bjd_optimized_type_markers.end(), result.second))) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr)); + } + + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type"))) + { + return false; + } + + get_ignore_noop(); + if (JSON_HEDLEY_UNLIKELY(current != '#')) + { + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value"))) + { + return false; + } + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr)); + } + + const bool is_error = get_ubjson_size_value(result.first, is_ndarray); + if (input_format == input_format_t::bjdata && is_ndarray) + { + if (inside_ndarray) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read, + exception_message(input_format, "ndarray can not be recursive", "size"), nullptr)); + } + result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters + } + return is_error; + } + + if (current == '#') + { + const bool is_error = get_ubjson_size_value(result.first, is_ndarray); + if (input_format == input_format_t::bjdata && is_ndarray) + { + return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read, + exception_message(input_format, "ndarray requires both type and size", "size"), nullptr)); + } + return is_error; + } + + return true; + } + + /*! + @param prefix the previously read or set type prefix + @return whether value creation completed + */ + bool get_ubjson_value(const char_int_type prefix) + { + switch (prefix) + { + case char_traits::eof(): // EOF + return unexpect_eof(input_format, "value"); + + case 'T': // true + return sax->boolean(true); + case 'F': // false + return sax->boolean(false); + + case 'Z': // null + return sax->null(); + + case 'U': + { + std::uint8_t number{}; + return get_number(input_format, number) && sax->number_unsigned(number); + } + + case 'i': + { + std::int8_t number{}; + return get_number(input_format, number) && sax->number_integer(number); + } + + case 'I': + { + std::int16_t number{}; + return get_number(input_format, number) && sax->number_integer(number); + } + + case 'l': + { + std::int32_t number{}; + return get_number(input_format, number) && sax->number_integer(number); + } + + case 'L': + { + std::int64_t number{}; + return get_number(input_format, number) && sax->number_integer(number); + } + + case 'u': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint16_t number{}; + return get_number(input_format, number) && sax->number_unsigned(number); + } + + case 'm': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint32_t number{}; + return get_number(input_format, number) && sax->number_unsigned(number); + } + + case 'M': + { + if (input_format != input_format_t::bjdata) + { + break; + } + std::uint64_t number{}; + return get_number(input_format, number) && sax->number_unsigned(number); + } + + case 'h': + { + if (input_format != input_format_t::bjdata) + { + break; + } + const auto byte1_raw = get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number"))) + { + return false; + } + const auto byte2_raw = get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number"))) + { + return false; + } + + const auto byte1 = static_cast(byte1_raw); + const auto byte2 = static_cast(byte2_raw); + + // code from RFC 7049, Appendix D, Figure 3: + // As half-precision floating-point numbers were only added + // to IEEE 754 in 2008, today's programming platforms often + // still only have limited support for them. It is very + // easy to include at least decoding support for them even + // without such support. An example of a small decoder for + // half-precision floating-point numbers in the C language + // is shown in Fig. 3. + const auto half = static_cast((byte2 << 8u) + byte1); + const double val = [&half] + { + const int exp = (half >> 10u) & 0x1Fu; + const unsigned int mant = half & 0x3FFu; + JSON_ASSERT(0 <= exp&& exp <= 32); + JSON_ASSERT(mant <= 1024); + switch (exp) + { + case 0: + return std::ldexp(mant, -24); + case 31: + return (mant == 0) + ? std::numeric_limits::infinity() + : std::numeric_limits::quiet_NaN(); + default: + return std::ldexp(mant + 1024, exp - 25); + } + }(); + return sax->number_float((half & 0x8000u) != 0 + ? static_cast(-val) + : static_cast(val), ""); + } + + case 'd': + { + float number{}; + return get_number(input_format, number) && sax->number_float(static_cast(number), ""); + } + + case 'D': + { + double number{}; + return get_number(input_format, number) && sax->number_float(static_cast(number), ""); + } + + case 'H': + { + return get_ubjson_high_precision_number(); + } + + case 'C': // char + { + get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char"))) + { + return false; + } + if (JSON_HEDLEY_UNLIKELY(current > 127)) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, + exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr)); + } + string_t s(1, static_cast(current)); + return sax->string(s); + } + + case 'S': // string + { + string_t s; + return get_ubjson_string(s) && sax->string(s); + } + + case '[': // array + return get_ubjson_array(); + + case '{': // object + return get_ubjson_object(); + + default: // anything else + break; + } + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr)); + } + + /*! + @return whether array creation completed + */ + bool get_ubjson_array() + { + std::pair size_and_type; + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) + { + return false; + } + + // if bit-8 of size_and_type.second is set to 1, encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata): + // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]} + + if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0) + { + size_and_type.second &= ~(static_cast(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker + auto it = std::lower_bound(bjd_types_map.begin(), bjd_types_map.end(), size_and_type.second, [](const bjd_type & p, char_int_type t) + { + return p.first < t; + }); + string_t key = "_ArrayType_"; + if (JSON_HEDLEY_UNLIKELY(it == bjd_types_map.end() || it->first != size_and_type.second)) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr)); + } + + string_t type = it->second; // sax->string() takes a reference + if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(type))) + { + return false; + } + + if (size_and_type.second == 'C') + { + size_and_type.second = 'U'; + } + + key = "_ArrayData_"; + if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) )) + { + return false; + } + + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) + { + return false; + } + } + + return (sax->end_array() && sax->end_object()); + } + + if (size_and_type.first != npos) + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first))) + { + return false; + } + + if (size_and_type.second != 0) + { + if (size_and_type.second != 'N') + { + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) + { + return false; + } + } + } + } + else + { + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) + { + return false; + } + } + } + } + else + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast(-1)))) + { + return false; + } + + while (current != ']') + { + if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false))) + { + return false; + } + get_ignore_noop(); + } + } + + return sax->end_array(); + } + + /*! + @return whether object creation completed + */ + bool get_ubjson_object() + { + std::pair size_and_type; + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type))) + { + return false; + } + + // do not accept ND-array size in objects in BJData + if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0) + { + auto last_token = get_token_string(); + return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, + exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr)); + } + + string_t key; + if (size_and_type.first != npos) + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first))) + { + return false; + } + + if (size_and_type.second != 0) + { + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) + { + return false; + } + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second))) + { + return false; + } + key.clear(); + } + } + else + { + for (std::size_t i = 0; i < size_and_type.first; ++i) + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key))) + { + return false; + } + if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) + { + return false; + } + key.clear(); + } + } + } + else + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast(-1)))) + { + return false; + } + + while (current != '}') + { + if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key))) + { + return false; + } + if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal())) + { + return false; + } + get_ignore_noop(); + key.clear(); + } + } + + return sax->end_object(); + } + + // Note, no reader for UBJSON binary types is implemented because they do + // not exist + + bool get_ubjson_high_precision_number() + { + // get size of following number string + std::size_t size{}; + bool no_ndarray = true; + auto res = get_ubjson_size_value(size, no_ndarray); + if (JSON_HEDLEY_UNLIKELY(!res)) + { + return res; + } + + // get number string + std::vector number_vector; + for (std::size_t i = 0; i < size; ++i) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number"))) + { + return false; + } + number_vector.push_back(static_cast(current)); + } + + // parse number string + using ia_type = decltype(detail::input_adapter(number_vector)); + auto number_lexer = detail::lexer(detail::input_adapter(number_vector), false); + const auto result_number = number_lexer.scan(); + const auto number_string = number_lexer.get_token_string(); + const auto result_remainder = number_lexer.scan(); + + using token_type = typename detail::lexer_base::token_type; + + if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input)) + { + return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, + exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr)); + } + + switch (result_number) + { + case token_type::value_integer: + return sax->number_integer(number_lexer.get_number_integer()); + case token_type::value_unsigned: + return sax->number_unsigned(number_lexer.get_number_unsigned()); + case token_type::value_float: + return sax->number_float(number_lexer.get_number_float(), std::move(number_string)); + case token_type::uninitialized: + case token_type::literal_true: + case token_type::literal_false: + case token_type::literal_null: + case token_type::value_string: + case token_type::begin_array: + case token_type::begin_object: + case token_type::end_array: + case token_type::end_object: + case token_type::name_separator: + case token_type::value_separator: + case token_type::parse_error: + case token_type::end_of_input: + case token_type::literal_or_value: + default: + return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, + exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr)); + } + } + + /////////////////////// + // Utility functions // + /////////////////////// + + /*! + @brief get next character from the input + + This function provides the interface to the used input adapter. It does + not throw in case the input reached EOF, but returns a -'ve valued + `char_traits::eof()` in that case. + + @return character read from the input + */ + char_int_type get() + { + ++chars_read; + return current = ia.get_character(); + } + + /*! + @return character read from the input after ignoring all 'N' entries + */ + char_int_type get_ignore_noop() + { + do + { + get(); + } + while (current == 'N'); + + return current; + } + + /* + @brief read a number from the input + + @tparam NumberType the type of the number + @param[in] format the current format (for diagnostics) + @param[out] result number of type @a NumberType + + @return whether conversion completed + + @note This function needs to respect the system's endianness, because + bytes in CBOR, MessagePack, and UBJSON are stored in network order + (big endian) and therefore need reordering on little endian systems. + On the other hand, BSON and BJData use little endian and should reorder + on big endian systems. + */ + template + bool get_number(const input_format_t format, NumberType& result) + { + // step 1: read input into array with system's byte order + std::array vec{}; + for (std::size_t i = 0; i < sizeof(NumberType); ++i) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number"))) + { + return false; + } + + // reverse byte order prior to conversion if necessary + if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata)) + { + vec[sizeof(NumberType) - i - 1] = static_cast(current); + } + else + { + vec[i] = static_cast(current); // LCOV_EXCL_LINE + } + } + + // step 2: convert array into number of type T and return + std::memcpy(&result, vec.data(), sizeof(NumberType)); + return true; + } + + /*! + @brief create a string by reading characters from the input + + @tparam NumberType the type of the number + @param[in] format the current format (for diagnostics) + @param[in] len number of characters to read + @param[out] result string created by reading @a len bytes + + @return whether string creation completed + + @note We can not reserve @a len bytes for the result, because @a len + may be too large. Usually, @ref unexpect_eof() detects the end of + the input before we run out of string memory. + */ + template + bool get_string(const input_format_t format, + const NumberType len, + string_t& result) + { + bool success = true; + for (NumberType i = 0; i < len; i++) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string"))) + { + success = false; + break; + } + result.push_back(static_cast(current)); + } + return success; + } + + /*! + @brief create a byte array by reading bytes from the input + + @tparam NumberType the type of the number + @param[in] format the current format (for diagnostics) + @param[in] len number of bytes to read + @param[out] result byte array created by reading @a len bytes + + @return whether byte array creation completed + + @note We can not reserve @a len bytes for the result, because @a len + may be too large. Usually, @ref unexpect_eof() detects the end of + the input before we run out of memory. + */ + template + bool get_binary(const input_format_t format, + const NumberType len, + binary_t& result) + { + bool success = true; + for (NumberType i = 0; i < len; i++) + { + get(); + if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary"))) + { + success = false; + break; + } + result.push_back(static_cast(current)); + } + return success; + } + + /*! + @param[in] format the current format (for diagnostics) + @param[in] context further context information (for diagnostics) + @return whether the last read character is not EOF + */ + JSON_HEDLEY_NON_NULL(3) + bool unexpect_eof(const input_format_t format, const char* context) const + { + if (JSON_HEDLEY_UNLIKELY(current == char_traits::eof())) + { + return sax->parse_error(chars_read, "", + parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr)); + } + return true; + } + + /*! + @return a string representation of the last read byte + */ + std::string get_token_string() const + { + std::array cr{{}}; + static_cast((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + return std::string{cr.data()}; + } + + /*! + @param[in] format the current format + @param[in] detail a detailed error message + @param[in] context further context information + @return a message string to use in the parse_error exceptions + */ + std::string exception_message(const input_format_t format, + const std::string& detail, + const std::string& context) const + { + std::string error_msg = "syntax error while parsing "; + + switch (format) + { + case input_format_t::cbor: + error_msg += "CBOR"; + break; + + case input_format_t::msgpack: + error_msg += "MessagePack"; + break; + + case input_format_t::ubjson: + error_msg += "UBJSON"; + break; + + case input_format_t::bson: + error_msg += "BSON"; + break; + + case input_format_t::bjdata: + error_msg += "BJData"; + break; + + case input_format_t::json: // LCOV_EXCL_LINE + default: // LCOV_EXCL_LINE + JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE + } + + return concat(error_msg, ' ', context, ": ", detail); + } + + private: + static JSON_INLINE_VARIABLE constexpr std::size_t npos = static_cast(-1); + + /// input adapter + InputAdapterType ia; + + /// the current character + char_int_type current = char_traits::eof(); + + /// the number of characters read + std::size_t chars_read = 0; + + /// whether we can assume little endianness + const bool is_little_endian = little_endianness(); + + /// input format + const input_format_t input_format = input_format_t::json; + + /// the SAX parser + json_sax_t* sax = nullptr; + + // excluded markers in bjdata optimized type +#define JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ \ + make_array('F', 'H', 'N', 'S', 'T', 'Z', '[', '{') + +#define JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ \ + make_array( \ + bjd_type{'C', "char"}, \ + bjd_type{'D', "double"}, \ + bjd_type{'I', "int16"}, \ + bjd_type{'L', "int64"}, \ + bjd_type{'M', "uint64"}, \ + bjd_type{'U', "uint8"}, \ + bjd_type{'d', "single"}, \ + bjd_type{'i', "int8"}, \ + bjd_type{'l', "int32"}, \ + bjd_type{'m', "uint32"}, \ + bjd_type{'u', "uint16"}) + + JSON_PRIVATE_UNLESS_TESTED: + // lookup tables + // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes) + const decltype(JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_) bjd_optimized_type_markers = + JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_; + + using bjd_type = std::pair; + // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes) + const decltype(JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_) bjd_types_map = + JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_; + +#undef JSON_BINARY_READER_MAKE_BJD_OPTIMIZED_TYPE_MARKERS_ +#undef JSON_BINARY_READER_MAKE_BJD_TYPES_MAP_ +}; + +#ifndef JSON_HAS_CPP_17 + template + constexpr std::size_t binary_reader::npos; +#endif + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/input/input_adapters.hpp b/vulkan/nlohmann/detail/input/input_adapters.hpp new file mode 100644 index 0000000..33fca3e --- /dev/null +++ b/vulkan/nlohmann/detail/input/input_adapters.hpp @@ -0,0 +1,492 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // array +#include // size_t +#include // strlen +#include // begin, end, iterator_traits, random_access_iterator_tag, distance, next +#include // shared_ptr, make_shared, addressof +#include // accumulate +#include // string, char_traits +#include // enable_if, is_base_of, is_pointer, is_integral, remove_pointer +#include // pair, declval + +#ifndef JSON_NO_IO + #include // FILE * + #include // istream +#endif // JSON_NO_IO + +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/// the supported input formats +enum class input_format_t { json, cbor, msgpack, ubjson, bson, bjdata }; + +//////////////////// +// input adapters // +//////////////////// + +#ifndef JSON_NO_IO +/*! +Input adapter for stdio file access. This adapter read only 1 byte and do not use any + buffer. This adapter is a very low level adapter. +*/ +class file_input_adapter +{ + public: + using char_type = char; + + JSON_HEDLEY_NON_NULL(2) + explicit file_input_adapter(std::FILE* f) noexcept + : m_file(f) + { + JSON_ASSERT(m_file != nullptr); + } + + // make class move-only + file_input_adapter(const file_input_adapter&) = delete; + file_input_adapter(file_input_adapter&&) noexcept = default; + file_input_adapter& operator=(const file_input_adapter&) = delete; + file_input_adapter& operator=(file_input_adapter&&) = delete; + ~file_input_adapter() = default; + + std::char_traits::int_type get_character() noexcept + { + return std::fgetc(m_file); + } + + private: + /// the file pointer to read from + std::FILE* m_file; +}; + +/*! +Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at +beginning of input. Does not support changing the underlying std::streambuf +in mid-input. Maintains underlying std::istream and std::streambuf to support +subsequent use of standard std::istream operations to process any input +characters following those used in parsing the JSON input. Clears the +std::istream flags; any input errors (e.g., EOF) will be detected by the first +subsequent call for input from the std::istream. +*/ +class input_stream_adapter +{ + public: + using char_type = char; + + ~input_stream_adapter() + { + // clear stream flags; we use underlying streambuf I/O, do not + // maintain ifstream flags, except eof + if (is != nullptr) + { + is->clear(is->rdstate() & std::ios::eofbit); + } + } + + explicit input_stream_adapter(std::istream& i) + : is(&i), sb(i.rdbuf()) + {} + + // delete because of pointer members + input_stream_adapter(const input_stream_adapter&) = delete; + input_stream_adapter& operator=(input_stream_adapter&) = delete; + input_stream_adapter& operator=(input_stream_adapter&&) = delete; + + input_stream_adapter(input_stream_adapter&& rhs) noexcept + : is(rhs.is), sb(rhs.sb) + { + rhs.is = nullptr; + rhs.sb = nullptr; + } + + // std::istream/std::streambuf use std::char_traits::to_int_type, to + // ensure that std::char_traits::eof() and the character 0xFF do not + // end up as the same value, e.g. 0xFFFFFFFF. + std::char_traits::int_type get_character() + { + auto res = sb->sbumpc(); + // set eof manually, as we don't use the istream interface. + if (JSON_HEDLEY_UNLIKELY(res == std::char_traits::eof())) + { + is->clear(is->rdstate() | std::ios::eofbit); + } + return res; + } + + private: + /// the associated input stream + std::istream* is = nullptr; + std::streambuf* sb = nullptr; +}; +#endif // JSON_NO_IO + +// General-purpose iterator-based adapter. It might not be as fast as +// theoretically possible for some containers, but it is extremely versatile. +template +class iterator_input_adapter +{ + public: + using char_type = typename std::iterator_traits::value_type; + + iterator_input_adapter(IteratorType first, IteratorType last) + : current(std::move(first)), end(std::move(last)) + {} + + typename char_traits::int_type get_character() + { + if (JSON_HEDLEY_LIKELY(current != end)) + { + auto result = char_traits::to_int_type(*current); + std::advance(current, 1); + return result; + } + + return char_traits::eof(); + } + + private: + IteratorType current; + IteratorType end; + + template + friend struct wide_string_input_helper; + + bool empty() const + { + return current == end; + } +}; + +template +struct wide_string_input_helper; + +template +struct wide_string_input_helper +{ + // UTF-32 + static void fill_buffer(BaseInputAdapter& input, + std::array::int_type, 4>& utf8_bytes, + size_t& utf8_bytes_index, + size_t& utf8_bytes_filled) + { + utf8_bytes_index = 0; + + if (JSON_HEDLEY_UNLIKELY(input.empty())) + { + utf8_bytes[0] = std::char_traits::eof(); + utf8_bytes_filled = 1; + } + else + { + // get the current character + const auto wc = input.get_character(); + + // UTF-32 to UTF-8 encoding + if (wc < 0x80) + { + utf8_bytes[0] = static_cast::int_type>(wc); + utf8_bytes_filled = 1; + } + else if (wc <= 0x7FF) + { + utf8_bytes[0] = static_cast::int_type>(0xC0u | ((static_cast(wc) >> 6u) & 0x1Fu)); + utf8_bytes[1] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); + utf8_bytes_filled = 2; + } + else if (wc <= 0xFFFF) + { + utf8_bytes[0] = static_cast::int_type>(0xE0u | ((static_cast(wc) >> 12u) & 0x0Fu)); + utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); + utf8_bytes[2] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); + utf8_bytes_filled = 3; + } + else if (wc <= 0x10FFFF) + { + utf8_bytes[0] = static_cast::int_type>(0xF0u | ((static_cast(wc) >> 18u) & 0x07u)); + utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 12u) & 0x3Fu)); + utf8_bytes[2] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); + utf8_bytes[3] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); + utf8_bytes_filled = 4; + } + else + { + // unknown character + utf8_bytes[0] = static_cast::int_type>(wc); + utf8_bytes_filled = 1; + } + } + } +}; + +template +struct wide_string_input_helper +{ + // UTF-16 + static void fill_buffer(BaseInputAdapter& input, + std::array::int_type, 4>& utf8_bytes, + size_t& utf8_bytes_index, + size_t& utf8_bytes_filled) + { + utf8_bytes_index = 0; + + if (JSON_HEDLEY_UNLIKELY(input.empty())) + { + utf8_bytes[0] = std::char_traits::eof(); + utf8_bytes_filled = 1; + } + else + { + // get the current character + const auto wc = input.get_character(); + + // UTF-16 to UTF-8 encoding + if (wc < 0x80) + { + utf8_bytes[0] = static_cast::int_type>(wc); + utf8_bytes_filled = 1; + } + else if (wc <= 0x7FF) + { + utf8_bytes[0] = static_cast::int_type>(0xC0u | ((static_cast(wc) >> 6u))); + utf8_bytes[1] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); + utf8_bytes_filled = 2; + } + else if (0xD800 > wc || wc >= 0xE000) + { + utf8_bytes[0] = static_cast::int_type>(0xE0u | ((static_cast(wc) >> 12u))); + utf8_bytes[1] = static_cast::int_type>(0x80u | ((static_cast(wc) >> 6u) & 0x3Fu)); + utf8_bytes[2] = static_cast::int_type>(0x80u | (static_cast(wc) & 0x3Fu)); + utf8_bytes_filled = 3; + } + else + { + if (JSON_HEDLEY_UNLIKELY(!input.empty())) + { + const auto wc2 = static_cast(input.get_character()); + const auto charcode = 0x10000u + (((static_cast(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu)); + utf8_bytes[0] = static_cast::int_type>(0xF0u | (charcode >> 18u)); + utf8_bytes[1] = static_cast::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu)); + utf8_bytes[2] = static_cast::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu)); + utf8_bytes[3] = static_cast::int_type>(0x80u | (charcode & 0x3Fu)); + utf8_bytes_filled = 4; + } + else + { + utf8_bytes[0] = static_cast::int_type>(wc); + utf8_bytes_filled = 1; + } + } + } + } +}; + +// Wraps another input adapter to convert wide character types into individual bytes. +template +class wide_string_input_adapter +{ + public: + using char_type = char; + + wide_string_input_adapter(BaseInputAdapter base) + : base_adapter(base) {} + + typename std::char_traits::int_type get_character() noexcept + { + // check if buffer needs to be filled + if (utf8_bytes_index == utf8_bytes_filled) + { + fill_buffer(); + + JSON_ASSERT(utf8_bytes_filled > 0); + JSON_ASSERT(utf8_bytes_index == 0); + } + + // use buffer + JSON_ASSERT(utf8_bytes_filled > 0); + JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled); + return utf8_bytes[utf8_bytes_index++]; + } + + private: + BaseInputAdapter base_adapter; + + template + void fill_buffer() + { + wide_string_input_helper::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled); + } + + /// a buffer for UTF-8 bytes + std::array::int_type, 4> utf8_bytes = {{0, 0, 0, 0}}; + + /// index to the utf8_codes array for the next valid byte + std::size_t utf8_bytes_index = 0; + /// number of valid bytes in the utf8_codes array + std::size_t utf8_bytes_filled = 0; +}; + +template +struct iterator_input_adapter_factory +{ + using iterator_type = IteratorType; + using char_type = typename std::iterator_traits::value_type; + using adapter_type = iterator_input_adapter; + + static adapter_type create(IteratorType first, IteratorType last) + { + return adapter_type(std::move(first), std::move(last)); + } +}; + +template +struct is_iterator_of_multibyte +{ + using value_type = typename std::iterator_traits::value_type; + enum + { + value = sizeof(value_type) > 1 + }; +}; + +template +struct iterator_input_adapter_factory::value>> +{ + using iterator_type = IteratorType; + using char_type = typename std::iterator_traits::value_type; + using base_adapter_type = iterator_input_adapter; + using adapter_type = wide_string_input_adapter; + + static adapter_type create(IteratorType first, IteratorType last) + { + return adapter_type(base_adapter_type(std::move(first), std::move(last))); + } +}; + +// General purpose iterator-based input +template +typename iterator_input_adapter_factory::adapter_type input_adapter(IteratorType first, IteratorType last) +{ + using factory_type = iterator_input_adapter_factory; + return factory_type::create(first, last); +} + +// Convenience shorthand from container to iterator +// Enables ADL on begin(container) and end(container) +// Encloses the using declarations in namespace for not to leak them to outside scope + +namespace container_input_adapter_factory_impl +{ + +using std::begin; +using std::end; + +template +struct container_input_adapter_factory {}; + +template +struct container_input_adapter_factory< ContainerType, + void_t()), end(std::declval()))>> + { + using adapter_type = decltype(input_adapter(begin(std::declval()), end(std::declval()))); + + static adapter_type create(const ContainerType& container) +{ + return input_adapter(begin(container), end(container)); +} + }; + +} // namespace container_input_adapter_factory_impl + +template +typename container_input_adapter_factory_impl::container_input_adapter_factory::adapter_type input_adapter(const ContainerType& container) +{ + return container_input_adapter_factory_impl::container_input_adapter_factory::create(container); +} + +#ifndef JSON_NO_IO +// Special cases with fast paths +inline file_input_adapter input_adapter(std::FILE* file) +{ + return file_input_adapter(file); +} + +inline input_stream_adapter input_adapter(std::istream& stream) +{ + return input_stream_adapter(stream); +} + +inline input_stream_adapter input_adapter(std::istream&& stream) +{ + return input_stream_adapter(stream); +} +#endif // JSON_NO_IO + +using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval(), std::declval())); + +// Null-delimited strings, and the like. +template < typename CharT, + typename std::enable_if < + std::is_pointer::value&& + !std::is_array::value&& + std::is_integral::type>::value&& + sizeof(typename std::remove_pointer::type) == 1, + int >::type = 0 > +contiguous_bytes_input_adapter input_adapter(CharT b) +{ + auto length = std::strlen(reinterpret_cast(b)); + const auto* ptr = reinterpret_cast(b); + return input_adapter(ptr, ptr + length); +} + +template +auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) +{ + return input_adapter(array, array + N); +} + +// This class only handles inputs of input_buffer_adapter type. +// It's required so that expressions like {ptr, len} can be implicitly cast +// to the correct adapter. +class span_input_adapter +{ + public: + template < typename CharT, + typename std::enable_if < + std::is_pointer::value&& + std::is_integral::type>::value&& + sizeof(typename std::remove_pointer::type) == 1, + int >::type = 0 > + span_input_adapter(CharT b, std::size_t l) + : ia(reinterpret_cast(b), reinterpret_cast(b) + l) {} + + template::iterator_category, std::random_access_iterator_tag>::value, + int>::type = 0> + span_input_adapter(IteratorType first, IteratorType last) + : ia(input_adapter(first, last)) {} + + contiguous_bytes_input_adapter&& get() + { + return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg) + } + + private: + contiguous_bytes_input_adapter ia; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/input/json_sax.hpp b/vulkan/nlohmann/detail/input/json_sax.hpp new file mode 100644 index 0000000..90583d6 --- /dev/null +++ b/vulkan/nlohmann/detail/input/json_sax.hpp @@ -0,0 +1,727 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include // string +#include // move +#include // vector + +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN + +/*! +@brief SAX interface + +This class describes the SAX interface used by @ref nlohmann::json::sax_parse. +Each function is called in different situations while the input is parsed. The +boolean return value informs the parser whether to continue processing the +input. +*/ +template +struct json_sax +{ + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + + /*! + @brief a null value was read + @return whether parsing should proceed + */ + virtual bool null() = 0; + + /*! + @brief a boolean value was read + @param[in] val boolean value + @return whether parsing should proceed + */ + virtual bool boolean(bool val) = 0; + + /*! + @brief an integer number was read + @param[in] val integer value + @return whether parsing should proceed + */ + virtual bool number_integer(number_integer_t val) = 0; + + /*! + @brief an unsigned integer number was read + @param[in] val unsigned integer value + @return whether parsing should proceed + */ + virtual bool number_unsigned(number_unsigned_t val) = 0; + + /*! + @brief a floating-point number was read + @param[in] val floating-point value + @param[in] s raw token value + @return whether parsing should proceed + */ + virtual bool number_float(number_float_t val, const string_t& s) = 0; + + /*! + @brief a string value was read + @param[in] val string value + @return whether parsing should proceed + @note It is safe to move the passed string value. + */ + virtual bool string(string_t& val) = 0; + + /*! + @brief a binary value was read + @param[in] val binary value + @return whether parsing should proceed + @note It is safe to move the passed binary value. + */ + virtual bool binary(binary_t& val) = 0; + + /*! + @brief the beginning of an object was read + @param[in] elements number of object elements or -1 if unknown + @return whether parsing should proceed + @note binary formats may report the number of elements + */ + virtual bool start_object(std::size_t elements) = 0; + + /*! + @brief an object key was read + @param[in] val object key + @return whether parsing should proceed + @note It is safe to move the passed string. + */ + virtual bool key(string_t& val) = 0; + + /*! + @brief the end of an object was read + @return whether parsing should proceed + */ + virtual bool end_object() = 0; + + /*! + @brief the beginning of an array was read + @param[in] elements number of array elements or -1 if unknown + @return whether parsing should proceed + @note binary formats may report the number of elements + */ + virtual bool start_array(std::size_t elements) = 0; + + /*! + @brief the end of an array was read + @return whether parsing should proceed + */ + virtual bool end_array() = 0; + + /*! + @brief a parse error occurred + @param[in] position the position in the input where the error occurs + @param[in] last_token the last read token + @param[in] ex an exception object describing the error + @return whether parsing should proceed (must return false) + */ + virtual bool parse_error(std::size_t position, + const std::string& last_token, + const detail::exception& ex) = 0; + + json_sax() = default; + json_sax(const json_sax&) = default; + json_sax(json_sax&&) noexcept = default; + json_sax& operator=(const json_sax&) = default; + json_sax& operator=(json_sax&&) noexcept = default; + virtual ~json_sax() = default; +}; + +namespace detail +{ +/*! +@brief SAX implementation to create a JSON value from SAX events + +This class implements the @ref json_sax interface and processes the SAX events +to create a JSON value which makes it basically a DOM parser. The structure or +hierarchy of the JSON value is managed by the stack `ref_stack` which contains +a pointer to the respective array or object for each recursion depth. + +After successful parsing, the value that is passed by reference to the +constructor contains the parsed value. + +@tparam BasicJsonType the JSON type +*/ +template +class json_sax_dom_parser +{ + public: + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + + /*! + @param[in,out] r reference to a JSON value that is manipulated while + parsing + @param[in] allow_exceptions_ whether parse errors yield exceptions + */ + explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true) + : root(r), allow_exceptions(allow_exceptions_) + {} + + // make class move-only + json_sax_dom_parser(const json_sax_dom_parser&) = delete; + json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete; + json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + ~json_sax_dom_parser() = default; + + bool null() + { + handle_value(nullptr); + return true; + } + + bool boolean(bool val) + { + handle_value(val); + return true; + } + + bool number_integer(number_integer_t val) + { + handle_value(val); + return true; + } + + bool number_unsigned(number_unsigned_t val) + { + handle_value(val); + return true; + } + + bool number_float(number_float_t val, const string_t& /*unused*/) + { + handle_value(val); + return true; + } + + bool string(string_t& val) + { + handle_value(val); + return true; + } + + bool binary(binary_t& val) + { + handle_value(std::move(val)); + return true; + } + + bool start_object(std::size_t len) + { + ref_stack.push_back(handle_value(BasicJsonType::value_t::object)); + + if (JSON_HEDLEY_UNLIKELY(len != static_cast(-1) && len > ref_stack.back()->max_size())) + { + JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back())); + } + + return true; + } + + bool key(string_t& val) + { + JSON_ASSERT(!ref_stack.empty()); + JSON_ASSERT(ref_stack.back()->is_object()); + + // add null at given key and store the reference for later + object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val)); + return true; + } + + bool end_object() + { + JSON_ASSERT(!ref_stack.empty()); + JSON_ASSERT(ref_stack.back()->is_object()); + + ref_stack.back()->set_parents(); + ref_stack.pop_back(); + return true; + } + + bool start_array(std::size_t len) + { + ref_stack.push_back(handle_value(BasicJsonType::value_t::array)); + + if (JSON_HEDLEY_UNLIKELY(len != static_cast(-1) && len > ref_stack.back()->max_size())) + { + JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back())); + } + + return true; + } + + bool end_array() + { + JSON_ASSERT(!ref_stack.empty()); + JSON_ASSERT(ref_stack.back()->is_array()); + + ref_stack.back()->set_parents(); + ref_stack.pop_back(); + return true; + } + + template + bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, + const Exception& ex) + { + errored = true; + static_cast(ex); + if (allow_exceptions) + { + JSON_THROW(ex); + } + return false; + } + + constexpr bool is_errored() const + { + return errored; + } + + private: + /*! + @invariant If the ref stack is empty, then the passed value will be the new + root. + @invariant If the ref stack contains a value, then it is an array or an + object to which we can add elements + */ + template + JSON_HEDLEY_RETURNS_NON_NULL + BasicJsonType* handle_value(Value&& v) + { + if (ref_stack.empty()) + { + root = BasicJsonType(std::forward(v)); + return &root; + } + + JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); + + if (ref_stack.back()->is_array()) + { + ref_stack.back()->m_data.m_value.array->emplace_back(std::forward(v)); + return &(ref_stack.back()->m_data.m_value.array->back()); + } + + JSON_ASSERT(ref_stack.back()->is_object()); + JSON_ASSERT(object_element); + *object_element = BasicJsonType(std::forward(v)); + return object_element; + } + + /// the parsed JSON value + BasicJsonType& root; + /// stack to model hierarchy of values + std::vector ref_stack {}; + /// helper to hold the reference for the next object element + BasicJsonType* object_element = nullptr; + /// whether a syntax error occurred + bool errored = false; + /// whether to throw exceptions in case of errors + const bool allow_exceptions = true; +}; + +template +class json_sax_dom_callback_parser +{ + public: + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + using parser_callback_t = typename BasicJsonType::parser_callback_t; + using parse_event_t = typename BasicJsonType::parse_event_t; + + json_sax_dom_callback_parser(BasicJsonType& r, + const parser_callback_t cb, + const bool allow_exceptions_ = true) + : root(r), callback(cb), allow_exceptions(allow_exceptions_) + { + keep_stack.push_back(true); + } + + // make class move-only + json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete; + json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete; + json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + ~json_sax_dom_callback_parser() = default; + + bool null() + { + handle_value(nullptr); + return true; + } + + bool boolean(bool val) + { + handle_value(val); + return true; + } + + bool number_integer(number_integer_t val) + { + handle_value(val); + return true; + } + + bool number_unsigned(number_unsigned_t val) + { + handle_value(val); + return true; + } + + bool number_float(number_float_t val, const string_t& /*unused*/) + { + handle_value(val); + return true; + } + + bool string(string_t& val) + { + handle_value(val); + return true; + } + + bool binary(binary_t& val) + { + handle_value(std::move(val)); + return true; + } + + bool start_object(std::size_t len) + { + // check callback for object start + const bool keep = callback(static_cast(ref_stack.size()), parse_event_t::object_start, discarded); + keep_stack.push_back(keep); + + auto val = handle_value(BasicJsonType::value_t::object, true); + ref_stack.push_back(val.second); + + // check object limit + if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast(-1) && len > ref_stack.back()->max_size())) + { + JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back())); + } + + return true; + } + + bool key(string_t& val) + { + BasicJsonType k = BasicJsonType(val); + + // check callback for key + const bool keep = callback(static_cast(ref_stack.size()), parse_event_t::key, k); + key_keep_stack.push_back(keep); + + // add discarded value at given key and store the reference for later + if (keep && ref_stack.back()) + { + object_element = &(ref_stack.back()->m_data.m_value.object->operator[](val) = discarded); + } + + return true; + } + + bool end_object() + { + if (ref_stack.back()) + { + if (!callback(static_cast(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back())) + { + // discard object + *ref_stack.back() = discarded; + } + else + { + ref_stack.back()->set_parents(); + } + } + + JSON_ASSERT(!ref_stack.empty()); + JSON_ASSERT(!keep_stack.empty()); + ref_stack.pop_back(); + keep_stack.pop_back(); + + if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured()) + { + // remove discarded value + for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it) + { + if (it->is_discarded()) + { + ref_stack.back()->erase(it); + break; + } + } + } + + return true; + } + + bool start_array(std::size_t len) + { + const bool keep = callback(static_cast(ref_stack.size()), parse_event_t::array_start, discarded); + keep_stack.push_back(keep); + + auto val = handle_value(BasicJsonType::value_t::array, true); + ref_stack.push_back(val.second); + + // check array limit + if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast(-1) && len > ref_stack.back()->max_size())) + { + JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back())); + } + + return true; + } + + bool end_array() + { + bool keep = true; + + if (ref_stack.back()) + { + keep = callback(static_cast(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back()); + if (keep) + { + ref_stack.back()->set_parents(); + } + else + { + // discard array + *ref_stack.back() = discarded; + } + } + + JSON_ASSERT(!ref_stack.empty()); + JSON_ASSERT(!keep_stack.empty()); + ref_stack.pop_back(); + keep_stack.pop_back(); + + // remove discarded value + if (!keep && !ref_stack.empty() && ref_stack.back()->is_array()) + { + ref_stack.back()->m_data.m_value.array->pop_back(); + } + + return true; + } + + template + bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, + const Exception& ex) + { + errored = true; + static_cast(ex); + if (allow_exceptions) + { + JSON_THROW(ex); + } + return false; + } + + constexpr bool is_errored() const + { + return errored; + } + + private: + /*! + @param[in] v value to add to the JSON value we build during parsing + @param[in] skip_callback whether we should skip calling the callback + function; this is required after start_array() and + start_object() SAX events, because otherwise we would call the + callback function with an empty array or object, respectively. + + @invariant If the ref stack is empty, then the passed value will be the new + root. + @invariant If the ref stack contains a value, then it is an array or an + object to which we can add elements + + @return pair of boolean (whether value should be kept) and pointer (to the + passed value in the ref_stack hierarchy; nullptr if not kept) + */ + template + std::pair handle_value(Value&& v, const bool skip_callback = false) + { + JSON_ASSERT(!keep_stack.empty()); + + // do not handle this value if we know it would be added to a discarded + // container + if (!keep_stack.back()) + { + return {false, nullptr}; + } + + // create value + auto value = BasicJsonType(std::forward(v)); + + // check callback + const bool keep = skip_callback || callback(static_cast(ref_stack.size()), parse_event_t::value, value); + + // do not handle this value if we just learnt it shall be discarded + if (!keep) + { + return {false, nullptr}; + } + + if (ref_stack.empty()) + { + root = std::move(value); + return {true, & root}; + } + + // skip this value if we already decided to skip the parent + // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360) + if (!ref_stack.back()) + { + return {false, nullptr}; + } + + // we now only expect arrays and objects + JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object()); + + // array + if (ref_stack.back()->is_array()) + { + ref_stack.back()->m_data.m_value.array->emplace_back(std::move(value)); + return {true, & (ref_stack.back()->m_data.m_value.array->back())}; + } + + // object + JSON_ASSERT(ref_stack.back()->is_object()); + // check if we should store an element for the current key + JSON_ASSERT(!key_keep_stack.empty()); + const bool store_element = key_keep_stack.back(); + key_keep_stack.pop_back(); + + if (!store_element) + { + return {false, nullptr}; + } + + JSON_ASSERT(object_element); + *object_element = std::move(value); + return {true, object_element}; + } + + /// the parsed JSON value + BasicJsonType& root; + /// stack to model hierarchy of values + std::vector ref_stack {}; + /// stack to manage which values to keep + std::vector keep_stack {}; // NOLINT(readability-redundant-member-init) + /// stack to manage which object keys to keep + std::vector key_keep_stack {}; // NOLINT(readability-redundant-member-init) + /// helper to hold the reference for the next object element + BasicJsonType* object_element = nullptr; + /// whether a syntax error occurred + bool errored = false; + /// callback function + const parser_callback_t callback = nullptr; + /// whether to throw exceptions in case of errors + const bool allow_exceptions = true; + /// a discarded value for the callback + BasicJsonType discarded = BasicJsonType::value_t::discarded; +}; + +template +class json_sax_acceptor +{ + public: + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + + bool null() + { + return true; + } + + bool boolean(bool /*unused*/) + { + return true; + } + + bool number_integer(number_integer_t /*unused*/) + { + return true; + } + + bool number_unsigned(number_unsigned_t /*unused*/) + { + return true; + } + + bool number_float(number_float_t /*unused*/, const string_t& /*unused*/) + { + return true; + } + + bool string(string_t& /*unused*/) + { + return true; + } + + bool binary(binary_t& /*unused*/) + { + return true; + } + + bool start_object(std::size_t /*unused*/ = static_cast(-1)) + { + return true; + } + + bool key(string_t& /*unused*/) + { + return true; + } + + bool end_object() + { + return true; + } + + bool start_array(std::size_t /*unused*/ = static_cast(-1)) + { + return true; + } + + bool end_array() + { + return true; + } + + bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/) + { + return false; + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/input/lexer.hpp b/vulkan/nlohmann/detail/input/lexer.hpp new file mode 100644 index 0000000..4b3bf77 --- /dev/null +++ b/vulkan/nlohmann/detail/input/lexer.hpp @@ -0,0 +1,1633 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // array +#include // localeconv +#include // size_t +#include // snprintf +#include // strtof, strtod, strtold, strtoll, strtoull +#include // initializer_list +#include // char_traits, string +#include // move +#include // vector + +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/////////// +// lexer // +/////////// + +template +class lexer_base +{ + public: + /// token types for the parser + enum class token_type + { + uninitialized, ///< indicating the scanner is uninitialized + literal_true, ///< the `true` literal + literal_false, ///< the `false` literal + literal_null, ///< the `null` literal + value_string, ///< a string -- use get_string() for actual value + value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value + value_integer, ///< a signed integer -- use get_number_integer() for actual value + value_float, ///< an floating point number -- use get_number_float() for actual value + begin_array, ///< the character for array begin `[` + begin_object, ///< the character for object begin `{` + end_array, ///< the character for array end `]` + end_object, ///< the character for object end `}` + name_separator, ///< the name separator `:` + value_separator, ///< the value separator `,` + parse_error, ///< indicating a parse error + end_of_input, ///< indicating the end of the input buffer + literal_or_value ///< a literal or the begin of a value (only for diagnostics) + }; + + /// return name of values of type token_type (only used for errors) + JSON_HEDLEY_RETURNS_NON_NULL + JSON_HEDLEY_CONST + static const char* token_type_name(const token_type t) noexcept + { + switch (t) + { + case token_type::uninitialized: + return ""; + case token_type::literal_true: + return "true literal"; + case token_type::literal_false: + return "false literal"; + case token_type::literal_null: + return "null literal"; + case token_type::value_string: + return "string literal"; + case token_type::value_unsigned: + case token_type::value_integer: + case token_type::value_float: + return "number literal"; + case token_type::begin_array: + return "'['"; + case token_type::begin_object: + return "'{'"; + case token_type::end_array: + return "']'"; + case token_type::end_object: + return "'}'"; + case token_type::name_separator: + return "':'"; + case token_type::value_separator: + return "','"; + case token_type::parse_error: + return ""; + case token_type::end_of_input: + return "end of input"; + case token_type::literal_or_value: + return "'[', '{', or a literal"; + // LCOV_EXCL_START + default: // catch non-enum values + return "unknown token"; + // LCOV_EXCL_STOP + } + } +}; +/*! +@brief lexical analysis + +This class organizes the lexical analysis during JSON deserialization. +*/ +template +class lexer : public lexer_base +{ + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using char_type = typename InputAdapterType::char_type; + using char_int_type = typename char_traits::int_type; + + public: + using token_type = typename lexer_base::token_type; + + explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept + : ia(std::move(adapter)) + , ignore_comments(ignore_comments_) + , decimal_point_char(static_cast(get_decimal_point())) + {} + + // delete because of pointer members + lexer(const lexer&) = delete; + lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + lexer& operator=(lexer&) = delete; + lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor) + ~lexer() = default; + + private: + ///////////////////// + // locales + ///////////////////// + + /// return the locale-dependent decimal point + JSON_HEDLEY_PURE + static char get_decimal_point() noexcept + { + const auto* loc = localeconv(); + JSON_ASSERT(loc != nullptr); + return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point); + } + + ///////////////////// + // scan functions + ///////////////////// + + /*! + @brief get codepoint from 4 hex characters following `\u` + + For input "\u c1 c2 c3 c4" the codepoint is: + (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 + = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0) + + Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f' + must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The + conversion is done by subtracting the offset (0x30, 0x37, and 0x57) + between the ASCII value of the character and the desired integer value. + + @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or + non-hex character) + */ + int get_codepoint() + { + // this function only makes sense after reading `\u` + JSON_ASSERT(current == 'u'); + int codepoint = 0; + + const auto factors = { 12u, 8u, 4u, 0u }; + for (const auto factor : factors) + { + get(); + + if (current >= '0' && current <= '9') + { + codepoint += static_cast((static_cast(current) - 0x30u) << factor); + } + else if (current >= 'A' && current <= 'F') + { + codepoint += static_cast((static_cast(current) - 0x37u) << factor); + } + else if (current >= 'a' && current <= 'f') + { + codepoint += static_cast((static_cast(current) - 0x57u) << factor); + } + else + { + return -1; + } + } + + JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF); + return codepoint; + } + + /*! + @brief check if the next byte(s) are inside a given range + + Adds the current byte and, for each passed range, reads a new byte and + checks if it is inside the range. If a violation was detected, set up an + error message and return false. Otherwise, return true. + + @param[in] ranges list of integers; interpreted as list of pairs of + inclusive lower and upper bound, respectively + + @pre The passed list @a ranges must have 2, 4, or 6 elements; that is, + 1, 2, or 3 pairs. This precondition is enforced by an assertion. + + @return true if and only if no range violation was detected + */ + bool next_byte_in_range(std::initializer_list ranges) + { + JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6); + add(current); + + for (auto range = ranges.begin(); range != ranges.end(); ++range) + { + get(); + if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range))) // NOLINT(bugprone-inc-dec-in-conditions) + { + add(current); + } + else + { + error_message = "invalid string: ill-formed UTF-8 byte"; + return false; + } + } + + return true; + } + + /*! + @brief scan a string literal + + This function scans a string according to Sect. 7 of RFC 8259. While + scanning, bytes are escaped and copied into buffer token_buffer. Then the + function returns successfully, token_buffer is *not* null-terminated (as it + may contain \0 bytes), and token_buffer.size() is the number of bytes in the + string. + + @return token_type::value_string if string could be successfully scanned, + token_type::parse_error otherwise + + @note In case of errors, variable error_message contains a textual + description. + */ + token_type scan_string() + { + // reset token_buffer (ignore opening quote) + reset(); + + // we entered the function by reading an open quote + JSON_ASSERT(current == '\"'); + + while (true) + { + // get next character + switch (get()) + { + // end of file while parsing string + case char_traits::eof(): + { + error_message = "invalid string: missing closing quote"; + return token_type::parse_error; + } + + // closing quote + case '\"': + { + return token_type::value_string; + } + + // escapes + case '\\': + { + switch (get()) + { + // quotation mark + case '\"': + add('\"'); + break; + // reverse solidus + case '\\': + add('\\'); + break; + // solidus + case '/': + add('/'); + break; + // backspace + case 'b': + add('\b'); + break; + // form feed + case 'f': + add('\f'); + break; + // line feed + case 'n': + add('\n'); + break; + // carriage return + case 'r': + add('\r'); + break; + // tab + case 't': + add('\t'); + break; + + // unicode escapes + case 'u': + { + const int codepoint1 = get_codepoint(); + int codepoint = codepoint1; // start with codepoint1 + + if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1)) + { + error_message = "invalid string: '\\u' must be followed by 4 hex digits"; + return token_type::parse_error; + } + + // check if code point is a high surrogate + if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF) + { + // expect next \uxxxx entry + if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u')) + { + const int codepoint2 = get_codepoint(); + + if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1)) + { + error_message = "invalid string: '\\u' must be followed by 4 hex digits"; + return token_type::parse_error; + } + + // check if codepoint2 is a low surrogate + if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF)) + { + // overwrite codepoint + codepoint = static_cast( + // high surrogate occupies the most significant 22 bits + (static_cast(codepoint1) << 10u) + // low surrogate occupies the least significant 15 bits + + static_cast(codepoint2) + // there is still the 0xD800, 0xDC00 and 0x10000 noise + // in the result, so we have to subtract with: + // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00 + - 0x35FDC00u); + } + else + { + error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF"; + return token_type::parse_error; + } + } + else + { + error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF"; + return token_type::parse_error; + } + } + else + { + if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF)) + { + error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF"; + return token_type::parse_error; + } + } + + // result of the above calculation yields a proper codepoint + JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF); + + // translate codepoint into bytes + if (codepoint < 0x80) + { + // 1-byte characters: 0xxxxxxx (ASCII) + add(static_cast(codepoint)); + } + else if (codepoint <= 0x7FF) + { + // 2-byte characters: 110xxxxx 10xxxxxx + add(static_cast(0xC0u | (static_cast(codepoint) >> 6u))); + add(static_cast(0x80u | (static_cast(codepoint) & 0x3Fu))); + } + else if (codepoint <= 0xFFFF) + { + // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx + add(static_cast(0xE0u | (static_cast(codepoint) >> 12u))); + add(static_cast(0x80u | ((static_cast(codepoint) >> 6u) & 0x3Fu))); + add(static_cast(0x80u | (static_cast(codepoint) & 0x3Fu))); + } + else + { + // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + add(static_cast(0xF0u | (static_cast(codepoint) >> 18u))); + add(static_cast(0x80u | ((static_cast(codepoint) >> 12u) & 0x3Fu))); + add(static_cast(0x80u | ((static_cast(codepoint) >> 6u) & 0x3Fu))); + add(static_cast(0x80u | (static_cast(codepoint) & 0x3Fu))); + } + + break; + } + + // other characters after escape + default: + error_message = "invalid string: forbidden character after backslash"; + return token_type::parse_error; + } + + break; + } + + // invalid control characters + case 0x00: + { + error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000"; + return token_type::parse_error; + } + + case 0x01: + { + error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001"; + return token_type::parse_error; + } + + case 0x02: + { + error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002"; + return token_type::parse_error; + } + + case 0x03: + { + error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003"; + return token_type::parse_error; + } + + case 0x04: + { + error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004"; + return token_type::parse_error; + } + + case 0x05: + { + error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005"; + return token_type::parse_error; + } + + case 0x06: + { + error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006"; + return token_type::parse_error; + } + + case 0x07: + { + error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007"; + return token_type::parse_error; + } + + case 0x08: + { + error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b"; + return token_type::parse_error; + } + + case 0x09: + { + error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t"; + return token_type::parse_error; + } + + case 0x0A: + { + error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n"; + return token_type::parse_error; + } + + case 0x0B: + { + error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B"; + return token_type::parse_error; + } + + case 0x0C: + { + error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f"; + return token_type::parse_error; + } + + case 0x0D: + { + error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r"; + return token_type::parse_error; + } + + case 0x0E: + { + error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E"; + return token_type::parse_error; + } + + case 0x0F: + { + error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F"; + return token_type::parse_error; + } + + case 0x10: + { + error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010"; + return token_type::parse_error; + } + + case 0x11: + { + error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011"; + return token_type::parse_error; + } + + case 0x12: + { + error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012"; + return token_type::parse_error; + } + + case 0x13: + { + error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013"; + return token_type::parse_error; + } + + case 0x14: + { + error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014"; + return token_type::parse_error; + } + + case 0x15: + { + error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015"; + return token_type::parse_error; + } + + case 0x16: + { + error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016"; + return token_type::parse_error; + } + + case 0x17: + { + error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017"; + return token_type::parse_error; + } + + case 0x18: + { + error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018"; + return token_type::parse_error; + } + + case 0x19: + { + error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019"; + return token_type::parse_error; + } + + case 0x1A: + { + error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A"; + return token_type::parse_error; + } + + case 0x1B: + { + error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B"; + return token_type::parse_error; + } + + case 0x1C: + { + error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C"; + return token_type::parse_error; + } + + case 0x1D: + { + error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D"; + return token_type::parse_error; + } + + case 0x1E: + { + error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E"; + return token_type::parse_error; + } + + case 0x1F: + { + error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F"; + return token_type::parse_error; + } + + // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace)) + case 0x20: + case 0x21: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3A: + case 0x3B: + case 0x3C: + case 0x3D: + case 0x3E: + case 0x3F: + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4A: + case 0x4B: + case 0x4C: + case 0x4D: + case 0x4E: + case 0x4F: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + case 0x58: + case 0x59: + case 0x5A: + case 0x5B: + case 0x5D: + case 0x5E: + case 0x5F: + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6A: + case 0x6B: + case 0x6C: + case 0x6D: + case 0x6E: + case 0x6F: + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + case 0x78: + case 0x79: + case 0x7A: + case 0x7B: + case 0x7C: + case 0x7D: + case 0x7E: + case 0x7F: + { + add(current); + break; + } + + // U+0080..U+07FF: bytes C2..DF 80..BF + case 0xC2: + case 0xC3: + case 0xC4: + case 0xC5: + case 0xC6: + case 0xC7: + case 0xC8: + case 0xC9: + case 0xCA: + case 0xCB: + case 0xCC: + case 0xCD: + case 0xCE: + case 0xCF: + case 0xD0: + case 0xD1: + case 0xD2: + case 0xD3: + case 0xD4: + case 0xD5: + case 0xD6: + case 0xD7: + case 0xD8: + case 0xD9: + case 0xDA: + case 0xDB: + case 0xDC: + case 0xDD: + case 0xDE: + case 0xDF: + { + if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF}))) + { + return token_type::parse_error; + } + break; + } + + // U+0800..U+0FFF: bytes E0 A0..BF 80..BF + case 0xE0: + { + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF})))) + { + return token_type::parse_error; + } + break; + } + + // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF + // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF + case 0xE1: + case 0xE2: + case 0xE3: + case 0xE4: + case 0xE5: + case 0xE6: + case 0xE7: + case 0xE8: + case 0xE9: + case 0xEA: + case 0xEB: + case 0xEC: + case 0xEE: + case 0xEF: + { + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF})))) + { + return token_type::parse_error; + } + break; + } + + // U+D000..U+D7FF: bytes ED 80..9F 80..BF + case 0xED: + { + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF})))) + { + return token_type::parse_error; + } + break; + } + + // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF + case 0xF0: + { + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) + { + return token_type::parse_error; + } + break; + } + + // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF + case 0xF1: + case 0xF2: + case 0xF3: + { + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF})))) + { + return token_type::parse_error; + } + break; + } + + // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF + case 0xF4: + { + if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF})))) + { + return token_type::parse_error; + } + break; + } + + // remaining bytes (80..C1 and F5..FF) are ill-formed + default: + { + error_message = "invalid string: ill-formed UTF-8 byte"; + return token_type::parse_error; + } + } + } + } + + /*! + * @brief scan a comment + * @return whether comment could be scanned successfully + */ + bool scan_comment() + { + switch (get()) + { + // single-line comments skip input until a newline or EOF is read + case '/': + { + while (true) + { + switch (get()) + { + case '\n': + case '\r': + case char_traits::eof(): + case '\0': + return true; + + default: + break; + } + } + } + + // multi-line comments skip input until */ is read + case '*': + { + while (true) + { + switch (get()) + { + case char_traits::eof(): + case '\0': + { + error_message = "invalid comment; missing closing '*/'"; + return false; + } + + case '*': + { + switch (get()) + { + case '/': + return true; + + default: + { + unget(); + continue; + } + } + } + + default: + continue; + } + } + } + + // unexpected character after reading '/' + default: + { + error_message = "invalid comment; expecting '/' or '*' after '/'"; + return false; + } + } + } + + JSON_HEDLEY_NON_NULL(2) + static void strtof(float& f, const char* str, char** endptr) noexcept + { + f = std::strtof(str, endptr); + } + + JSON_HEDLEY_NON_NULL(2) + static void strtof(double& f, const char* str, char** endptr) noexcept + { + f = std::strtod(str, endptr); + } + + JSON_HEDLEY_NON_NULL(2) + static void strtof(long double& f, const char* str, char** endptr) noexcept + { + f = std::strtold(str, endptr); + } + + /*! + @brief scan a number literal + + This function scans a string according to Sect. 6 of RFC 8259. + + The function is realized with a deterministic finite state machine derived + from the grammar described in RFC 8259. Starting in state "init", the + input is read and used to determined the next state. Only state "done" + accepts the number. State "error" is a trap state to model errors. In the + table below, "anything" means any character but the ones listed before. + + state | 0 | 1-9 | e E | + | - | . | anything + ---------|----------|----------|----------|---------|---------|----------|----------- + init | zero | any1 | [error] | [error] | minus | [error] | [error] + minus | zero | any1 | [error] | [error] | [error] | [error] | [error] + zero | done | done | exponent | done | done | decimal1 | done + any1 | any1 | any1 | exponent | done | done | decimal1 | done + decimal1 | decimal2 | decimal2 | [error] | [error] | [error] | [error] | [error] + decimal2 | decimal2 | decimal2 | exponent | done | done | done | done + exponent | any2 | any2 | [error] | sign | sign | [error] | [error] + sign | any2 | any2 | [error] | [error] | [error] | [error] | [error] + any2 | any2 | any2 | done | done | done | done | done + + The state machine is realized with one label per state (prefixed with + "scan_number_") and `goto` statements between them. The state machine + contains cycles, but any cycle can be left when EOF is read. Therefore, + the function is guaranteed to terminate. + + During scanning, the read bytes are stored in token_buffer. This string is + then converted to a signed integer, an unsigned integer, or a + floating-point number. + + @return token_type::value_unsigned, token_type::value_integer, or + token_type::value_float if number could be successfully scanned, + token_type::parse_error otherwise + + @note The scanner is independent of the current locale. Internally, the + locale's decimal point is used instead of `.` to work with the + locale-dependent converters. + */ + token_type scan_number() // lgtm [cpp/use-of-goto] + { + // reset token_buffer to store the number's bytes + reset(); + + // the type of the parsed number; initially set to unsigned; will be + // changed if minus sign, decimal point or exponent is read + token_type number_type = token_type::value_unsigned; + + // state (init): we just found out we need to scan a number + switch (current) + { + case '-': + { + add(current); + goto scan_number_minus; + } + + case '0': + { + add(current); + goto scan_number_zero; + } + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_any1; + } + + // all other characters are rejected outside scan_number() + default: // LCOV_EXCL_LINE + JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE + } + +scan_number_minus: + // state: we just parsed a leading minus sign + number_type = token_type::value_integer; + switch (get()) + { + case '0': + { + add(current); + goto scan_number_zero; + } + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_any1; + } + + default: + { + error_message = "invalid number; expected digit after '-'"; + return token_type::parse_error; + } + } + +scan_number_zero: + // state: we just parse a zero (maybe with a leading minus sign) + switch (get()) + { + case '.': + { + add(decimal_point_char); + goto scan_number_decimal1; + } + + case 'e': + case 'E': + { + add(current); + goto scan_number_exponent; + } + + default: + goto scan_number_done; + } + +scan_number_any1: + // state: we just parsed a number 0-9 (maybe with a leading minus sign) + switch (get()) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_any1; + } + + case '.': + { + add(decimal_point_char); + goto scan_number_decimal1; + } + + case 'e': + case 'E': + { + add(current); + goto scan_number_exponent; + } + + default: + goto scan_number_done; + } + +scan_number_decimal1: + // state: we just parsed a decimal point + number_type = token_type::value_float; + switch (get()) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_decimal2; + } + + default: + { + error_message = "invalid number; expected digit after '.'"; + return token_type::parse_error; + } + } + +scan_number_decimal2: + // we just parsed at least one number after a decimal point + switch (get()) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_decimal2; + } + + case 'e': + case 'E': + { + add(current); + goto scan_number_exponent; + } + + default: + goto scan_number_done; + } + +scan_number_exponent: + // we just parsed an exponent + number_type = token_type::value_float; + switch (get()) + { + case '+': + case '-': + { + add(current); + goto scan_number_sign; + } + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_any2; + } + + default: + { + error_message = + "invalid number; expected '+', '-', or digit after exponent"; + return token_type::parse_error; + } + } + +scan_number_sign: + // we just parsed an exponent sign + switch (get()) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_any2; + } + + default: + { + error_message = "invalid number; expected digit after exponent sign"; + return token_type::parse_error; + } + } + +scan_number_any2: + // we just parsed a number after the exponent or exponent sign + switch (get()) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + add(current); + goto scan_number_any2; + } + + default: + goto scan_number_done; + } + +scan_number_done: + // unget the character after the number (we only read it to know that + // we are done scanning a number) + unget(); + + char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + errno = 0; + + // try to parse integers first and fall back to floats + if (number_type == token_type::value_unsigned) + { + const auto x = std::strtoull(token_buffer.data(), &endptr, 10); + + // we checked the number format before + JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); + + if (errno == 0) + { + value_unsigned = static_cast(x); + if (value_unsigned == x) + { + return token_type::value_unsigned; + } + } + } + else if (number_type == token_type::value_integer) + { + const auto x = std::strtoll(token_buffer.data(), &endptr, 10); + + // we checked the number format before + JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); + + if (errno == 0) + { + value_integer = static_cast(x); + if (value_integer == x) + { + return token_type::value_integer; + } + } + } + + // this code is reached if we parse a floating-point number or if an + // integer conversion above failed + strtof(value_float, token_buffer.data(), &endptr); + + // we checked the number format before + JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size()); + + return token_type::value_float; + } + + /*! + @param[in] literal_text the literal text to expect + @param[in] length the length of the passed literal text + @param[in] return_type the token type to return on success + */ + JSON_HEDLEY_NON_NULL(2) + token_type scan_literal(const char_type* literal_text, const std::size_t length, + token_type return_type) + { + JSON_ASSERT(char_traits::to_char_type(current) == literal_text[0]); + for (std::size_t i = 1; i < length; ++i) + { + if (JSON_HEDLEY_UNLIKELY(char_traits::to_char_type(get()) != literal_text[i])) + { + error_message = "invalid literal"; + return token_type::parse_error; + } + } + return return_type; + } + + ///////////////////// + // input management + ///////////////////// + + /// reset token_buffer; current character is beginning of token + void reset() noexcept + { + token_buffer.clear(); + token_string.clear(); + token_string.push_back(char_traits::to_char_type(current)); + } + + /* + @brief get next character from the input + + This function provides the interface to the used input adapter. It does + not throw in case the input reached EOF, but returns a + `char_traits::eof()` in that case. Stores the scanned characters + for use in error messages. + + @return character read from the input + */ + char_int_type get() + { + ++position.chars_read_total; + ++position.chars_read_current_line; + + if (next_unget) + { + // just reset the next_unget variable and work with current + next_unget = false; + } + else + { + current = ia.get_character(); + } + + if (JSON_HEDLEY_LIKELY(current != char_traits::eof())) + { + token_string.push_back(char_traits::to_char_type(current)); + } + + if (current == '\n') + { + ++position.lines_read; + position.chars_read_current_line = 0; + } + + return current; + } + + /*! + @brief unget current character (read it again on next get) + + We implement unget by setting variable next_unget to true. The input is not + changed - we just simulate ungetting by modifying chars_read_total, + chars_read_current_line, and token_string. The next call to get() will + behave as if the unget character is read again. + */ + void unget() + { + next_unget = true; + + --position.chars_read_total; + + // in case we "unget" a newline, we have to also decrement the lines_read + if (position.chars_read_current_line == 0) + { + if (position.lines_read > 0) + { + --position.lines_read; + } + } + else + { + --position.chars_read_current_line; + } + + if (JSON_HEDLEY_LIKELY(current != char_traits::eof())) + { + JSON_ASSERT(!token_string.empty()); + token_string.pop_back(); + } + } + + /// add a character to token_buffer + void add(char_int_type c) + { + token_buffer.push_back(static_cast(c)); + } + + public: + ///////////////////// + // value getters + ///////////////////// + + /// return integer value + constexpr number_integer_t get_number_integer() const noexcept + { + return value_integer; + } + + /// return unsigned integer value + constexpr number_unsigned_t get_number_unsigned() const noexcept + { + return value_unsigned; + } + + /// return floating-point value + constexpr number_float_t get_number_float() const noexcept + { + return value_float; + } + + /// return current string value (implicitly resets the token; useful only once) + string_t& get_string() + { + return token_buffer; + } + + ///////////////////// + // diagnostics + ///////////////////// + + /// return position of last read token + constexpr position_t get_position() const noexcept + { + return position; + } + + /// return the last read token (for errors only). Will never contain EOF + /// (an arbitrary value that is not a valid char value, often -1), because + /// 255 may legitimately occur. May contain NUL, which should be escaped. + std::string get_token_string() const + { + // escape control characters + std::string result; + for (const auto c : token_string) + { + if (static_cast(c) <= '\x1F') + { + // escape control characters + std::array cs{{}}; + static_cast((std::snprintf)(cs.data(), cs.size(), "", static_cast(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + result += cs.data(); + } + else + { + // add character as is + result.push_back(static_cast(c)); + } + } + + return result; + } + + /// return syntax error message + JSON_HEDLEY_RETURNS_NON_NULL + constexpr const char* get_error_message() const noexcept + { + return error_message; + } + + ///////////////////// + // actual scanner + ///////////////////// + + /*! + @brief skip the UTF-8 byte order mark + @return true iff there is no BOM or the correct BOM has been skipped + */ + bool skip_bom() + { + if (get() == 0xEF) + { + // check if we completely parse the BOM + return get() == 0xBB && get() == 0xBF; + } + + // the first character is not the beginning of the BOM; unget it to + // process is later + unget(); + return true; + } + + void skip_whitespace() + { + do + { + get(); + } + while (current == ' ' || current == '\t' || current == '\n' || current == '\r'); + } + + token_type scan() + { + // initially, skip the BOM + if (position.chars_read_total == 0 && !skip_bom()) + { + error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given"; + return token_type::parse_error; + } + + // read next character and ignore whitespace + skip_whitespace(); + + // ignore comments + while (ignore_comments && current == '/') + { + if (!scan_comment()) + { + return token_type::parse_error; + } + + // skip following whitespace + skip_whitespace(); + } + + switch (current) + { + // structural characters + case '[': + return token_type::begin_array; + case ']': + return token_type::end_array; + case '{': + return token_type::begin_object; + case '}': + return token_type::end_object; + case ':': + return token_type::name_separator; + case ',': + return token_type::value_separator; + + // literals + case 't': + { + std::array true_literal = {{static_cast('t'), static_cast('r'), static_cast('u'), static_cast('e')}}; + return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true); + } + case 'f': + { + std::array false_literal = {{static_cast('f'), static_cast('a'), static_cast('l'), static_cast('s'), static_cast('e')}}; + return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false); + } + case 'n': + { + std::array null_literal = {{static_cast('n'), static_cast('u'), static_cast('l'), static_cast('l')}}; + return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null); + } + + // string + case '\"': + return scan_string(); + + // number + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return scan_number(); + + // end of input (the null byte is needed when parsing from + // string literals) + case '\0': + case char_traits::eof(): + return token_type::end_of_input; + + // error + default: + error_message = "invalid literal"; + return token_type::parse_error; + } + } + + private: + /// input adapter + InputAdapterType ia; + + /// whether comments should be ignored (true) or signaled as errors (false) + const bool ignore_comments = false; + + /// the current character + char_int_type current = char_traits::eof(); + + /// whether the next get() call should just return current + bool next_unget = false; + + /// the start position of the current token + position_t position {}; + + /// raw input token string (for error messages) + std::vector token_string {}; + + /// buffer for variable-length tokens (numbers, strings) + string_t token_buffer {}; + + /// a description of occurred lexer errors + const char* error_message = ""; + + // number values + number_integer_t value_integer = 0; + number_unsigned_t value_unsigned = 0; + number_float_t value_float = 0; + + /// the decimal point + const char_int_type decimal_point_char = '.'; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/input/parser.hpp b/vulkan/nlohmann/detail/input/parser.hpp new file mode 100644 index 0000000..bdf85ba --- /dev/null +++ b/vulkan/nlohmann/detail/input/parser.hpp @@ -0,0 +1,519 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // isfinite +#include // uint8_t +#include // function +#include // string +#include // move +#include // vector + +#include +#include +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ +//////////// +// parser // +//////////// + +enum class parse_event_t : std::uint8_t +{ + /// the parser read `{` and started to process a JSON object + object_start, + /// the parser read `}` and finished processing a JSON object + object_end, + /// the parser read `[` and started to process a JSON array + array_start, + /// the parser read `]` and finished processing a JSON array + array_end, + /// the parser read a key of a value in an object + key, + /// the parser finished reading a JSON value + value +}; + +template +using parser_callback_t = + std::function; + +/*! +@brief syntax analysis + +This class implements a recursive descent parser. +*/ +template +class parser +{ + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using lexer_t = lexer; + using token_type = typename lexer_t::token_type; + + public: + /// a parser reading from an input adapter + explicit parser(InputAdapterType&& adapter, + const parser_callback_t cb = nullptr, + const bool allow_exceptions_ = true, + const bool skip_comments = false) + : callback(cb) + , m_lexer(std::move(adapter), skip_comments) + , allow_exceptions(allow_exceptions_) + { + // read first token + get_token(); + } + + /*! + @brief public parser interface + + @param[in] strict whether to expect the last token to be EOF + @param[in,out] result parsed JSON value + + @throw parse_error.101 in case of an unexpected token + @throw parse_error.102 if to_unicode fails or surrogate error + @throw parse_error.103 if to_unicode fails + */ + void parse(const bool strict, BasicJsonType& result) + { + if (callback) + { + json_sax_dom_callback_parser sdp(result, callback, allow_exceptions); + sax_parse_internal(&sdp); + + // in strict mode, input must be completely read + if (strict && (get_token() != token_type::end_of_input)) + { + sdp.parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), + exception_message(token_type::end_of_input, "value"), nullptr)); + } + + // in case of an error, return discarded value + if (sdp.is_errored()) + { + result = value_t::discarded; + return; + } + + // set top-level value to null if it was discarded by the callback + // function + if (result.is_discarded()) + { + result = nullptr; + } + } + else + { + json_sax_dom_parser sdp(result, allow_exceptions); + sax_parse_internal(&sdp); + + // in strict mode, input must be completely read + if (strict && (get_token() != token_type::end_of_input)) + { + sdp.parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); + } + + // in case of an error, return discarded value + if (sdp.is_errored()) + { + result = value_t::discarded; + return; + } + } + + result.assert_invariant(); + } + + /*! + @brief public accept interface + + @param[in] strict whether to expect the last token to be EOF + @return whether the input is a proper JSON text + */ + bool accept(const bool strict = true) + { + json_sax_acceptor sax_acceptor; + return sax_parse(&sax_acceptor, strict); + } + + template + JSON_HEDLEY_NON_NULL(2) + bool sax_parse(SAX* sax, const bool strict = true) + { + (void)detail::is_sax_static_asserts {}; + const bool result = sax_parse_internal(sax); + + // strict mode: next byte must be EOF + if (result && strict && (get_token() != token_type::end_of_input)) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr)); + } + + return result; + } + + private: + template + JSON_HEDLEY_NON_NULL(2) + bool sax_parse_internal(SAX* sax) + { + // stack to remember the hierarchy of structured values we are parsing + // true = array; false = object + std::vector states; + // value to avoid a goto (see comment where set to true) + bool skip_to_state_evaluation = false; + + while (true) + { + if (!skip_to_state_evaluation) + { + // invariant: get_token() was called before each iteration + switch (last_token) + { + case token_type::begin_object: + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast(-1)))) + { + return false; + } + + // closing } -> we are done + if (get_token() == token_type::end_object) + { + if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) + { + return false; + } + break; + } + + // parse key + if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string)) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr)); + } + if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) + { + return false; + } + + // parse separator (:) + if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr)); + } + + // remember we are now inside an object + states.push_back(false); + + // parse values + get_token(); + continue; + } + + case token_type::begin_array: + { + if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast(-1)))) + { + return false; + } + + // closing ] -> we are done + if (get_token() == token_type::end_array) + { + if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) + { + return false; + } + break; + } + + // remember we are now inside an array + states.push_back(true); + + // parse values (no need to call get_token) + continue; + } + + case token_type::value_float: + { + const auto res = m_lexer.get_number_float(); + + if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res))) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr)); + } + + if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string()))) + { + return false; + } + + break; + } + + case token_type::literal_false: + { + if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false))) + { + return false; + } + break; + } + + case token_type::literal_null: + { + if (JSON_HEDLEY_UNLIKELY(!sax->null())) + { + return false; + } + break; + } + + case token_type::literal_true: + { + if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true))) + { + return false; + } + break; + } + + case token_type::value_integer: + { + if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer()))) + { + return false; + } + break; + } + + case token_type::value_string: + { + if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string()))) + { + return false; + } + break; + } + + case token_type::value_unsigned: + { + if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned()))) + { + return false; + } + break; + } + + case token_type::parse_error: + { + // using "uninitialized" to avoid "expected" message + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr)); + } + case token_type::end_of_input: + { + if (JSON_HEDLEY_UNLIKELY(m_lexer.get_position().chars_read_total == 1)) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), + "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr)); + } + + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr)); + } + case token_type::uninitialized: + case token_type::end_array: + case token_type::end_object: + case token_type::name_separator: + case token_type::value_separator: + case token_type::literal_or_value: + default: // the last token was unexpected + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr)); + } + } + } + else + { + skip_to_state_evaluation = false; + } + + // we reached this line after we successfully parsed a value + if (states.empty()) + { + // empty stack: we reached the end of the hierarchy: done + return true; + } + + if (states.back()) // array + { + // comma -> next value + if (get_token() == token_type::value_separator) + { + // parse a new value + get_token(); + continue; + } + + // closing ] + if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array)) + { + if (JSON_HEDLEY_UNLIKELY(!sax->end_array())) + { + return false; + } + + // We are done with this array. Before we can parse a + // new value, we need to evaluate the new state first. + // By setting skip_to_state_evaluation to false, we + // are effectively jumping to the beginning of this if. + JSON_ASSERT(!states.empty()); + states.pop_back(); + skip_to_state_evaluation = true; + continue; + } + + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr)); + } + + // states.back() is false -> object + + // comma -> next value + if (get_token() == token_type::value_separator) + { + // parse key + if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string)) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr)); + } + + if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string()))) + { + return false; + } + + // parse separator (:) + if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator)) + { + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr)); + } + + // parse values + get_token(); + continue; + } + + // closing } + if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object)) + { + if (JSON_HEDLEY_UNLIKELY(!sax->end_object())) + { + return false; + } + + // We are done with this object. Before we can parse a + // new value, we need to evaluate the new state first. + // By setting skip_to_state_evaluation to false, we + // are effectively jumping to the beginning of this if. + JSON_ASSERT(!states.empty()); + states.pop_back(); + skip_to_state_evaluation = true; + continue; + } + + return sax->parse_error(m_lexer.get_position(), + m_lexer.get_token_string(), + parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr)); + } + } + + /// get next token from lexer + token_type get_token() + { + return last_token = m_lexer.scan(); + } + + std::string exception_message(const token_type expected, const std::string& context) + { + std::string error_msg = "syntax error "; + + if (!context.empty()) + { + error_msg += concat("while parsing ", context, ' '); + } + + error_msg += "- "; + + if (last_token == token_type::parse_error) + { + error_msg += concat(m_lexer.get_error_message(), "; last read: '", + m_lexer.get_token_string(), '\''); + } + else + { + error_msg += concat("unexpected ", lexer_t::token_type_name(last_token)); + } + + if (expected != token_type::uninitialized) + { + error_msg += concat("; expected ", lexer_t::token_type_name(expected)); + } + + return error_msg; + } + + private: + /// callback function + const parser_callback_t callback = nullptr; + /// the type of the last read token + token_type last_token = token_type::uninitialized; + /// the lexer + lexer_t m_lexer; + /// whether to throw exceptions in case of errors + const bool allow_exceptions = true; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/input/position_t.hpp b/vulkan/nlohmann/detail/input/position_t.hpp new file mode 100644 index 0000000..8ac7c78 --- /dev/null +++ b/vulkan/nlohmann/detail/input/position_t.hpp @@ -0,0 +1,37 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // size_t + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/// struct to capture the start position of the current token +struct position_t +{ + /// the total number of characters read + std::size_t chars_read_total = 0; + /// the number of characters read in the current line + std::size_t chars_read_current_line = 0; + /// the number of lines read + std::size_t lines_read = 0; + + /// conversion to size_t to preserve SAX interface + constexpr operator size_t() const + { + return chars_read_total; + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/iterators/internal_iterator.hpp b/vulkan/nlohmann/detail/iterators/internal_iterator.hpp new file mode 100644 index 0000000..2991ee6 --- /dev/null +++ b/vulkan/nlohmann/detail/iterators/internal_iterator.hpp @@ -0,0 +1,35 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/*! +@brief an iterator value + +@note This structure could easily be a union, but MSVC currently does not allow +unions members with complex constructors, see https://github.com/nlohmann/json/pull/105. +*/ +template struct internal_iterator +{ + /// iterator for JSON objects + typename BasicJsonType::object_t::iterator object_iterator {}; + /// iterator for JSON arrays + typename BasicJsonType::array_t::iterator array_iterator {}; + /// generic iterator for all other types + primitive_iterator_t primitive_iterator {}; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/iterators/iter_impl.hpp b/vulkan/nlohmann/detail/iterators/iter_impl.hpp new file mode 100644 index 0000000..4447091 --- /dev/null +++ b/vulkan/nlohmann/detail/iterators/iter_impl.hpp @@ -0,0 +1,751 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next +#include // conditional, is_const, remove_const + +#include +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// forward declare, to be able to friend it later on +template class iteration_proxy; +template class iteration_proxy_value; + +/*! +@brief a template for a bidirectional iterator for the @ref basic_json class +This class implements a both iterators (iterator and const_iterator) for the +@ref basic_json class. +@note An iterator is called *initialized* when a pointer to a JSON value has + been set (e.g., by a constructor or a copy assignment). If the iterator is + default-constructed, it is *uninitialized* and most methods are undefined. + **The library uses assertions to detect calls on uninitialized iterators.** +@requirement The class satisfies the following concept requirements: +- +[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): + The iterator that can be moved can be moved in both directions (i.e. + incremented and decremented). +@since version 1.0.0, simplified in version 2.0.9, change to bidirectional + iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593) +*/ +template +class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions) +{ + /// the iterator with BasicJsonType of different const-ness + using other_iter_impl = iter_impl::value, typename std::remove_const::type, const BasicJsonType>::type>; + /// allow basic_json to access private members + friend other_iter_impl; + friend BasicJsonType; + friend iteration_proxy; + friend iteration_proxy_value; + + using object_t = typename BasicJsonType::object_t; + using array_t = typename BasicJsonType::array_t; + // make sure BasicJsonType is basic_json or const basic_json + static_assert(is_basic_json::type>::value, + "iter_impl only accepts (const) basic_json"); + // superficial check for the LegacyBidirectionalIterator named requirement + static_assert(std::is_base_of::value + && std::is_base_of::iterator_category>::value, + "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement."); + + public: + /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17. + /// The C++ Standard has never required user-defined iterators to derive from std::iterator. + /// A user-defined iterator should provide publicly accessible typedefs named + /// iterator_category, value_type, difference_type, pointer, and reference. + /// Note that value_type is required to be non-const, even for constant iterators. + using iterator_category = std::bidirectional_iterator_tag; + + /// the type of the values when the iterator is dereferenced + using value_type = typename BasicJsonType::value_type; + /// a type to represent differences between iterators + using difference_type = typename BasicJsonType::difference_type; + /// defines a pointer to the type iterated over (value_type) + using pointer = typename std::conditional::value, + typename BasicJsonType::const_pointer, + typename BasicJsonType::pointer>::type; + /// defines a reference to the type iterated over (value_type) + using reference = + typename std::conditional::value, + typename BasicJsonType::const_reference, + typename BasicJsonType::reference>::type; + + iter_impl() = default; + ~iter_impl() = default; + iter_impl(iter_impl&&) noexcept = default; + iter_impl& operator=(iter_impl&&) noexcept = default; + + /*! + @brief constructor for a given JSON instance + @param[in] object pointer to a JSON object for this iterator + @pre object != nullptr + @post The iterator is initialized; i.e. `m_object != nullptr`. + */ + explicit iter_impl(pointer object) noexcept : m_object(object) + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + m_it.object_iterator = typename object_t::iterator(); + break; + } + + case value_t::array: + { + m_it.array_iterator = typename array_t::iterator(); + break; + } + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + m_it.primitive_iterator = primitive_iterator_t(); + break; + } + } + } + + /*! + @note The conventional copy constructor and copy assignment are implicitly + defined. Combined with the following converting constructor and + assignment, they support: (1) copy from iterator to iterator, (2) + copy from const iterator to const iterator, and (3) conversion from + iterator to const iterator. However conversion from const iterator + to iterator is not defined. + */ + + /*! + @brief const copy constructor + @param[in] other const iterator to copy from + @note This copy constructor had to be defined explicitly to circumvent a bug + occurring on msvc v19.0 compiler (VS 2015) debug build. For more + information refer to: https://github.com/nlohmann/json/issues/1608 + */ + iter_impl(const iter_impl& other) noexcept + : m_object(other.m_object), m_it(other.m_it) + {} + + /*! + @brief converting assignment + @param[in] other const iterator to copy from + @return const/non-const iterator + @note It is not checked whether @a other is initialized. + */ + iter_impl& operator=(const iter_impl& other) noexcept + { + if (&other != this) + { + m_object = other.m_object; + m_it = other.m_it; + } + return *this; + } + + /*! + @brief converting constructor + @param[in] other non-const iterator to copy from + @note It is not checked whether @a other is initialized. + */ + iter_impl(const iter_impl::type>& other) noexcept + : m_object(other.m_object), m_it(other.m_it) + {} + + /*! + @brief converting assignment + @param[in] other non-const iterator to copy from + @return const/non-const iterator + @note It is not checked whether @a other is initialized. + */ + iter_impl& operator=(const iter_impl::type>& other) noexcept // NOLINT(cert-oop54-cpp) + { + m_object = other.m_object; + m_it = other.m_it; + return *this; + } + + JSON_PRIVATE_UNLESS_TESTED: + /*! + @brief set the iterator to the first value + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + void set_begin() noexcept + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + m_it.object_iterator = m_object->m_data.m_value.object->begin(); + break; + } + + case value_t::array: + { + m_it.array_iterator = m_object->m_data.m_value.array->begin(); + break; + } + + case value_t::null: + { + // set to end so begin()==end() is true: null is empty + m_it.primitive_iterator.set_end(); + break; + } + + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + m_it.primitive_iterator.set_begin(); + break; + } + } + } + + /*! + @brief set the iterator past the last value + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + void set_end() noexcept + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + m_it.object_iterator = m_object->m_data.m_value.object->end(); + break; + } + + case value_t::array: + { + m_it.array_iterator = m_object->m_data.m_value.array->end(); + break; + } + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + m_it.primitive_iterator.set_end(); + break; + } + } + } + + public: + /*! + @brief return a reference to the value pointed to by the iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + reference operator*() const + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end()); + return m_it.object_iterator->second; + } + + case value_t::array: + { + JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end()); + return *m_it.array_iterator; + } + + case value_t::null: + JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); + + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) + { + return *m_object; + } + + JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); + } + } + } + + /*! + @brief dereference the iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + pointer operator->() const + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + JSON_ASSERT(m_it.object_iterator != m_object->m_data.m_value.object->end()); + return &(m_it.object_iterator->second); + } + + case value_t::array: + { + JSON_ASSERT(m_it.array_iterator != m_object->m_data.m_value.array->end()); + return &*m_it.array_iterator; + } + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin())) + { + return m_object; + } + + JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); + } + } + } + + /*! + @brief post-increment (it++) + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp) + { + auto result = *this; + ++(*this); + return result; + } + + /*! + @brief pre-increment (++it) + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl& operator++() + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + std::advance(m_it.object_iterator, 1); + break; + } + + case value_t::array: + { + std::advance(m_it.array_iterator, 1); + break; + } + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + ++m_it.primitive_iterator; + break; + } + } + + return *this; + } + + /*! + @brief post-decrement (it--) + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp) + { + auto result = *this; + --(*this); + return result; + } + + /*! + @brief pre-decrement (--it) + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl& operator--() + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + { + std::advance(m_it.object_iterator, -1); + break; + } + + case value_t::array: + { + std::advance(m_it.array_iterator, -1); + break; + } + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + --m_it.primitive_iterator; + break; + } + } + + return *this; + } + + /*! + @brief comparison: equal + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > + bool operator==(const IterImpl& other) const + { + // if objects are not the same, the comparison is undefined + if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) + { + JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object)); + } + + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + return (m_it.object_iterator == other.m_it.object_iterator); + + case value_t::array: + return (m_it.array_iterator == other.m_it.array_iterator); + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + return (m_it.primitive_iterator == other.m_it.primitive_iterator); + } + } + + /*! + @brief comparison: not equal + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + template < typename IterImpl, detail::enable_if_t < (std::is_same::value || std::is_same::value), std::nullptr_t > = nullptr > + bool operator!=(const IterImpl& other) const + { + return !operator==(other); + } + + /*! + @brief comparison: smaller + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator<(const iter_impl& other) const + { + // if objects are not the same, the comparison is undefined + if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object)) + { + JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object)); + } + + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object)); + + case value_t::array: + return (m_it.array_iterator < other.m_it.array_iterator); + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + return (m_it.primitive_iterator < other.m_it.primitive_iterator); + } + } + + /*! + @brief comparison: less than or equal + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator<=(const iter_impl& other) const + { + return !other.operator < (*this); + } + + /*! + @brief comparison: greater than + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator>(const iter_impl& other) const + { + return !operator<=(other); + } + + /*! + @brief comparison: greater than or equal + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + bool operator>=(const iter_impl& other) const + { + return !operator<(other); + } + + /*! + @brief add to iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl& operator+=(difference_type i) + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object)); + + case value_t::array: + { + std::advance(m_it.array_iterator, i); + break; + } + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + m_it.primitive_iterator += i; + break; + } + } + + return *this; + } + + /*! + @brief subtract from iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl& operator-=(difference_type i) + { + return operator+=(-i); + } + + /*! + @brief add to iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl operator+(difference_type i) const + { + auto result = *this; + result += i; + return result; + } + + /*! + @brief addition of distance and iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + friend iter_impl operator+(difference_type i, const iter_impl& it) + { + auto result = it; + result += i; + return result; + } + + /*! + @brief subtract from iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + iter_impl operator-(difference_type i) const + { + auto result = *this; + result -= i; + return result; + } + + /*! + @brief return difference + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + difference_type operator-(const iter_impl& other) const + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object)); + + case value_t::array: + return m_it.array_iterator - other.m_it.array_iterator; + + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + return m_it.primitive_iterator - other.m_it.primitive_iterator; + } + } + + /*! + @brief access to successor + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + reference operator[](difference_type n) const + { + JSON_ASSERT(m_object != nullptr); + + switch (m_object->m_data.m_type) + { + case value_t::object: + JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object)); + + case value_t::array: + return *std::next(m_it.array_iterator, n); + + case value_t::null: + JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); + + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + { + if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n)) + { + return *m_object; + } + + JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object)); + } + } + } + + /*! + @brief return the key of an object iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + const typename object_t::key_type& key() const + { + JSON_ASSERT(m_object != nullptr); + + if (JSON_HEDLEY_LIKELY(m_object->is_object())) + { + return m_it.object_iterator->first; + } + + JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object)); + } + + /*! + @brief return the value of an iterator + @pre The iterator is initialized; i.e. `m_object != nullptr`. + */ + reference value() const + { + return operator*(); + } + + JSON_PRIVATE_UNLESS_TESTED: + /// associated JSON instance + pointer m_object = nullptr; + /// the actual iterator of the associated instance + internal_iterator::type> m_it {}; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/iterators/iteration_proxy.hpp b/vulkan/nlohmann/detail/iterators/iteration_proxy.hpp new file mode 100644 index 0000000..76293de --- /dev/null +++ b/vulkan/nlohmann/detail/iterators/iteration_proxy.hpp @@ -0,0 +1,242 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // size_t +#include // input_iterator_tag +#include // string, to_string +#include // tuple_size, get, tuple_element +#include // move + +#if JSON_HAS_RANGES + #include // enable_borrowed_range +#endif + +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +void int_to_string( string_type& target, std::size_t value ) +{ + // For ADL + using std::to_string; + target = to_string(value); +} +template class iteration_proxy_value +{ + public: + using difference_type = std::ptrdiff_t; + using value_type = iteration_proxy_value; + using pointer = value_type *; + using reference = value_type &; + using iterator_category = std::input_iterator_tag; + using string_type = typename std::remove_cv< typename std::remove_reference().key() ) >::type >::type; + + private: + /// the iterator + IteratorType anchor{}; + /// an index for arrays (used to create key names) + std::size_t array_index = 0; + /// last stringified array index + mutable std::size_t array_index_last = 0; + /// a string representation of the array index + mutable string_type array_index_str = "0"; + /// an empty string (to return a reference for primitive values) + string_type empty_str{}; + + public: + explicit iteration_proxy_value() = default; + explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0) + noexcept(std::is_nothrow_move_constructible::value + && std::is_nothrow_default_constructible::value) + : anchor(std::move(it)) + , array_index(array_index_) + {} + + iteration_proxy_value(iteration_proxy_value const&) = default; + iteration_proxy_value& operator=(iteration_proxy_value const&) = default; + // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions + iteration_proxy_value(iteration_proxy_value&&) + noexcept(std::is_nothrow_move_constructible::value + && std::is_nothrow_move_constructible::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations) + iteration_proxy_value& operator=(iteration_proxy_value&&) + noexcept(std::is_nothrow_move_assignable::value + && std::is_nothrow_move_assignable::value) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor,cppcoreguidelines-noexcept-move-operations) + ~iteration_proxy_value() = default; + + /// dereference operator (needed for range-based for) + const iteration_proxy_value& operator*() const + { + return *this; + } + + /// increment operator (needed for range-based for) + iteration_proxy_value& operator++() + { + ++anchor; + ++array_index; + + return *this; + } + + iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp) + { + auto tmp = iteration_proxy_value(anchor, array_index); + ++anchor; + ++array_index; + return tmp; + } + + /// equality operator (needed for InputIterator) + bool operator==(const iteration_proxy_value& o) const + { + return anchor == o.anchor; + } + + /// inequality operator (needed for range-based for) + bool operator!=(const iteration_proxy_value& o) const + { + return anchor != o.anchor; + } + + /// return key of the iterator + const string_type& key() const + { + JSON_ASSERT(anchor.m_object != nullptr); + + switch (anchor.m_object->type()) + { + // use integer array index as key + case value_t::array: + { + if (array_index != array_index_last) + { + int_to_string( array_index_str, array_index ); + array_index_last = array_index; + } + return array_index_str; + } + + // use key from the object + case value_t::object: + return anchor.key(); + + // use an empty key for all primitive types + case value_t::null: + case value_t::string: + case value_t::boolean: + case value_t::number_integer: + case value_t::number_unsigned: + case value_t::number_float: + case value_t::binary: + case value_t::discarded: + default: + return empty_str; + } + } + + /// return value of the iterator + typename IteratorType::reference value() const + { + return anchor.value(); + } +}; + +/// proxy class for the items() function +template class iteration_proxy +{ + private: + /// the container to iterate + typename IteratorType::pointer container = nullptr; + + public: + explicit iteration_proxy() = default; + + /// construct iteration proxy from a container + explicit iteration_proxy(typename IteratorType::reference cont) noexcept + : container(&cont) {} + + iteration_proxy(iteration_proxy const&) = default; + iteration_proxy& operator=(iteration_proxy const&) = default; + iteration_proxy(iteration_proxy&&) noexcept = default; + iteration_proxy& operator=(iteration_proxy&&) noexcept = default; + ~iteration_proxy() = default; + + /// return iterator begin (needed for range-based for) + iteration_proxy_value begin() const noexcept + { + return iteration_proxy_value(container->begin()); + } + + /// return iterator end (needed for range-based for) + iteration_proxy_value end() const noexcept + { + return iteration_proxy_value(container->end()); + } +}; + +// Structured Bindings Support +// For further reference see https://blog.tartanllama.xyz/structured-bindings/ +// And see https://github.com/nlohmann/json/pull/1391 +template = 0> +auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.key()) +{ + return i.key(); +} +// Structured Bindings Support +// For further reference see https://blog.tartanllama.xyz/structured-bindings/ +// And see https://github.com/nlohmann/json/pull/1391 +template = 0> +auto get(const nlohmann::detail::iteration_proxy_value& i) -> decltype(i.value()) +{ + return i.value(); +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END + +// The Addition to the STD Namespace is required to add +// Structured Bindings Support to the iteration_proxy_value class +// For further reference see https://blog.tartanllama.xyz/structured-bindings/ +// And see https://github.com/nlohmann/json/pull/1391 +namespace std +{ + +#if defined(__clang__) + // Fix: https://github.com/nlohmann/json/issues/1401 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wmismatched-tags" +#endif +template +class tuple_size<::nlohmann::detail::iteration_proxy_value> // NOLINT(cert-dcl58-cpp) + : public std::integral_constant {}; + +template +class tuple_element> // NOLINT(cert-dcl58-cpp) +{ + public: + using type = decltype( + get(std::declval < + ::nlohmann::detail::iteration_proxy_value> ())); +}; +#if defined(__clang__) + #pragma clang diagnostic pop +#endif + +} // namespace std + +#if JSON_HAS_RANGES + template + inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy> = true; +#endif diff --git a/vulkan/nlohmann/detail/iterators/iterator_traits.hpp b/vulkan/nlohmann/detail/iterators/iterator_traits.hpp new file mode 100644 index 0000000..84cc27a --- /dev/null +++ b/vulkan/nlohmann/detail/iterators/iterator_traits.hpp @@ -0,0 +1,61 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // random_access_iterator_tag + +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +struct iterator_types {}; + +template +struct iterator_types < + It, + void_t> +{ + using difference_type = typename It::difference_type; + using value_type = typename It::value_type; + using pointer = typename It::pointer; + using reference = typename It::reference; + using iterator_category = typename It::iterator_category; +}; + +// This is required as some compilers implement std::iterator_traits in a way that +// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. +template +struct iterator_traits +{ +}; + +template +struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> + : iterator_types +{ +}; + +template +struct iterator_traits::value>> +{ + using iterator_category = std::random_access_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/iterators/json_reverse_iterator.hpp b/vulkan/nlohmann/detail/iterators/json_reverse_iterator.hpp new file mode 100644 index 0000000..006d549 --- /dev/null +++ b/vulkan/nlohmann/detail/iterators/json_reverse_iterator.hpp @@ -0,0 +1,130 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // ptrdiff_t +#include // reverse_iterator +#include // declval + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +////////////////////// +// reverse_iterator // +////////////////////// + +/*! +@brief a template for a reverse iterator class + +@tparam Base the base iterator type to reverse. Valid types are @ref +iterator (to create @ref reverse_iterator) and @ref const_iterator (to +create @ref const_reverse_iterator). + +@requirement The class satisfies the following concept requirements: +- +[BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): + The iterator that can be moved can be moved in both directions (i.e. + incremented and decremented). +- [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator): + It is possible to write to the pointed-to element (only if @a Base is + @ref iterator). + +@since version 1.0.0 +*/ +template +class json_reverse_iterator : public std::reverse_iterator +{ + public: + using difference_type = std::ptrdiff_t; + /// shortcut to the reverse iterator adapter + using base_iterator = std::reverse_iterator; + /// the reference type for the pointed-to element + using reference = typename Base::reference; + + /// create reverse iterator from iterator + explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept + : base_iterator(it) {} + + /// create reverse iterator from base class + explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {} + + /// post-increment (it++) + json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp) + { + return static_cast(base_iterator::operator++(1)); + } + + /// pre-increment (++it) + json_reverse_iterator& operator++() + { + return static_cast(base_iterator::operator++()); + } + + /// post-decrement (it--) + json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp) + { + return static_cast(base_iterator::operator--(1)); + } + + /// pre-decrement (--it) + json_reverse_iterator& operator--() + { + return static_cast(base_iterator::operator--()); + } + + /// add to iterator + json_reverse_iterator& operator+=(difference_type i) + { + return static_cast(base_iterator::operator+=(i)); + } + + /// add to iterator + json_reverse_iterator operator+(difference_type i) const + { + return static_cast(base_iterator::operator+(i)); + } + + /// subtract from iterator + json_reverse_iterator operator-(difference_type i) const + { + return static_cast(base_iterator::operator-(i)); + } + + /// return difference + difference_type operator-(const json_reverse_iterator& other) const + { + return base_iterator(*this) - base_iterator(other); + } + + /// access to successor + reference operator[](difference_type n) const + { + return *(this->operator+(n)); + } + + /// return the key of an object iterator + auto key() const -> decltype(std::declval().key()) + { + auto it = --this->base(); + return it.key(); + } + + /// return the value of an iterator + reference value() const + { + auto it = --this->base(); + return it.operator * (); + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/iterators/primitive_iterator.hpp b/vulkan/nlohmann/detail/iterators/primitive_iterator.hpp new file mode 100644 index 0000000..0b6e849 --- /dev/null +++ b/vulkan/nlohmann/detail/iterators/primitive_iterator.hpp @@ -0,0 +1,132 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // ptrdiff_t +#include // numeric_limits + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/* +@brief an iterator for primitive JSON types + +This class models an iterator for primitive JSON types (boolean, number, +string). It's only purpose is to allow the iterator/const_iterator classes +to "iterate" over primitive values. Internally, the iterator is modeled by +a `difference_type` variable. Value begin_value (`0`) models the begin, +end_value (`1`) models past the end. +*/ +class primitive_iterator_t +{ + private: + using difference_type = std::ptrdiff_t; + static constexpr difference_type begin_value = 0; + static constexpr difference_type end_value = begin_value + 1; + + JSON_PRIVATE_UNLESS_TESTED: + /// iterator as signed integer type + difference_type m_it = (std::numeric_limits::min)(); + + public: + constexpr difference_type get_value() const noexcept + { + return m_it; + } + + /// set iterator to a defined beginning + void set_begin() noexcept + { + m_it = begin_value; + } + + /// set iterator to a defined past the end + void set_end() noexcept + { + m_it = end_value; + } + + /// return whether the iterator can be dereferenced + constexpr bool is_begin() const noexcept + { + return m_it == begin_value; + } + + /// return whether the iterator is at end + constexpr bool is_end() const noexcept + { + return m_it == end_value; + } + + friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return lhs.m_it == rhs.m_it; + } + + friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return lhs.m_it < rhs.m_it; + } + + primitive_iterator_t operator+(difference_type n) noexcept + { + auto result = *this; + result += n; + return result; + } + + friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept + { + return lhs.m_it - rhs.m_it; + } + + primitive_iterator_t& operator++() noexcept + { + ++m_it; + return *this; + } + + primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp) + { + auto result = *this; + ++m_it; + return result; + } + + primitive_iterator_t& operator--() noexcept + { + --m_it; + return *this; + } + + primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp) + { + auto result = *this; + --m_it; + return result; + } + + primitive_iterator_t& operator+=(difference_type n) noexcept + { + m_it += n; + return *this; + } + + primitive_iterator_t& operator-=(difference_type n) noexcept + { + m_it -= n; + return *this; + } +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/json_custom_base_class.hpp b/vulkan/nlohmann/detail/json_custom_base_class.hpp new file mode 100644 index 0000000..d1e2916 --- /dev/null +++ b/vulkan/nlohmann/detail/json_custom_base_class.hpp @@ -0,0 +1,39 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // conditional, is_same + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +/*! +@brief Default base class of the @ref basic_json class. + +So that the correct implementations of the copy / move ctors / assign operators +of @ref basic_json do not require complex case distinctions +(no base class / custom base class used as customization point), +@ref basic_json always has a base class. +By default, this class is used because it is empty and thus has no effect +on the behavior of @ref basic_json. +*/ +struct json_default_base {}; + +template +using json_base_class = typename std::conditional < + std::is_same::value, + json_default_base, + T + >::type; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/json_pointer.hpp b/vulkan/nlohmann/detail/json_pointer.hpp new file mode 100644 index 0000000..4fdcd9a --- /dev/null +++ b/vulkan/nlohmann/detail/json_pointer.hpp @@ -0,0 +1,988 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // all_of +#include // isdigit +#include // errno, ERANGE +#include // strtoull +#ifndef JSON_NO_IO + #include // ostream +#endif // JSON_NO_IO +#include // max +#include // accumulate +#include // string +#include // move +#include // vector + +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN + +/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document +/// @sa https://json.nlohmann.me/api/json_pointer/ +template +class json_pointer +{ + // allow basic_json to access private members + NLOHMANN_BASIC_JSON_TPL_DECLARATION + friend class basic_json; + + template + friend class json_pointer; + + template + struct string_t_helper + { + using type = T; + }; + + NLOHMANN_BASIC_JSON_TPL_DECLARATION + struct string_t_helper + { + using type = StringType; + }; + + public: + // for backwards compatibility accept BasicJsonType + using string_t = typename string_t_helper::type; + + /// @brief create JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/json_pointer/ + explicit json_pointer(const string_t& s = "") + : reference_tokens(split(s)) + {} + + /// @brief return a string representation of the JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/to_string/ + string_t to_string() const + { + return std::accumulate(reference_tokens.begin(), reference_tokens.end(), + string_t{}, + [](const string_t& a, const string_t& b) + { + return detail::concat(a, '/', detail::escape(b)); + }); + } + + /// @brief return a string representation of the JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_string/ + JSON_HEDLEY_DEPRECATED_FOR(3.11.0, to_string()) + operator string_t() const + { + return to_string(); + } + +#ifndef JSON_NO_IO + /// @brief write string representation of the JSON pointer to stream + /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/ + friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr) + { + o << ptr.to_string(); + return o; + } +#endif + + /// @brief append another JSON pointer at the end of this JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/ + json_pointer& operator/=(const json_pointer& ptr) + { + reference_tokens.insert(reference_tokens.end(), + ptr.reference_tokens.begin(), + ptr.reference_tokens.end()); + return *this; + } + + /// @brief append an unescaped reference token at the end of this JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/ + json_pointer& operator/=(string_t token) + { + push_back(std::move(token)); + return *this; + } + + /// @brief append an array index at the end of this JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/ + json_pointer& operator/=(std::size_t array_idx) + { + return *this /= std::to_string(array_idx); + } + + /// @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/ + friend json_pointer operator/(const json_pointer& lhs, + const json_pointer& rhs) + { + return json_pointer(lhs) /= rhs; + } + + /// @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/ + friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param) + { + return json_pointer(lhs) /= std::move(token); + } + + /// @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/operator_slash/ + friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx) + { + return json_pointer(lhs) /= array_idx; + } + + /// @brief returns the parent of this JSON pointer + /// @sa https://json.nlohmann.me/api/json_pointer/parent_pointer/ + json_pointer parent_pointer() const + { + if (empty()) + { + return *this; + } + + json_pointer res = *this; + res.pop_back(); + return res; + } + + /// @brief remove last reference token + /// @sa https://json.nlohmann.me/api/json_pointer/pop_back/ + void pop_back() + { + if (JSON_HEDLEY_UNLIKELY(empty())) + { + JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr)); + } + + reference_tokens.pop_back(); + } + + /// @brief return last reference token + /// @sa https://json.nlohmann.me/api/json_pointer/back/ + const string_t& back() const + { + if (JSON_HEDLEY_UNLIKELY(empty())) + { + JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr)); + } + + return reference_tokens.back(); + } + + /// @brief append an unescaped token at the end of the reference pointer + /// @sa https://json.nlohmann.me/api/json_pointer/push_back/ + void push_back(const string_t& token) + { + reference_tokens.push_back(token); + } + + /// @brief append an unescaped token at the end of the reference pointer + /// @sa https://json.nlohmann.me/api/json_pointer/push_back/ + void push_back(string_t&& token) + { + reference_tokens.push_back(std::move(token)); + } + + /// @brief return whether pointer points to the root document + /// @sa https://json.nlohmann.me/api/json_pointer/empty/ + bool empty() const noexcept + { + return reference_tokens.empty(); + } + + private: + /*! + @param[in] s reference token to be converted into an array index + + @return integer representation of @a s + + @throw parse_error.106 if an array index begins with '0' + @throw parse_error.109 if an array index begins not with a digit + @throw out_of_range.404 if string @a s could not be converted to an integer + @throw out_of_range.410 if an array index exceeds size_type + */ + template + static typename BasicJsonType::size_type array_index(const string_t& s) + { + using size_type = typename BasicJsonType::size_type; + + // error condition (cf. RFC 6901, Sect. 4) + if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0')) + { + JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr)); + } + + // error condition (cf. RFC 6901, Sect. 4) + if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9'))) + { + JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr)); + } + + const char* p = s.c_str(); + char* p_end = nullptr; + errno = 0; // strtoull doesn't reset errno + const unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int) + if (p == p_end // invalid input or empty string + || errno == ERANGE // out of range + || JSON_HEDLEY_UNLIKELY(static_cast(p_end - p) != s.size())) // incomplete read + { + JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr)); + } + + // only triggered on special platforms (like 32bit), see also + // https://github.com/nlohmann/json/pull/2203 + if (res >= static_cast((std::numeric_limits::max)())) // NOLINT(runtime/int) + { + JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE + } + + return static_cast(res); + } + + JSON_PRIVATE_UNLESS_TESTED: + json_pointer top() const + { + if (JSON_HEDLEY_UNLIKELY(empty())) + { + JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr)); + } + + json_pointer result = *this; + result.reference_tokens = {reference_tokens[0]}; + return result; + } + + private: + /*! + @brief create and return a reference to the pointed to value + + @complexity Linear in the number of reference tokens. + + @throw parse_error.109 if array index is not a number + @throw type_error.313 if value cannot be unflattened + */ + template + BasicJsonType& get_and_create(BasicJsonType& j) const + { + auto* result = &j; + + // in case no reference tokens exist, return a reference to the JSON value + // j which will be overwritten by a primitive value + for (const auto& reference_token : reference_tokens) + { + switch (result->type()) + { + case detail::value_t::null: + { + if (reference_token == "0") + { + // start a new array if reference token is 0 + result = &result->operator[](0); + } + else + { + // start a new object otherwise + result = &result->operator[](reference_token); + } + break; + } + + case detail::value_t::object: + { + // create an entry in the object + result = &result->operator[](reference_token); + break; + } + + case detail::value_t::array: + { + // create an entry in the array + result = &result->operator[](array_index(reference_token)); + break; + } + + /* + The following code is only reached if there exists a reference + token _and_ the current value is primitive. In this case, we have + an error situation, because primitive values may only occur as + single value; that is, with an empty list of reference tokens. + */ + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j)); + } + } + + return *result; + } + + /*! + @brief return a reference to the pointed to value + + @note This version does not throw if a value is not present, but tries to + create nested values instead. For instance, calling this function + with pointer `"/this/that"` on a null value is equivalent to calling + `operator[]("this").operator[]("that")` on that value, effectively + changing the null value to an object. + + @param[in] ptr a JSON value + + @return reference to the JSON value pointed to by the JSON pointer + + @complexity Linear in the length of the JSON pointer. + + @throw parse_error.106 if an array index begins with '0' + @throw parse_error.109 if an array index was not a number + @throw out_of_range.404 if the JSON pointer can not be resolved + */ + template + BasicJsonType& get_unchecked(BasicJsonType* ptr) const + { + for (const auto& reference_token : reference_tokens) + { + // convert null values to arrays or objects before continuing + if (ptr->is_null()) + { + // check if reference token is a number + const bool nums = + std::all_of(reference_token.begin(), reference_token.end(), + [](const unsigned char x) + { + return std::isdigit(x); + }); + + // change value to array for numbers or "-" or to object otherwise + *ptr = (nums || reference_token == "-") + ? detail::value_t::array + : detail::value_t::object; + } + + switch (ptr->type()) + { + case detail::value_t::object: + { + // use unchecked object access + ptr = &ptr->operator[](reference_token); + break; + } + + case detail::value_t::array: + { + if (reference_token == "-") + { + // explicitly treat "-" as index beyond the end + ptr = &ptr->operator[](ptr->m_data.m_value.array->size()); + } + else + { + // convert array index to number; unchecked access + ptr = &ptr->operator[](array_index(reference_token)); + } + break; + } + + case detail::value_t::null: + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr)); + } + } + + return *ptr; + } + + /*! + @throw parse_error.106 if an array index begins with '0' + @throw parse_error.109 if an array index was not a number + @throw out_of_range.402 if the array index '-' is used + @throw out_of_range.404 if the JSON pointer can not be resolved + */ + template + BasicJsonType& get_checked(BasicJsonType* ptr) const + { + for (const auto& reference_token : reference_tokens) + { + switch (ptr->type()) + { + case detail::value_t::object: + { + // note: at performs range check + ptr = &ptr->at(reference_token); + break; + } + + case detail::value_t::array: + { + if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) + { + // "-" always fails the range check + JSON_THROW(detail::out_of_range::create(402, detail::concat( + "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), + ") is out of range"), ptr)); + } + + // note: at performs range check + ptr = &ptr->at(array_index(reference_token)); + break; + } + + case detail::value_t::null: + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr)); + } + } + + return *ptr; + } + + /*! + @brief return a const reference to the pointed to value + + @param[in] ptr a JSON value + + @return const reference to the JSON value pointed to by the JSON + pointer + + @throw parse_error.106 if an array index begins with '0' + @throw parse_error.109 if an array index was not a number + @throw out_of_range.402 if the array index '-' is used + @throw out_of_range.404 if the JSON pointer can not be resolved + */ + template + const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const + { + for (const auto& reference_token : reference_tokens) + { + switch (ptr->type()) + { + case detail::value_t::object: + { + // use unchecked object access + ptr = &ptr->operator[](reference_token); + break; + } + + case detail::value_t::array: + { + if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) + { + // "-" cannot be used for const access + JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr)); + } + + // use unchecked array access + ptr = &ptr->operator[](array_index(reference_token)); + break; + } + + case detail::value_t::null: + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr)); + } + } + + return *ptr; + } + + /*! + @throw parse_error.106 if an array index begins with '0' + @throw parse_error.109 if an array index was not a number + @throw out_of_range.402 if the array index '-' is used + @throw out_of_range.404 if the JSON pointer can not be resolved + */ + template + const BasicJsonType& get_checked(const BasicJsonType* ptr) const + { + for (const auto& reference_token : reference_tokens) + { + switch (ptr->type()) + { + case detail::value_t::object: + { + // note: at performs range check + ptr = &ptr->at(reference_token); + break; + } + + case detail::value_t::array: + { + if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) + { + // "-" always fails the range check + JSON_THROW(detail::out_of_range::create(402, detail::concat( + "array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), + ") is out of range"), ptr)); + } + + // note: at performs range check + ptr = &ptr->at(array_index(reference_token)); + break; + } + + case detail::value_t::null: + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr)); + } + } + + return *ptr; + } + + /*! + @throw parse_error.106 if an array index begins with '0' + @throw parse_error.109 if an array index was not a number + */ + template + bool contains(const BasicJsonType* ptr) const + { + for (const auto& reference_token : reference_tokens) + { + switch (ptr->type()) + { + case detail::value_t::object: + { + if (!ptr->contains(reference_token)) + { + // we did not find the key in the object + return false; + } + + ptr = &ptr->operator[](reference_token); + break; + } + + case detail::value_t::array: + { + if (JSON_HEDLEY_UNLIKELY(reference_token == "-")) + { + // "-" always fails the range check + return false; + } + if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9"))) + { + // invalid char + return false; + } + if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1)) + { + if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9'))) + { + // first char should be between '1' and '9' + return false; + } + for (std::size_t i = 1; i < reference_token.size(); i++) + { + if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9'))) + { + // other char should be between '0' and '9' + return false; + } + } + } + + const auto idx = array_index(reference_token); + if (idx >= ptr->size()) + { + // index out of range + return false; + } + + ptr = &ptr->operator[](idx); + break; + } + + case detail::value_t::null: + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + { + // we do not expect primitive values if there is still a + // reference token to process + return false; + } + } + } + + // no reference token left means we found a primitive value + return true; + } + + /*! + @brief split the string input to reference tokens + + @note This function is only called by the json_pointer constructor. + All exceptions below are documented there. + + @throw parse_error.107 if the pointer is not empty or begins with '/' + @throw parse_error.108 if character '~' is not followed by '0' or '1' + */ + static std::vector split(const string_t& reference_string) + { + std::vector result; + + // special case: empty reference string -> no reference tokens + if (reference_string.empty()) + { + return result; + } + + // check if nonempty reference string begins with slash + if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/')) + { + JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr)); + } + + // extract the reference tokens: + // - slash: position of the last read slash (or end of string) + // - start: position after the previous slash + for ( + // search for the first slash after the first character + std::size_t slash = reference_string.find_first_of('/', 1), + // set the beginning of the first reference token + start = 1; + // we can stop if start == 0 (if slash == string_t::npos) + start != 0; + // set the beginning of the next reference token + // (will eventually be 0 if slash == string_t::npos) + start = (slash == string_t::npos) ? 0 : slash + 1, + // find next slash + slash = reference_string.find_first_of('/', start)) + { + // use the text between the beginning of the reference token + // (start) and the last slash (slash). + auto reference_token = reference_string.substr(start, slash - start); + + // check reference tokens are properly escaped + for (std::size_t pos = reference_token.find_first_of('~'); + pos != string_t::npos; + pos = reference_token.find_first_of('~', pos + 1)) + { + JSON_ASSERT(reference_token[pos] == '~'); + + // ~ must be followed by 0 or 1 + if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 || + (reference_token[pos + 1] != '0' && + reference_token[pos + 1] != '1'))) + { + JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr)); + } + } + + // finally, store the reference token + detail::unescape(reference_token); + result.push_back(reference_token); + } + + return result; + } + + private: + /*! + @param[in] reference_string the reference string to the current value + @param[in] value the value to consider + @param[in,out] result the result object to insert values to + + @note Empty objects or arrays are flattened to `null`. + */ + template + static void flatten(const string_t& reference_string, + const BasicJsonType& value, + BasicJsonType& result) + { + switch (value.type()) + { + case detail::value_t::array: + { + if (value.m_data.m_value.array->empty()) + { + // flatten empty array as null + result[reference_string] = nullptr; + } + else + { + // iterate array and use index as reference string + for (std::size_t i = 0; i < value.m_data.m_value.array->size(); ++i) + { + flatten(detail::concat(reference_string, '/', std::to_string(i)), + value.m_data.m_value.array->operator[](i), result); + } + } + break; + } + + case detail::value_t::object: + { + if (value.m_data.m_value.object->empty()) + { + // flatten empty object as null + result[reference_string] = nullptr; + } + else + { + // iterate object and use keys as reference string + for (const auto& element : *value.m_data.m_value.object) + { + flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result); + } + } + break; + } + + case detail::value_t::null: + case detail::value_t::string: + case detail::value_t::boolean: + case detail::value_t::number_integer: + case detail::value_t::number_unsigned: + case detail::value_t::number_float: + case detail::value_t::binary: + case detail::value_t::discarded: + default: + { + // add primitive value with its reference string + result[reference_string] = value; + break; + } + } + } + + /*! + @param[in] value flattened JSON + + @return unflattened JSON + + @throw parse_error.109 if array index is not a number + @throw type_error.314 if value is not an object + @throw type_error.315 if object values are not primitive + @throw type_error.313 if value cannot be unflattened + */ + template + static BasicJsonType + unflatten(const BasicJsonType& value) + { + if (JSON_HEDLEY_UNLIKELY(!value.is_object())) + { + JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value)); + } + + BasicJsonType result; + + // iterate the JSON object values + for (const auto& element : *value.m_data.m_value.object) + { + if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive())) + { + JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second)); + } + + // assign value to reference pointed to by JSON pointer; Note that if + // the JSON pointer is "" (i.e., points to the whole value), function + // get_and_create returns a reference to result itself. An assignment + // will then create a primitive value. + json_pointer(element.first).get_and_create(result) = element.second; + } + + return result; + } + + // can't use conversion operator because of ambiguity + json_pointer convert() const& + { + json_pointer result; + result.reference_tokens = reference_tokens; + return result; + } + + json_pointer convert()&& + { + json_pointer result; + result.reference_tokens = std::move(reference_tokens); + return result; + } + + public: +#if JSON_HAS_THREE_WAY_COMPARISON + /// @brief compares two JSON pointers for equality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/ + template + bool operator==(const json_pointer& rhs) const noexcept + { + return reference_tokens == rhs.reference_tokens; + } + + /// @brief compares JSON pointer and string for equality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/ + JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer)) + bool operator==(const string_t& rhs) const + { + return *this == json_pointer(rhs); + } + + /// @brief 3-way compares two JSON pointers + template + std::strong_ordering operator<=>(const json_pointer& rhs) const noexcept // *NOPAD* + { + return reference_tokens <=> rhs.reference_tokens; // *NOPAD* + } +#else + /// @brief compares two JSON pointers for equality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/ + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator==(const json_pointer& lhs, + const json_pointer& rhs) noexcept; + + /// @brief compares JSON pointer and string for equality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/ + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator==(const json_pointer& lhs, + const StringType& rhs); + + /// @brief compares string and JSON pointer for equality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_eq/ + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator==(const StringType& lhs, + const json_pointer& rhs); + + /// @brief compares two JSON pointers for inequality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/ + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator!=(const json_pointer& lhs, + const json_pointer& rhs) noexcept; + + /// @brief compares JSON pointer and string for inequality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/ + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator!=(const json_pointer& lhs, + const StringType& rhs); + + /// @brief compares string and JSON pointer for inequality + /// @sa https://json.nlohmann.me/api/json_pointer/operator_ne/ + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator!=(const StringType& lhs, + const json_pointer& rhs); + + /// @brief compares two JSON pointer for less-than + template + // NOLINTNEXTLINE(readability-redundant-declaration) + friend bool operator<(const json_pointer& lhs, + const json_pointer& rhs) noexcept; +#endif + + private: + /// the reference tokens + std::vector reference_tokens; +}; + +#if !JSON_HAS_THREE_WAY_COMPARISON +// functions cannot be defined inside class due to ODR violations +template +inline bool operator==(const json_pointer& lhs, + const json_pointer& rhs) noexcept +{ + return lhs.reference_tokens == rhs.reference_tokens; +} + +template::string_t> +JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer)) +inline bool operator==(const json_pointer& lhs, + const StringType& rhs) +{ + return lhs == json_pointer(rhs); +} + +template::string_t> +JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator==(json_pointer, json_pointer)) +inline bool operator==(const StringType& lhs, + const json_pointer& rhs) +{ + return json_pointer(lhs) == rhs; +} + +template +inline bool operator!=(const json_pointer& lhs, + const json_pointer& rhs) noexcept +{ + return !(lhs == rhs); +} + +template::string_t> +JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer)) +inline bool operator!=(const json_pointer& lhs, + const StringType& rhs) +{ + return !(lhs == rhs); +} + +template::string_t> +JSON_HEDLEY_DEPRECATED_FOR(3.11.2, operator!=(json_pointer, json_pointer)) +inline bool operator!=(const StringType& lhs, + const json_pointer& rhs) +{ + return !(lhs == rhs); +} + +template +inline bool operator<(const json_pointer& lhs, + const json_pointer& rhs) noexcept +{ + return lhs.reference_tokens < rhs.reference_tokens; +} +#endif + +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/json_ref.hpp b/vulkan/nlohmann/detail/json_ref.hpp new file mode 100644 index 0000000..b8bb6a7 --- /dev/null +++ b/vulkan/nlohmann/detail/json_ref.hpp @@ -0,0 +1,78 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +class json_ref +{ + public: + using value_type = BasicJsonType; + + json_ref(value_type&& value) + : owned_value(std::move(value)) + {} + + json_ref(const value_type& value) + : value_ref(&value) + {} + + json_ref(std::initializer_list init) + : owned_value(init) + {} + + template < + class... Args, + enable_if_t::value, int> = 0 > + json_ref(Args && ... args) + : owned_value(std::forward(args)...) + {} + + // class should be movable only + json_ref(json_ref&&) noexcept = default; + json_ref(const json_ref&) = delete; + json_ref& operator=(const json_ref&) = delete; + json_ref& operator=(json_ref&&) = delete; + ~json_ref() = default; + + value_type moved_or_copied() const + { + if (value_ref == nullptr) + { + return std::move(owned_value); + } + return *value_ref; + } + + value_type const& operator*() const + { + return value_ref ? *value_ref : owned_value; + } + + value_type const* operator->() const + { + return &** this; + } + + private: + mutable value_type owned_value = nullptr; + value_type const* value_ref = nullptr; +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/macro_scope.hpp b/vulkan/nlohmann/detail/macro_scope.hpp new file mode 100644 index 0000000..97127a6 --- /dev/null +++ b/vulkan/nlohmann/detail/macro_scope.hpp @@ -0,0 +1,482 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // declval, pair +#include +#include + +// This file contains all internal macro definitions (except those affecting ABI) +// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them + +#include + +// exclude unsupported compilers +#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) + #if defined(__clang__) + #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 + #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) + #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 + #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #endif +#endif + +// C++ language standard detection +// if the user manually specified the used c++ version this is skipped +#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) + #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) + #define JSON_HAS_CPP_20 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 + #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 + #endif + // the cpp 11 flag is always specified because it is the minimal required version + #define JSON_HAS_CPP_11 +#endif + +#ifdef __has_include + #if __has_include() + #include + #endif +#endif + +#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) + #ifdef JSON_HAS_CPP_17 + #if defined(__cpp_lib_filesystem) + #define JSON_HAS_FILESYSTEM 1 + #elif defined(__cpp_lib_experimental_filesystem) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif !defined(__has_include) + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_FILESYSTEM 1 + #elif __has_include() + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 + #endif + + // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ + #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support + #if defined(__clang_major__) && __clang_major__ < 7 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support + #if defined(_MSC_VER) && _MSC_VER < 1914 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before iOS 13 + #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + + // no filesystem support before macOS Catalina + #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #endif + #endif +#endif + +#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_FILESYSTEM + #define JSON_HAS_FILESYSTEM 0 +#endif + +#ifndef JSON_HAS_THREE_WAY_COMPARISON + #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ + && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L + #define JSON_HAS_THREE_WAY_COMPARISON 1 + #else + #define JSON_HAS_THREE_WAY_COMPARISON 0 + #endif +#endif + +#ifndef JSON_HAS_RANGES + // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error + #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 + #define JSON_HAS_RANGES 0 + #elif defined(__cpp_lib_ranges) + #define JSON_HAS_RANGES 1 + #else + #define JSON_HAS_RANGES 0 + #endif +#endif + +#ifndef JSON_HAS_STATIC_RTTI + #if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0 + #define JSON_HAS_STATIC_RTTI 1 + #else + #define JSON_HAS_STATIC_RTTI 0 + #endif +#endif + +#ifdef JSON_HAS_CPP_17 + #define JSON_INLINE_VARIABLE inline +#else + #define JSON_INLINE_VARIABLE +#endif + +#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) + #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] +#else + #define JSON_NO_UNIQUE_ADDRESS +#endif + +// disable documentation warnings on clang +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdocumentation" + #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" +#endif + +// allow disabling exceptions +#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) + #define JSON_THROW(exception) throw exception + #define JSON_TRY try + #define JSON_CATCH(exception) catch(exception) + #define JSON_INTERNAL_CATCH(exception) catch(exception) +#else + #include + #define JSON_THROW(exception) std::abort() + #define JSON_TRY if(true) + #define JSON_CATCH(exception) if(false) + #define JSON_INTERNAL_CATCH(exception) if(false) +#endif + +// override exception macros +#if defined(JSON_THROW_USER) + #undef JSON_THROW + #define JSON_THROW JSON_THROW_USER +#endif +#if defined(JSON_TRY_USER) + #undef JSON_TRY + #define JSON_TRY JSON_TRY_USER +#endif +#if defined(JSON_CATCH_USER) + #undef JSON_CATCH + #define JSON_CATCH JSON_CATCH_USER + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_CATCH_USER +#endif +#if defined(JSON_INTERNAL_CATCH_USER) + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER +#endif + +// allow overriding assert +#if !defined(JSON_ASSERT) + #include // assert + #define JSON_ASSERT(x) assert(x) +#endif + +// allow to access some private functions (needed by the test suite) +#if defined(JSON_TESTS_PRIVATE) + #define JSON_PRIVATE_UNLESS_TESTED public +#else + #define JSON_PRIVATE_UNLESS_TESTED private +#endif + +/*! +@brief macro to briefly define a mapping between an enum and JSON +@def NLOHMANN_JSON_SERIALIZE_ENUM +@since version 3.4.0 +*/ +#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ + template \ + inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [e](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.first == e; \ + }); \ + j = ((it != std::end(m)) ? it : std::begin(m))->second; \ + } \ + template \ + inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [&j](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.second == j; \ + }); \ + e = ((it != std::end(m)) ? it : std::begin(m))->first; \ + } + +// Ugly macros to avoid uglier copy-paste when specializing basic_json. They +// may be removed in the future once the class is split. + +#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ + template class ObjectType, \ + template class ArrayType, \ + class StringType, class BooleanType, class NumberIntegerType, \ + class NumberUnsignedType, class NumberFloatType, \ + template class AllocatorType, \ + template class JSONSerializer, \ + class BinaryType, \ + class CustomBaseClass> + +#define NLOHMANN_BASIC_JSON_TPL \ + basic_json + +// Macros to simplify conversion from/to types + +#define NLOHMANN_JSON_EXPAND( x ) x +#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME +#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ + NLOHMANN_JSON_PASTE64, \ + NLOHMANN_JSON_PASTE63, \ + NLOHMANN_JSON_PASTE62, \ + NLOHMANN_JSON_PASTE61, \ + NLOHMANN_JSON_PASTE60, \ + NLOHMANN_JSON_PASTE59, \ + NLOHMANN_JSON_PASTE58, \ + NLOHMANN_JSON_PASTE57, \ + NLOHMANN_JSON_PASTE56, \ + NLOHMANN_JSON_PASTE55, \ + NLOHMANN_JSON_PASTE54, \ + NLOHMANN_JSON_PASTE53, \ + NLOHMANN_JSON_PASTE52, \ + NLOHMANN_JSON_PASTE51, \ + NLOHMANN_JSON_PASTE50, \ + NLOHMANN_JSON_PASTE49, \ + NLOHMANN_JSON_PASTE48, \ + NLOHMANN_JSON_PASTE47, \ + NLOHMANN_JSON_PASTE46, \ + NLOHMANN_JSON_PASTE45, \ + NLOHMANN_JSON_PASTE44, \ + NLOHMANN_JSON_PASTE43, \ + NLOHMANN_JSON_PASTE42, \ + NLOHMANN_JSON_PASTE41, \ + NLOHMANN_JSON_PASTE40, \ + NLOHMANN_JSON_PASTE39, \ + NLOHMANN_JSON_PASTE38, \ + NLOHMANN_JSON_PASTE37, \ + NLOHMANN_JSON_PASTE36, \ + NLOHMANN_JSON_PASTE35, \ + NLOHMANN_JSON_PASTE34, \ + NLOHMANN_JSON_PASTE33, \ + NLOHMANN_JSON_PASTE32, \ + NLOHMANN_JSON_PASTE31, \ + NLOHMANN_JSON_PASTE30, \ + NLOHMANN_JSON_PASTE29, \ + NLOHMANN_JSON_PASTE28, \ + NLOHMANN_JSON_PASTE27, \ + NLOHMANN_JSON_PASTE26, \ + NLOHMANN_JSON_PASTE25, \ + NLOHMANN_JSON_PASTE24, \ + NLOHMANN_JSON_PASTE23, \ + NLOHMANN_JSON_PASTE22, \ + NLOHMANN_JSON_PASTE21, \ + NLOHMANN_JSON_PASTE20, \ + NLOHMANN_JSON_PASTE19, \ + NLOHMANN_JSON_PASTE18, \ + NLOHMANN_JSON_PASTE17, \ + NLOHMANN_JSON_PASTE16, \ + NLOHMANN_JSON_PASTE15, \ + NLOHMANN_JSON_PASTE14, \ + NLOHMANN_JSON_PASTE13, \ + NLOHMANN_JSON_PASTE12, \ + NLOHMANN_JSON_PASTE11, \ + NLOHMANN_JSON_PASTE10, \ + NLOHMANN_JSON_PASTE9, \ + NLOHMANN_JSON_PASTE8, \ + NLOHMANN_JSON_PASTE7, \ + NLOHMANN_JSON_PASTE6, \ + NLOHMANN_JSON_PASTE5, \ + NLOHMANN_JSON_PASTE4, \ + NLOHMANN_JSON_PASTE3, \ + NLOHMANN_JSON_PASTE2, \ + NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) +#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) +#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) +#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) +#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) +#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) +#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) +#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) +#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) +#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) +#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) +#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) +#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) +#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) +#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) +#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) +#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) +#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) +#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) +#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) +#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) +#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) +#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) +#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) +#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) +#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) +#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) +#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) +#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) +#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) +#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) +#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) +#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) +#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) +#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) +#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) +#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) +#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) +#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) +#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) +#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) +#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) +#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) +#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) +#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) +#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) +#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) +#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) +#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) +#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) +#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) +#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) +#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) +#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) +#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) +#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) +#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) +#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) +#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) +#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) +#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) +#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) +#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) +#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) + +#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; +#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); +#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1); + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_INTRUSIVE +@since version 3.9.0 +*/ +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ + friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +/*! +@brief macro +@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE +@since version 3.9.0 +*/ +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } + +#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ + inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ + inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } + +// inspired from https://stackoverflow.com/a/26745591 +// allows to call any std function as if (e.g. with begin): +// using std::begin; begin(x); +// +// it allows using the detected idiom to retrieve the return type +// of such an expression +#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ + namespace detail { \ + using std::std_name; \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + } \ + \ + namespace detail2 { \ + struct std_name##_tag \ + { \ + }; \ + \ + template \ + std_name##_tag std_name(T&&...); \ + \ + template \ + using result_of_##std_name = decltype(std_name(std::declval()...)); \ + \ + template \ + struct would_call_std_##std_name \ + { \ + static constexpr auto const value = ::nlohmann::detail:: \ + is_detected_exact::value; \ + }; \ + } /* namespace detail2 */ \ + \ + template \ + struct would_call_std_##std_name : detail2::would_call_std_##std_name \ + { \ + } + +#ifndef JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_USE_IMPLICIT_CONVERSIONS 1 +#endif + +#if JSON_USE_IMPLICIT_CONVERSIONS + #define JSON_EXPLICIT +#else + #define JSON_EXPLICIT explicit +#endif + +#ifndef JSON_DISABLE_ENUM_SERIALIZATION + #define JSON_DISABLE_ENUM_SERIALIZATION 0 +#endif + +#ifndef JSON_USE_GLOBAL_UDLS + #define JSON_USE_GLOBAL_UDLS 1 +#endif diff --git a/vulkan/nlohmann/detail/macro_unscope.hpp b/vulkan/nlohmann/detail/macro_unscope.hpp new file mode 100644 index 0000000..c6620d1 --- /dev/null +++ b/vulkan/nlohmann/detail/macro_unscope.hpp @@ -0,0 +1,45 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +// restore clang diagnostic settings +#if defined(__clang__) + #pragma clang diagnostic pop +#endif + +// clean up +#undef JSON_ASSERT +#undef JSON_INTERNAL_CATCH +#undef JSON_THROW +#undef JSON_PRIVATE_UNLESS_TESTED +#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION +#undef NLOHMANN_BASIC_JSON_TPL +#undef JSON_EXPLICIT +#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL +#undef JSON_INLINE_VARIABLE +#undef JSON_NO_UNIQUE_ADDRESS +#undef JSON_DISABLE_ENUM_SERIALIZATION +#undef JSON_USE_GLOBAL_UDLS + +#ifndef JSON_TEST_KEEP_MACROS + #undef JSON_CATCH + #undef JSON_TRY + #undef JSON_HAS_CPP_11 + #undef JSON_HAS_CPP_14 + #undef JSON_HAS_CPP_17 + #undef JSON_HAS_CPP_20 + #undef JSON_HAS_FILESYSTEM + #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM + #undef JSON_HAS_THREE_WAY_COMPARISON + #undef JSON_HAS_RANGES + #undef JSON_HAS_STATIC_RTTI + #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON +#endif + +#include diff --git a/vulkan/nlohmann/detail/meta/call_std/begin.hpp b/vulkan/nlohmann/detail/meta/call_std/begin.hpp new file mode 100644 index 0000000..364cc89 --- /dev/null +++ b/vulkan/nlohmann/detail/meta/call_std/begin.hpp @@ -0,0 +1,17 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); + +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/meta/call_std/end.hpp b/vulkan/nlohmann/detail/meta/call_std/end.hpp new file mode 100644 index 0000000..463f070 --- /dev/null +++ b/vulkan/nlohmann/detail/meta/call_std/end.hpp @@ -0,0 +1,17 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN + +NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); + +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/meta/cpp_future.hpp b/vulkan/nlohmann/detail/meta/cpp_future.hpp new file mode 100644 index 0000000..412b5aa --- /dev/null +++ b/vulkan/nlohmann/detail/meta/cpp_future.hpp @@ -0,0 +1,171 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-FileCopyrightText: 2018 The Abseil Authors +// SPDX-License-Identifier: MIT + +#pragma once + +#include // array +#include // size_t +#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type +#include // index_sequence, make_index_sequence, index_sequence_for + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +using uncvref_t = typename std::remove_cv::type>::type; + +#ifdef JSON_HAS_CPP_14 + +// the following utilities are natively available in C++14 +using std::enable_if_t; +using std::index_sequence; +using std::make_index_sequence; +using std::index_sequence_for; + +#else + +// alias templates to reduce boilerplate +template +using enable_if_t = typename std::enable_if::type; + +// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h +// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. + +//// START OF CODE FROM GOOGLE ABSEIL + +// integer_sequence +// +// Class template representing a compile-time integer sequence. An instantiation +// of `integer_sequence` has a sequence of integers encoded in its +// type through its template arguments (which is a common need when +// working with C++11 variadic templates). `absl::integer_sequence` is designed +// to be a drop-in replacement for C++14's `std::integer_sequence`. +// +// Example: +// +// template< class T, T... Ints > +// void user_function(integer_sequence); +// +// int main() +// { +// // user_function's `T` will be deduced to `int` and `Ints...` +// // will be deduced to `0, 1, 2, 3, 4`. +// user_function(make_integer_sequence()); +// } +template +struct integer_sequence +{ + using value_type = T; + static constexpr std::size_t size() noexcept + { + return sizeof...(Ints); + } +}; + +// index_sequence +// +// A helper template for an `integer_sequence` of `size_t`, +// `absl::index_sequence` is designed to be a drop-in replacement for C++14's +// `std::index_sequence`. +template +using index_sequence = integer_sequence; + +namespace utility_internal +{ + +template +struct Extend; + +// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. +template +struct Extend, SeqSize, 0> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; +}; + +template +struct Extend, SeqSize, 1> +{ + using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; +}; + +// Recursion helper for 'make_integer_sequence'. +// 'Gen::type' is an alias for 'integer_sequence'. +template +struct Gen +{ + using type = + typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; +}; + +template +struct Gen +{ + using type = integer_sequence; +}; + +} // namespace utility_internal + +// Compile-time sequences of integers + +// make_integer_sequence +// +// This template alias is equivalent to +// `integer_sequence`, and is designed to be a drop-in +// replacement for C++14's `std::make_integer_sequence`. +template +using make_integer_sequence = typename utility_internal::Gen::type; + +// make_index_sequence +// +// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, +// and is designed to be a drop-in replacement for C++14's +// `std::make_index_sequence`. +template +using make_index_sequence = make_integer_sequence; + +// index_sequence_for +// +// Converts a typename pack into an index sequence of the same length, and +// is designed to be a drop-in replacement for C++14's +// `std::index_sequence_for()` +template +using index_sequence_for = make_index_sequence; + +//// END OF CODE FROM GOOGLE ABSEIL + +#endif + +// dispatch utility (taken from ranges-v3) +template struct priority_tag : priority_tag < N - 1 > {}; +template<> struct priority_tag<0> {}; + +// taken from ranges-v3 +template +struct static_const +{ + static JSON_INLINE_VARIABLE constexpr T value{}; +}; + +#ifndef JSON_HAS_CPP_17 + template + constexpr T static_const::value; +#endif + +template +inline constexpr std::array make_array(Args&& ... args) +{ + return std::array {{static_cast(std::forward(args))...}}; +} + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/meta/detected.hpp b/vulkan/nlohmann/detail/meta/detected.hpp new file mode 100644 index 0000000..1db9bf9 --- /dev/null +++ b/vulkan/nlohmann/detail/meta/detected.hpp @@ -0,0 +1,70 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// https://en.cppreference.com/w/cpp/experimental/is_detected +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + nonesuch(nonesuch const&&) = delete; + void operator=(nonesuch const&) = delete; + void operator=(nonesuch&&) = delete; +}; + +template class Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template class Op, class... Args> +using is_detected = typename detector::value_t; + +template class Op, class... Args> +struct is_detected_lazy : is_detected { }; + +template class Op, class... Args> +using detected_t = typename detector::type; + +template class Op, class... Args> +using detected_or = detector; + +template class Op, class... Args> +using detected_or_t = typename detected_or::type; + +template class Op, class... Args> +using is_detected_exact = std::is_same>; + +template class Op, class... Args> +using is_detected_convertible = + std::is_convertible, To>; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/meta/identity_tag.hpp b/vulkan/nlohmann/detail/meta/identity_tag.hpp new file mode 100644 index 0000000..269deff --- /dev/null +++ b/vulkan/nlohmann/detail/meta/identity_tag.hpp @@ -0,0 +1,21 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +// dispatching helper struct +template struct identity_tag {}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/meta/is_sax.hpp b/vulkan/nlohmann/detail/meta/is_sax.hpp new file mode 100644 index 0000000..4e02bc1 --- /dev/null +++ b/vulkan/nlohmann/detail/meta/is_sax.hpp @@ -0,0 +1,159 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // size_t +#include // declval +#include // string + +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ + +template +using null_function_t = decltype(std::declval().null()); + +template +using boolean_function_t = + decltype(std::declval().boolean(std::declval())); + +template +using number_integer_function_t = + decltype(std::declval().number_integer(std::declval())); + +template +using number_unsigned_function_t = + decltype(std::declval().number_unsigned(std::declval())); + +template +using number_float_function_t = decltype(std::declval().number_float( + std::declval(), std::declval())); + +template +using string_function_t = + decltype(std::declval().string(std::declval())); + +template +using binary_function_t = + decltype(std::declval().binary(std::declval())); + +template +using start_object_function_t = + decltype(std::declval().start_object(std::declval())); + +template +using key_function_t = + decltype(std::declval().key(std::declval())); + +template +using end_object_function_t = decltype(std::declval().end_object()); + +template +using start_array_function_t = + decltype(std::declval().start_array(std::declval())); + +template +using end_array_function_t = decltype(std::declval().end_array()); + +template +using parse_error_function_t = decltype(std::declval().parse_error( + std::declval(), std::declval(), + std::declval())); + +template +struct is_sax +{ + private: + static_assert(is_basic_json::value, + "BasicJsonType must be of type basic_json<...>"); + + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + using exception_t = typename BasicJsonType::exception; + + public: + static constexpr bool value = + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value && + is_detected_exact::value; +}; + +template +struct is_sax_static_asserts +{ + private: + static_assert(is_basic_json::value, + "BasicJsonType must be of type basic_json<...>"); + + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + using string_t = typename BasicJsonType::string_t; + using binary_t = typename BasicJsonType::binary_t; + using exception_t = typename BasicJsonType::exception; + + public: + static_assert(is_detected_exact::value, + "Missing/invalid function: bool null()"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool boolean(bool)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool boolean(bool)"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool number_integer(number_integer_t)"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool number_unsigned(number_unsigned_t)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool number_float(number_float_t, const string_t&)"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool string(string_t&)"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool binary(binary_t&)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool start_object(std::size_t)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool key(string_t&)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool end_object()"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool start_array(std::size_t)"); + static_assert(is_detected_exact::value, + "Missing/invalid function: bool end_array()"); + static_assert( + is_detected_exact::value, + "Missing/invalid function: bool parse_error(std::size_t, const " + "std::string&, const exception&)"); +}; + +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END diff --git a/vulkan/nlohmann/detail/meta/std_fs.hpp b/vulkan/nlohmann/detail/meta/std_fs.hpp new file mode 100644 index 0000000..fd18039 --- /dev/null +++ b/vulkan/nlohmann/detail/meta/std_fs.hpp @@ -0,0 +1,29 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#if JSON_HAS_EXPERIMENTAL_FILESYSTEM +#include +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ +namespace std_fs = std::experimental::filesystem; +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END +#elif JSON_HAS_FILESYSTEM +#include +NLOHMANN_JSON_NAMESPACE_BEGIN +namespace detail +{ +namespace std_fs = std::filesystem; +} // namespace detail +NLOHMANN_JSON_NAMESPACE_END +#endif diff --git a/vulkan/nlohmann/detail/meta/type_traits.hpp b/vulkan/nlohmann/detail/meta/type_traits.hpp new file mode 100644 index 0000000..e1b000d --- /dev/null +++ b/vulkan/nlohmann/detail/meta/type_traits.hpp @@ -0,0 +1,795 @@ +// __ _____ _____ _____ +// __| | __| | | | JSON for Modern C++ +// | | |__ | | | | | | version 3.11.3 +// |_____|_____|_____|_|___| https://github.com/nlohmann/json +// +// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann +// SPDX-License-Identifier: MIT + +#pragma once + +#include // numeric_limits +#include // false_type, is_constructible, is_integral, is_same, true_type +#include // declval +#include // tuple +#include // char_traits + +#include +#include +#include +#include +#include +#include +#include + +NLOHMANN_JSON_NAMESPACE_BEGIN +/*! +@brief detail namespace with internal helper functions + +This namespace collects functions that should not be exposed, +implementations of some @ref basic_json methods, and meta-programming helpers. + +@since version 2.1.0 +*/ +namespace detail +{ + +///////////// +// helpers // +///////////// + +// Note to maintainers: +// +// Every trait in this file expects a non CV-qualified type. +// The only exceptions are in the 'aliases for detected' section +// (i.e. those of the form: decltype(T::member_function(std::declval()))) +// +// In this case, T has to be properly CV-qualified to constraint the function arguments +// (e.g. to_json(BasicJsonType&, const T&)) + +template struct is_basic_json : std::false_type {}; + +NLOHMANN_BASIC_JSON_TPL_DECLARATION +struct is_basic_json : std::true_type {}; + +// used by exceptions create() member functions +// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t +// false_type otherwise +template +struct is_basic_json_context : + std::integral_constant < bool, + is_basic_json::type>::type>::value + || std::is_same::value > +{}; + +////////////////////// +// json_ref helpers // +////////////////////// + +template +class json_ref; + +template +struct is_json_ref : std::false_type {}; + +template +struct is_json_ref> : std::true_type {}; + +////////////////////////// +// aliases for detected // +////////////////////////// + +template +using mapped_type_t = typename T::mapped_type; + +template +using key_type_t = typename T::key_type; + +template +using value_type_t = typename T::value_type; + +template +using difference_type_t = typename T::difference_type; + +template +using pointer_t = typename T::pointer; + +template +using reference_t = typename T::reference; + +template +using iterator_category_t = typename T::iterator_category; + +template +using to_json_function = decltype(T::to_json(std::declval()...)); + +template +using from_json_function = decltype(T::from_json(std::declval()...)); + +template +using get_template_function = decltype(std::declval().template get()); + +// trait checking if JSONSerializer::from_json(json const&, udt&) exists +template +struct has_from_json : std::false_type {}; + +// trait checking if j.get is valid +// use this trait instead of std::is_constructible or std::is_convertible, +// both rely on, or make use of implicit conversions, and thus fail when T +// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) +template +struct is_getable +{ + static constexpr bool value = is_detected::value; +}; + +template +struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if JSONSerializer::from_json(json const&) exists +// this overload is used for non-default-constructible user-defined-types +template +struct has_non_default_from_json : std::false_type {}; + +template +struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +// This trait checks if BasicJsonType::json_serializer::to_json exists +// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. +template +struct has_to_json : std::false_type {}; + +template +struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> +{ + using serializer = typename BasicJsonType::template json_serializer; + + static constexpr bool value = + is_detected_exact::value; +}; + +template +using detect_key_compare = typename T::key_compare; + +template +struct has_key_compare : std::integral_constant::value> {}; + +// obtains the actual object key comparator +template +struct actual_object_comparator +{ + using object_t = typename BasicJsonType::object_t; + using object_comparator_t = typename BasicJsonType::default_object_comparator_t; + using type = typename std::conditional < has_key_compare::value, + typename object_t::key_compare, object_comparator_t>::type; +}; + +template +using actual_object_comparator_t = typename actual_object_comparator::type; + +///////////////// +// char_traits // +///////////////// + +// Primary template of char_traits calls std char_traits +template +struct char_traits : std::char_traits +{}; + +// Explicitly define char traits for unsigned char since it is not standard +template<> +struct char_traits : std::char_traits +{ + using char_type = unsigned char; + using int_type = uint64_t; + + // Redefine to_int_type function + static int_type to_int_type(char_type c) noexcept + { + return static_cast(c); + } + + static char_type to_char_type(int_type i) noexcept + { + return static_cast(i); + } + + static constexpr int_type eof() noexcept + { + return static_cast(EOF); + } +}; + +// Explicitly define char traits for signed char since it is not standard +template<> +struct char_traits : std::char_traits +{ + using char_type = signed char; + using int_type = uint64_t; + + // Redefine to_int_type function + static int_type to_int_type(char_type c) noexcept + { + return static_cast(c); + } + + static char_type to_char_type(int_type i) noexcept + { + return static_cast(i); + } + + static constexpr int_type eof() noexcept + { + return static_cast(EOF); + } +}; + +/////////////////// +// is_ functions // +/////////////////// + +// https://en.cppreference.com/w/cpp/types/conjunction +template struct conjunction : std::true_type { }; +template struct conjunction : B { }; +template +struct conjunction +: std::conditional(B::value), conjunction, B>::type {}; + +// https://en.cppreference.com/w/cpp/types/negation +template struct negation : std::integral_constant < bool, !B::value > { }; + +// Reimplementation of is_constructible and is_default_constructible, due to them being broken for +// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). +// This causes compile errors in e.g. clang 3.5 or gcc 4.9. +template +struct is_default_constructible : std::is_default_constructible {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction, is_default_constructible> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + +template +struct is_default_constructible> + : conjunction...> {}; + +template +struct is_constructible : std::is_constructible {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_constructible> : is_default_constructible> {}; + +template +struct is_iterator_traits : std::false_type {}; + +template +struct is_iterator_traits> +{ + private: + using traits = iterator_traits; + + public: + static constexpr auto value = + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value && + is_detected::value; +}; + +template +struct is_range +{ + private: + using t_ref = typename std::add_lvalue_reference::type; + + using iterator = detected_t; + using sentinel = detected_t; + + // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator + // and https://en.cppreference.com/w/cpp/iterator/sentinel_for + // but reimplementing these would be too much work, as a lot of other concepts are used underneath + static constexpr auto is_iterator_begin = + is_iterator_traits>::value; + + public: + static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; +}; + +template +using iterator_t = enable_if_t::value, result_of_begin())>>; + +template +using range_value_t = value_type_t>>; + +// The following implementation of is_complete_type is taken from +// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ +// and is written by Xiang Fan who agreed to using it in this library. + +template +struct is_complete_type : std::false_type {}; + +template +struct is_complete_type : std::true_type {}; + +template +struct is_compatible_object_type_impl : std::false_type {}; + +template +struct is_compatible_object_type_impl < + BasicJsonType, CompatibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + // macOS's is_constructible does not play well with nonesuch... + static constexpr bool value = + is_constructible::value && + is_constructible::value; +}; + +template +struct is_compatible_object_type + : is_compatible_object_type_impl {}; + +template +struct is_constructible_object_type_impl : std::false_type {}; + +template +struct is_constructible_object_type_impl < + BasicJsonType, ConstructibleObjectType, + enable_if_t < is_detected::value&& + is_detected::value >> +{ + using object_t = typename BasicJsonType::object_t; + + static constexpr bool value = + (is_default_constructible::value && + (std::is_move_assignable::value || + std::is_copy_assignable::value) && + (is_constructible::value && + std::is_same < + typename object_t::mapped_type, + typename ConstructibleObjectType::mapped_type >::value)) || + (has_from_json::value || + has_non_default_from_json < + BasicJsonType, + typename ConstructibleObjectType::mapped_type >::value); +}; + +template +struct is_constructible_object_type + : is_constructible_object_type_impl {}; + +template +struct is_compatible_string_type +{ + static constexpr auto value = + is_constructible::value; +}; + +template +struct is_constructible_string_type +{ + // launder type through decltype() to fix compilation failure on ICPC +#ifdef __INTEL_COMPILER + using laundered_type = decltype(std::declval()); +#else + using laundered_type = ConstructibleStringType; +#endif + + static constexpr auto value = + conjunction < + is_constructible, + is_detected_exact>::value; +}; + +template +struct is_compatible_array_type_impl : std::false_type {}; + +template +struct is_compatible_array_type_impl < + BasicJsonType, CompatibleArrayType, + enable_if_t < + is_detected::value&& + is_iterator_traits>>::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 + !std::is_same>::value >> +{ + static constexpr bool value = + is_constructible>::value; +}; + +template +struct is_compatible_array_type + : is_compatible_array_type_impl {}; + +template +struct is_constructible_array_type_impl : std::false_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t::value >> + : std::true_type {}; + +template +struct is_constructible_array_type_impl < + BasicJsonType, ConstructibleArrayType, + enable_if_t < !std::is_same::value&& + !is_compatible_string_type::value&& + is_default_constructible::value&& +(std::is_move_assignable::value || + std::is_copy_assignable::value)&& +is_detected::value&& +is_iterator_traits>>::value&& +is_detected::value&& +// special case for types like std::filesystem::path whose iterator's value_type are themselves +// c.f. https://github.com/nlohmann/json/pull/3073 +!std::is_same>::value&& + is_complete_type < + detected_t>::value >> +{ + using value_type = range_value_t; + + static constexpr bool value = + std::is_same::value || + has_from_json::value || + has_non_default_from_json < + BasicJsonType, + value_type >::value; +}; + +template +struct is_constructible_array_type + : is_constructible_array_type_impl {}; + +template +struct is_compatible_integer_type_impl : std::false_type {}; + +template +struct is_compatible_integer_type_impl < + RealIntegerType, CompatibleNumberIntegerType, + enable_if_t < std::is_integral::value&& + std::is_integral::value&& + !std::is_same::value >> +{ + // is there an assert somewhere on overflows? + using RealLimits = std::numeric_limits; + using CompatibleLimits = std::numeric_limits; + + static constexpr auto value = + is_constructible::value && + CompatibleLimits::is_integer && + RealLimits::is_signed == CompatibleLimits::is_signed; +}; + +template +struct is_compatible_integer_type + : is_compatible_integer_type_impl {}; + +template +struct is_compatible_type_impl: std::false_type {}; + +template +struct is_compatible_type_impl < + BasicJsonType, CompatibleType, + enable_if_t::value >> +{ + static constexpr bool value = + has_to_json::value; +}; + +template +struct is_compatible_type + : is_compatible_type_impl {}; + +template +struct is_constructible_tuple : std::false_type {}; + +template +struct is_constructible_tuple> : conjunction...> {}; + +template +struct is_json_iterator_of : std::false_type {}; + +template +struct is_json_iterator_of : std::true_type {}; + +template +struct is_json_iterator_of : std::true_type +{}; + +// checks if a given type T is a template specialization of Primary +template