From 7ea5958ede8f798f5f59440b5e6e1a20562a8db2 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sun, 26 Jun 2022 13:49:33 -0700 Subject: [PATCH 001/103] Removed BOOST_LEAF_NORETURN for [[noreturn]] --- benchmark/deep_stack_leaf.cpp | 4 ++-- example/capture_in_result.cpp | 4 ++-- example/error_log.cpp | 4 ++-- example/error_trace.cpp | 4 ++-- example/lua_callback_result.cpp | 4 ++-- .../print_file/print_file_outcome_result.cpp | 4 ++-- example/print_file/print_file_result.cpp | 4 ++-- example/print_half.cpp | 4 ++-- include/boost/leaf/config.hpp | 21 ------------------- include/boost/leaf/error.hpp | 6 +++--- test/lightweight_test.hpp | 2 +- 11 files changed, 20 insertions(+), 41 deletions(-) diff --git a/benchmark/deep_stack_leaf.cpp b/benchmark/deep_stack_leaf.cpp index 1c5676a7..beea2c62 100644 --- a/benchmark/deep_stack_leaf.cpp +++ b/benchmark/deep_stack_leaf.cpp @@ -37,14 +37,14 @@ namespace boost { - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e ) + [[noreturn]] void throw_exception( std::exception const & e ) { std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); std::terminate(); } struct source_location; - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e, boost::source_location const & ) + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) { throw_exception(e); } diff --git a/example/capture_in_result.cpp b/example/capture_in_result.cpp index f2aec02f..94ced74c 100644 --- a/example/capture_in_result.cpp +++ b/example/capture_in_result.cpp @@ -103,14 +103,14 @@ int main() namespace boost { - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e ) + [[noreturn]] void throw_exception( std::exception const & e ) { std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); std::terminate(); } struct source_location; - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e, boost::source_location const & ) + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) { throw_exception(e); } diff --git a/example/error_log.cpp b/example/error_log.cpp index c8ccc81a..3ae442b5 100644 --- a/example/error_log.cpp +++ b/example/error_log.cpp @@ -133,14 +133,14 @@ int main() namespace boost { - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e ) + [[noreturn]] void throw_exception( std::exception const & e ) { std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); std::terminate(); } struct source_location; - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e, boost::source_location const & ) + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) { throw_exception(e); } diff --git a/example/error_trace.cpp b/example/error_trace.cpp index 706f577e..603fc490 100644 --- a/example/error_trace.cpp +++ b/example/error_trace.cpp @@ -133,14 +133,14 @@ int main() namespace boost { - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e ) + [[noreturn]] void throw_exception( std::exception const & e ) { std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); std::terminate(); } struct source_location; - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e, boost::source_location const & ) + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) { throw_exception(e); } diff --git a/example/lua_callback_result.cpp b/example/lua_callback_result.cpp index 47ac6839..f2b407cd 100644 --- a/example/lua_callback_result.cpp +++ b/example/lua_callback_result.cpp @@ -158,14 +158,14 @@ int main() namespace boost { - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e ) + [[noreturn]] void throw_exception( std::exception const & e ) { std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); std::terminate(); } struct source_location; - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e, boost::source_location const & ) + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) { throw_exception(e); } diff --git a/example/print_file/print_file_outcome_result.cpp b/example/print_file/print_file_outcome_result.cpp index 6710829d..991a2e09 100644 --- a/example/print_file/print_file_outcome_result.cpp +++ b/example/print_file/print_file_outcome_result.cpp @@ -217,14 +217,14 @@ result file_read( FILE & f, void * buf, int size ) namespace boost { - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e ) + [[noreturn]] void throw_exception( std::exception const & e ) { std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); std::terminate(); } struct source_location; - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e, boost::source_location const & ) + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) { throw_exception(e); } diff --git a/example/print_file/print_file_result.cpp b/example/print_file/print_file_result.cpp index 46f5af25..bd733241 100644 --- a/example/print_file/print_file_result.cpp +++ b/example/print_file/print_file_result.cpp @@ -209,14 +209,14 @@ result file_read( FILE & f, void * buf, int size ) namespace boost { - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e ) + [[noreturn]] void throw_exception( std::exception const & e ) { std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); std::terminate(); } struct source_location; - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e, boost::source_location const & ) + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) { throw_exception(e); } diff --git a/example/print_half.cpp b/example/print_half.cpp index f6caaa8e..faab781c 100644 --- a/example/print_half.cpp +++ b/example/print_half.cpp @@ -104,14 +104,14 @@ int main( int argc, char const * argv[] ) namespace boost { - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e ) + [[noreturn]] void throw_exception( std::exception const & e ) { std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); std::terminate(); } struct source_location; - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e, boost::source_location const & ) + [[noreturn]] void throw_exception( std::exception const & e, boost::source_location const & ) { throw_exception(e); } diff --git a/include/boost/leaf/config.hpp b/include/boost/leaf/config.hpp index 7c7e7d2b..48df7527 100644 --- a/include/boost/leaf/config.hpp +++ b/include/boost/leaf/config.hpp @@ -195,27 +195,6 @@ #endif -#ifdef BOOST_NORETURN -# define BOOST_LEAF_NORETURN BOOST_NORETURN -#else -# if defined(_MSC_VER) -# define BOOST_LEAF_NORETURN __declspec(noreturn) -# elif defined(__GNUC__) -# define BOOST_LEAF_NORETURN __attribute__ ((__noreturn__)) -# elif defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130) -# if __has_attribute(noreturn) -# define BOOST_LEAF_NORETURN [[noreturn]] -# endif -# elif defined(__has_cpp_attribute) -# if __has_cpp_attribute(noreturn) -# define BOOST_LEAF_NORETURN [[noreturn]] -# endif -# endif -#endif -#if !defined(BOOST_LEAF_NORETURN) -# define BOOST_LEAF_NORETURN -#endif - //////////////////////////////////////// #ifdef _MSC_VER diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index 179b9068..b8c7685f 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -103,13 +103,13 @@ namespace leaf_detail namespace boost { -BOOST_LEAF_NORETURN void throw_exception( std::exception const & ); // user defined +[[noreturn]] void throw_exception( std::exception const & ); // user defined } namespace boost { namespace leaf { template -BOOST_LEAF_NORETURN void throw_exception( T const & e ) +[[noreturn]] void throw_exception( T const & e ) { ::boost::throw_exception(e); } @@ -121,7 +121,7 @@ BOOST_LEAF_NORETURN void throw_exception( T const & e ) namespace boost { namespace leaf { template -BOOST_LEAF_NORETURN void throw_exception( T const & e ) +[[noreturn]] void throw_exception( T const & e ) { throw e; } diff --git a/test/lightweight_test.hpp b/test/lightweight_test.hpp index 7b7ffd47..46a31a8b 100644 --- a/test/lightweight_test.hpp +++ b/test/lightweight_test.hpp @@ -10,7 +10,7 @@ #ifdef BOOST_LEAF_NO_EXCEPTIONS namespace boost { - BOOST_LEAF_NORETURN void throw_exception( std::exception const & e ) + [[noreturn]] void throw_exception( std::exception const & e ) { std::cerr << "Terminating due to a C++ exception under BOOST_LEAF_NO_EXCEPTIONS: " << e.what(); std::terminate(); From ff4f5da286da4395f3c28196bdcb316e361b28f1 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sun, 26 Jun 2022 22:14:28 -0700 Subject: [PATCH 002/103] throw leaf::exception(....) becomes leaf::throw_exception(....) --- .vscode/launch.json | 2 +- doc/LEAF-2.png | Bin 115562 -> 159860 bytes doc/leaf.adoc | 119 ++++++------ example/asio_beast_leaf_rpc.cpp | 2 +- example/capture_in_exception.cpp | 2 +- example/lua_callback_eh.cpp | 4 +- example/print_file/print_file_eh.cpp | 16 +- include/boost/leaf/capture.hpp | 8 +- include/boost/leaf/error.hpp | 33 ---- include/boost/leaf/exception.hpp | 172 ++++++++++++------ include/boost/leaf/result.hpp | 4 +- ...accumulate_nested_error_exception_test.cpp | 2 +- ...mulate_nested_new_error_exception_test.cpp | 4 +- test/capture_exception_async_test.cpp | 4 +- test/capture_exception_state_test.cpp | 2 +- test/capture_exception_unload_test.cpp | 4 +- test/defer_nested_error_exception_test.cpp | 2 +- .../defer_nested_new_error_exception_test.cpp | 4 +- test/diagnostic_info_test2.cpp | 4 +- test/exception_test.cpp | 114 +++++------- test/multiple_errors_test.cpp | 2 +- test/preload_exception_test.cpp | 4 +- test/preload_nested_error_exception_test.cpp | 2 +- ...reload_nested_new_error_exception_test.cpp | 4 +- test/try_catch_error_id_test.cpp | 2 +- test/try_catch_system_error_test.cpp | 6 +- test/try_catch_test.cpp | 6 +- test/try_exception_and_result_test.cpp | 24 +-- test/visibility_test_lib.cpp | 2 +- 29 files changed, 273 insertions(+), 281 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index abdc4a4c..5f995048 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "(lldb) Launch", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/bld/debug/lua_callback_eh", + "program": "${workspaceFolder}/bld/debug/capture_exception_async_test", "args": [ ], "cwd": "${workspaceFolder}", "stopAtEntry": false, diff --git a/doc/LEAF-2.png b/doc/LEAF-2.png index 1237ef2a02d788eaaed54993ee92ea6675026466..56803bb8b508a52bb7610fc4ff5a8ff5991d15fb 100644 GIT binary patch literal 159860 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%0A$mCVhyS zO>Xr&{V$M;t$^-#V4f;U3OacIf|q1B*oNIJ1gspzgWqvZ0^>I9W$yb)VPK>JEzH4< z73756b52sHu6_pFBXax2h30yVnQ(+j0=O#!xS^pR3Bc#11~mvEVcuOL*WgL6v(1Jbx4@!C06ufL19em4Uc{!#Z)=d7WLgS54g(p9D7%1b%3s zfP%=z6KoPytlX|H!0-VoY}vQbAiC9P$Of>xp^H%Y+n^3^Qzm@rnO6;?e;-@JE_f#K zupjRsB$k-5W!xSp6%+=jla8-V5C>XmgmbM)P9`00FkyBSxT(24_&YU!`rN_zC#csh z)0C=_jnyX`3xm?Z$vwR_lEB+>_t5MAmTia&HH0# z?N}j*E-lyS5#DE9mx9|(qHcSPg}Qz{bHy|F*1=Z8#1D^ycxrvTQsdxI<35p>!lCjNj<~hIDCveCHpAWKP^6(P;GQ!YD{!vpH)91_TqaV_gj^xcBMhPq7 zsB!?dK^eB8gLO82vu%wrzhcf^Pt<6?9Uv<#QK7>Q*j3-)f8r46cq^^BI$bGMyjh6htP0(lwS%mzDV7kF_8EJ55;VPyiLL+43_pzWY|V^T-v7P z_&{JVM$}K5ej7wjr#*l&B>1y5w@QC48UEy&5PHlez36J9heVP88{^}aw2mOp&6 zuthy)!DbZ?ce(kyE?lww6rftA7$@W)>zSgCXPedd=#<|^Pa6=tT!-EJ8HHv~%GSoh z8#q_^RZV=my6y{RY;{E^oj#?<_;7(_+ttjmfa}^oYrtiVtbY7RbG<6ou`J&#u0XUZ zV&3rkU`tKuOtehhFP4Fudx3|J!>XKWi~wKHb4Ji7w%-66t7dk+Ok|=Y;|1Dx-9-3A z&N^TY;0^+dIn*>X9vLJW-b|c&eM&a6Sp@ocT-Fp9q|si?!d8DB;lvLY>KFa4&)u20 zrnGp~%8kpvRr&)}OT)M~e+GrLxMwf<4KP29K3YD(>chxxs{86FQOO^b9qndS@TT!P zQo}zw01zO|!|U4!0COKpV(Bs873fgdc;zU*kq##->ZR%@4LAB;X1@1`UB2cnPm!T= z0=+)hD>f428gQXx;`MAwTA&lQn_{tac;9$eyjLT6`WeK4&;_%;?W`|`2Fzo)UPsq41sgSFT>A(kWsJZ zDRsRaz{sNVE{#mFG(*+N$ct|le@m_^OYfcW#RYRtKOyy{5Sfo?7TNf_v8X?eX=7=bxZ`>3#DEUhA->8$_4LgT4;kWCJ$tC53oXHzfK%VQB9 z{wHn}Yo{E$ZxeJ}%^ik-P)qb-?csJpw49!1mVwk7Hg z?|~y<)lUpqvI~4Xu67f<=qBB*89@P1vYlsqyY~*#^H=hJ?Pzu#9p66ctOQjXUO~<+ z>8-3VCs97CqaX!!;>uevd%3I@TyiEw^w_??nKRQDVM6*N>isQjhM%bt#kauF_xI2% zW~;L(udtFaQ2HHGx2)iLU7ZgyF%ZaPUwmhf!7D;DwlOpILh~i}Mc;Jg!lQnHXOmFb z0mp1DV+Q>UBokFw&s?)tf#Q2U>6P{a`B-mGiymBm%?K-85CLk0757t0lCS}1-x~n< zT=guH2)j~_Cn4F3B-Nhk(wtwB*da$gfKv?gBLeHfeVM{K+mWk5Ep=ACsFu>}>8!<^ z!-CGyor}d$@5k$X&J@NNBEWsY&2>YE$`}W4##fX)5>(nBU`%AhrbVbHFpe;VcIt@Q zn!p2<{GNVadDMlog^nx2u1ZM33zOrj#i$R)F)4RiT)5NU zAn6`!2J}=D!@GmS8fht3yaZkd!S@aV%z2!_IL*Av;?nJ3*)ix*OVRpRhA7QVB7wbX z4F_oBR5a>XO-gYSQYJF29+aNpJ7TxYQC>g4V0r8bF}S3O8K)x2bLDUM4Z zE5?K9841s59kowoMh2^@tY66g-jmCSS{m1UZ~}gS$Z$!ieOC}T|57>nsjm>2)Y%z_ z;jp^|YPCu%G@q!A8NFL}RsyCAq5}I<)-8M*v2{3UVxV$&%_M2{LX08rA*w3sXC)(v zLJc4`V@Jp~Sz3v2=Aix?5L&pt6}K-23R+5gIwH7-Iq7mBV( z!>s$Qrvr@fT-o^z2C{Oc+v=#43FvYQwxmA@qfRNoZ~iM!T(~eReSH*OR+?dVF9FO! z#Q=DpB5`8C)h~N~v^WYkgUq-D+FvREHTwWNT-CYIRe!_5Dgo%}4XvxHFM)eNbOO$J zN&W=F_RB%ce~0ny#N89&D3NQWkap$|e=Yy9e{LxlOEYJhfeDkAUKHjqM_u1htm)zUS)Ni@Su}!eC z0k=Sxv2UJ_T6yl{8*j|^Y*4?8zyvWB842FSvc7fKT$aoCvr}XXy{;Ym4P0n;9~m1O z1n;vsl9{uhCFQ4&>y>PJwiUd%<7($XQ^P{AsozXjq-ihwxSq?2%YT9wtgO$kjYX^i zQ-!~K*ex?%`RNTiFBi{=2hZ9VCK%ZPgg9S#X1#~YuOAou-wVic%A^Kw%qcWeEji~KSq&i6a9GNyzH;ka-er> z(qBf2&1obHFph1x@stlnpgx-8+rf$x=TXhrM4#!550xcw=;E&raMc2K`Le&Un&;jG zqx98F7H*zBus?2_K%epq$6ViSV8#lia?9wKTMZ#AzfyR+ek&&QCqt^r99{2ZqF%WB z+N>pP_0BOI7Hdr%n7l_;q$_FK-~m5Qu-d;m=CxXEirrrrE_x|*oziLx_`1`7d_Cy+ zqu2)Mh_W_}s?7Me@oerYv=xP_5JF?p#YFsas4J#U>m5$;oyJx~RNqIdxpqzdD_njA zI`a4W!r1YLw54I4SG_>-)l}Qm_>)N-CIV!#pAZS-7JvV^R7vwo98z)x+6sIEH@ZQb zfJ7ebg-YgV{L#X$_-JjLio&h!dsUB=cOO%xti{t#RRQswyk{2;lj{4KOx%_YpA5gJ zz4zpAP-nrka-?9qiJ~*zJ^$Pr?FRoyzYE}c?xr8Zx@JA;`kMJ9pP>-tgzRT=94zOy zCr(MW3hQ<+O#AFyZrYnN@i(PMm$e&D22PTdD}Op?C<~+tRp>udf<2SA;C(ymmH!;q zTf-*RJ%f%@FUF;bNm%C_r;DBb?TQAVYEUMpw#EMN`-c)ZX~ODEsmYv#_&i09l0|x{ zDpV~|@ur4`hC1FOegS@R=F6vs-Ju94P8O?vSDaMMnUR$;%O7nm{;0%v&F{GE?(Xi* zaw?TMsbEYuG+u-Ka_-G{D#Y}w$j9pjRS^|;L*UatCK6;Dl|chERb%8N7kGT$=Ytw; zflgJuk=;}sZ5mR|oKkHQ^dY-W{|NDgVBU%p5r$$iY%PYXB&#Y6SnI~2qzb|fCGl&Y z$(t+8B9TbX$laI#L3iijpOft#w-H)ySl7IL4bVBXy?XhC$Q$E)a0g2LN$O2T?l}k_sZ(BK> zMBE4H9f%>5e-F)(Llu;mYSmk$csgqM>x~)zD2!5adFgWMd!~d;3YU*L?x($D?JvRO z;VJ%>1QI+B9;t_xsY9xC%H z-gAN>MA=_H?eq?Mg(auFlGID%7>+n!u{%*P%D1Je#|y%W%U^Hf z@~kEV5rhB2>p^jDx~Kx=yLayn+2W`IK3b(Ir^H<>T=#)^A~CV_{R*Z(dhof*AYqRh zAr-PY8qZIDHb*bbb4MVmxEUMqwB0^W8O{?TLNzxvCD@`mUwoi+E+b<$b;P=udbpdmn)AWXb~3 zqiDxNWHE>}m5+QsBL1?6z|dpZ7v06v_X=3(>9P4wP9OI1q3xbo#ya|8u3RX1kH!bK zJ_^K_U-(*jFD*7pPJP!T#SP)b&{{GF?dUIny8uLRQ%w}Jp$xyd7kNP|UaET029e!d z(M8&*97I0xXW&UoK|3gJArnz_)paCJWhB}k4~-|1ma;EOA2VfVRp-Yok*ecg$I#{2 zKND}()*{mReEw$fROoN;0d67vbM^h6BAKLhX;59VMvp(6+-j&qJDd^-l7k$Y;P@v}lhYNDmemgl8YWh`Jx%_8h z-rwsJ;lF-g*4{g3=$y{_)jxh%#evH%2#zv0C{;es$$&hhZw(zE-H@h^`BxI1$c<=s z2f9U^Nu7fetb}$m>#My23KP`x>Q(K@WfyP&o~*fp>rU?Q+V!HGi{8ZWnftxQ5%W(b zmbp(k_pzfQ=qOHLA)cPrX<%Q2;jI6Y*I=x;g9(4Hcj#8xJ(1kAGxgr3T5#@7B=bg5 zQBlVzYmUZV$fr=YGYcF5N6uoNAe}?H_n`JMts}lhi4B?f4cx&{5+c!4%CPQ!F`p)1 zKOZM9GUp~vR)42)$M_Q>-Tb2&(u^KFB~rLKE*)ij5KkMj>z-3~>V0kJ^Vz&R0AH$s zN>UO0c}!fo$ok19F5V(pA6c)OOlHWAD08S~&i@a_&Qnl+r-yVHNZDkohO$M;?+Km$hoY=+FL>`FO6O z|0w8g?HTj*13`#GrF7Xa3;UU70iY1Y!5|(u%0E0wVJ)DkQ&V9C72Ldjsyt}^)48YI z%GXt7<;>Hl7z|VyH&IdBy*3i0x6jsi-(IYElF)G1yKJet4e^rl^4>NUxG1n;BEGyX z+`3>(RWGRU9d_X4dS9kTHbq1U*=?GrDx1O6PliE*GN2jE#cLBvTXrh>Y=I2aP~65= ztz5f46TS@aKDQB(R8fSmkt$CVayMu``4FHwMOKlxdh@y8X|UQp>$g>PKjy0PJM%uA zLhGpN6|ld1q!miHPrP*PZrF;();H@<3WyR9AUJ3r+O*@ebpIGtq`y=*v66pGDSZzH zyFB${>#M-TmM{X0sbEZ|2*(0JZmf+XoIC{w|7pVjb5G}o=dG*AtS{;X)1}_c;3WZz zD95Kj1k*UVY7f8;mj z{X#@R^3mySDuviE9RUs9SSab5AlMG6R4-?)YG~|#@>#Z>3`8fin|R$oQalAcjbaG= zobj&NpA6@~;yKdfQ!RhWLCY>D?%`?U1G0Hi&=j~WPq-cRo4Tc8>U1%0)8IO`Rla-F z%bUA6%x$oTs21I@#fS#~2{2BTQh3R-_{_^)&p<__sX6pk-obk_ZHv=kiN8VS_$X{E zZf3!ZAg4;e*K{F)HeiwqHgS1fl^LoELY#d0l6F9TK!j6HmT6ONq@@4purU4CIZ~51 zh7#HYljT2FC@Zql+2k)$NJcO-3tmzH{w?}!s9wq_{%Yyl_SjTGDH3|&GcYZAwl(SP zwW#0J<4LQhFtO3Q#7lhqt7qkbz{9RfFt_v~>u*f%4!4~Wc0dAW1_JRZ*BlehPJnXZ zI<$E~c+IX81u$C0v$;ay<~tJ1X5D623ieNany%HNQzdMnw7jbEWV~Xh&z9>mEr4F_ zxb$aYP8(NLe(`7=N#*p8;MCwxGWd7EWCafoFJR-4 zqjz6w8?gKJ!teh+0c>Pv#fyN1@rTdA^xcCqdhx>Z3{P#HIq@r(8~rHUV_wkZkw>sN z)BVeQ61Lgksi}~s8bcFvB?WUe(p&&CNByNn<~xO7nnciVxUs)AA?7NW*L*gm56t=c zIYn;9ZYT4qn%W6;aBD{U<6bx^nlGx+V9wBZN~;&N?tOn?9Xdh4Fj zJ(oi7l1hj!Qn{s2D!QOtD^Zc;7RHQvr-X=55mF+<-je%emE6mHR=KR$j4jq?Gqc%# z&ll_S`M%%%KK@g7cFyyh^SnMD&r{Y5iL>O-#2kW`k|H{HTmFaTHIVYzosY@7uP>Zn z)oo;G;UHeBonrUl#GD4~u_^SKD?k6loz&%#GZ)>GFy+S*R+=X9PjOPowNu0wg)Pf2uikPD%6j5t7_i4XSRSuzlM&^;t0&Kye> z1u=nkvNZ*Y_BF#DnTd1DQ0^6%QUYH3e9VH%TgHB$ug;0~tG{L@>3F;J`^Rs@%}uaA zi=rB)rVD{o)$hLS6MP}CJ1rk9+I_Wf_ipqd{)sz zY8*(}FNAJB`@4eawxq3naH1%?AbM0_=~)UtP6qn{!cT4LY5j^*>?;2ay&A^RBSx!4 zWoxgv?=olmLwIO{w*51E^IVqN@#bA~46onu9zC{8Uv{gGx$ix_B@#+#v6s*qB5>-Q zRpp4SQwy;C-iuOmHJZ`tmmiUXT_eBua25o`*jCB;^a7UV5qxh-xRx}$<6utOK#mh$kwjj zJ3d;@NI7%rN~xVXGync>*;*(PC~7G35vJIMV-+@1WD4UO6v59kp>TZF^RaWn7DdNC zGkze6@4y6bw{w8JBrjjt(ah_pY!MAz&G}g^y+-BOlhb7*P{B+3OhRr2=KTVdhbi-Y zpz@$RzSx@Ww=>1jiLl9hd4yh=i(F$<+F6A~6sG#*gfARLx8Vizn8oK~zM}583s=5=U=#?(~(%W14vT9vz>Wl(<@IXp8^H@?* zYr}O}nX5%#Txt+~SOT=RhZ-$v4T19&0cD;cQn;doVb-ik)KFfhTs@du+*kHc;1`rC zHG=f6`QX_<94bKcek&s%YHx{p*8*zNq>eowVO@%`9-!C62dZGr-lYmjEW!7Mn=?nFG+EH z_n!7rjvN|zfOQ(0`edUvkM;a;pRp2ZTa1dq@D%50iqZ=7wI}B{YeZ{$>F_3|>Y=uI zwv3Tj_a3S=c@_3~p?RzeJ-E|+M=n6DS1KfD$S*~>|eQQoJlBn_7a9ao$u(fak* zVU{3QmcQR#@pU3}6YUsY^!on&`|%w26Y^rOcdP7$dex3KvilcQyNI)rM{WYKNlwepXrI9hTV0rt)EvJr{yOzM|TqJ?TOFWZCo(@;)8W}8%6Dm!NZn8J~(Heb_|2`dTcUNE2 zOySPOq#n{CH%jA9BtPy6zRp(MKA_h$6(_1%4-H7Kk_ull9HIu)FmHwLVvbgfHQzp7CA}*qaTbHz5ZC0!Hh6a=Y_-8L^b`1q3Oxi!w6n_JI#CWL|w!?f+`EWI%w{hZ832 zEGM;H*2RSiJ}f3v7HsnhpB!>}@GQrn?*t;*0Ebohmt9s+hHapRvi$ z%vAAA3eRr4!(ysL);skh9`T1K{w#$Ngge4(*=Wg{*kXO^K_P2vP^HHkUFL@s8FgoM z^7cP?I~kZ*yewSrcmV5bvX1w1x2=aqO~`61({of9%i11YP>O!NUCP|Ac?#z#Jfcm) zkVK2{!sWVHOc!Bl=6Fg-eEK8~D|`nrXTI!}s&~b!n6~?;j$Ki#w|*k%9U6$-EnCv)jDPObH1!sIvD7ofAK=)>j|0g-!!y~n zU@j}xZXJY{$G7yR(z=iOMD2N)$R}MsR|$j)D^5TJCh8d3z+o={@f#J*d<=TyB^^i2q9298gx82d#YIfwASUQ zQOw5DwG&`apPV5sM1r6q`AKhAU!ZTP+&|?GA-dym_(6RkGdhCAYxcVbkbmlGl)1O; z2P@XWEEMsw5pNPbwjFkoka!Xy_7yf6$b?zfDMa@{Hr>_Hqr6EG#OVq z_~e7|*}cAbXVr7D++n!2iWt!(B)HmD1F&1ln^F&lm9;TV_JIXrDzG-hkB0_Tl8p59eC)v&T#a%IvvN!CGwM5%Qoq4NdO3Q3 zs(`Gr!cFd(v0P&+VDKo>8I_f~`Ir*2nkiY+Dw|xDlOP!|{J=zEi~bg;LV}g5qo+&3 zr`_^|xQe@3qaYkhsK|V+a)UIR*(ax*6c&BFqYjD_^Bxys`Myx_3#on3MCoEh8{sAu z_g)*vUwgrI>i_RWyvNr_Y)`Xc$eZmOEpZwyiBK=Qd`R*lc1R1~g?;}#v_dKgD?9sW zr-2@-zuNzF!#U%7(&p*L-i0@_Y!;L2yk#^X?Pb0KE^u+z-C&Y)!r7PX)r(QbR0*b% zye#lA3fRng)eOqWVYbjX>qHpK>vrtWKo$p2u#qM!^K269I72NPqdR~OV|`)WvRxOY z$eLSODa_{59RjWhW9co6)hBzE4)~`A%#_2pRHPghbtsI5l9&6Xowt>C7KprF4e1iF zR}iOtonPa_E#c_+O$^Izb$_R9Te_H>dHm^<&)Rk{)97Flb11>~+Tpb%SLptlfhP{# z(AqEGl<~z4xhri5ENWxd=@pW^$(_q214_w$?7+rWCIF_dTsVd$+?C`(tWqY>jN&ZV zSxAGt+BQrit7{uFvcBfG!6c94KNMSNnlX657aj39wPNZqIi7{k7njrTX03Npiq>p$ zDVVpHIycf#aDbP(N=U&}zAe6|H&-H!DK1L>s(Eg<^4a1Ypj_Ceose!_Zw5O2>IIQ$ zgEH|scYosdsy@ZVWTK5*?uV-HPqM%iH0tlQ(o5B-#QnS+2+)P)b;Wxj-`0e`> zUfTQh?#jocM>rlj|K}ZMdtwzkgH_kw-JSGVKLr$rhB@miFman4Z?QIN@EE$|pEu+u z+?CUs%aYNyx3}N7kE(FWTMkwkTDEXhi5^s;(~s$}}mIG=&XT)^ngWwC^nZFPTxU!pv2eJaS*E}C0@Uz!Q2HGF&E znrKeTa>aV6`F#-Pzr4djAf*?MDI>>|0~Ztf_j8ij+)&nsm6gV2Kr1)nE;Y+w0{?<#NEF;0QxSK*^f7oUihFVms2l;%V#o3U)6exLCkUh8_>$Qv+X+NR~ys z+o!Ei<2WKh*l*8N(4fKs!a37QtFFYm*_~3ZDpl=A_-L%%LVVgn)oz8Gd366wt^C~D z2}P-K$hVi%M=m>vow|HTk-T9o;D~ssqQgHF-B}KlHc!f`n<$a#Q^@L2x>EsM8$LB1 zooqqjdJy+0e9FpXt>?ijB^mP`uCcpr$ZPQi#IMRV?P+Rv%_^%i&)9(t@zNL1Z0jDl zMLW7FuB6wrMsys{tz;;V(*bwqxKf|}Ogdgz!8&4BNpjsE#)91Qsmi%5mDC_F9``}< z+X;Z|B%fJ~n?PyCFFQ&|KwVZBwl3gGjyQU`#VZh9rjZp(SF=xUfxKx%Lg z?_PGo2p|Hx29mq$xhqKfTyH#2Vw7)9ZNZx>N=j_^yx5gDijxIgLM@3s+>ywPR#~SP zV9XE|6&GvZh>$n>S&C+e}t;Z!F!0+WF(b_v^bDnyR>?iH5Ix zZa}E0eWw)UY6j$i8&{?P1!gPY;4n`=E1IiQ%X_?<;=AaEUV^cFAVDYIA;<6Tq@Gnt zoFtvUv#!x-i|pVbK6$JR$he6`P3OjtTyIZs3E8p%b}#+`3V+-ocWo{t-}x)}caBI? zoRzRdsWr$AjD{Pyz=-8h1deb1CIv|z?JLNrsZN2GEosF%!Wg=N5Y8`%4tCzHp2(U& zd&z`_PgPqEqwy;-H7I3FD(m9Hv*6-&ZyK+O!&2*=UgpHtX#})ezhQv8udeUu4rD`F zf^Fy06TRR9KN%wx=PaB3PWq|0N49M9fyGtn!k19M%te%s5RoZ%TBg=|siYeH1c8-q z(VogBpAOIDL`*qASAH3^+|fY|v8S~(B>Qm1LJjdVULaZFAiIFn?_UZofzL+f-VdAI zZgGo*T1+00y#F9i=_lYeb1TLn#y$Ka8lU)6z5K^XCY2X!roLtI7*YvXcIPP5dPUPY z8wP_$+lp^I5vIc0_(!En7I{@7i>p>_@ABCB2rh)^*6;S5E2r>@QeCI@(4!`_LZCxF zyf~IKJ3c(C3mhY2oYZGko^I{l7+|hq9EAJp?%ZE-7NT#a%9pEe+Ke+)mJILO8?Zc4 z%9*m8wQ<2zK&*=Tp;V*8Df3s7^t}f^-X5=GbdZBLRN-QyP4)t)un}|LSiaVb*;26o z3-AE=XD>t%z_gu8-s|hi{B}!P9jMcB;ZtQ3`1l8-cMvaw6~|<+sPAuxtGEFk8OxJm z$w3_xB0ptf14vV(etwaE* z*oR^J+xC|JD3|hPmu=?hBA`+hs&r+ZzybC2G!9Hgi`ULKGNYAP4Pdpf%D}DLo9`I= zoeNgXK{(cs%7Kc`(VU3brddsC8&I6@E=lgYe_TJ{@Ja?Pg#>IDmabNo#11*dnEjwn zRj&tjzlpAR6aN)17&hwnOpwAk=`>f5yi zSM0D31BeiHHiPrmisNT4V+0GVPYSZPX>GjEK-f8nd#cp+A`{PFf4+F&Ik{yyI$1UM z%}LF~CgrXVZf_^tLrU8Ffc_^!RBEq0hGP7^-b?)(AV12S!Mo6`_fQ|wW5DjZg< z!tftG8|@|^mVvsHXMnwliOGdy88xZ1RTOP^SrgZ%F9V}qHb$!3CO`XKKyxWE%G+ZR zh1ffSr*<2Hwz3Em7bUU|K<%zp$Q;m|`Xo9xM`ZN&4%@voSzJbpB**)EHB26wYyMZ$ z(yK_Qz4#QQ4X-Rk1Jx!W>~tIUg>pcAVMYH5MU5kK)7zHr-#ZG#9c#V3jUqLCqFsuf zjf(lwN19H?{r)F7a`k4+ch99N^f|B0S0Nercs&(X-%l1zbQy2=I=IB_T@$vE;=MXI zQGcus{PlLKLD&alB-WmyO5l(7xnWI_~^1JsmD z5deR-40!rxYP>tKt8s-Uo9V0d=Ap{mgT?V?-#T!g^#CUjkXoyl+zQIs*+thXRATzY02Q#eit!y8} ztU*$)aY1A^{YhQ&LOGVNsx>)=5k+B`j;4|i?`~TW{NmP7>w+hspF>|5GGA(?BU0r9YgD1 zc5|~mLYn(YTzR~Fmt5)Ue5T6u>bdQ9T95L`x>Sl~Cu{4+p_9WKlqG2o99CJkgjQ_4 zH8^qZ{Sm#F5W;+L_hmKu$toPe1wrKa`n?72hCYzJm(vG^RoB!Lq}We3^Tvh;Y#Wq2 zobTd1aNS@IYn}bKVdnC*m#yQ%?KR5@U!zzbUGzQW^!h1i(s8s06mBljG^UG>>T6eR(d6$*+=>-oG9ENaX*zP0cSpct%5rN&V>Ljj7!@ z%oKfayF)h7Ku_2>Vyswe(oiQ;Nr(_u*fhiyUxN(c2T$Yd%*;#yZSq+x-bA*O-hG7i zL9tTrNS@CMM^!Ep1&OM_)o8)9Se3npisP`BQrwIBf67^cjK4#OL~AZ>>bjy+)!Bksn4!iiN$`N(@^p8ZxRWgxg*^ z6BBhp$SUC2!Ne{~_Z>6!I~s}@wga6>4wv-W^@r@W;qIC^>paLwX0cn3rkqJ59<=lh zzb3n_K{=ih|3>R`xZbtW4?lrFwka_ggud;NQ2-?Mr&0)eOI<^S1(w~{6R#%#jiu~^ zdsz0@;yHKyi1vQ*`o&tGab)xhdc0sAUEi(H9@Jd;K;zQmIPC7y_kZb)UT?5CAslI> zo=w@jA=R(aB|Ub1p>WL7c6ZXTwZtP;MaTCuKeWdy_v6wNihzREt`~6NewF?H($|Lt z+%EI7m{6Y}d_}y;8}q!Q%Sc>k45aTV*c{LwX7|iU-Lp@sdcr?icl^xo;l->EFQJ&f zjUC_sV7mw;)i_M}F}c8!u+hAKFWAo&(ZybKR`8M+`^}jj5Y#COODE^6SB;laQ{c$? zL3bY&xIJEuvgqW=_=$r%)gkt+9-`4~T6Bmj!k%$<$1(@`3>_TXJw1Asgp9se<;sMK z=3=x({>;Du`M?14cKYitKTf0N--yw#>04t%L!=HH%iXj}lDbDJX+IOTWJSEx`mjI| z*EKE_s$Mis3U%PA)T1!eDv`gk=(w@m+#(yM^{l4r#~7K+Ey1Oz(wvgM)GjiC&e|=H z3Vgm%(Y9dmKrT7>*rRa76!jJdJ@ssZ3~tWDErFeD^9q_aZ3_$hF5l4|Ghr_9=L#EtHQqT zuG$yr?N?SDq>q5N&LZ~!C6?FriMqRioleG`19qcZ*Zl&xWPOh--g)NYbpsAX1EZ6l zTAK-#)1n|)`{|NC^Mi#NWp-0g1Juj2PFR*MxS6 zeonWD6NF*grSvltb`0{X=(cvaLvFuNu<2niR;5$~2Ab6 zhEE+l-QAyv)rYdea(?*b9{8@8;Lv7PZx1qj+EFn1+-~YMpk_1?9ZEqQT1Uj8%^pxx zQCAGAn3%rU3=_9FG3Yiu%mb+;F3!3Saq9;?IXqJ2Y^MgmnKk{fA^qzb`@CQPl+=J_ z(9ci3TdOvgb$KfS9N9~4W>#ho8d?=pZx@sx?z0wPb-7q1IYE#W%oPTHxq2hJ?@re* z;K9Mg_CBSP83{Jod%(r~5Gj0SJ=Y z9xAHmCf0#wSTSlynuoZB)p2Lb%k-TQWcAknj@=6#g{}LI#hTs)1gthk$y}2X`XrD6{$1KbKN_B5Id9a24_6 z-5r_cj>d4n{@(t-AmY&pZQb4bYIL~ANN%oH7de?q^Yt9JtyUQxfF~oj|1X^PWu4|y z?nK`8_)5G$V~i&_j?5pyw;L^;of_kjUS3|F*uj@L_UnouFjoXS{w4dT(g%f4=~07qm2 z?`JMnnlfdK_f#+?Far>h2H)eMACW%mHz~Y8FnjmT%MA8lNJ6g?@<}e~2c2$v0IG?< zP@)D+vO$~Zm`-%nPBV4=45H-ff5X!r*gyf&v{^-tDwDhLyiD*>n1;>cnY65d8IwCg zo#?aVau10XGe1qk={RpKekl}WI}q-GNj4JPG?(Ja=ivS#8u?@0%F4@$oprN9tiNy&eu#67N+?TM<8N;tHVw6)N6N5VVoqjBj5ky*Y`icYe;vZ%XcoF z{caOV&0_JtMLFwMg|3TCSY}xx$yRtY%L`@(CkxM7!4OZ^&MHtRYaGPfCyrsN=Iyl`l^g#$>+-d z7Nf;_YL8V_X6IVhdMHF!i^}osRNh%`3#N4q= zp?pUJO4maA_X&Z$^7Cw->f58eS3|10IC6xwaFQ{(nppQo2uh5se`Fy{YIGM&F;!{8 zv$O}7!f70X%75aifs@n;`?HE9HL&(oMX{g>)qTz!@{q?k`4VXk;tRX!x|weku~qvk~BNF>&?H(pclS9 z_}d-JDgZ>bXLF@XvUa@ptFG?g#;R@v!9ICL!oo~!2Yj_VxA%GA&*0{4`X>S(+27fa zHMZSL9i)wARuzNe^Zv8?R1KrsL~)UX>#yC(lc{}v_P3QEjS)vVMyV$2eyk_qBS*Z> z@)<6mgD3qZw)csbKb?`{KnWDfzYxZ}Z2H??tk@jau#J{n{+64kmq|;a1b+OiuG?>G zttc%~8z;5^_B?){Q}4}7t_hmjb zacmQ%h|nEk{7=FYFw9yFz|LoGJ9e&t+bJS}r*3AjMUqWVDWy$>ym9_Zg znQg~oRiovM{I)>KXBbphBwEBO-gguPV2pqQgTwxBb>qMEG=p0UZ+?@Z_H@^Nn^MPn zSc~W$QRtJceSK9g01A2<`Ka*r|M;jRTx)Y`kACDcehw%RE^mq`$A3|Wrqc#y8SFyz zvn@i@3u*ja(j`jscl!azchIrj3`j-$MDzt!+L2SZzs{FLBj0-jnezYo-W71%us}D; z()1A(GvcapgXTDif*!|%nHJ7u;E&O#iKk z(+5t$fF_0ua73`ly7=dQw&j5dS0&A2d9DAF%@q zzz$?7i;mgv@h45j9o@9!EMwl2C@~`SKaP>XiU(`Vbf{HWm-8pwZ}D5$pLUGnHz$@5 z>t=^M6X#PRALI2a4SMl?TU+Wo=^-w^AB(@|vm{GC(E443Yw`M0eKIsa>kjo)@`Bc0}AaktNx+;Uj7bHi`;b5r6c7j2*BDdVSg z@hKl+dmEm-TjNman!}4@+=6*2i4{TiAl|UMRvB*?*i>8$BdPv2((2YPUrNKgN6-4| zS#S06_03gr6JR_BlbmuMaO3rD)-9L#F-^L&ScM^#=Gp%ISU)i}EP#toge7kJxBJlg zC%8J+Qq@1#&?@rSci_|}?(&ii6p4!E-N?(w^>`&@VX7jY+p<;Q zszTQOO3;{Z)Q=8&sMT*A*VdbJ9p_+5J*&8%Kp^+Kc%r_q9{i{IqlFWDC5FZR@Af}M zp9qI)we6(~p|tf1rgY%9Dc#ngYSjji0?x}EkLY5v**UPhSx&t{_$hhjz%0`>;wha6 zVAm_5kQGf6dLKs!Pbjt4BfmKyHp$+j8%aUFLO%xxrS5l0ISf`A<%X9X=o{S`d{koi zoA}74ga46$hyJxctHxS{A|lZ(#Ok**8}kRm2+ca&`%j*I8bcfB?yL0(G|P=spdqBO zs?`Q`u}6|+ia<9YY)XWnw1XdFwejCaBW8JX>4s#@htkzQVr*xtxHTq0Y9U?9;Mgg?{r@|U zO3uI!`lwc7H+8@$;ERGIT%F9hhSyVVR4PaI?S?hD{ZBHo!NLaBe)~B_JkVHQJm@Fs zM|e&_B!=V8Dg^^KO>t;z^vq&U_x~YVH+Si4NSe+IVED_v$CiHG=XEyFX@n@K;<@HZ zQ9Q09DPY{ZR=JO2=Ja-W`ZVPKP-+`mYA31A62sq<`H`^VstxR~aJX3AqTH?{JJ8r6 zj>MBxP^rXy)2?+X^v#ksTea|ZFk0&urCXWPBpzcqBvzhkK1^)-N-socuXskZYwqcK zmjZbj3^S80FlhAk@yP*V8L_K-*0$I6fW0e61S9;E)5P z^|yFao2L#wvzQ2D*n(O-J$6lF+y15gAI})UZ-vA1tQ~&~w&h^-=EhvRWyC8cB#-!# zOxRx$-qzffee`DnH^Zera74+=$01eYH~^^{gE7)U`?clfK^>SK>^YTlfl;2735?sT z=f8&rWf9?5i7frnqm{Nl6z&I^9XvpOqL0 zcq632ojSy^fzPHnEWG`mN-(Ih#vxDSY}ZWouETmawmaTZ`g{<#DwuS;b~4=&Q{}KI zt#n3thpc3geq0@8NIF__!!d~A9WI1V8t5*Tl3J^vSkL8h9W$oq^=MCXX#t_sdDssO zx_hP7Y{Q?*i9yblopF#XM5HMOQ=7_SNX0jCX`|94Q1ts~)5BH5a7QDg$x|ZkF!0)e zz@Okf8c17Pz^?FEH9gjX;%~atHD$*@b51xWcF||;)SJ;FF@GZDQ9Pr(X5uAvPbIK5 zBp%J5nwpxIZPrD~nVFiu;nKe*?Ftx7zy(q`Hs87ER<8EIZhgkci2VsTyq{;xi^07K zex)}@dmrmqoWndA=;*@(&;Cx8t0z4ZkMsDb%L%GosvdQ1*mp@FwVh(4+6aWge8(Nu zq+0IPOP8o}umiP}8I^Prc-1hIz93)yiKb~tBC-kR(pN6LtqZjJFbC*jAd#lY1}6nl zhP||k0w1~sLprsIVl~E3)w(v8bai+6GY9E3&6&h&$jYBwKY5-oZ&XqgiyUw_*u{`= zZ2uU9gNhvd6Lg3;pVbh#Pc~d zlibkuJwBNWTEE;ue#`2JI0*1R?n#^~V$6r3oPG^;^=Gh0@Q+|~b=fy>rZ;uxJ=oO8 za`pPS=}ogpn+YACLv(3s7ny;bM=-CRwz}MIVFV-eZU$ zWgmvpMIV@5dN&mVlpOkW>P_bHzU~P$v^`EcXxNQ;X=<_ z)dFpfJ7pCcnUs^bX9j%q{KpjCz{Mct!!uG|o9rE`c?N&HPul?(1s=L%V#SZjp7Czv zW9R?%F=hDJS@Fk^5E3%~*L2Tt!O?IH{$zs24R?o~_kRr9Kq%Jk$QmPoi$v)(5IUlO z&=0WDHi*l?M4yEZK20Nn;~4xI$ItZa{$YxHJr@md;KZDtzKt9M9086}9hzi~1Ta&NxINRSHPP9e!G+F3wj}Y;1~g zm|1cV0^{sEF;+%J82JRZLbz?O9Qh``wgDLe;4s&~*)9Z2%;D4YS0TqiTSJB(vc z5ZBaMH;)C5;IxJ|@b+qc`f|{>ofBW760|$1w-twOE16ncaZ({m12RoGBM94UqVbC5 zeSU%F<}KMMATLX_=72871Nt2ir+7I{I@Q(scyE-6fJKx-t7)5HuF{PSH zVv;bT9L6$${=Wz#J7iNQqPg(WftJ0QpK{2tddSkAtFBzA@hVgxC*IsH_?r~(QD@&2 zKBFp%ZDR&*(UV|z!(N9AFt1Rt9?@b&{e>4zW|Zj%9t(p5iYyPA76X=tJfuaRxwlVJ zy+@x{1<-=HIY_nrIngFew$ZW0LLp0SMwho<6rhQ7CX*tR=HG9l!zdvxmYY`&*3M(W zxyc<`r3L>a@x&bH+w#;39DyG8-a_G#%uI?REgWE(Pp8nteYC0{b1Rp?UtV^(ec(H9 z!T@-UGkVc?4>j*3wK4-o_cfAT+bBKc^w)X+bw&YcyTt||?y`r6V;{+*GHtX@__?hu z|Fy#+7-(m~foDID&ZyYnnLVc?weLn9?wh@$spCs$2M!k+HBh|VbeuLb=wqup=(8fD z#KKuF)N?BdSMq4KLmowH@t~T&RR+xvZP#rYL2qUxa zB-hrju|RUh?}>+rC4t1@u1RvHRY$IxRCRAMNcKVl zP4=tazW+FGj)m+1Jq~pKAen*H>*u>e6w}IwWrkRFl1P|%xq8LC8KsY&b}xEvxmIzD z7`IR(rV#o6jqk-1^2wFM`kBN(WF8}mU1HfrnC-X zN*m}9M2KX}AuWVK5KSSx;gRL^X;F1dal;?kzZx#VhCKthSS%(-&zP?lz)F-LmAf_* zGl`bdzKc8QWF5+=ufPE}XZub>m2E&WQ1G+!)`4fOveW*b*n-5UH<#|-MUA^pq;Cap z=AE!;tTSKu7|C|I&HDU*?8ifRxK|N2_tnhi`aCGU;oGd6=YsZ_&U$`50_XdUSrtvF zfdoeMLW$V_ez=qH_U&6fXqMuzY&>4H2F{uzCfZ@euE6mhyVy)b9&a{LdyK0vHB>a@ zA-*CmhJ$VRb}9Tzmpko?pa*~(c$}+U{%Z*HT;TodLW|86%M{C^Une4+D;p*!kTu#^ z!%lS=`QS&kRpucjw47*aQanUkFoLj2+?fhaYcDvjc2}f6W7Tlch_*=M=uod&?7(Y# zm-Zx}>@(hP|8cS|PJyYGOZ?-^+v(4p`@>mF*5MPFrI6D!21Askc@CEia;ao{POqT~ zyqYK8qaLoK+z*#qN}H4!x0FgwtTQj`C@yi3hNv=R(|5+5ui)`~5lt#oLhV)JvNQO> zCm|S#Qh05>ED?+NuP31q!xh(2Yj$^Y2Yo96DQhYY1fxGH&Ch$7>c~bZjm(I4(_PF` zQXfgWa)&>L?I((Q-!@}f8bQ)JwP}^@C3d zUO6m!@f10nNMIN9UnqNAqg8x3`X?i_JQ*$npYJy)vb|9ry&_O zYL6Msj$bgHD=mzt4G*6sC_YcSzvU_9JFbXpPMbpTB3@bWcIlfTEAGJuO`pP5w&na? zd2?oJA+bt#x!SI&scV)bl8++M1lMq<-Q7SXa=(c2A^jCnOs^*y@007iO%EOMTBq>mQd zLzuDLbRx28SCnu*8elzTjkxOvyg2YL68*{EsuRJu=E|1gkr7yql~LYRdh}S)-ceN~ zTU@!?RDQ3#zPi?{Fft3CPFU9wrfx_Dl)8ZpBDso2ejLw+QHvxc>)&`BrkgN7noss+7m0{

h)C!(f*V`Y(zaL=>7bsD{2rZ3;37f9udC3RUu+r6@#P)n3i$lc~|tH@_`{C0_hF8tq%IR}_u)UmuUmXf-k; z8LtL83})gTekn3UolHk=9SMwtP5g|zko8Py{&6mM7vsaIAGw`lHf<0kR&QRp z&|J3KKU_T68R$gxBRMI<C^a{@bttoSBJ=6!d-df*VgptSDS~$-(*E__ zeL_69jgKr$U=3>Go@OL<=9Ffy4*P!RsrT5xm?3^d9@Tppa_e(;1wKqk;68z@sMSoc zVKEObXasK_Z)!SZkyw)1B&zH|O%o@Dqb%nQ>UDmd+`sW4Tpy7n0 zn+mc(>dU9`7Q)oZeWBji9IpN~Gc((wgkuS>PcMr(w0hau*}|*$?%r)oS4ulQ+wjoo z)h9ZaEq!KCx^8bAH9)H)^uU(;+nhV6>`j_?iADL&@c5TNWp- zWC(ZTPON)DKA^j3XWTiif*tfof*-jfPizcHrJ93Ey4rTaajVx& z__Ey!7`$UgfkDCi8;p0i;jbirV$S!eCw&rL77BRQ4$$MmkJn>1x8>%XMWZNa?zp4W zZdB#3r3dQgw|5bVTw+hTvjCs4?JTR~t<-w>_w3Xi3F`K!Z;Lc4wx1Bm%SyC2+XP0_ z7I^CoaC)x$`uX7)9t>q)MGrZr@wNhk9Wiw!q}%5M0n> zhGEvsU;srr+ik%e}DM@+k{WE^LOqvJ{zB0dbRh}JSmw=P7;DklE zdbU2*bXkMx#$oxf8`#A50)r>NhWds%=lDX;TG$6(b>9CN#yPjQ;nL%;bs}e7>&4Bb z!?fT(@jv^MY_7WD>(mi2xC3mEA*6pyEj3}q?+HY{)M_( zvv%!sI9-3woUX8UqL3aFQ7c>LbjvJLjfK2Mi+b_VH$4@0K*6A+pi6jkgf6m$_Vipk^$s>L;2#a#+DzGT!JczwOZ=`7&L&JppLM+IXaWC|=`K<)p}fOM#y z5p4Kt2% zkHDIU-V*H|Zx-^3`%tQ=pYP^9NAwQD9ZpAD%eEC)adL+QV=d9ZmRhHqqO|WQnVAwi zIn1M{0B^Ysy7#OEkfIanP4;H;f|*@^vBhY;begk_Qx%pg;^)i=#y=IJ#3~?8Ikx-} zCB7Y-<3t}nf1q+EsCPxP&@WRYTh~ILbfgJFI`Yms%TMtma2uZCPWk|z-Wcg;zk(Qk z380Ztz>Iy4vsv}8Yoz7UoUGGe!+%X%-a_;yY@8?H@h5JTwcuR}zHo=nrnQL=zq3}Y z9ahiC;h|zHY=(ChJf;G~#Ds@bx4cr9H_+b77~wVx@!eMojy~p!0Eb?frGO z6{9Z>$E8D~UgfVC(bO2R_j>hWvuk|d+bH}j3XAyHrrs+Y-$;-Y?1*cqux_!8({z!> z=zF~4qhDucUP^~;4Hs|gT#=-oIfu6l>cm-8iJj4?)hy^0W|Y6p5zNPPV0P}cDZ2Vt zVG+U+j37P*hR;q2_lKZ)J<+KR*okXL-gF$V`2qSH5 z{pQ1q)j=(}ym9988ORExd*;x_2A(0xRY&5}^OW1j>qd_>8tS6tt=p#H6?)Y+XxlJG zM8os1Yo_3hZQ=&y7g;30;Iqb@Y9kvk*66~2U9=|8=BHVcAsAjxCN=w$%-AAdJgZ5< zvBTTox%jR&wsv=y_p?YAd~D0U$43XBqvjfTzp`Ghp*$Iwpjap@Z9yM*+@A%#ym0=# z(Amb^aV;B|Lo0FK&}w-o;!f1R1bv@9tLv-iE1*v#FCXsuI&eC3f&tYt%NENde5&-Mz`oZn4=P8Nx{D%r|Hp9BEbF;! z_R2*(Xg>vONdp?D%9A~w7lf$Hr#GHd`CA~5kqA*8FOPMsSuFogmHB3)+lYVan$tM{ zXDQe@P9N8FP8}H>);ae^tWYGDT3`Tw0ldzBN1D|mxRHQhXT z^V6cjVRuqgZ}qnq^{HCU3r&9M!ueZN5Pg$SIDUqpTJ;rB9#7yqsCLG^+9Z|eunqR* zsMM1PWP?S>j?o82aPJT*BVZs(`(E)FRbQkt*=SuA+X9XHR+ry-*9$LS*L3d#IvTsC z+IYSBjBl|1m@M?1R>M|SqCu@mGtmysrKi|-YET6}%I0z((sntH@nTZu7)Q*Ue+h|M zgoi(BJY2d;4FT|DMT%-V)ekru=+>An(Ffhnn7~nqs;|q)o-Gw^VSQEBnCZDXpAx|4j z_WyQkkfdi=;dm-@%Axkr2990s9=Mxj$4W)2?6uqFUbtB^%wdfZ7F8~)WN7Dmk6X}X z<8}xd#KkJeF8kM+0s7Sqf`(qkCD(>3>_t+N<{%ceBuo20N9D<@7!hFDWpn?2zmUg& z1c&6!_3sCCwcw5BUyjGLpTGk9!Oto5sNN3T)g7vE_n=7OZ3u z9Wj867EB06qUE*KZT>zNs_<&zKWFtekX7S^qse#>b`%Wcrt2EXetYIW9{nRzMI z%8YeDHvG23k~GdvqxBe2yoaFG`UPPTWj>ELMx{T<{->&u@JDWPwv*jpqI)jYwSh!k zM$-FSS?}2P~w|VeA&U43h8<u2xR}GyX_s6-kvw(_WfG_bAi;TJA4Es=_-D*yBrsbfF0Z?yPG$hp z<8`mycjKxLJoP>NAp7}0oFs{DRH#MMmi7&S33qHEwD**HTaRLZy5gTLf$+De^mdWqEhZv>a##nB4ByMjzOFJ8r9Ah3B3PaG7Uscmv! z@?YP^^fCCi5;Za%&-UK7bM>z%jnMH6B3)MN2cXRTne>t?i^+tyLr6K1`S|G0-vk7MK zJ`l;&E;IH&7ID7ppP+7+eoIcuo4idbE-Z}d@a7cvR(K*0#gJQ}g+`3IOXZg)W z(Jjv$k(9r>@bNcHh{H>fYBd_0LikecJ`!f}jc-A^4|YYm}LpFGBx7|4Il?j66p zZpOG@J`9?RKz(NmIaI|~kg9d=LLNytUfhQCMzj)6)ae5^9CBagFyU=>B^D&|-zR>V ziD{QvV(z)fVGG^rtkvI|OFgi48*~go8W+UU*pL~;?8aaOV{b)iG-TIoVSJZE|JkN# zD0(RRR|N=wm&2u~@bt@(n4^B!I=1-| zH!pkpd}@ymL09O|+>WKv8uY_7uyq@C>t#_(WVVRq{{mEAxk##{gX$|1$qzNn3i&Nw z3o-oobf2Fy_P(iK^GGI@_DTOfy+68vx>!^KckQj|f6jDEXcSvZV(D)YnuOFlnSp+O zjUY9UeY6rFi`>aNmI@(4ue+~L&#>i>YGp9O(a7TrA*|m+h3$XA6pLw!qT*%uJe)on z(mW406TRPFKTOQ)gHRO`szLvsZ+wPC5{2W=1jAsfmZ-TpHjcV^#poL_-|J%UNMfnM zZ*n(~jnot^BWVwc1dDWc$U(8ldMuiHh!8#A0+^cElsQ|Gse1gcsak}=R10WIBBXe8 zFGYT_F#iW->^>@J4NWIaylD~=vwz!7~0c!Q; z#Q%66WifbWt^8QVjs+%N=0Rw<09rmN&`@ItTE5;@hxg@|QQ^5UvmQO!;8Ez75X<3X z9jCTxo;r?%LH+JM&|)II>F@v<9uK)^1vJ9TA0KIkHyO*7x>tU(lH)mtBE?U5s}-h2 zTM912=2MVIHRi;4_}sXWmq#^@zyt;I>)vb=%0y{WK`eIdg;?%>csN92bE-P|urt`$ zi$g)evD9cm-7!n8EA1~XGy7}8`AYGbIGhHeAdhr0CYS@yp&6L6%biAqeeES5v0ClO z$C%oBaA&Q8a>=@B8j6Q^e?E8X!|r{_YyEmWVL}^Ppx@=nV^8<)N<~7w@Fs}gK(87o z=M+W^@arQr9SJ+0H&m%sDKc_l8*imZHlClk`H*1fZlrpjSQ*upIP0y&>TPGPXHEu6 zzET1oH?uF?X#R;W&@f`f?QYXQO`Pa3Qd1b>+b8jVcL_~LRLad-B45HD69i6^8XTEapvBprX!*k^e>z8C&;g-e zevqwWzepq_A~8{Ofu04uRDAbRA>X6qY}_Sp61rT=C;MzY4jN{*A+145q)!IS-AY#W zT3MK)xGmSBzG+y1bUYKh>Py^qHnwE{VqUFw)d|+#U9SI+urCjUa{vCjH;l4g68L+g~_my6Z=s}!Wm;_D5Uo=0hBUbt2?UF7< zZnDz#Hqztz9~u|p#e&>f-ak&Iez-9mnx&3@j^yhcz#?WJ?d@8G(Xls#FpJeX4wE%s zJE=@Z`Q*6Q%kgjJOS{?bSDA3y3>UUw`$EOC@Z;&eC|^O3A~p&DVLQ=p5Z_LxhV2%% zY;5V-I5V6k3z?FS$ysOdu0n`u6~+ev1*ZLl_>wHl;86w1UN0}N=kpCzZ>ls~F``h5 z-Y6pmIp22Ar-t(m-i5fFsqrsRMuA)R=Bjmu>Q(iPeD@7RSt*Y=EE=6&)NZB~YX-ln|3Ix2n~U=HOI7~-0Z$fq*pi-@fjGYT2$02@AHYdo4%&>&KZqvmE5AENAdsK0!)-yhT%TgRp z?zuJV>&3h^974X>BgDH#f0mM`6vgXH(WHLRVNCwO9c%Q?Qs;xF>TY#p1R7;@bW}tP zWY=OUinoNecl(sofkbE~XjlH(pk{??m zR+#~V)&n9)bB~;SQa$3%g*;^-kU6hIVX^7bLyUY&a|AtU*vSfz+*@iw0NY5PzMKNH z6%drCnk7Im4uavsu}j_Cd`47xn;8s{SlkeHk2TECC|f~qNkWBEWW~*2pK$g((rxZ~ z`G+eXk4dSY!#IG?4GLTqVb)sgTy^hhy+>lY*$i^6ygQtrCc z?>9czz>D>vyQ(Ylo`#`QOGAnLOZ59$!;UvId6EHje5nY%T@Wos&af1#Ncy( z)!WKwMm4y>jHO9ctUl1%iCf746Tpi@shS$bl;~148Z*n zbzTPGDq#SNR*c3@j(R2{z*X(YY=GB~JUUDpTgbfFe!Y&dIGx!6@5w>*_T(M12n=A8 zgShFdBMk0w)hapyH$#tgn;G}x@9Rb88s2z&e_LQ*d$_|WfFo=5zdxFj8}XR?c&I!@ zWAHSQO?rE*6A0PB7BpzHWGrg54<9FGr$?vlD*o~@Nuh%1MZrX)OxtUIJd<=DtXm@a zRVx6w&#oL5k|oF=?Dl%DJKr#CL%lNmfc}ok^%SxDXo#?tD1kER@vPxF1%qsWuMHLEGCYtSn-Od*#$mv^?I1doFX*6Pe!4d%lBA)R&LF_ zjo$X=@DB?m+rtGMho)8c&qu(hggl~b`H#pV{*eahD=L#@WD;4+pu>&zx z2|SH3R0 z)r1lE7_ZFdy{d?8cLLddom4uio$0WY2Z2T~36y32R%BE$;+ftXse|D}y*;8=UL2A@ zJrE_-oEpbe@*JXwt3RPzdxwoI<60|&@TY28t($l6XILeDsHLmw||F^V5s7ep# z!CArLBgElTQ39PpF1?ib?|{N*Sb6DWn@H!7-xA1o3;EtF%{msZ-wR}ngz)YcA08jg zNKR7f^7YXQ(V&B-FwjeAE_v!yuxC4s7%WB+%653QCb>a8fN0)9)8$*4Wa0tgckS(_)w{ zln1oZU~r{7@zorqMRtlLZ2SE|a*!gAMI)OF=meqaBo#W~%x{VP&}5>Ky__U;f6sp8 zG!8S|8@&x}o&QL(V}1Yl^77E4`_j}x10kJsM;go;?*uSw+%WOg`VK?W)SXOG7u{qx zx}DpjqS2){sZza1Bw2+(<_?A3=$%^u`Z3{_*(Zb9Sj75Sk1|%KLVVys6I-13wYc4` z7AO-aM%+=#D;rJyUGfT_xC~%V?VD3-6IpB#B^E&5F@ka>sQ#{|TVT|ksXipyp8Pnx z6K3A3V`L5~noWqGtJ^_SAyyCqynOUz4-9E{gFwIZp+5DZCryY+K^5#I z$oMhsjC7rd^056axJ(x(wU5D$&6JI?p-W7rknXHUs0i_u8`tSu`rIh*_^KZ*^0M-_ zyE5sB^^ETMy!R};v-v9PB8AQD-?g8D3=8=1NKkb@MNeLngDW{)zlYox4y-W=#zZ}b$iim1s^W7z z_gDk`$c^o9QmD}}DwbN#VAPZfe^UuZ{V5IElV&fm1z-8LZuZWiuvnB)IBG0Y&}CzJ z_2ml+J7{?&y+!Y_y z)l-T!Mxma83_0>fg&kWFi`ow%8pgX?zS_4X>ng-F3{?JRzC0DnYI`$+8((=?tbQ;# zPUm*Gh)BkXXnntnDdw+RA*!1AnBxcnIoY%fgO-G@-{up~xQUk(_^9Jod9L}z{N8a2 z1IaU8%ZC#Wp@b0d%EQ&IFbVgHOJ9nB^(VcR8P0)mH`TNPQLmGcamax!Le%5LfJi_X zmvWAefJBvx(PlUk^}>b%fsE2_Nko~`M`&*^l_g&oPBZeWtmGZc_!!F&pHtu`Y~e)- zQ_wtK=h-Nzg^t*LlCmxfi-9b{2MY9C93JdZaRIme1V6r)&A|O-O_H4;eQJD+mn4_1 z?eNL<4pQh~j7UZ#n2Grpnj$cv8qD3mxbWw&`)9a~Kf*(O1i`Q8D}a(KasK=K!(Nq* zu@nnjT6$PA3|qPO+%)`c+3!lp^L4`eVlQ%5g%Lc49!xEYA za__yrN3VE9g)T>+X$=~5sj7vPtW4-Bwa};xi`Bc4shs*DOl3vB(FgVWA=fw6p1wjNg(mfW$_`xo8nA8WH@x z%A`vC0_7DeWrJ_&q6WV$Pnd&h>oc9#ytI551z|g)3a0%{!>m-rFX`TgS%u@K5Q(9MzgD%X~;<~^sqpct>?m`P)7 zg=ouM8e2ZgQBbT$&Bbgz+G0ZmAst3ttSl`(BO!TZ5N9$lxv=;Z&8OrvP+8}2zp(y* z8Eb)Ln|D0e6Re0VxrumLwXu^jBySB(?n5KeBD;k}6+K^U)mG=}{LY zB>=vhuDSoT``uL_LRy%1E7&6aMeI8b8(WNTv5KJ}lC^Jj>%*OkQ)uTF(Ne+dn;-fZ zsw^!a(;S+R!vR-lU+LcM5Ee)aL82&o3-OBFlfsFv$#}^}jY@bkgMx)cXs$D)a+w;x zSSu9z`=WGKgzZi|>iHBd3{o(7?Qj%uVFuA_IElX|%tPXE#^>((%+&-^or8wSL8Z&I ztKmhPrAeCkC@^EoVA_plb&G|Tgr$dQiwJQ@9Ty^)GRdJ0fde~{V>Tne@J~GG5mQ4A zB=J6o3{KDS*}6Tz=Dkr)7xMFQ0eRq4d5$@8la*kWAs-fulIYxrKs*KHm~Csr8oNd6 z#4{i#lXeJ^gev%6lkDV#6kASRFch~eSuMLSyXc9V(VCb$ivL%xxk0+$;{?=&q^z0gkZ(D$SVFcg(lx z_w6(@r>bJ2>?4E5mcH*Y^MZDGmS)TdoRe) zmSPHStTAkccCuxm7$QFEK3wgAIp9Iv(I_b|2q0Y)`^TPI%kCLwEk91OGoVi;rI&Y| zk&OF*2R;>9;ZukP|LtTxc^Rez!`%H1kMG|nZgvKo>AK-Z;Fy8Mstc``Y_Y7q5juPY zElZlA)!fI+!;mr#&?((8BBBY+2}xCO?F?P8dMeE51O7&E!Pr=4E*+Vgv#Hua^RN^1 z1V~~Q$#<6_F-%)}sPql`kYMG3HCtBTtA`;88OC}avO?!?KwXKwnSE^iLQ`pn%h(*E zu_>W*rP-(|ZCuK!O%+J37eE92$CkM$d4LjY?sB1tIx|~GxrX{rxTu;A7-Ha3P`q=&_(E)GY{_>nJs zHErF?_-NkPG99WkF%+t#D8bTvIR2Jir55bxleSV7(TxOggjMm1f;^&7s0pTB4YxB2 z+}7vBW1>Vd>kLwyCAbN>I!7U5dU!yW(@HVRmNOcgyCoZA$ioPSqY(b(QN*T352f2> z`fwg8zf}X1z5EmG(!j~;hm$TLmdk>z1`0wfF1*kbxAV-ZqZ~WUBZmx-%Kvo4uTp+? z-q#lp)GmLx-|@k((i#*+eIN7wKV@CYXXepk7L6!hYL`&yG25=Tl|!M`KV%~jGW_CJ z%r8lu+dVuB$GaqvW7&)toCbF#o~xpxY)9kHf8%958k=I&GA!IqDFop6eP1hH{9D9* zywZ4amVjjpQi+XiP*o%$kt!hMv6T4*;Quy;VjPJomi!ssypS$#q7H3C{8t6+Z`TLw z0^0#0GVJj-wQopJw2q<@EFmmouWiZ-YZ-~~e6ANrm41EkZ5(J5GlE*V50Q^o?2XZ7LF&5OF-PEN|z`4e9td8E0Afb&z z2_FAs7BUNgSQc`g4?9stis_$4#$?o8lBc|OhY;LgrBD7S$AwC%*tuq%J{>-|k(4E5 zK2$;^iaE?d2Nn-QwPNLQ0P}oULI5d7Sdp7Lo1p$KJ|~2-U*XfpQVj<-H|d?(`^OHT z64d{#5=K-kx1Sd|8W0a94Z;&vQrkTPePYo|3%pBzZkf)=#=GjVBmE#kMS6ekHb{dc zG8l~w7d4waASsZ}GynxK7q3I{9C-wpXm!oV1&WD?p-f^Qn!7jdoLT;XL`s{+dC;A@ z?GR>;ejHh_^#NOhA2{Cb5L5i{zQ)WfDU$V3%H%0tEnpC~441=yfZrl_C8;B8#al zLNNo2YXlP56)N?F%Dw&Kk)K*yylDUsj~Vm=I_|5|vbG2aiHa4NAJ)JqED|HN4__Dh zo2?E(;ve5zQ}5jjmc{Oovh&{<%M$HM6Qm(rEm97dg5LNqp$86}I;Thp)i>CPPn;k` zZ_>t`oMKO3iu|N`k?+{1+e;O>LP%ugHe-2C*s&lCtfYM+K~&e+od%5;w`UOX-QoH) zHhd2R+qhTaJY_y$PzOU%U)<{|6-YAaxLB8++dc>yTNoQpsScm>KOQTPOYPad`4|zP zT2bne!rEeS1V9~phNwZ0c)bLICn-?~;yHX+n0a$J>EY6~KUlLNq-{p8nZz;{AEFK( z!l`SqSU%>?e09l{PduCiA@F@7_B(2FSqS*F-$NLbh8wWXo&(z_!&QjI5hOj2eq^F& zld*E6z0zlI->+}|gpx&EENBVKF#3=?57ZycCMUO0^Vz(3X;|$2);oNCdHn(M*JUEG z5E~SVZSkIg`lE~eMtpyhyH3VEU`!;mP4ZDI`?Ls^i+IaEU{vOn|4JSDA;TrNcxqfY zl0a`^divyVp{AE#t-fDQ;DP`mul&k=aHV1yo12m8o+BVWF7#{3L(#ENce|R?DgK&E zhtwRuDsDb{e9J@mIRIxDo8k&saP*LAw!q)39#9VFKXLopI&Kk(;UiwY%N}W0Vkc9( z3#t+<%?XzB5bV+#EEzO`@lvUt)8C@a)q{HHm&f|Jj#Jo&GMIUfP+GWM1kp?AutH-( z(m5?5%g5o}mMF!JM%g3%7$Jg#r6bW-z&56htgNoMo7l;i!fm1{y8C+XvuNBs+afqs zSHpi55<~o(yhbvYb%<_7J+}r=-`0};dcO`m6b^PuxH={Dbdisx&nN)&dK zWA((S=2d(>K%um3@FVY>8901D>?pX*Oxbm&i;`XXmbtbaZFP z6UhcndTAmn>Y zUqqqPQ~kbBDI^&TMxlBlv!TXrRvB&v3<`Ky@X|-ytxVk#srICiHD!*d&m6$VMb*31 zRY%Rb$U4gGDy^PS4o6u^4?Yl})Lhk(9=j5v5u-N=ftce-6idrR)!hnGjK{glHrP1K!VmTKZiW10u%wJf!}iWx2V$Y<}?J zG*0z84u(_?+KXficb5uSzE@2D=^L`b>sfI|$Qs>}PLiub#x2$XvoX<<4$2tec8@=^gdr#QobC*oGXV8#F z3&&y`$pVvXzMe-Y9z;pQ?Q?J2=l021`7K4fW2^q*x5U9cLsbbc`lC_&LZeqCDmMc4 z1OmW~WYJI)o{FVsLDdQ1G_ixzl(`RTC$ckqG;nEmu{`k$4Rn7mF(@y;fk6`R>-^-y z+$eYROTK0xp5((dBYUl6+f)RpFA&1_QVklW5O7Uth1kvSAMfaNrP)GPPBy8nA8|}K zZ1+6$5djbS(f9q~&4WUK?8H`HBp%9ctWSPgn)VPK7?Os9BG(&= zuq}EBY)gQVvdmHZg|0BJlmMe2e|73M_+CPt_in2XVqS+GmZqiE(J~C^+|Z|TJ$ZP0 zd<>ldN7d+*aVBdVKgPk7x#=&b0Lm1A%&+tymGiVYw|Lrc(m5gN!a*6eDlAWpF)qgp zmr}M?IrJON;kH0>X_wpLZxH7xKD3tAU428C5qQ5$25}PKE_HdE!#Ou9g<5q@M_@>* zK$v%{rEj}hoKkJG9A=Gywl~#&Mcb25RctWlT$OYo6`@bAEO!k~6kebT?B=BpwC%v- zPq!Y{c5=yu%%5raTC8ccC`;qmij+lI>uGstz1QKqC07|`h0;d$qEI+pBvLm3r~71n z_sG4@*@bMMErI{@B_B-XOsKpJM|=B&Ii!werDX5UX){(N#1$}uNNYUuqQ5O_sgEq&$j*pgoy`V(uToB{i-1C;Q45aght?8}!z!fHRYM7hr9Ou9Jyw&K9}9|f zY#3k-3qSF_5cp&5N^iAGM~Yu|U9sm4a*u(|OeclN>vWlq`ib8kt~RE0tVUA);i3NX z3ZMEjq2dxcreQQrss-ULS1${N24IT+&r?_Pmcz%6+m6J&n#PT)P`Mb;fn~o7w!VF> zoowANSJ~*EozqG=su1ahw3;l!VB7iW8QkLf|L=n^5m>>{mUbt}ZZqA}S6czsz1jq# zk+IhEw&z#e)(J&?`duc~Pi>!^h31)ajDEVALbsMe!0rEgnIDiMv0^uq+#(+VuqeIq zIiQOA`9jYbIXO8(0Vz!JXBXwa1kqmm@ncg1g{i4l77Cws_Cm2MjnrKr+gs+vJj(L3 zi}z14$oUcp3W*jW-8RonkX9P*@xIowycwJaZcgWrC^CI*-373 z*jBkQnX~{952w<@ws0CAj_gq^v7omI=h!km9r%?bhb<)SpA=1Wz08QS5B5BVE-oc= zth|Am25*RFFjXI_c7W+=J0L008UOQTxQt?6_Xf)5e9h1T<6h5uph~C8(D)#f8Y%!w z@~seo-4JO>TP~R=OgVgFw8=oBt8!J-T8958vMff7ozL%-{Me|}UC}v>(ZL`4v9pF1c1I()(pJ6%$uG0Z-gSRP0ROSJY5nI%D0;1(2Dk zXMZL0!jW7mHAZ|a?)q>tIUr9~b3mrFAW78%PIRpplVM^P{iPr3o!3QH8=ibq2axDnVR4e13P2K-cVi-)eu)|9*>sMbmk&=W#M5w^y*5 zzSPD5k-Z2?**Yo zY8=^(gl%g=@$&54bsz5!)+f!#u${}l+>Q*1N8h4JoqDM#l9an(X0qFROhzhcMKnE~ zSla!VrK@BiJf7^vpij~uZW|)4wT&Hxe*R29uWNG^L)Fdwv+nrO*yo) zyO#f7PjBvu<;t`*Jqs0@Cg|7UsFDg`j%_QFcq|(!pmm*Sm}OM6*~H<_gS~P7U-u3% z3sqaojtzZDXFxU0rJNJ*`=8_MKYDF`v?_VnPf@C-Fmm!*;s68tOHmtETp~AM!D$uJ zE}8dMiSflCwBkcSCX;#=rX7R+D9GdVy8VYDw0^ zG>;{f)W-gEM0!oLt{Tg#_};ke3V9RUD^9BqUvDNZ_1P*Y1hljLpK`nq-}=Bk7HJ;3 zlmj(^7PSQrNroA6s<_`~{uOlnr+wugEJ4bipe%Yl-%q3dUTG>`Fbl0m?XK(=|EI#? zvmZB^n&@D6eV$~ehA92z1rHNyxl-pp9y}D=;;ZyuX2b7khnW!84eu`R8dA6oLBO7Ysc1dj_#0)v?pis*pJhIHio!Y*(;^13-e|^%hDt* z_^!gL;`s>eOt&&2Ym@2?IsC&gj!Ush@^8~6e5R@95w#{3#ykuqRA``Mg~@S7*CTEB zj5w{BRVQRurS+3Bq+!*`zF?8)gZWkz33uUqv2|0#?k463Z?v|pE)2>w<30&94&xbG zo0$w^UGpu_v4l>^Jh1liiz=;-<_m!1?Auh^nuvdIL2gAXZ9)tEPy~q18kvk71G%KXK9gfr(0=!5`tB6=e4<5cj|UpDySOx zr6o!{7amBNSDJQ8W~y;?3@rc{xM;74oEJ$4h4@QgD`%cz+#{|p{%DcC@`N&Z za&pqpZ>bi{bNF>Y)MrOmDp$7ckEFSCx>D~8;!!#1Q>wU>YJ?Ko{N#0fSVNA~Uo|DBR=xcS?oSJ-on~2*U9j@;rBUY`fU2vK z@a9|W)}&`8rDm%Xybq9Da)x|0p-BkN!kt$|NR6-v9EZ2UJ;qSN;>)ol4B#nO{E?*U z3z=-o-Jq3{f+cng^~E#7cvb&>i-$gp-4T60RAk`Qr&KuncDn8}09&C-jVT!6xX)q5tV^B%@XGO=QJKydSO*$eN3D}_vQA&m^UAjU2}#n=a}5Hak&wzKuz?_*1BuUY$kKF++Iu4)E$0+9NTm5AC4F zmQT-~;Z0p(*{dgDL-ihf3@EyF%3S69k1!K@HoMe3&Gy6zs}FHEmqouawJ)r?1UH`} z9rQJcm+>vgURE9-_Ta1Wm>NW{UA;J0N2M;afo$6oFTl|cLD@Rhb*G>*7J;r>YjJvb zau2>fe{tgoth8&D^x12K zb8St0=GDUCwfUap`|r>2U;9?t##9~FqS)|Mn+`y`*iWfoMmy43z|etT8u-}jyUZ}! zxT`lXRSJ7ip{-@pGdphztoabY?f!t|J`lo28Mv~_J9gi|3*6tNKFYE4BfD$x7?#lw ztp6-YmAa;{kT0D`^9hZe(rf+e&RKnM$Sz&FpH$lhh3$tI&~utT77OUbO$q^HJJ!5F zXzKZ`adgy>kMZO`*G!QE@ele&Iiea0Y91PH@rg}3`(K{{G)E&4GC6-;0@K9`52qe5 zUaOPNdIJAuGke704tp_o?O#*E!0GR7X6#KBinABejYh88xf*%uNEN5w@ zxI}tD<0!r6*ysv#9BJrCzj#L1Z%OYz$04VQjsdsgD5-l$Xo`9>xa>0SsTUFpvjRDE z02*o!+^q15o?HQmIbjZ*b1yp#tF?OVpKw^U2D={vOj~#XKrEN)CU!x$Iy4-ruH`=j z2C*6mnI$>#s~i)R17n^J8a68BtzD1=SBq>j86(_Pk6?+=Otg0h5DkPN{uGGx9rS?r z;$3c3h1InVLtd?k87LpUMuH;z0LP?Jg6rZK$Iehx>?cDfs(0&m^Mi0r(UL1JbIT--}d#1Kl$G0;@_{JXNT38tp3x~#9k?7K@+pBZ1a-W_`?EQQh%V= zW&xyUT^wRoU90gxfBFH!a}Z5XRek3(&lGZM9A%1{m(s<>F z4FXW5?wM%cq@>y(tJmt?U}>^h*X-@e)j!q*qc62fgzUX0oT7_o=cX`fAw;}nCNrr& z)*zNDN7KBn5bzbDCJLx&x>O=LK;oSmZ^C9eKqD#qp6UUIUomWyTRT_lyu|NC$MFSA z_X;-TLp6^v#nX^#vN$TUGZfS#`WTj3e4~y88ALTF* z`&$o`gK65MTx+QdAjL9O0?6w+p}gYMfFWRypl5bwkGT~ZSb?H}w!6Jw8WgM-hC%O{gm@oaU7173ip8%7cuqo4t z4S9w$94U{}A9#j5vWz`bO-ua+0VU$XBPkak!$15=Ys?praT&krYc4Te z&R=$9UwKAOgRpXIrLqATHP<1};sE&wV*p~&M!1xc>$s$<=cqZS_ltwjSYMo^>iM_Y zXFv50mf7NBT~*DEeDsFF`^Os$)jdHg`p%=VkzS&h=e9blu>|D*Go8Pj4qpW1KW)N_ z6)puK@v^Cq4jK0nukYaby;==h9Dn~fdBNeE((>*{$Ck0$a9aTP0C{q!df6(Kv{9=^Xo4h? z?8lX?mWd~6Vy<9tOT1rFLBE%r+39~^MMX!|JBgRpmGUxvL%&+ReP1*Gd_`3sC9j7U zDhoj5xi1HEGQ(B}ML#8NP<0qb=GX}dq+%ZMWWs;+wImPqX+v;BW%UmIKJ2gPu*|52 zuCB6&AMWPlcRSYY6p8;>t?eLJ zPy)SoU9QMhPME7EmJFZYa@!rP*_msY5@0>VR-P!>L+wJk2++exC z8%~frUOhg~djJe^0NLdF+rZcaU0(&p5sXIQn=SXgbFq5B2TL-+`9|WG(0c( zqg<4DQ;Zocpx5m*^t;3Fgx-dP5_&NVo^(V1X9eC_W5!yrUIjW;+Neq~Au(?~=xnMw z-|n3Ou8zlwzbvhJJ;lUMJ2HsEf;G*w88B>u+>iTUeXJ1Vz+O7q^Vlq>DEa$$pPD4q z$G69`RU!E6|4wEudfsgad!>KX4u5Jo1Fu2k$BKe$8_6w>&$Oh7BPlzGT+q>F!gN_U z*LKORpsTAIM2HL}Z`<`^r_j~T8x3^Kol&|5=U%;DiVoV8RczXA^wPAH-$3nQo?QNj zA-O}dU2h^$&|URh*u&#Tw+0#A8yGw0>za!Gm3jOY$Egkp_o>n~5# z1+pY3%D7(t4!8sriF%qMAM2oGZs6sO_Gi3=KK4dz-tov&QOJLfJL3xt92ugPm9HNy zVXYxxG5S@yRfs><=Mp~bn>u&wx*EYB!sD>xZ7fcX{|3s5ppPj7f(`YR<&(3OkiX z%gWCmxXc~DtJk?#$Hb(pC|BUOTl%w(2^w23G`6Lvo-rmhnT{u98BZJ{Z{-sVGB7m! zau{=_O)BBE!;|kHQdZs`rDtj`wlMQayRVsnf_Cr@Y4#@rCF3|M{bYl4d84czd#077 zx{^_h4K@0dV6a2;z$2DzeA@!+uc-&ReiK-spUuojd*}oELzmw{nXaiDQD<%Gq9+N^ z!K+VXh(mX=U4no687jRHXT3{=t8Q>)dtuqxP`W z>|kiodxF^ot$V^>pm6fh;XRA$1k_IA8cC$~4IE)$5poQDF7YjDG`@+vbmtkJ+`1zj zg&`YXUhb)I=I0aSn|-fL-!Ps~W`u{oHQ-RfEKM&=Zoc0tDDhcofqw0f_Sy@>f1IW< zS|BRK*-$bbORYZHQrH@CD(!_%!zj!0W0?@wXSsZ5*Jx|Uiq5~q^03}3IyQDvgtQl4 z{M(^qp1&6taT032!lbgYvwMM(R8v%sEb(|@2EgaDkmZA1+Neg*#Ni}7w#1n7RHn~V6)~TB|1fUxEkV)6cXcYcF}knd+QNmA#t+K zU+(n*!VbqN`X;K|+0d0@2O6B7=khT&m{fd*LqibQB4l?GKi#`4zsk~4=k<_CvDa1Eys8b(Vo|581sZ#)zJ83;+W(uzBKscJGary4x3hk61P!#0a5X>RK_Hp~qT*{gWT&isyrgXG444o#e)8LqZkr!<# zKa1Z3CnU8E?Kor17W=7_H>_${US+GuehNn;gc>W5PK-nHgj+=)`B?5!)u5_FLKwp&^pN;cOg<67hue^La z-jV*W#%FS%>I;YD_18+vGm$80z~Xd=YTgOO#qUGi)JX!$?BXXloxg5;)Lm%ePrEZD z?K)E}(NZV|0@VZ9n0sa@%UtqW-2+h@i!7`7LieF_DjG~w^}$2VNyo!aL0`*u;;}GP znM-=b7q>o7KF`J3aiq!oT#Vo_U~~M4`C=V;xzhc;@DKpxxjV7&} zyZioM$H>LiFHaR07xy*G>X~N_%_j{I>`d@Yh0iK)D`W zpA1NFu?dN+I}Jlq#$Vp5!7LMR35Zwz_=DjIJ(B4Oi4s2_^!YHFKtN9D=CLbuGp_C} zHkY#m`V{GX^5J{-DO>0`?k6>EKva?DU7t;qGXox}ykWRRIpbC>O;69Vn(vjK)9?Wg z)H1-Gjfh5mubLVCnN{sJ$}I^}P2eW-j!7pSrWE@9a~HDWJbOt^>HqnJ@8T>~6}?j= znVAjc^Rl!biVw+~#tkpbZDwTj%^TWRY3pct zr30LgGXQ)^)HwPy+!2?)Qm08@JkMb_i4PxC;~ttA zWXB%0*W~DnsyZmVPw(lUUs(6=-=BE&*s;)}GybFZ_B^(F%|e~TWn)|Q80NX=BE9J9 zdXl)~yyCoN@vd6>Asb#F?5!;&>W%_@_gPPtZ6^xZCZc0_8w)I}Oj{jKw#16NCj)Tq z95gdKn-$+24w%9zF6JJ0*!MG2Z$ykCqR?*89{rhC$tR{ z2-(PD9t-`2x%N@R%~{zN)j8&Ty*CZ&+^Qaq-}*dY|6=*`?$5j~yr9cn^}gR-inC1` z-SWe^;`ZnuGnaJR^7kT~wP)nd!h;==ouJ{nys%e*H9^M?s&n^cP=|6Wui&GOuIhNf z23UY&--)#P;jv`ZE~R8cvHcF=j;xErJ^su0m%F$ZwI}pdwl;04=V^=|FsuPbBVxxEZui8n1mz;rZq#diATy(mFgSD9E=f&?Dxi z*}bl9vL?%}aW`CLrlIoIS^W{`a0rLwdtW$bg}wgJIk01$EiP%??{Hw9PuWg93rZLt zimL_I2~&+d^&MCHx#ly@g#d;{iO8%nGTeRQ$JcjNb2t=~lizjkLNEg+0J4S1fBBD} zH2bwTCF3+N)Z-y(Y|JS^&MPtKSB<$b|5&C5Ftb?pu4S#n2XmQNEnSR2uW@8G6pPaFjXJUQMN1c5;hRF5OxrD6Icjr zgo6a$zPsb$eV@<0tjUo2&LDjCXtX-FmG5%O=MA1L;x$W!6~IFt$z3H5W^-TM3DH9T zk}rEdmwdTQ+@B-e>va3&nQC=RI_3j+gN!mhnt$ym)sDCHq7ttz8&qWJR*U!Q^%@x& zd1=QFZL0^Z?`p*h-_KgN#7hqLg)ZM&=9|;qJovivPwB57 zO;#G&qP0H zRq%vuth@G-Svti)E=wQ7*Q?b$*z^Osyeh=2=by=8={|GN5a?{2Z!Y4x^Vu6rExi`= zmi`uFKNv}sc0@~uNGDO);dDsI9J11E=Wk+`_o<9^N2#BxPf(8 zFn6#1+DpsAkaIiG2~MoEPXdL{S=Y4HE(2p@CmR#IQ}nQ#zxErYnKso4XjZJ!xz-dR zG!eA_n6>5ElT3?y7g-kfFS0F~Of0hc@;0zFa5R{etW(+AF5<6@fteQrFQz@l6u7gq zvzKt^eoxx$B%H3E3UEh8@ zjRj_?nfPl1>9>*l=E&G2jA0f*`j>1dT|No14(w`_u#8P*)UR9O^md|kLBiP zW%cL+Ii7{gu`bWcg?!S+M{%xluFzRTK5= z^fvza`s@5x>F2bK3cXE)c1LS7{`*nP^?MqT;%|B(*f(hj4jXHizXtG5h!#Po=WFon zs*X4PObU$+B@W%A%czhcc|m)P+b@rkjlzWt;oiSn5l@1J1_lPVZ%Tig3>->o+s1PE zbwTw)_F|81a@oPtx57*|h+O+!-r3yQ$2np6rS_nAb6zOi6XOz6=wj zE`4X&Oi5REa2PKcdu^GYa4e*_eQfL|bZ3K~U7ll<7tymm@Pzb$^n^71#+E_{!9C++ zF0UkeX1DUSr?Rj2{2c_yVvE(tLY96;^S)3jxw`_8ew3ExTAgZ^XD3L>Sh1FqFxB|K ze4UQBJ9rp}DSz}7`k#wOu9Dl2=fS%S4GsHR%Jtr^QfJ?v`K%z#v#rWCxrV~t1?+Z5 zd3@b82X+MI?KYJ*<~E)-u{K~4iPzi5ca3Y6sHte&ZZtfE{T65IrCrqU#id1b!`*U4 zCrB2$OzmO+gAPJ-u6rG##w?+WZ2~}cM(EIOB8qxFIIvOBHIz$&LjpMLlJV`smlN0u@V+@e)6l3;NBbB zH;iwf3O`Uzdkc0oe{M2>SaV}7KTJ^My$XayN`iSX$ss^ zyTUzbPwhO!)v?0?gP%9$W@R};N0~^NTTfdxZ!>SDhc!waVn1oEVTP99 ze6(g?Lt|-qd2gbGm4C&x`t5P+_UN5>>iaD5Syl7t+(0+QJ>!;1J77C^f3cm2KQDOn zm7Ez_wg?%z9g9wzIT4)jBRp4R|7xJq2X(h1da4iq7I2N$$ zAl?!my?#~5fAsHV)EL7x44izhSD+sx`zMPEx4iGu!f7{@7uDp>d&fAKvyf^hhh-od zXZeeWijcaRT77kiL&2xT^5ZQFdAS1V4{x#*1SXI+n&@v|@9`ggEk*hHtrq3Cv%a?o zr&-t1?o6vB9osc1U(QB~mhaxmR|ex95!KBmt6%g}yfX}zn4OQ-okBA$F#6DNukddCRi2mzdcumc~XYNUuvADCS5Su(3<}Vwfnq$#I)U4 z4}gq#J%+3FuHD3T|J$i9Kq?Gq?YW(J%HHTk6|!E*77&j6Ji&j)I`+9$jSyrl@Oz(G znHU+ji!Ws52FkA9@5|@M8y-gI)Kyb`K&*d3lkrUn;d>(ZrLn*BG`Z%SO(@)*1}Vck zOc&0bHE?HZagEp$!QD1`M~6e(Ye+=)$rFgh4v8!$OY`==vK!iTr{@K#29tt&8b^Dx zVfX#nNxlHC!D;}!OX;<4eJt_L;Y)dOO$ajdI)&4e9jwvrFW2K8Du-@E=dRzkGxblN zJkjxPt~1Ir^{lNnS8{j)?qG~}r>=S#(offyr7!Fbjp`|!5VPHe1hoU@LAP`-4sbVk zLNJTJR^$CHnMVY-=9U)saJ24f5f@mQug$jY12Sqrb&+j$^pmhb{0HG= zpOY_^pc|SkJ1{8q{390xfS_&W+TJs->O%EPHqgM?nM^5(%DSQNvMhDv{Ek`%@7KdS zWN<`qTQ)4t17k6FK|15|5rm)9oViE_JtUro^&#Qt`;T?TZAxw^2{%4DvUWH3B4LnD zdc62-hHz4dS(R7u2gsFN-bmWtD(=~ON}89HE^oYzFYcb!7FG3)=~2&ZUOYVL5>8W~V*6 zd8w+adeQRxMMU{oyt)zoVb3-`lg+EwY_PJ9CW13j(YXHfQ*GPcvm)tsA{%H(Gv`d} z$n7X{MqK=numJX6Q@n5?>v|fr-j-E-FML?)TQ4uD^mbz2xfy*ZH2eUO79RxW{mmO+ zfUtHq`bzRjlMA37zs)CdnuK%LmY+H|*{}HRu~k2y9o)ZpBt7ad5|b4y{Cp7Alsos5 zL6p{FLpEUW|M+_Ec&h*Rf4oqXO=TXtRD_J|O*CXSlvNR#kv%(+k>W^^$f%4EQT8rn zm65%UopH>=F%FL3_0;Rt`}=u+KfkYkyS-lL`FuPdkH>Xg_v?PYU-2bsPU@N4P*S}4 zgYuobp5f;no^Lj*wFW+zZeaCi7stV*=0eddo#25tv6oSHikcMR74U1FwwMY{e*Ww8 zbF{CVs_4%T4P;(2o{Ph+;>RxV?waas&)w#6y0RaSU@mG>lJbcloHo zSHgsed4Lq=7p#$*^A!tQy|f-cjir#a-WNWCn~-TfSLm>YjRZ;zlmMGo^1hX>x{8p;?QhjO0uX}^-MM-Giw2bY~ zfq1LD1rxWM_+UT&AW2afdS|7^`=3Y32UQc>q3xrR9+<-a(BORgGqmr>Npi%Nr4vy1 z3l@Edpug4SmjTsy(SXZ^fKAr=cq^VH?#Ul<%sqd$rD%*L59~;EBPqs8aZ0AylCZGA zLBtxk1>zMa1hRE|uWtKjZN$A>{Mbv!7hbW{lhYm?eAOA@X z3_6thny~9ye2aB&AufT}rmmHUHr3r@_moD3!)X{qE`(K$8-ahe@a(8Ai~wN7K6i9l=*-s zZjjPdmL`jrYs)RlL)+g({YL_RgEhtIqdQbN6XIc<5_e$USEBdKi2x$db8u$h)Jh^U z`geDBK8n%RWUC*7!VFsq!*Zr|?Vvp}ysUHPC?*L~&LZ>E6dt|-H~SIS`%)+d;l8Ql zxc+?{TwiAwa>1_TnB;JszrEr%D*QQ7% z_wBrEHvW7ebf_88baNJ0=h;yyUFGf1%6>4C#H?Qd=B#XO4}P-NErL)npP~O&4R`Ka zL$qKS#J~z4@UEbwL{LFN4j@A20`y0+A8Z#&z&>XYL1f9|AUwc@UouOoO`QVtF%m-+>Cds zjPl|EsX>ib*s@{bCz(iRrKbA{49_@S8qZ%vjGa)2=+$EWfbw@FmQ*5fVf3 z*(b{0PpcCCGPhn1O)u|u26pf=a7?iZ*z6w)R^kx3_OZHR^sx|`uD&2s{|*S`gSvR< zI^IWD(R{gnu?+H;LBzW5^Q9nrmklGyefXCmYyF7B@AWIv(JEYf`4c6zhDD3CiU9gZ z`8Y6+bYVo7p^{gU9I_m$^xL)?ty2>5H*8#Z_9Mp>3h79_0C0F-vU4mR+3x{n5N7qq zV?&S~Z-ZJtC8TvqEX;ig#^&_is4@w0%-fGAr=+9F-h|0b^qtyJIC5Rv-@VV69B>Zv zs{NBP5A71DZ#WcOw(zEXg;n2^W@)$#lOT;&fssw!iw?+nDvdta0JI3nhHt zl!&$WE>&4~E38nw@89&b4r#^{lMeaEI7krIz&6f(_T9Og$QAD_jJ|WUQ0h@OkJyT)0Xfa|wxbp9uF@ zhE9_zm=rhqUxtx+DLgGFblsr*9apI6Sc(Svy7Iz2fPHAIVUe=gQN+_fUrVLHp~%#R%kfKF()@QF>HK4HY4IV)bY30GsG(KL zKPF;!Ah>PMxVJMoZRIC_@{1<3Nmbi(PAP8FqeSl9I@$Z+KC`~_bXlP?m*CFMBAq6= zS}X53+!lLo;@Dm|&28HI@JJBt zYhU)W>ord^__ZQvKJf2bsz?Mh+?UXzGjRr!_SIdll!i_G-G{y;?wQT&b7L$J?xrn_ zyY`K4`Kfhj{Amb1W5^ug{IL47=$5%xfC<<~2*&L&svV?BNS866kbSbuK3SwNd4TuM z-%za~c#--PPlFauqzdbfMs;9%ay0Ga2g-L;LqHZ9*_J2srFr^Vc+Z#idRE8lJN61E z9`nW!CO*=sIgLp~K{6S{Y(0^`i&tZLdJxA2Bklahgf6LS9xNj&2_sU$jZe&(uDZ|zM z_-kLgs^YW5U^tpJWP-*WFcU-<2Dh~1 z#D0|7N2W1S{5mkc6jWi>pLbiU=*^oi90XpoK*6rlmKFYv!@idal~+`hDszi^?{F;i zObxLm1;#%Z*FG8+anl5nmtUOhVJc?ZX9pV#=j>iI(fHlrU9#0)$sJj%8~qkOm|I1X z8>?IbEY+te0L-7TQrx-DHOIB_63n5D_PHX^>J=;sdq>~DSATQKG0!O=Gdp`LE}LHf z)f%i(c3t>yda$QJm#&ERrUEI%>uWGA-U)PLDm5FAm#-u?(N3<7;0FYQf>i&_W%6ao zHj1BCETb9)V@ANJH%hWLQi$9^p&?PYTFd%M{22$bq`)Ex!8tG6I+ko-*d@)A$vT3Q{Bfoo?uX@{n>_FMFh_qE6IOicUoN~p%&2;Gds z4Q{eSKwBBRweDst^eq&IC2CB?%@&WH5b)d71xFb@9ayCiIoa#vXSuZ9KT$+HC4Jr! zg{&0*p&@6(N<70&rOMds@bGRri|5Zg{U)1Vt4o!F^XF1hejPI*jl&8entHe#rpUpE za$@ND5G%347x0jZ2ZyS3V@1v9VHRxDd|~#($}(u7{o0fd9Ey$@3#yD>yDXFFqm z&8Ot)J7@bs@?T##*h<6uLhQaNZ5P33F=anHcrCpki3)B7jZK~=P zx7UtDB2HN$2s0bFd}K0LA>BD~%r~}skD4~a-#BZT8>W%9i96Tjrwdyn%kJ*MN|Zs=BA8<4nbbC^Xv7nc;GXVRs@R=)s)2UF7D#@ptraE(qI zC@irjMT)U3q{QIPNnx~#(;}H3cyujB#r0d7U}61t5s3O@&wzT0za(m|qcUmo4w|wL#af6v5V=<`U?8 zW?e70U<=HeIe$BRU`MitpG^o8t-g#7GVWBzma+YQHb+e77I_`?@w2Lprcvn!5 z%!Mc|HpkCIi`i2OMD$g}%K$pq6WMhBsN~TSt%CF-!s_LdZx8qH(i1#^_&1lnT4#N0 z$J4`zS?w`LLLGkK`$ojFnHe<|(6nCD1xHZ9J$wPmi*Mi~b?P&++HGil+{H!}rB1cEBC4+(Q={ z(RVeraXa0AhY;fyWck?E(Cv+%DO4GMHtK=Zrkuv3w}w1*yO`A8s6G^&aKR7GL>yDszLI||N?h{7p}upcg*|=Qf;^`c3c`4db}lNM6SA}9iQGPJ z_saGpoK*Xckhj5bGf{WEW3T6iNhkiaSlUyQf_Ne>cP;iSbAFnjdpIwqPH!qr@ck!V zEJsd27nI(IGSSc!6l6cmXO31lTZ&oM8Qst6Hz-4C`4i|XQ!Tpb71DP^$Twg%jIwoP3(84$d_xW z6kzUTa2c?sdfl#IhJ8j&$JVhfHzc_)2Z$ENZoYYbQ=W&3z+r2BR4@7ASN(lg8wDa%qErR`&eY zEWjxWnkPasFKN<*CD>?t!VxpYAxnrs%nmcYk3)7nE7}g1N9&d)7G4V7vQ?){V$6hh zQP3BiwEk)Yg}hB`vI@$K_kqXx@000F_57h->T{M0vazG@UHrDGlB{%2Q{XGS2?skZ z)m_t+7OTn8Etwe^RGl?ybmL2Mr85- z{T9b4PbCL#Z4@(VHR~QD4V^dNsYa8lOF;-oS(@;TrdlNsj@kA@X?{DL4-@(AR$T^e zsV=xuvdqp{7c^Oib)`sue0?9z(n0_$p(oYQsUzl$Yes2=`FQJhiL1Qj!WsuTYK6#(MM zRR5CxmS$YEWc-<)4j-Hzw+8kT*t;239Hr3XOL=A4_~5`ocnmy#Ks|3r&~J5`!5#?a zqC8GNfKhkmvoFMw#9MP<)R%lj-MtQ3)Rsg=dA-1tMaGwDZ+wZHq|F8T4^^yW8)^H8 zsf?EV?<;(JGR#_c*(sznOsxsdwCAnsU6!^`aT~QvK+z}m(UGkl_;~H;4I4WbRNSj3 z6@M5{fuHo4{&iGRIgWK&-CViveRdo9205J!kK_={VtPxC)9EM#IIHf6E6-4CouYOL zwsmr%;(BVy5Ow0IkEkB5@;jQ2>3Bg1LdQEj9)Ci8L2cpfb-vs3r(j zF>f>qYR!HeND7-*EBJb#V-R_cXfv{oE^iVN7mT7WEHg z%CH))z5`mM#Y<Cue#+& zgg&oT_ceiQmA)nNFkiFvjP$yA@MO&9$;OYUprW!v{pc|0LJr!WHmY!OL>LOj7qku8 zH8h}i+Sgz**qX?yoKg6~q( zJg%iP*MF60mf_dq=62%ueI(2Iu*8Yan4(OIn2S5zVU_4NnqW8*T z;TqsP^gnd}tl9)0CYBffU@!TfM)ZaYjEo*%hOc_F38PG0`D!~{c^n{M?B{*5qov!3wv(|pvcC6vwfK`gr-5IK^ zA=PJ?oz;U(0*;}#_OX}@iyGRX6~5f|Gxh|Hfe-J=vm6+L%e5Vi6sr^a@JLB-5eLUk zd}|(vd^T{vvQ)TkjfbyqAvnNq!DZl9&}MVzredTJgjmzQW*`2=ix*lwKsKD}#``l1 zo0b~62Wq~uYKkd=y6U-~@4b@z_yG_7hjYUL&t2rTgT`dGX*O>sLsA#ddKM?6*`-1I z=dx!7;;KW3dsXTJ<$&TNYUn9{uJ&>&_Q9Vr5gacF#28Tgn^-g*-;dX$Ph))ExY58V z=V~)7p`&_}cR!v%iYV?gUy{ypcBcJe%CS{DAYZr?>cH(PxPjcRG-FMN40s|}p9l_* zH5J(R=C|E8w1wpBt}*|My`QHQ0wKGGiw*TMY5q8S1EdSN3*j*RLkcbyWVVgP_Ei&S z&42enh6>g>f!U$o>;&;sxt*U8mN8L;m3H}kdg3!b-$lxTs!K06#SX%OIq}UM6AEo3 zzYg~R!PT!n5L$eG495OVUtDUDd{cf7fJcA$EJuUwX%=DF0;bzhO*`ztvbh=az1Ns- zI<@nR|M~vx^|%@XC?(3*M4Mh|@V)F*X4d`D^h%9(JnuCO%|0j`@=#uVp-*P(s7g1EBbnKGHKl&STSORnC)Gg{`m?B|Z zH?(=9{EXLsq6jGs9B(Ttu^cbX&2vn6*EwH`-OPV^Q(pVxiGo0l;qArDr#}F+dfP`L zw>-t$d$yn;OSAuzl}^Vl!Qs{cbXjuks*lG-Mz!-C?XRO#-Ma;NkNvHmpV;yQK!!~b z17wSXodS61HLb+zzbEixP8r`+J z*c0zmxKv9j2R`3zSCcYeQxZIQDqIRv1x}G-;A>-o$Tv9cmjyi>6^=^R)TtZ?Z^)s+}@F+QX2kaf?u2@r+u;Z1}UUdyEFfIHKeN?aX# z&Byv3c;S7+au%L-3^^?Q^>zn%Qz_(7G$=;M3}W=*OPj{g)F?q!Up=|K6d6F%Sq&-3 zh!enr)%g%Oe}-^*AJ>bWX~o|Io*7oYW@4qdM{9`y)3FNYzdWLbq77VR>3n0qlOY7& zzFb9^q@uR0bBDb?3C<6C0%X)2nNepIF}XQ8blIDUKJy1UwS88m7_S{0Li+-PKKVBS z5OluOpu(nJU@6Ma7nh`ebKlr}0rUuLnWy8<^F$UF0g_G)$1J`>Ww4 z*`r3}Y#>hw@3})iemk$H1}K0Z)=WpFo~+NE|1!M5LW+4@S-BwGG;?yz;dG5VhD+ap zvO%wZRjA-8N9`G1{j%H45N$;C=03c&2}o-AKbFrfwQ|naNr6{Gux4{yXrdqpV?g%z z#>m)@Uj!}_nQ>WzAonvaTQQV-WL-BM;uAHNy zyj;PEA0_9S!LrJ0BTc(NPf5eduuivbDrn~l?WS54zuV|7DDy|Uk)b>(8^il*a zBrc>pjltmL-vkGQKIOPgC=Y)0z*w-{6ijLf*+%at>oOQP7hNSxrV^Bc-&Cb&060o_ z_!C2DQ)w}j9q}=d@xmRo{;gkYyFT3TL34kxGv0)@R4L*n&vQ)?sH^I3465l$Pn064 zgS%qg0L}5Xney$q#xn%0`>G=~GeWuLOxFYpZ^8&jw3RsRxZtG()@yXRGSv%4#*{F0 z!+4<_)Bn%%&(!T%o$K#@4MeF7y4=X>pByepJ2*4x2GyTfPkDvKg^&g5vW?_ZIA>&)nH zIm`m2zR6b-qoL175q}Cv!1{j_&Rx|Ec(Jw_DA^2>2TOBqU+daX#v6@(ru83Dl20=} z2U;R*1*3jRP5ZI^1dioy2n;4~`>-M2H;m>Md5oEl?vj64ojcArX8P(5IlBJHzEO0^ zEcVYgDOL)_3FL6cH`-D2rtbNBLx^Kqg7GJ&e;*v@eOQbb%YUR(kc|-h2$-CjsBq^H z8#ls*Kk(r~5zr46-uqPVr3@z}Y5W=8f2wL+#?{d>>Wcw0(T%3N-wg?F*5+`{tXZ z#AV_Z|p?=vGcph+v!o5 zUY6B!XALT|7u~njsFtb;s%8@RP*L4S)Xwky8?{dh_)s(UNnWOqBwAZaV04chJBo)) z0go*Zu1Y@_bR8K`WP>u;KF|ZXI@K^?;S3a`dOEiwIAz5pC1up)jRn7ntxy$Akj{<6 zEikLNSD^cCczRHo8}7*UE8b9j6$62Vn$sufrHfxF46~r3QFdfEHR?~Odf?n{qZe9x^d{p%TQDi*hbDWFjG$Cx9O~xXSO|kl7j)Ji zQ%*yNbK31=liSoSssIHC(b!H+nH*6G70)T+6PZ(Ve1s`Rv76C4d`W)eBWUR7h=Pwilh(6maXSgX}&-HD9 z?paFVh^zb-cD?ruw>baLAS>etn@Dm?oqw*TApM=Ug|GX*=fVIrj6X>JXiNla3-CfF zy5my8n2f*0!~{gSZ9(r(ylQDkdufr43cdLJ#P6}eUk!;@UW}rCQaR@dV-JW8h7h9opf3TP>}gm67A_9K9O9C{aEj3?X&M zs9nFPF826L*!At6+mhrZA}7=gIL#G1zBBiFW>x`n!j9Y}&a=O6^4%vC1I}j{O<8`M zU+ZRdbhYPsS!|c{B@6Af^}GZnKW`g9hJH5XORRmS%}$StH;$1|_m~eP+Qdrr-fMh* z0_#5r6czGKikrfP^s3@Btw-*aFZ$iPul{E3)!29Rx>AiH$))m~>+f3}d0+`*Gkb?I zlmRtKfMJs(6{{*c^PcP|=_^|}^BsJ@_3hC#rYCrYD%HI^vjZic`k}07)w#eh$#FKN z+5@3mlmixZv8$`gn_pr|TBQ1nL!YN~5e=(Y_0Z%~FKBkJZ_2&kh#m$Ipn~HlyIns+ zch5R8k0#~?h@D@hc+ro8C<5di3k1>$lOZ^!LS=c{2eZwqus$!srWQ8!=O#s5hFF;F zDSK0|K|O_NCLF$c+={O>s3NSz6a^alV zmuy|l>fV)YoO1UYPYx~B^u)@=AJ#s#_j1Fq4j}tuJd=wq-{tFWzrl(=ir=Xu&It8B z()=~t?^NYxXKPEg?bj%c;I9q0^{9&NDP>c7`c%cwK4HyECC)pAJ8U#KCyZI0;@zl) z8dI+xnhA85+2P*FpoXnweFGD;)WGpkH_+zQNoLWRZtK&KMp~k!>9iCFV2ss@kljC$}qj5 zC5j2}rHa_AMnjG7uL9EGWKfGx>W23g_7KQPur&l(3$;`9cJT^rh7eMWM)Z z_p9A8$_GnOFM;*C6-V?R3R@_2b#L-LI4qFYFJ7iZs0>& z*~wM(-*4r;9nWhJw5QxiX8@Q8lG5!Ck4+QbZraSB38(B1oS+bHI>|CeIBCrMhu6${ zy5o#us?%7wXyx(TJlO0e`3?uP?w@ANgxD5eB@9mZfXcy#xu)>~cI$ zq>j=}c^j^SA5hxBdR)^Rx|_Eiv3M5tc}jAQwRG4jk^b+`@q!wB-ZtLfc48D)i*8f#iKcN{Z>TZD-@<`1r$&jnQ9zgY<+D*}W_0jaCT6JuVJjy{oGI zx83`9lN^C>rg(k9?v;{X>1+g_mj!q^=C?Q{C|oHCnoAb5nRnlV&{Feg7oK=Q= zBV5T(#HgJu8003nE4WUzez4Lx^auUW(Caryce-JebPNl+Z?zilG%lDm=|T_)0Uif1 zuF~E3DQ3p%>;Q>)@#$P*jhm*4I_^3H)6IVXl7Ac+E;J+nnA&aMZd(zeN%`yRw!n<`zQQ;$~}mPrP35MCG)|w9ODI&OjBrIV4{uN8zg6& zmUYd+7w$uE&2(lV-UvQ9*Yebwk9qCyK5SyXf}_n*t`TD5ZQJ|b5$7C2G$i-tZhyii zVR`jX13$t*O>WV>+i*LEx`*yy_-`A^h_Qs5;h=|krBni=B%Z?aUDI>$d~Vau()jAQ z#V)u*l}tCOA=Kfq-kW!;6_;F=dU z8{EjIytNp(!=RUT2fx?~lC^TH<&qEY^TCJ~!k+TSx{;CXB4#Qef z#$M$hTs{*As@Z-ZTq47tX-{#p`2D`t4MnC9ON-EkE#)5(k;Iiv&cUjz-25<;V9YJ> zII+{{C&m8f4Ll=*D@|cGW5BqZq__qzW@jcVcL134WkBM_*OtvH6Q}r%V~!;G;=_s( z0S_pH(UxvNZ@}e1wH;$c(X|YNpG&~YXKfzq15=g;Ks#&}b95rVNrZZX#1|!^q)OhcssAs^rs)o zWswFq9&>&Dk=$MR9t2gg#&~ zc;Z~`E*()MYOb%~K8%06P;zh$(1T?=n1)0l+fU^$#tHWxiQZ%y=Fbh&v5N7eZa>^p zr4xS!ddT*9k2XO$>fO%xMX*n)V-3KaVnzKu-7L;1(}9PW(1-u<;r~sL?sVL74Y_a4*AAJQ*0T+w%cI?_WOlj z9Gtecwp-UdfhyRer&f#;j2v6m6_Bo1WPbOtH$VRiw5fs}y zV3A&FeYmysU2!12?vMEDLEn6(xOKGX#+*|CuB8s6)KLAD0p?>~x2XuL^#{wRn5+X2 z(q{-(i~Q6cij8h@wNIHKnR{en)y7;^qH$j_NBtC47|(wvfg)rZbt|M)q}p&-oj3&e z>Eb}i{u*Io+*p!v2D+S+&2U3wvEC~7w<9I=Ur0;#_d#yFzbi6ilL_tRSuA1}faq+W zl}ClU>zSHX#9wa_$io&d3!OYE*I-3;!o6cCmS5vWfO?n49~smU*_j9PZ=INf4@HWX z(2eg+{1_3izm{8#*^{gk+&}zLWVdCX%YWHI+P)tv5$Bo;P!kT8mddRGmw4HKg)rS- zH|V?kbNdzO^%X}-OM7SsO(0yBIaq7)amA3ccTLI`crfy+C zT_#}csdOn4<-SY-lb-W?EqK%%R2j@UFx~&+7L2tGAuSzT=$y`~-%D87B z3RWM4(Q}r$dg_2aMK{}aX&_FIT8)qDAB^vBMij0>a;R`RK!0u`+LsdVNt7dbebgiO zqRA4)M?XT7$6CQ<3UH3rkP@*bZyp)w+kECBX=z>E(}q7S%5zz@upez@%#z{e%iqQ3 zQS3rpLc^<{43(Kv8&(-=wd!3_mF6W-2c$Z+gIa2WAYm}hkD=UUG*KpnDK|euXzaPF zp@^qK)3a(*2L|=jT+^~EFgeP5?c#S&Y|kq(5A*+t-8Y z!;hSLX2k^&gXL?bAUnzeFctLewlWVVVdW7V(IM^aH_9SQsRd+y|z1D8& zE0whDOHiHFMlY-Ad%VUHKDb_9_nQ``Q~Yw&rK`)?)}^;YD%^>lyGp3{v}ykfx@M1_Pd^n+Zb zX&XwW@l0}_^{%0x5rXC2*~VinNVjR*i$V9@1%{7f4J)2Mr_+-}E~u4*R2VB?zw}ue zYc9eD)cY!>+3@eA<5j@$#?qIsi-RR!q3{wcgCk9~-uZ@VT5_U?*IYrjWtc8-#bzb^ zl-D5PY3n{?5x0(d%&^%XL<3zyPg50fgl&86&f;)Q{=2Cf|F&HDV!8qzfrtNH=o{0H zJM_SuZ6i!|M~{^cGlX$BlddoCln{epGTm{UmiV}f^4-&7#Thgi37-sXG)WmPE0}W%gDOx7DjxqB3-%Q>B2UQrK@M+ z_YBws)K@^zCn<$KDgZs2a&L!K`{5fM!yqT%k)jX9*)b9MB3U-~{?#(#Uyf3XN#9w+cg zs4zc}JM=@kgl1gYzGwKU$or}<%(>hMp5X(Nh&^{q>(N^x5RtCHzex_UNzV=07fIoZY zHXpfRKhn(!U9Ef&G@w<6?hF+3M4`8!H+}rVlPTrm(<=cT)oy1^E{Hm*YE%4o75fRP zV*MUtb79>0p`A16_rX5H)2tDrlI)|lD0+3rB01&k_pToEUq8AjB974|L~bKgo@;cvKjXn9A$P~- zq32Omxmi#Fk@Bh9j*4S)-@k|dWK=o9;?2lnINSg88Uh4`lnke8^?b7l1}GNW%}azY z{E-Uci`RdFH-)o;MzBkw|5m;x@8>|+u5tH(*+?7`Y|FA<*35TLCRMz(GM>x~Py#ok znRm+_c}hx^!n~=$a+GP)lRsZ|y1*9=tB>g#xrLXd~!*cwj(1E^( zz%u)v8JT$H7QU%PdL_&Hg2Fl6cR$DsEV~Vx8-QV^bXFld(BocH_p>AFJWi}^%yk#I zzS{T9&L!)SZ6IcBAi>PvF{M*jRPorrPvi^dvi9x8Zjv4nC$HY}=2QMGoFy8PE|?l2 z$HLXwLObw-4_3lwOv+Sw=Pg@(ES?#^ad3Pu_C42*NvL2mi>R4!ldq-TYg zu{jn~SN%p9fSyCjPa9c=hAv|@t|^7~6?}5hDrtX>)UO+pN!-^+FqxX}M=W{^B02do zGb2GIQMW$YU_=qo)%^+17Z9(3{X}&BT(!S9=3YLj|qUYFaT|aAd)r-v@-5E9L}mFg!8-~SlJ;v_^oKA z5{+NbT#LqlpJ0RJZY#^8(2$ca-(pU`?NY|Is`EnZ$sdg7S*vyJYR5Qba9^P>-pwfFKPh5R?G4t87lw{egz5v6Vhb!4$rj8PkiJT( zo81ng9u8>IR5<&T{qVZ_MXH~46*ob=o4!=7R4FAqa*a_Bq{ zH>Irl)@!_{0SWZrn4@0&=5r4)8E>0kFB9%JAc$>R&#v{7y`-vPf*zN#plmf_-4m(}F_lC4KIm)uI`^5B`lSSHseDchqX@_%b3>L-)B#gDx ziAlUya*J5|bn%tsxl8U<8^1Xg>aP2~E@tF`_w$EbJzt;}I5Z;;SAFAlbEb7Dt{-k1 z-4(`AB3HF};CA4`i-VAXIa$Q(yuBcXp%27`7f0mO?e5P1zqHC}8srJFgSxWdU;-Xa zD`SCUN9k@}IUeM$7mD5jx#(O#I{u}qs?kPZp6XuA! zbV>aYy#ljl$ZpXO>~WZUil2%?h|`vcHVHX*#;h+ttf@Ay&iYUjL)ZV zE%sIW24RVE;3C&ny`?cc?XS?e13*BdF_$=I0Zc;690%o$kEqaH-9dWVOi6Y*CEs)H zK=Rfo{q!AE{g|H|ajh7P@gV)2opdPd{cgU0^EccU&#Y+1X@`k?Id8*n0N3;Xf`azr z3mrT4rrc;H5a*{ zaIdHjVa#`woOC;h(#kMPpEwd5htzOnvd&g zf@NboMpZDmdYcGtdstI2HWjAchhNkUAV!~lx4%b=*iHljF6QW70A0}4rHCO|wXbhW zq!RJC7%ePWAPkU~`bYxhZ13R5n}Nd1>%i2l;GkO}!gex<@%poY{42snQKmt)|4Zfx zGUSZWLHr%)RD=`O58h@x4u1A zdD^^7Gv9=2k^LoDyff{DtrfH0GTq*LpGCxEYLHb7fTA^6QksqtMI1hCQwDr`Q|7AW zmQ2C^0u}HYbPh|weciZSZD(XDC{pJ7i`Gb9;OFO~tjBWd`uGPHRfXWB?xFq&ZVd3D zN=>ZxP%ILO&SNz&T)Sdn6Z$pYx*1>)b7E!CfOh=!#cgE7{5p;AT4v_SHDLMSD>o5U zC>CH2Y-J}d2Y~DnIqv=Vn}2{@0C|r8H^_5^+{>bWm8>G*MCVn%JJkE}ckXd&R1J|i zPvxJ#Ula(X!Z3INFGoso&0aXX5?fc*j?}HzlaG9h$kpClL<~kpeTjdA-;+H6m49%$ zdcWN1sJW#)CRTlkDb7m$e?OfRUKIj)Ec~Bqo;cT{kGPC_Pu2dZ$23?WUAvqsh%TTT$ z3IRcY(54d1J)fP)oVru&T6X=@ocpsdN6I~3ckbQ0C)=JxvTa(CPZ9N56Zx@sDa^}l z?f%mzPdaGWHrdwZ3GOm5JiM{eO|YOWC($}89JzSQzZ?`YD%`BsQo0o`aJA;{%=*fP zs1kvbsJPn0A7@a(b!Y{5Qr5wGZ6Xsxd=oB`A0Jt>AOEV$%y6mFrL;*qN$Xa0t(S=+`p#i6OK<^2y5-l$Txs8I0j{@seQ_u=8Ds0o{2{{@6= ztB@4AgXnT@6y;j+luVp@_m$E?Iyts_yRJdWrq&e#VW7i(0LQdqS{t#=kA$ z@%CO>~I|d2Io%&@=CKqFA*ox2LD3|b~FA%pT-Q0%e%5toC)Z+36o-*gwvr5-`pbrXIbxDZ3ZRPe^5`5u_0{Er2i)!?a0 zm;Y|mBAhx`OFOPBH~p?r#*9Bg`pSEb8?$FP9E)$_UzOH0=EP4;rf+_fxIOdl!VRd9 zFzR#-oYCIdQmAdIZWD>$cS-@VPgelW!42VteGv-y`o{Z{1y8w9{ilwVqV|lxF6Q2D zpECrtwDFIaX=^p})p^sG%%d&h?c4Uueo|~J(gl!l9P)8{*DU|rhyo)dIW^1{s-m&` zC;ZHTe*CML@6}nmY1Zg@gCymEO4Q>SR!5$p>{oN2jvyum;{6?Xh@*vNFZGOeP~z?w^`ZNdtJZGazJfjqz7HwEx!l34&E3d zb~#&@%?S+Jz%db=S8tK?J1<>PIrx7*aDMD&Z>iU>U{at8*Np1q;rn!hO$m?pxIEgA zQXppx{qv`pKZh=-`g$)yzIi1?d8>v_(~X8~LpU=)VqSWZmRUu*zea-sujcU!r(ZCp z=zS$J{c;lS*q|-^?6G+*-Qw+&PLX@*{@HEx!;hCHy*jsjU!6rIb5V`oRB%-~J=t>A z4f|go^|y%*^JcjD7T>4xP{dAg0#UJeNn&;V@zFns*Jn<<^j(U?l!4Mm0+&}+0Zkss zMc> zmBg^kUxR7pezkx13;$@#{m+{lB2at#DD7KR2ai--%5 z(k7h<-%d&E@Nevi>L)e~1JnVl*a`HR{>J11bc^@7up||Gt;HbpN0Ca&R1C=i98SYzy?Zeh}~Yjz?)V!q+s}cI?LTs7iu&%MFw#X=^6|c%rp1YsW$yp=|j^5@5I5LjlP|KJT@bB9v+Ie)gd(Gr9Tba3eyjpa0%y-yZ7S?Bgwsc-_7>9?AsOhIRge&Y50; zPdRLzSS7-H-ODqoe&1tiO6M$js^aB;yFytUW9~<|EHAkar9t@M?GYIm5w3XUb&z|j zpLYrz?H9$$gTt#IQc_Yr*#AA+{8SGIq4gpzZh)A7&TSmFpn-UQo~aZIS4#u8@SYQL z0aFU2iC0|{^Cr0-DEx`)?yX5%p6|c56O$_xm(6x@XR?C7=k`Hv(Dj>)8PC$orAq^tLp5fNSAw zho-rE(v_cQKDM3Zuqq^ML`C`v-2LRvP4Misiaom7`jqpvr^se?wMu@#Ba*x6C+MFB zPSE=flQ;Mi61?x+vFVH0heu+eFwNJ=0q1l`uYS?#s#5Cv#s3(WMX~r~%N>|Y-ds_W z-%~H7f5;TKn!7&K-z&a-ajFShL4E)Gk2r}TrhuHP;v~bXlH_|N1Dm;jmv6AVw*Ei2 z<8u|#5K!5xgacOIa-(ivm!`nqu7Hm2_m1d9r}(bJXy4m2BA!Je(mfV|=S`XFtL7nH zjv2W7vMW3>t9;0R^Qgz*v>N-P1KwxwknX?gJ;LZ?X!;;w_3oo@?%SSV3L}qQiukeS zp@>voaob(HImx_*u6faG^j1+N;e%yT>8G9?yAV(h*`)ZlyhCr@z~WE|4;6d z?p4!0zneSoIUW^R<&a~)KynZ~2&ozY&9rriCG`)1)0ow(0}}zOpOTLD+nKwY%3oX) z1&Y@Qoczw)ELdV!(Xq|W+pM$R*-fyfe2?Godd!|%>^O?v!ui8wqVuYPm-NQG>`)Z%` z#wL0FW|P0T52Zq|$C>^6+KS%qk=HKPHFYF*U;58$i#zmvo)~Lc^;r94n@qJQnb8$1 zHu<9pw{@#Uc8{0lZd{s8roa~*#pLReZLFT-QSJf`vf=>+BW@7Nxb%M|(@5}iTf66- zXm{pa{FDkQ=7!_BH0&jFL#Fz*oYyqt^fJT$A7O7E2xS}njZYLMQcq;dQreIuLXoY7 zlr>wDrDWd{W-^Q=kM>YP$eulWMh2r&D9ey#Fve8&88Zq)W(@CjQ~Ex?x9{(re`oG{ zuIpUqI_u}06LwA{Z@jAF9fL=8u(bRU+jX0qc-HP_%C}_DS4h5p;gUyD+!7)FZ4&%w zjKCE^yYVO;TX0$7&$!gW$o&slwl2|ar-69hR@V!}v+iK7+!2(gfK5)?FEjjJ=7c|3 zKjSp*31=9xbMfRj&%%k!+4~xJ*oY91+D(qVr4j!$x<{Bhk$d5j? z?fAY5u^mj@Lfte&m&) zSRTzDR=Z<`_PT@W_@f?C<-|zrNT>@E7<>BjMfHuP#pTJ6At;BN>azh>I}v=PJz=Fg z@I$HxZ06yrLD{FXWyIsWgnin^8EUL{$V<1o`{>N(V!ijvGXNG>Jm(hq6ppGhGM5Mi zmA3nE^+xtGJjngw!P5iz+RF*`OHQLd#eLuJNTl~b-JE1Vngw1^!rR zjYIoOWON{)ZczIsm|#TvPBr^y@>^(8ciyeK8mH}#gR;15rPg2399Cv4l=|hu6Mkc@ z1-NIgG-sM6M}dp6=Lay_+h3OC%%^!HAVaj*!y03U!JX=PlUdVVFzztG>KQHxp%=~o zTgN_sD-Rc7^u*C*Z;X@~8t;jaSOG@C(>r(WwCITjm}hH79Upr(1E6)6gg5q-9S2on zu?mA;2=_Zsoo!CAWPz-EDX@y7i>9nf{6Iy9#i#AfRXE^Ib3Nq?76oD@&hh4;Z`1xO z7wX3Mr6n2Jbr}}&)KHBOl`@AbMkzml|0?D;)Q?&q%FvG}D8w9>uP!JWU|E<2eDj82 zaW0>Z7HS4zNI;{=R$zrdt+$2dGZH97l#H*;em()KaN(WxqEU4k~OTaAh zD5=8P*F^gw^mUN!idx(a8AY-9nYf~yTbf>eAe-dA5~==_HEUrxNMZAYEbm<}`^4VYV+2JBHd@M11vW`7A&1~q(WV0UsP&Y@N`v^aLjMX7iAm2ZrWm@fLR((l5SwH_xG#qH z)|W2lDeMwxG&Z!&Mn}Y?ZUAG+BCN5Mo_rO=R%beo=cJ)Nteeb^9Gsj95446?FlmdR z<4D!GEiCNF#EC2IaVv$h_cWSdBciK!n{krInF_#iqx%ysmn-It&WcXo)LR4&L;Jsb zEF=3SRfKENl)^xeiw7|a+{zNJl>rrA&!&>;pihUdb7+sb!%T$uQhMzt>B4LC!v!_% zeESI0pbzj(GhEyF4$GCj|0hxHtOcR7tXTD~si@4xPNMFl61uROK`uPlRPxvbA>GFq zQ?0j#x+y9#&-c8+idCJIAZZeWnknsDBh@Ph?wmXlnW*yb%bb&&cwQD7_o1v+2VApm zGZ%tL%%Rp0a^(>0LddWPNwA_w?pe805*@N&o$8Z4%k`a6b<$HBkkN_QWjPCyIH8L# zE80JK`e=XxeHp_0dZkz=E=9hLmg=gq*q`6@ZRsb!WIW)2nm)~dW{wGgY55Oi(HCbl zREIY0nS45_*#&=rX98p3a!8BK&=aXx3@`+u`b*@B%bhOpkL8TEYppEJ0OK`TDz-qy zAH+hOhpH%G2-xfl$lRMQrq1LmTo4HBA(Ikp;nvPI=5md4Z^~4PQN59YY2Z_SLKFIH|QZ? z;-+fPB3mg@JQD9{+f{7HAw9ypZY}mX&8i!nZ$rv+kj(%)0VOds5~V+>?hFP)z$dsa zY18wO%8sF`{f?c6uAC{k;=l>ByUXmoOTd4tx0pw-3)|;EmBidN{T4xiT=}>?ENo+n z_|)-J<2!=9HymPH^;70vL8YRLfS12N3*VE!VF{ES9~Wx1^Q!DoWFNx}7xZe|X>rbA znq2`7R=k3mOj;Uyp$UB1lo@r>VtXqV0Yqz3xK5R)ob-f6Scvf}nJB_i=rJPkk|_ElpdG1T4@Xm%+Klzuv88HZmIw z<3$h!BDOcz7dwmpoY2!!8`E&FpA76yQBk)**!E&h4RXw2^2R~J_NG(fJ5Sr%EJp{N z^*|LUY}s1}oH8YWo0A&k=P$PInuB-N_ON@r23uGU30O_i6!Q;GHMi|!)GP;@Azw#a(d6!w}%cYFZ-b)`DASKNJLvISHSPdAbWBZtV#%RBRxPx)Kh*|yKWtU; zY7}vlcZJjWEiY!&f*v0S5pVl8$nspEL~U0!F^Msu8Z81Q7mmTdu_15Z+-)LN5A5Yf z)-FXZ_w^%xByEx)=Drh+rRY^}B1);D0>stsipvo% zX(9Zz*-U_hA#uB1EKcOfF-}XZzIZ0BYQVfty6}w(F*hn2d!A0D#CQ2@t<$O!oxGX| ztWm`ZW7IA}0$;I*$R^rAmE84?dj2U&Cv2Xn?euDpMo4PU$#gWME*RGtot7wpnMd&i$GtyS%Vr-Nt6yex?)t!v)pGni5vn z0K489`1ZM^eb-_`su}G5tu+>dI+{QEHwGRykV~`k&kgR;#>h&l^EcZN^Beh#`{|GJ z9Qx}hCSPZ724v=6A*$B}gonv?8QN?aQ6^p&Zk6ipw56gST4W^G7*>wg%iP3=y}+tZ zsihUTES$XellQTKP`))6-|H8nd?)%8EjQ`8U6eei7-RK1&PbF{Fv&MWME7Xh1w1h_ zEkVB+Ck`kUtBrXJE`Br)Q8YVXVb)FqshE!*eF2)lypowdgP>3rzXNwBWb(XyL9J?# zsg6v67N&{BkyMl?r1hEA8?@(EVGy1HY$Q$E%U#IU4;&(%CjGkO95%YZ1$uY9l6OIy$3pWJL8 zM!d^)ql+aSW9*{Qv4B((NME(oSW?%!9i=>lta{?ehl#oyP#WPj$Xx7z9&*DQkQlp+ zM^_ri|J%9g9^5ty5-yS4Y76AuUzxQ)us{>GuBF-kd?%nt8ORWme8KW?W(VFFToU}w z0GU&rvsV+8R>W#%k#2aaR|@>-&XR-cGfQmo+XD7DGsHYl;;+ac1KBmAJV!v*PFG%9 z2BKDYmgOaH*^;Y7E&56+{)5&R}oWnjmJ!$05hb)b32D&L7?7;tahzAJw zO5D$s%E5_VZJASA&BYwv{KG{Qu2qwBjR_>QE3OG5?7FVPymttU0WyW_{pT+%{~n?#x>IZMojMKjx;hJIvD z?}4&Pf$!sF?Mpzo%&NQuYG;`kKs6c9pF5(L;vRZIATfvj`5cO`bqmkPnI!_!N=Y~F zxlcx*c_`Y*0*9srZ5hyEPBy_|9n+xVyB2Tr4sMc0{Z)MiMUV@ zvW){#S*IW)j<8!9vtjL=V@r9nAIj%1vzhE$jb=AzPbyU@A0uzQ%s2vMIkwlI@`yu- zYg^YshLkLo;oa{kQ4-!bH|zPTQx_QC<`-jnv+e8=RRj-R=!JHyQ%cC z`fVco=woo>w%aasZlhMD*Em6<&RL)E(pk-QpLW-oTay$T$R8!r+sN~q3O3MBO$LU==X1d{pH9O|MG+uKs`KQdBzy@CL8kBuICY zFhpAJ4pew;_lKOMdyNZs6Ml3*pDF`}9&~IQ(9;6mN5}!1b3_ga)%Dx^xF`XlDIbHE zN6x`vhg8&f`}`u>1?G3NnH>FfMi}N#o~@kObHVyGSQ6VJa6|LU)0}B!EXZ!eZqV~8 zG3hIwj&B2uTybd>xO}PBTB$UpHx!;W@)0oVU7*=D-CU=(7iuR4dEu54X?j4K(;w3P z30YBU(tz|_;h)uS0&n#L2yg|QQqmw1ip6nzflu-nLu0-h$8&4NgCS%(BId@3VdHjE~NhgXxnNZX&Qi^4n|ARY*^BWP8ttJs823c(*ee zCnbv>K)I_5u{!wvm}tWHZ&w60C!(w-cUXWa8V^MWZVBgM&3&AwrgeHsie~LVz*&q@ zCkmTW0_Gmd=a0Gf_O6zn16d-_?jIQ6PI_pNQAgmrRCU<>yQ}&amCd$;Xq_2$A>$>- z&$$y5oaYVpMR@!6E9`+O1g}J-VcMCZ^w#1+y@g{@3#e(187TMU3_{*VxCe5vSyLF@ z0PuUwQz0h^{LM8~8v(vn&|=XnXD2x-*midu7M@ihJNJNi^LDT@e@-sSJ<%y%Xn|=V z;F8^>SK)3j(z;L0C#OPcQZ?L`RDk?9Y#s&qL%kVz5L>$nGEPJV?iE^;joVl%)JG3~ zck79~RC9ah!RhG&D;s(=JPffBks`soNAW*=3A)sgEo zj~j2)dK32;R+0tfwNKmUsoTLp@aEI3tw^UppNdE`G)pCpdH}#7Xs?H*nQrsN3I5U+ z`Qh*ytO)ozx9f1BMqdCuZ>#!ed@;NV^J#*{Y*Qh;RD5Gyg4MQ*$eKhF-MsMlC)!vP z`k!V>b?f{^RgcPaeSux>YSVK@c-?(5B~%cK9j%Z)QAMGc>bPKdMP6XSgCzxw0%T$k zIQ^o6?L9P756=i;@h6vRj8&;K9$%PKZM={r1fOCc{n@`v2akhPM6uh=JO?8LWq{sR zFnxhq)#;av3*jB1pYUSQ0;hvWHg4jNPQ+&jDNDx6O`Ns&0WC!i@p5xt`!xF2j%y@4 z$JLnd2#cRWS`qb&9}qrowV;a_3(OAOpqkf91#HN(GZt9!1ic=4P{zQL5i_Jnlu(P= z;j%FTrhKUWhqn6#U@O1@NE0QqarQ)$KlY}OyLx@KwAEdsYAb=D+_(9bkoU@i6_)b4 zE4ASs@BF|Im(aIGTWv=_@jJmj=&)>AL(g~GcPze5Rf65W|J#pB7<6;6RTj+4m+o>g z2f)on{q5wTzylyoA`_-xl?>V+MldHs{J%c7wU18PrApMx<;vlD_%$-yr?l19+u$?wzSw;(X zI;QyVxMNF_>zdxycGVY5_HgN~YOwLH&i;%T2uy9OwuS5tn{UUIZpSTIvVa@scBfWC zm!8Qe3&=sf3LqGFY!j9&p~BKhcbUZM9NsbVt!JwN=3P%EHe(&gdl!A7Dk{RP3T%X% z?ng%iZ3D(+stoM@T6|ffF!dBeeC3CD+}r&cOsfq^4CYPt6k5tlD)$I~K`x<3=?k$K zoJ3|W)9q-hVLmP}Il5V}(rO0g<35djoKFXHM+ zm8cN(HORGTwABCy5ZM?dg$ebBVuT_4qH}IjNsidpEEbvVOii)rEMN0^4P!f|=V;YM zStt{IZ6%4Wtt8h+53Gm{uN_F$sPD}ZyYm<=$~^lRpeGata#Bh3wmfSE|Hol=S+TeR zs}$wg#jW1P|01pkZW|~&tl>NkfbHd{>?3vQ8OXALY(_=EKy=48vg9;4p)_zpi{4rf zGbbMW@e+56&&3*|_Oa8TAq`WDBCs2`7*&jFDpO6o&u^o4=V}fr)1{|-%ID&-(ib&J zjazdrE020&isWOUl!L9c)=+nR@uWl5OP4Rjw!lEnF@#P|Ajg$gV`e|k0(WJBv>C%u4CxN(La1k#-rnjRGhom_-O3$TXVTGdozd|sgZ zp)-m|*>?Hh-WWXhE;ve3u5Rx0#}La)ZrQCE8ysW5m z^8nk`;@qq3KExKtf`8VeB0_4Qq*>ZjJyF1Vt^hc0V1iG}wR+Id%T@7wysdo;lp2Ub z`vK&HORtq#MT%>(g_W&xMX@OPc>=b?$nNFikc0_eqhVX^`}{$m0dh1k6Qr6vn_e9i zRaL6TMv>pDYE+XA=`NI4;u)e3jdy?$qSlUuI{RnX*LT(p`8Vdw84L*Ce*!h;NgC1Y z+G$xKMay2y+IIFOLH6d=6!mFb!G8yzahm z-U3~CFa|OGtjnRu)&~W6JNChrZ5neOGax}`VqIM0);0c&(r#Ttyh%1nJi6rFl;TG% z@7EsU!SZSM(T4*;`zA|tmB6_dU0*%UG1Y0WB`ds?LD4kr(~+4?GwxcGM}hNvT1mT4 zu?JX|B``BH)2aqtwogU_z!RKzK^>^UTKB*|W7C%b@*Tq*bO-&l$$Re{_3s&$^T$>? zx#vrq(b22a9P$BdG|+9{hP2)EKBd;AP@FB0D3nG!4<_x=hZ8mHZBf?sN2ZW?5CNkt zYKKaKNX4@%?PY+UvMe{Y?Qp?Yo@%?F&Y~Pqf!m5v%_XMo`1&V&Rv;WwoR>)Tsmm3? zuE~~S5#}xaD>rI|u$N3j6DE{Z2Cp}?s=ahK24({2IrSj&%FPr}!slU5D2LsbQF<~1 zSAr}J$YNZm>&HyFxN`PLT~LQj2xK0@G*hDiE(ZV_e>u^|Kr>3ay~THG4D0rVn*8&L zeT0+lLiZrxdsYI(O2;{16ZP6dDaFeGS%G_50;bcZTK5|OTic zC;`AM<*3$4E!LiwtG;%l^C<{pjN2pBMU`xF z#DO1nCWYg*dm4R6sCa8~F91BvfLTm7&@44@SS)Y^>Q-i!xlDDCIaG8CE|8rFPW8^+ zn&>G6Wu_DDTJ!SjsTg2;uAL+421eonv)AW65|@qSGa2v(3|9~Eeq(!L@O-REj|n;e zN4OhrnmMVYp=)|{M2K>(y#+M%D?Q~{eLAh;6VEZOD|cozB@a-)1l%9m21BO2mbdd} zjIQGaPM&=RilZ+1qLw~(8!I}%V5~=sGAe;QOMV4&O?9pV;bX@IFkye3(BnT3)qFaPbni@4+F5TMlo(6r18$P zN9U5b@U;^D>y+p~MDHd;!|9p^vuK60Egc`X_H>WaU9r6qi-RF+(nda&J!JT%$c`&*N3Kv=c^z+cbySl-SRD z`_HB*0huRL{5o?9!uv=i50%LWNyXqrN4#q)l|o)!MHuKmyJ4pRg#ZIz@h#b(ng;Ip%x2v(F@hWraM|`8^@%x zHnlU*_PHLpZ5iJ(CwTNcK;q|NK&}wpLu#rcYZo8Q^~)7tuj*e< zGfJDj zt#!o7^6Y`TQ2`jOO0ATLZc>+`n#*M7^Enb7;1WI&akY)Y9_DBgK*Kk_R0og-B?8_< zo^$4N-F6-FJFcoU%E`l~_K8n=p5mi z7~5mJ@r52Kk0%ez$eM&$__IovBH6eH>*$fsa$|<@j1V`Tr)P2}0Qy0ER z&Frd*ZVZ)2t)p5uJKm*S%j&C7M4n4s{0Tbx49sf6<_?id$W>^0`6-e}Kb99}y&4Og zaHD%VMJ5BQ{E+$iNHgKN&v0;D7xp}U=TIYW6}fFvl+w0wW(K6a1$Vx)G~08wXhDYG zT;|w0PEwST`U_NZP^t4h-43-;cZku2?_SMWzZlLBBZFFe zL&$1Oz??mWaH(NW?dkp!qShh5Wkh5az)f)7ZpsjPuN6G{ayJC#AgkS;fs*nNb^; zw!H6yw61~&0fS9C-4_HtPCniTP?UYs;kBtkC8#Pj8C`d^mfPK%_Vl!S9WToT;oRF_ zk!8F=jc=b!7eJ$b;S(?AJI6c5%hG%^7)z9XjMP7`*ntf%|Ifn5AVaM-3(Zw5@5$!v z8{dv)9DJGvh8oj~_pvuil5@!=Xx>8m!cc-HFDzv3Py++1Uen4y&l0>g7r87-|C^-f z^y%3KNg{s^>@p+gF2VvbU??Av{X;ZP%1$+R1``@Xg#V+z6@ ziN{016uN7GR%9!It3V~FCB~S4eJ&=Rj`y$X2eHK1h2ne~bvf9*7Z!=3iP~MDo?@D6 z=fJaS;9W?!eG?7%Q@R9n!D6I*@SY0RP4eCp04O4e47rVMB=WrcQah1qGWu?Mt*6ozaa`g}qrq!WL$+xlFIIGWKFd zh)HwqgN(u1^6rJ8_~G``by}UVGYfF5`7b>Jhrda!*N!#VWiRu>m%>nVd$>MFV~IOcqwC?fnKzoILtJXNYI*@9_gpDP;S$F=P<%dG(97+f(;Wj&Lj*<$=LG@n`_ z?j(zFdxr2MyN6+Q8A06qPYLu#NKn&eHLq$1yH7n*mf3e-ey}6g!ryb7v__@n(|&kSX$3hXoJTF?0#+69PyP6N5A6_{{y#G za@Q578q)v}ERo))36%uANTnazR#PkrqOj`h-V445Av3}mr373dt(Q|3aZSB*k5T;1 z4<0{$oZXlvfX%J(R)m3>e0t40F-jWy^`S*c)e8OwPgZcOsK<(eca0j8k&yA1j4lKFFkZ^wM#)r=m4|(upkxrZ-Tll>qyh?SnD)1rV21! zGhK5PxTohHrabxq;D_g&jXEF6uR1o@z0NT4lnMGAX1?xbtyx+_h)Ny+hr#?KUX!p_ z89$QOF{~y6N-pie=P%ojCo#@<&sLA&(tPUA!_ph_Nck)Mn$;bCJw9Ic9AS(#F!&De z@ymOsOB7wX9htEt0Qz>#WJPNxNm*@#syAM2o7>DutbFP6xJ8%Ua8tr08q~kTZ{X|Z zYg!dso&RBv#Wuzkzi$?q1ut-Lv2yv9_pap&^2_xCob6|xV@K&PTQ1p2M&Yn`~cMwxH4wg zeiu0IIePlCOH(7(nOwF6s>w1bUDYtYEp%17Izd2S9_Q#q+7#CKKgdzwEKUHBLz%Y@ zrY`4S14F!J)%X^>!0$OwUO5P207}e@o@F1N)Z2RXI~#z2cqAWORNH0G5g05Crhi(; z9Ik8o;@kWVJgA&JW`<1yp#Lf*LQBLpwL@lTQ+o3~fEX+M?5wA&tLSve7t{zD&J&BR z#Tf4gfmCW}Xh`0qvpv#T_$#v8{2Q1r5eUu1GLSQW!eteZac? z*=4=2x}l@Ep*>&o28jA4SY5mliQY5=CZrh6^zE=Iw(e;k0xsV{#3w>P(K92fdJyB} zpQPPPtkKqVYJ4d4fK%stmU0!d!ISNgtjAajjQ@dtpcKG0Yz2KkDX9 zc!lDFUHVf$clz}Ez1Co44w!84>c;ksLAs{?H|WfrWn=>kmIM$)EB=0>Z82BYH-bLm_W6bChewk? zU)u>hLmJhB@m?*UB=||&?hS9!Lo%1IGCNKR02@nG0@3BHtJlzE!#D{3X<8b_6~GBO1Mi| zc+t0*)4mfF3|NDy$GKi&TTCu?i+9U=+FR!_I`zp`=#mZE;~lFtIgl6zmcrS8n%QBn zqdI(NnyRg%owWeq_t#a{yGOa%@H(7$gKNwWf0nH(3IuCOVER**Zg&v+zm{FT~BL76i-1_;G1oo##$47?nO7eEelm? z%J~KmBcFijpo)8T2YZrgLA9jf(QbN`%n0b@V4!8^f2!E`#c;x4uD2Ap({3nbgolS) ztna;Jr$Oq8zDO8DL0v?4Ky|LT^F%)d{F(~0ZqBst7%G21y}jbjIM@#yUmRI5A&saaOmSP7g1}eQMu#UgcS$H3JgR-H~ z+=}P=tKC4Tu>4~1bF2{a^>Mf(H1}f>bQhJ@0`pi^ls37lySupixFgWA!ad&g`EXBy z3T$rOc3qWrYdpcRrQy0+tN_uiWh8t}b=re=B(16(I;BBVZDWGY-NaA48gnL~zSACk zTw1#;Pb1&9$5%DjnraRXv={9Jn-KpSG5$HzX>>r9Q7IeCx!NIMGfHppt`?uVtY(OO z^6>G-uV25;fOZ3BAxl4+55}{UL`ar5MbrYN>L9VJ`Dw_n5Up;^T!!*nC^a7VO;Lw z?g!oF-Br=Df#yv03)D`uDQv>$Z;Q_yY`&(SJD?aSv3m7lwyui$TVHB_K3i_sJ^T)3gjwpvXSnf`B@aO|{pef-C?i(mozi=`+CGIhcdS38|&36{}&@ z+UNW5rF_g&l?MrpFbUFME<418l);x$_cM+A6$7;w6F+uu9(mB((a~{dco=nVYT8gF zj||$)#Mb1lsuK{dbeXlCVD}&NU-I7_aDsZIIAh?W6h!_F+P;4i{$~Ym`wb4dxw=lU z&<0|gp`HnQ_@WMhnK;p`EoHok^Cn#Y)R-F#3W1)A1AyxcG~H=cZOz(G>{Sy}lT*`F zGg7mg7mUgpXxQQ|j&6f#ANgb6{!ugFpKvuo-N3TC@#mkC081|Dn$A&Q%MNa@dGjhd zi5x|NasiyfxD-UR@% zV%D@TjGdkReBuf6ewzdGYg*D_kEEpJd0+@u_l3XqYE|~imJ6_&hg2H`J#485ecoE2 z=J{=pGq#vV7Z~>xlB@33kj%!(Kgq`^H^EJYefitH2s?DY_eg*DiS<89=YqWVrWEIu z*D0+JS>j!AGW^=L7r~&$EFSbDPcg_{1|2QJYbFcRk)|vNxmBRrlUCHl(e0a@Kb$x0 z7JUS!E&I3ovHkYf-UEe6UM(Y$t3rdVTYvjT4?WXYK7-ylcMOMgra?UAGGt)3R5-Uu zuZn8WRPFT=Xm1-2O%a>{VE?NXA?Mqqc4T?_W#6~~(_Nn^v<$gD(6k~ zKMmSF?|a|N`xUg=!YqNdTu%WK^TP~ijOt0#$e5thHRnR+uyf0En)DDlmcC3seyO&L zm`e`oea9f30kyc2urSNN@vgSuZ9Pn&<@SwQWll3ES4+D$3^W4<6ZUNy(D1g&1!!WY zC6ZQ>3jPQVs?UPzu|~Z8BEQT4qh9}{FCN4@lmd4JDOV18XF=U$mg#Cp4W^jdgt$QO zxLbjJPeoA>EDZiPl^LeMjXNrYzk)WfTe~&dcM?IXIRY@zqF>jE3a%i|Es-dWX)0bj z?5*fGSnrS*P^>#-T(1=D&FQ}hDeyvhcty#f`vd(7%iQZFfL>pE(e- zlKKDqZ=i6Zlh5$-^7=TpjBN3Nj6m?tFFOCXBs4jAMR2(U{Fa;h<+cCUZ#f|mnY^2k zeWSYeu57~pKLJEH>U`IUJ%s}|@3tyvg0&H>;QL?LIxj+jd*Qm@#G(6g6~BKP#tqqi z&Oqm6`HC+(L-&`m;dkNKf91}$cM2zZM>-(0pdlI5eY0ube(kf=MwJ1>^@5^h*nX9ySnQDg{I5^RSlzDGHt30B`?n_awwU}3d?VO(gX)BY8e5}P%>TSj=+ z$SU*=>zhNc$~^S#jw+1rPXuGtB^ka2HXQ)uvY$6vMM0tTiEOOu8rNLAo9SxbWhGbU z1cS{){og*4!){QVg}wE$C$-9H=I$!}!nnbW5lP0*y#C*IHLP&-=-iRmLLyKBJAN(C zx%FAu%|WeQ$55k{pcmy~$CeGhtM@@H82YSvPH&EF)G3Wl)@fSN1VoWsBTDUi*6@`s zdvqzZ$~8RWf2i-U8&LmaTX*Im>Gun{Yo{!aK{m}LL_kD5@n0eyKAjH8(ZL1qVc(qH z0WP-lfBezG2h-K8{hMz!$8Uf&EB!@A`EG9bZmMbq$*5AGVTFv*BKTWV^T$u}sfTT;wKrRKDPj}KOu5kKqIc_2DLJB@?7hTOZ5f7G2*@)z@L{g$_^f)14jVS+alNMG>Z z{#s}>zjSUY*{iztTN`Mm0%9nzg72UwfLGpz&A9a6{o_(adr0r+r>}u;f2v*)^mZ>F zzXQzg;opzAe}_8NX@dA_%K7Zi3yz@>=ZP-d|JL<*5=k2eg!KuKTH*fO)UvCFv znro6pnwwTq-PV^9`}XZyWdqvML)lowZ=C|YYK}WAD=SUetk>T8&umaE{$VW}DB(o|QrMVUVf`RDf6XhT{skUIaL_hw&kv)S2f@ABuh3fv`%)w5z~ zgP|Y4RShzxcb3-Xl`z8sD9{Ldxclx-Y=`1k}d}f&-h6#0RnUrz^6!2O^vZ( zXS0^W`tBYmaECf5R-_Fmo_Vu&hi%`poFuzKmpy;|=GD1;^GmpmGtmRT-U1`; z_cvMiK{%)4$(E6oKimxIP=&zR0JMQ=Y4w#St9pCO#tgFr69n344#b4^ zuCJ5hieRd9dHD+3>He)>I}{QWyeLgm-TGW}ZlF8gjO6|6FpsuOOiX+RPrv>1w9fXy zsj;>n^@u;u-@eOit9$OcN||)C)?`(mBRiW{)-TgDS1`q5E=Pge{)S&U6jk@C&ir+b zdu~Y_YoO|x@}>Mfl%wYXlXP#KS%GBO>gPa`0=KH7_3Sk0-S&0u`1gDZsklRk1{l?z zUkh{H6#3ozP)W?t?}a`)3$#?nwKjo1#WU~L&i~ZIhYxEBb6KHAiHc4~Y__ef*ZQbo zok+8XaL_MG!yNVk>&!Fuv8Zzk-!C(YXXir7iVNfOE;J-_K*X^E2xWmm?GS%|f4BcU zcSKcu>n#UAo1C+MF358*ElIEc7mu}Fkd8|Qa2~)@hapX}`Z3@GhKr3RcY{?*@KjtT zPJ+6&&nw@svxZ#>a#g=*k(6yN&HA`;1}LUqPwqU!cP34_zmJMG=v=cSI~0ECyF^5y zCOUtv-0}bCHyKwS9pV`QO#**dtV@e~fZ@#y+k@}RnjKx^*rNu3{?{0DlQMmyYyUw_ zHwzc2QZvn^H9(n18RgF^bp&spZ^VAP)>=YN zoIzjywbZrucbEZUa;_3{j{O&bfitw~*gA$Z$4l*9yAW%?M&7@W?;kDFtOXj*i2T0( zu$@q}I`Ls($KQSpL@y5Tq|%>*0#=2Zs^hj>4#qY)cmJa_q;&Q4Tx!CXAl>Qx`*{45 zfKyQ?#obU}BQ*Qw&6@)B>U%=|x^fG_*Pq@rq!xTq-W<+`+Rd#6x4*p`rWXn+(iCH-H@ zRQrv$1I6@{RI^U`lxtsShwT*>XOhsDP1n}kVF|@T(Z4n)e8t~?E_i42^!m~IKLOE~ zHUsohkWEhWFD_05=C9B~uG!U45%n|^kaPf_OF;LuDd1vOlGYce5AIy!wU#a*sMl0_ zy3;r8(Wbc~+u!mCDHV6_@s^Q=b>*O@FL)bYvuL$_qkWmv{fBD;DIWBEyjJCN#`NfK zY1e%|-(2|ms?ufuLpk7CKl}jT26tjZ>r@mKXS{8S*H`>n-phy4JH7tLiRuWNv7y9@ z*ZL8e0c+03vAm?oGcoh`a!*)oiR0wt#8>`e{`Y_p@bYozv|f$@QCQ?HA)Zj*7_XlK zr0O~N%G#O2iU6;MCSMLLkTvsPJHc0xueI84Fs=B`48CPs{goY52R;f+60O0GI{mad z&_|ziZ2=^Opbumo57EZ#R^j%1qHE@cm(GUTNqei`M=1pkR|B`RRFzyxlwW&HTgCuL zvP1=Lfn$mILP&%R#mlIz@x;KboIF()Wxt`5&o5zq7Z@x>8XJO6wFC7Y3$I^$2Uz^Z zx9taJ8AY<}Aa-uMhh}E{OcVWEJxM@GIKYR#BIT+QT|H|WS(~usmcyG7+uS}yZ3*5E z{%@N6&oou~e~I3+;E0=U-kL``VUTP8;i?WQO}%G|i@by+VmK$beA5O#%#|JgElfWF z%GLmLkIlGGv)I7u7fq-KHs7i=?4^H$GU-=aHiVzhwh|N)vR0#6ftFd2V^sjmcjyxX zls~eXhd_y$B(E7E=~Unh=Oz1rNKc|Hd&#fEEqc##M;|w({uaA09!5olwC{W!eei#5 ztl_(~>Nv>Dz-&0|n%4A&4d{u+%t^Do`s>QPm@rznkUw|Oc*4#ir*LfzVQ{52UJU-& zRt+`rtQ!3i@QWAXe!ic((uGS+JL>k2nf@v}Xj=fAFsPh|=+W#?Un5cn{GGz!(6!6a z{fggxem@C(?z4kc%e$E;r$9PB*bA!Q=>KJcNJ0JV2Ef@U8~>!m{?Dx+>u-A!0TgR| zc<8UKQ-L(vhWN00eA<#=-|h4NP75U#uia#r8j#O^1`_oVvg|93tD9b1lQtflrG4es z8ol*>qLo0GyM<@F7sb~ctB7BJvGzbZ^u;M;~INvW&T4~hgeBmxs$`;|H!Oc zKxS=2p8R=#{oGR|Hs2~Vj0!H5Wq16KklhJ&UKJs1AA0;}uRx<87QOvdD}{TpvaiSU zxZs0T0kXE3RqL2IzGZm-|5(Q@2Sn^1l242FuKyVIr}E9!`gS%d*=npk>;Lb>N(JJe z!;`qtxAjh>M-md!Y`60quJ7T95RtQfDk!1DE$yv;_TeGl2O+Od6O11o?u)PZ?=d+3LWb3d+gJt;vmNVv9*}H_1ih zRI;Yavsv?$f&!&?+>0xX%Ko3)hblw>Gl!)@&6#}CV|Q>$6SDg`5E-JUbNdO!4BzmA`vWh zpFX)H=X3p|;rfIP4kk~X7IVgqw-pq~-Sv28pO{?dqRMu@cnELA%N)}CCLCs05yE1O zL(PP}PB{nIBWa2U{lKdB>7&dURlZBWGv~fvP*Cih+Vyf}p=DTj%xcUTQ2ou5^J!H( z=If?kdunu0a&mKx@2w85ETvbLpbQf~`*j5ubC2u?FLIMm+rJzn1mn=Lj%W5LYZcGY z?%lhm@l9ok79sf5R`@ccJnm6xq;fUm-xO!+?aUs+)?Uvs1@w_dTa5RRGB z>>lP|dw`Z3?T*F&;p@u-q0ayRwTf+X)YdxEpxSPt+_zSxQgn%2lZ50-$T?&yDrJ;% zA6JdCMP3s=KRMwmb>bqyp<$dVChbm%aW#tnw z8SxfZ(0fzcOc!~sZi#Q`g)pe`DHDp1hvGsN{gTI3Gv2Jk#Q)OrjA7ex%L_}-3InGS zFZy_D@(;Z*YGw59swiI^FXXwTr?(50->Qv_TZ*T7L#{WypmbPTj^$DH;J0+7)6K=s zh&ijp%5{gSLyc6JPO8>hy89ci%7yY?y7biA>&WaDn=_ks;T7C6S2)bbux;%e)5EIA z6zDA>?#w&3hV;7PhTstH>s^_5@n7%kdN(eUARWiod0uPrFF_MQuNs{Z@xkY}1s>=L z-3=&3go^(P&kPseogAr!wp$8eWJLP+l!0m zkBi}G=XhLN>bL}p?JK%`#mzw%d^z$P%|Jbj2#k;_NqfV z59jXbs(;Y7KqU5E3h-6a0`S%Dx_cCpylZV!E~uEDYKTtbY}AU4Ncs+xYeAGH%?fbt zJZJwzK}aWuErKzpd9c9Zs29HUJ`SV4K2-zaTy7LTd~CMc+R#wAQo*5^V=E-L$GI7Y z1T4Ws7dxvdxabO6*BkiJKWfof=m0TDk*CV zHx0^le4RXz0V|%fI~fc9tc7+MBC0U!i2xLnp_DDY(}^RjCfYzyYToqp^sYO!uUPWU z5b}2~+r&*nu9e-P6Qxdpp+ZUF)%+UZSWs1tP%wym9XbXZ)Df!m6@&jgn!iE;A(*Vm zg-MsH6%3+%RdL~87Z!);ZLTYz+VlYT2kVMs@O+IiQ5DVEDzQAKJKA2(=%F~3)UO=- zEl^%#rq&moj20y7XTy)2QQwteW!aooM(a*u#r3Vwu}WJru1R^B+A``rX^&P@I_%$B zYteqwbOLT}Eqx1BSo6-T_AclNvk@N!j4%5hxOR6e_-=`BQ&V46I4q)f?b=mvpKKiY zFH$@R@O1+O?Rx&9;FtH5JSL%YJKF0Z%A-5m9YC@xWBA$D;rP0b2tf_QhrQ}uVWGZ~ z8J7KQbNbx&;iE?y*}XDaXBR$tioL%9a!t3E^sg4Rt<$ImtWc)sEFVW%H~$2z|6JzO z$&(Xj!iUW*6_+9lL+$;+;tI>Jxgsg3-3NO1xvXokkAs5)r7)yE z46K-!VrY=XO=wG=I!g)Dx;FL7&`?7ygWGsNtVu?2h&9>AOm~NVGJk-Wq2T<yiT}6}m=~$3$w8gXSffmfGE-RUagd2vu^JtmG0YeXnPbv!k1$On zj$siFJPXPX^c7Wkp~RUBm)%Qi@Te~FK#-uxo~34p5h^ABDe{l)*GBKIok^4BwLlTF z3OR1k*zq}LQECxR=!lD-8F$vx|M&~qjWAihZOZy$ujt4Lg9l_|GrRU)-v+kj^FC{6 z7<6}eZc4$ved0I5Dye5~&6axrBkN8zv`qCHDs^AiDfJ;V0K!-ZzSbQ;RjW$&e@ETY z94R!)=7bVnL5j^WCBQK;Ztv3=#|;fPLhKNPC$9Ro%|q7zaJ_RV}vf7RcK2-<=q|O&$Me$@DSmi3ge>Pq{inO{|;Df9dz`DFOPHj9W%{`X$K00O< z%^x|@)xrN`nVUsLJBy`ii4_wIzqz3FcKu^~fABdqQg%Oh^`UzK2jE$C<^!tX`v2Jc zA9&dN?8Wc|$9Qa7>NRWl`buo~e|)_W)E3NIlW)-NRnye;yKaX6|Ni*F0Jr4`qpC14 zG2%blp7TjqtlVV+&LfJr}G=)mJg0 z4}iyCSV2E5%!_fwxRgsLn7!k; zNg#V^hK9>tkqdtKw5zo>2z3I=&u%(mNGZ{Z>A{j&7+;VN5wJtbp+*bfP>UgT!uD-J zF-Pn`n<=E3zD`O?GJ&FbAL48YDA+{S)P!+KHZn0OA72RLxz*a=D0zPlwvb=QeE@4f z6g*zD1a?Sz9fEHkS@35zvg}~|m0vnE!4(>aWXj%IHKk3RXfz)=9P;`o0%obk;}p~KM_*O?eDkw) z1FkXNU$`ZdXZ1%5{dAT`oS8O6tEE9LrWHQ=&=@pa*~bAW4~oc0giy6G52gtub4r->EiVbkaLLz6_*s9G6OqgN4a;N2WHf;a`oKS4C4-S{ST zT&~}2XuL3R_#8V<*6vGL=xJ0~7^ZXi9)&YS7Uwpzl|Q_tq^xB}N8WU^tF?%XyU~`K z1Sn@mC5ZMo&X-i#>u}TL-JoeitH&jQwmA@nCqJZ5BsfE!09CM{BjeLq+vTS}Jzt-$ z5^5j=1BING5)Zlhnz`Ske%5VNZ$x4bRi~Itk211(`Yz4s`*LOAa84DPKS6v6=Ryj9 z4DM=O&=d-e%mGf5tv&+E&l$EownUfPvwaMKORnH;Ms3{imc_l;ixFv~-x;;XUHj`xLC09ZYNGZrb?Z zrHErg;5cjfE}YFXwsd2X+pakpQgAJn{>+%de}7N3X2HfqGGRZa3VXrrwpPQ7gGh)lFkJh+l}XOPG(c*VLfU#kf3eK7E*Fyz~(QZ$?5 zx6F@HS{;SKvYb~Xg{o}WdOSEhz}H!bcLwWOx!q>JT~BvD;E}t}9asflVnK{Jo3E7+ z;H$|^8zv!9z-YWJP}-ywoUW;W<<`Mep0 za)d#j&-RT@F@P&EP7FW~Z}a|ZorUZ|R4sms>q)Xbnqh(`INgNFI{Et0QP-ZEusl)3 zNX%S@$vy8B6crWaR$~`Fx&uf?1ID19vH)W@?8;z{MV!x4A3eSAS{a}eQwsf+fUcR$ z@yrIkXb8OU`HrkGEm~LzqgqHc6bE>&rgQ$3d?xsZ@8;5MHSDKU^b)Wd2M;zE1NMyC zR2X?5w32tvK4bc*^lGA!cyiu0fj$OU;vS|;C?*lNOe`XvMTYO#`YBFN1GaQyWBPHd zQpqxcIORoHo=BjH%S8BF? zOqkk=!CN_|xg}6bp7i#|`;FvcX|bc~$#Y$V@_hHd)(E?G+vX#lHzl_Ss|f+YRfhS= zL@Se0|GgT_iD(1gfsLqwMgkHgM-5)}-uixGVd-76M*7@|RKW6@ix;5A zRt~MzlSz9lV#hir<7+3*%lsn9yfmVG9kC$l;lE3tfuPah%$z^V$&?i{&${c?^w9-X zE5o+T^b2Kz{>oc!Wj?Uy651Q*Rug+K^!1T_0&)?TB@=i|a)oZ36y_AghUcx_qBx}h5DM$~J`ED|<6z`oI(V{g1~s$gU;9GPQ~ue* z7&jY7aVSA=K8BeNM#p*y`}o$$7d}{^B*CqpqrvUs&cx!d)gESq(rHOZ^o zygi(kX61>NK`5I*H!+{BI`pW9URyxnxYh&hdno(McE-I+CM4Uw(&aN)@ALSD+!xKG z-uO%xfLpBZVP*wsIM|rd%{w8aRGnhk`p?^<7FdAVq&_P`^14U1Vu#mYGRU3}ZI)F- z4Q_XjEG#2t0A+t8v43g;)65igHUPYQXM3Lsd3jcAvSyoi_n z=5+?m?=fITCp}}0y;n6NN@`l9r@P>y(>(-FtFb4Z={r4dOpnvY8BJ$fk(6UBM4mEZ zrw>FY3O|#l00t1oX~aXZOnIxOO)k~8uW8+d-|aTA6-;XCIJUxf0oM|vIH($qW_w7~ z^q0HE&rtBVt5XDUPYfQCxrDZTqny18c(8FFa{eis7EgS)o4eC5rrhF$KXhF zmY?e!skyU0&ojY>m>jV|4Q{&W8108xNBk3;;UCyt69r~&% z(hyv4cA}K_XQ*2dYtb`Tw8kR?lJxH=$rx4h5Dg0#N%MIopt#>4(%ne&i;?y5tfkR{ zbOTB&7Ds`3s)KdRXMsJrP$CPHee_sxz>e?u>%0phAPi?3#R16QCtM{l+vh?ybvd^V9eC}I()OVGkIz2mK3$!}FIW*bh6FzU9 zBREy(OC6XHKgv-`&?TsvWRJ&6yckkk1!>JXmmY^q@3yyH;tR-x7<_aqoP128u&q47 zX<|FCjlIB-tsZx${4uP3Od?(jCg$3-CvRo?HjX;f?-O`Es^sx;_Gy6cXtXl;m2>IN zlg3J>^v>79L3J6YWC9DJuU4%+u^GQn9-S37Rqf$FNyxM&g+_yy^Y#Ydl~OD%Nb zPa0X=D`+%Q0xDqv*ENN@?G=?a1xq6-KMDL=KPrP#8z?>xq=#|Ml_Bo+1HqOJ&;uBv z@Z{Y+@UpV1Ap2W1!uMwPgWSQ*`LXP5+?aj(1^c(&Xba)_$;aSjor9G6H?PjOIBk9+ zFGqkHsbTJ0Pt=+a3)30jS=YI|jKNk)v$lKkpM zeh;Xi0Y)!$a_#ES*2JKvb0%l`8;emj;3zi6o94od$tzl;#TUJWT{gdN=-tIH;o4|~ z19r|@l1reS#21^{$~9Q1c+PjS zWqpc@F)~Q6C)=jHIW&(p*PuN3Fhs#c5}Ewr=yt3y#nC}B;Y7rklZAi=#>vg;bVt25 z^DTP$nmy#e<4nW$uN5Z@ov7#pBCS;0k2P;YE_H+;i+ZuX)8Nb|VZ4IFMUGT1 zAlInr3!|(I#tFEHiiwTw-kGtg<2)oAM-JclUD_mAA+)clNljp=#a14#P=vhxg}D@l z=`rg^GEa1=_f2d(>eQ=b?xc>WA^G(o_KF2gV5}BJI}E%&ol|XhlM6NAE*^=d<80O1 zhfYw+9W6#Ql^#w;1T29&tky1dfi$YbaBo&i8=OqBkf@>HSWFZ)3ixHIvhpxK+N@qU zVu+`9db>n(QBP?5xYFEj2hum`@pp*#kyQ zTuEbY{9IZHaR`FOEf$jT7TrnqdjY4nRr z)|j+I*`F=b3{9ZiU0tgJr|yz;arPHcnC&{N>SRES#>NnLaY%owl&0Z4j=%DnVm)6j z=+jZ5>V)N{IiZ)n!hG%lAOVa=Uw)AKZt0{M1&1U{sU#% z&BM&W#9l<}Hjf@tA|(A~>N?f~tgq7O)zCdj`n8p$Le3unVh?f^mz%`J)38%zg>gc851^>d|G+#i>VBk19CBS$Lj|&IIQe0*TpWC%xuv z*1-Qc?3*g5Ai-jT59Os;UXZ5#Zuyk9T`aFa|&^YLZQo6V|-gKSLvDPva{3008ZX>9kVx0ICxijYf{|7$dvH6z2iF*Og8 zKsviH?PGF`SKRXw-fE#j+wYvk?t`XuRnoQ9c7-uK^y#9=Oj=+#&rF>CfHqSPO+O1f zFD6!_v=BjcqC=YE-Fcvl%0m6`OHSh5#g>IYa>g z*{y5JEpjSvCV*(zmms@3XXn|z<(FiSBIrR&NGM8=3GkgoRm7Z|a;;`qLP*b$aPB*e z3FfdUHgBnVsc){>oOvuSv4r=xSV>nulR5WrOqe zb}2mU4mVbw`6rLb3B(od z0pqTA?3Gcv)q5K2M}0Lq72`AN24=V3@f`0=if0OQdx-L78z1<~;Q?s%+ewfPEv9-rzF|@ z(lzgMAcvY~8P1S!SHrtg1Ai1u`}MptF^r3~(D^vpjd8vG!2)q?N|XM&j_91;E!0H7 z^%pMvvPN&-)}%(833pWXB?dD5Lxbxyo7ahF0FW$r5`lJ-EC?i%tWIT&P^_J_^pN#| zXzCLOle7Sdw+YA~kr4cHHzGp1nlq1G7wVUnAn`JH2!dIu;Ai`crcQ?s7gR_sNV}lQ zw*Ql5=7`H?NW8*WwXT~uBqxQkA0gMGnKy_SEDT}{Q7D6Wp^D-Ny4Vo~^6yB5B_ngu z9PQz1>0OAzI%)o^F<4|ouSeQ_xaND;lMFQ>q#g=skjsV=(YvRwUUwVcj5g#&Go2ab z2*TaXw2y7R`rt6KkXXSHOPu^#6a$;^hkJuOOksDU7cTYLGqhL{?*m4HC#{a*sn>J0b2 zjXg5_Ok~hbh(fk}os&hoiaArGjG>f49uDx`%ir8=dsvCmCk4sV#LNRFJNcbkc6=R- zHnZzlT=c}xcY=#REN2F3QeVLHNZ!$Lp|eSwDFZr=2=_clj^Kv$6-j@9*~rJFBUkkB z2Y$LX(-Le`x0S?=nys)|s9ot|rqybMCPYVHLtTHr%GJL4+3&@)vg0!I$17%xN(X-H zw9-kXJ?0_(@(Y+D#Q$`MR)0t?F`&4MISraPnsKi9LxoZK%(D;$xJRW+LbMTXW@soQ zDAz5KaI?!!@F96jn(f)hZW_N$YawI&Mhj7wU<~JqJ98U>~4;q`?|{l+5!nRte_f zT0VZ|jUT4w0({4jPM{M1T!^+QehVeUc6M!s*W*9T2vYpJZPAsXJfG~ELWbz6(Um#0U^UjcRtOxd?2b5KI67BI?k{2>8P_C5otMQBz3|~V-D3F=NTVZv~CZ-ceA9r-y>-# zO(>%#$~cy=pfY4}Vx0g?*Urqd`1+^tyYy2!Bh;c=7spfyo*AUxu1;+!277?$3p{=O zWW--i8O!y3OZ8E;@9=pka06Jkq;5+{str$Gg)xhOEPH(Gd?5){O==V&BzowNmQ(n_ zv-P(EM`9IbcE0Vck*$`q&sK==yj^r>8%v>fBSayE$_TR<$^y89cNqU!erbl6B$_3b zJn3U_d!Us)_o1V%lN0np#ovNH2171g!ZEbBzR!0F86RHKmn{73bpmmsnCfbP zGjcKCD=wk0G1r=(8Rds=4qi2|Tnt&UW<$|vY(j`((V&y}s5oSW;O>#RZv4x!^mA21eDd<@ z@XesllSY`nxM?xm0lC*|{dYFnXrldKn7u>E@?U~}U+V}VSS8afg>&GJ&gB=Br4Kg7 zM>|85LD}yt(0R`8c?8cK>4-2Xceus&3I*mg7@d+rI&TVi!zn| zd|8gs7L z&3$PzIQQN`Hl>*I=1XsB9WkIE5)t4(8TOBO`TFek=iF%r}WMN zg04o*-twZv(VO$r3vh`ULR2cC`aJV97<65)cN>8k_a0fpmrI2B+9K65q2*?B#|uRceo%ra`*3`D z>9!?~HNvS^(0=+&kL2AL{uFhn=`z(6H)kqWfnQY6gaW#TbT6>8JuVDiB)Ke?&=Nbf zFtkgnXb!FnQmsxEB);&XKOB=E>w=767moqSyw&ci2N-wvZW$x*2s^r8^TM;<`_Uy- z`sJs+BvnQ!qF+woCwrdqM3T%WbFpE}SQ0AV#XJM4(3%6hX@48z&3zlrgV#F%9Mdl zqpkX&Xu3z~AgWW3goV0v4H?oAvFZ6obL^~gTp#b2>)OPG9c2}&8cKFowR~u^ZlcSb znRD?ArOAWYX8}Bd4rz@-xZIn39i|`cvxH3ZL>0&!B{jw{)3BHcE272eCw@YtYrm1U zueBj4V%Ir)R*0#J@0&xCc}{3OBb#GDK1i7-j80f7;YI>akek&yTh^V7)@r0)4so+% z;OK90(M3akrRa=z*f_wkku%zMbxMwO8Ulu3z z6JSIkGoIm=x*r!U<90t798|rPw6b1!qjDN|i;c$b1il#Ww%>OsdL`u0|5GvGR^m=BO@ah^Sl#q$zFWB9}Gl7rtZRu z4nm4;Ws$h_CEPyTkx3%|>E%>9=)8htU&VnhT~PY^-v^-lu{%ksmNb%8BpB&Zu?m(QtBCA{OOc><2D7Z*>QLFF zC}`LJYz!)iWIn{sHx%>!^O)*fx&IkuAz#IeRV(TEzZcixuu}NptYj<4&f>qqaXgkL zQ3(mHrE;tH=I+Tf-(MwnaqeLd65B;0pt&@Vzn(UE|$Bf zy-)jbSM@nJC%bqdvx<@H`s-hXm`D=!Z`N@L&yngA8_8uIKq`jJbU7@viVJFD*pW5z z%Rq3rxP;QAYIzCE?^F`fQ^yrx346W|mHytNaaL+-^#_M})3C5GBAm)fO9WEpiezN| z+0mh$J9qj)t!PPw!@M=TaNqxWVQ7w&me5F!5|+*WpK(9LHtHzt{JG7|;)8#fVRdoRa)Wq+TEoaCaSRbIb^_cy=)v{t~;0X4U2k8D?HAx=fHq zJ3dIF4Py_^hg!A5`|Cfl$e78+@XTLwJ4)C!pWhyz$^~148Xx@N5skl}n#xqo;0}bE zKenm=CT7}3&0^xUIZIgC;AJRS`m*w2c!;;cWq`3#w#bA2&tq_HfsV{vBG@Iz&A%@U z`HNG!C4UkrOO+7wTOaZp1xvp5SHur{%{sGj<3&s4*6PuMcLdM>;FRKM}G z7SxCf2E%huO8DIwWt};4CKffaw;&n2HiRr9#dc$~vw&Gqq?cX-B+PL z{MOFLtoGY;NCj&Kc7xJgt7_Xp)l1iZRCjeyBph)^5E3u?nZ@QJ~Pyxbjv5MU*M`G?tFNY!$ar+&!|E2whk%V)FarS0Rm z!;gsNW7!*RvlCzK&R5R<*z3Kb|2>fr_*R#!eHo&{LkmOtIm+J+>il+{(${yADB!-m=SOV< z)v1CR49m#8cp<_8_5YIk&*vuyD245C26u&r{Y8i2h9G* z+b-24VrQglZQd2|Hu=`r(SQ@ImJXDy4%1$bMQ@odc2HV7x zJ-6HmrsyvhRK*HUodm(*ZN-NfD1}HD5GJ<}RxR)NfoviN5gQ9h9)rk~a;1#h93GZy z^H)Kgl`xnRz(*`px@-IY$XJ0j&{w7iVkTXuR-O$pbKHOlhm=Bx&TNwS86Qz{A>Cx| zO`*V;L`zFc@;~|~?pIbB-}^66WHo2m?&54{h}%dw#8F&Qe?nibIoawHs$ay_&Wx9e zog)*pl#uipveOrPmWj&H#&zp2w?6zVRBDYv(cHsA0UJ&?U+`N8Y7g(hF}KS8nk2nHz5_ zse(-#7dZ7;HLtx_cYH0P%%1QRrBIy*76G$`=iHf1GJLs@s8fp(mF`VXIaGQ{mr2)c z#fO)CK$}QBAm3uTK%)@F6K>~F3K|;ABgG!ap1iguMU&=Vygw490FK49k1Jj2I=$ff z(!v3*+jhWuSZHPx8`+$IB};Nr>_QhY4m4c9v8zFx(I!Cii-4B7x1{-irTZ@Y(7_l3 z1;{NGCkKb44r~M<755NoMs(p<#t-8&xJvWWN9G)n%uhkHuc)JI$6I9o2mu} zR3i=8sl=?q;DgL(V&$~>@o|PODC8+`Z~C7j+J4urjgN62gf#ZT_!R$aFx)~b{?2w% zjQ^N(8IkTU4AV4)>>J=$ETVzU64oYc^}k{U&7AL(Ov}9IoPa_1)$MnJnz?SxjJy0C zdli0~zAjC({bXAYlr07|uxpm#Jf8PJA7>&gm&iHT45`{}b$XN(#v}MDr}N18GTiXm zflh2Hgq7CBK&$6jxKxEc$n68{6RijN%l*`#*M?Kexb4I_Q+AhWd_41ntE4}|3gQGf z`=&C4)oamyX-=*eyl2^29Qzky9AyLleGVv<=_oKnNH<-$!#;(nXSmkbFlH&(-~rXK z3!FqOfaE+Skw{`dAs`eUx&XMi+@J%nPex6~kmccma(KYz2l(^Y9yp)^Mcx^A-YVp0 z4&7{TBS(s*P5L$gwTs?p=85sWWKOvErWyfmEnf zWbff0#y%p0l!?6V_i+_T2%Kf}VjT2EDl~|J1v_NM8_bEPIzEhBeZJ|A7Q`p}qY-oN zBF)9cSM26Rmkq_qvA<^y@(r5Z*|q(&v)cBI+f^JjOT9(+q(&B(d^j+^5s^5)V&I*g z58BKi_QzQENCiAdj#8b76I+U0q@}{y1b+_N?e)122lmdrL}ZSqQ@Wr#M;H2`WRUND zi7-iTzW@&^)(K6C!;SZ4vvt9oAZ2U=5{qm);$o<*kMRfnDtO<171yQHJ%H=axD&91 zV{`5jGzUO??p?POx)Rl#<#?E2>pjO+HxG|RA?%}uztM1DVa?i`k%n6iCdNz!iQ@=)XCMa zPc0M(Kg(I@t8uH=eFyztl*_Ugn&Z?{ybBHn`bt2VWr4N)47bX^*9kJcpypMrDlhBl z%IRESRe4Wi@NY}VOdF&b9$6gEN2K}26V7J`ay}wQhh?;sm?N^3rH^a}L0T%0L(iZ# z|NB#Lx6|exR7HeMtxreenD;o!SC9Q^S!h>373rQ2ym#D;x0b_uAiUnype>z)JZjLJ z5n1MoLAug{rrqraRE<}BFi>N1pvJI#+_c6@MCDZcZvLcvVyS!4jYN+dH2Lm#Nl76B z&Ju37Y@Gn?>M>*j z)@et5z*1{#Ys6r57W2#EBD`xE3cUuQlS8RaP6h>@sA|StX^zi0W;KUyz`n&=djwh$ zwGf~2Cob(wqztVf4z!tt>(}!4Q>CP&n44HEg5&QD^-qHPYiD%(eOauxM7fN+7NOAh zx6r07E^-o9R(ajQ9+4D;t1S*{XlTTXW;vflpc&LO_k%XaUF5WNWeASaDUhYgDircQ z!WIcxu5sMc#-H&8RIeHT&7e=UGmT+0lAH+8)2tw%7ZsprBcoqMgxeZNY;hMy-uB>9JOazch5WBB98 zkCTHYV+tG_!u4@^*xbVjF&$->e&Sc z#c>)~WLxfq_)7+(^ZZ-_LdT@*4VwIeGV$z6ue%l;3Fgb9D;K=<>W1#O zSEMKN2%|b2Z|OnjGkc){YHq_c6FyuvRj%}Td0X9HLP?JF@?N$Cid>p=aVja^N1n=H z<@lc}g$KP46-1=NB`^JKDF6UzXNn;mJQu^Y_+39qup4_^q^ZGd6?f_VqmU5IG-fT+ z&P5GQ<-w^!hh@D144kbu5-pX3z1mf`o03tWwJ+nYAICz%LQK1<)iS26KDb54>reY3 zOB)Ad=I%tP+RPx@mGR0#A^J*dJM6VWfIW0AE=sAe|jZL~iK|vCuvH7ZMzz zfszp_$gXYAG%c7~JFSVl6Vf7r)t0`So01P<%+@XM{#)gIpe_MHyb-=_0#`+KkH8?g zJbu5W1mO?dO6?6GqGScsw&V6@tO57#2!uTl?Kf7OoKb_0MMiaAQzM&f@R{ek>RdbN zYR)jrvu6+t(k%-)=&AEW4s5n2p_PbPEzHen@4KWA%1a+Y{Edk7bR$Y20xW{xawnp} zv@`cS7}x;kB~!PJlH%iJw(hnhd%a)$5bI9BSGFyn#I$~O=HYCtA-7w>=c*7JN!DF#lRy|&GJ{ubk zEkO}&<{7k-FMqDvUjp4Dc(5paTaP#YVG6;ST5?j7pXzdLz|sQw=)h)x4Y*Q9L%h~; zq%r;gQ%v+0bar}Vl{P}yGZjr;c!I_aK+R)2|*TGS(91nCW;C)+guIhs;|!z z{g2sKv^AQNVV08psRIA`Oo;q`Pr*f-Akp9e?%ArV5t={c?|!guP$j3hWza-K-r8v% zAP%(Y4l(#Pe5FK?)eyF2zECKz3S0+bh31R>B`}a_@ctGgh&;YLL#clB(@L{((zyXZfQc*`pCHSPHsgl*o%q5Ivf*T&pTanp zh0z4>uiS)ukW_;yKDdr?!NtLSGmccwlcC z`m6|n*5PtQoc&Covq(rp%5OlIga5#Tyte@)t?PZdxZaHoaje2#KV#su40h}CsuUJfu|n`h97Q!7r78D3)i~4S8I3Z<*NpyPm~mE;1~E z6M*pFKP%!5;mAv=T1w#TPzvszy=CN6&Su4)TJ#%9$oOvvNkBg!UuybSPpl%h*QGa) z9z8-q2^8+m>|jbkWuB}9rziT>qf~5!^VKbCI8AmvJNNDCe{ff_AlIz}{dN;Cz-95b z%#SqL06Sfwc=1^YIfJ()R{)cd;3>wp?fbLkON1Wtvf7;3UtFs$oY`b=3SPU52Hz`a zYiHaGP=7xX33}TG{Agk!is#us4fdCy2r#f=C2Dm3MXsu~h@|diCRni-Y^UaBq=mWh zhXsPRM5mM})@?L3G&KLhZ{Gw!HWlUUpE~Oa46%mM%tZI;D&Ycstz~KyQjy*c4S<^? z=2q|-Hh1t11-x)!BNc=X8-0*EV4lPrKuX5e6DqR4-7P?^mOo5#%m-J*6dCONmN|n$ z8vGu3*l7&!F(4Ti?CH5)!9TrKxN?QVkz?PDl=_(yY46X&O++ReHA!3+hP^1Z+z=Q- zrctybg`YS1>Lg}DgWd@!f4S8Tm?GCW&EH+W!ufMU?jDWaTa!Gh(NJp&7dV1T z9FLwWG#koHl}h{hU3F&UZ?QV?n(Z+6(yujt1Ue!w5?T5-yfaA8*XVv{+@9qxyju4J zizHW2br9-ur^k-QO}i7)%}eH2xoCXF0S>~15?nUcT7v_+7RiY}B)&*MKvj@2w)T)~ zN)Sy$iZs$GF!|Z#V<~(9sW2?HySM_pgGd%%+6|`V(j#}D>N)KagybPW@*8k*c#pnF zuPCN~^3_u864WF3Cu@B<(DmmZj_KCX;w27H3i9&OuaJLgRn_>dh5|EcUEXM3sabE@ zx@Ywaz%Ii-V{4d(_54MotmTI`{ub3Z-)rIwBG{QTwN(e{0HMHiSjsME1_ zG{0q%WD>9hvLYl7Q>;`Xj4$6;K97dMwzJ`;a#0T*Q(Lr|02cEuIQ6Fhb@n8g%M~X; zg7|fGb@5H`fjKG~rwribRgM_0-TL1?GjMp6@NiVOo;+Cn$n-<|nm2~2ztza()*UR` zGhRClGneyECH_Rq#4%MJ?CsZibXW!{e=%q`he@Fo$P7T3T%Tk2;^6w4?d(q~rXlCD z{#|~)z`8%b*cspyEY-Dz|2~{p2w!L~T_;xeVPmqb@cV7Z+^yT%ei@qlnbuzsgnvPM ze(3huR|B=8TUpc=gCGRcV{c7?6F3?D;Lusej0=4`JpO%ft>3EQ=;)}&w^d658_woRS%I_$=rLMoHu&nii8-|_Ph8%2JD*aaA8^~SV|NHh}o z^NUP8lZ20ni4o49TlHN1C-xjFE-piB>e%PoFJ~vY=XDJfW8yX}m)wJ`?rYVN^oN3p zI{>Q!RT==B6I}Lii^@UaPl({;7wUaSu+tGhunf`Fe=+jWsxtv=H}2#^KH~fLM|5BK z?hNy)nH?Opn>u{QBvJe)TE4>Z)Qu;-cHM)b(~ET9ll?>8Z4b4_~#c&Jag=0 zeSJMQaNgMF02%h|f?MKSRY&(ft+z?;lsNP`XBV~9%T(fdfnBS%g}j2o@X?P3(efXK zBKW^!X7?lOSDWfGE9P}<4@QAEs4!Om3ni~EpFk!KaC!5cTC*w6N5Z|K!gU)qcaG~? zz)^uA2@LhK8N1N4YanN9s4km+4#tS|In`V_sKxi^mvv!lKDqGy!u>}5@6{zHCR*P+ zTBSSsMdh>L>x~X7+UZR-0ZV8Wod7R`dFcOn+5Q@vTwR_+vb96EZk!YeTy}unYJTdf zUw8zZ^85naB8o(RyfP19-q-G%2to_PMDACpL;eN-NX#}^br=8=8rIAJ@`H?nOXv6W znO%KIc5kGbn7xIB;n3au{aoh-tYOrhE{Hc5SK>Kxz!JjHc(rf%}v>sJ3@JHMepFN@H@2L%rZwyMQvu2sRY;F;GCPYJ=>9yWVf1A=CsRS zz1l9EYMXn})NGSdoj=Ub`Oj*?fIf4LHo1hTZUeu#k5>fV0S#vUM*0=Z6R+`y)>cav zb9vBR_o2uJKq@TAe-L4ywJdLT_sbD}I;A z+}iH{%Xq)u&pO>O)Mo;zb z(rU2DjREmHt?@K3hO!kj2N%~M|+M^K~n0_ouQT8FRG;pSn0_m569C?|Gx6(^+&am61p2kZE@(PN_uIq|0yYcbs z;viNKAA%ACkgvS{vCpq6pe13~7Uk=gG8({F*o;hQ&QIB|BZ+0(kd7?)r1mL5nH6}P z5EE%hE7)fm4iM+Rj#&|U`h_wN`*u-Lay?7c<|BM1i+H&=Mi&QpHVpQ zVEWDCvkNABx&g?m0u=qhCD8bjdw&b~j$bWceg#^$;lOfbj!y1dAYqg1H(9?HKBlg* z_ZX|AnT5@9U$ysC-cPincfNmm>(76#IT%&v*`gFn6=Ze6xy0}KYRw)9bGqf~VP7DV zbwl6G12~~hI@hy5waeYU(_mvR)sMsq4ukHiYuUBr{%+|sNQ`&THzQO3$`-FXI>G9a zxYX$|ubQ;u&ufPy(W>8Z3w1ZxC^FBXuSP`SEi|to0p!fYziFA`=VfJ>7%#2j3Bhb$ zXeVG|oKk^QQYr5H`&t%h3FL887ql+@FmtEr*W=buu24;V{hqvx+x+ zH}2Bk68iBmu^pg@SI;DV&!}xz z?d&e9#?))}lSbQ)(Q-jUzLEZBW!ygkyYn6yohH_KnftYX_`Cv3w*NmbF$A662UdmK zfHj4CnWKTcMC0$5=$$*);`?63{e*1~m{JqWD_U_%gwDomyJ@T0ncJW3?;<13trR|7FYy^8i>T@>- zNiCRdt?XI-u1j$$f7>^`CW6>3B1|FB8PeVPDhv%0se^1^5YcP$9K9C8Ka}mZ_L~cF z6kLe0gO(!mwO0<>@`7!empH=Qv6uKBRy?P(vSKbS^^?)^q*aX)zZm}s^EPiyzCXlq za_CP%u!}2UjHD1Kd=H}E_Nb3nlECK?$b}_iHY_6ZA3>XP2^wh9uGmv`b;bpGq%!h5 zXB)Mg)vm9%?}cGncaQM}%(Zsh?Q~Y! z=icZ)QEEoS2eRVi&jA0i7g3oan7MreqPDS*z4<4ikv^|$jPQXh%Zd+xMY9V*$aMu>*WP-v5Fn-gFayn~)E2@PB`33S5y}JA##0HJ8f}_48->xn2fD$W z4O-0uZSqfBe8!61Y|bFikls46cd?yBh$ZaHsf zp_Ui?^0#QeY5A*VL%==$F>{ZeXTM|=4?^v5II>U#c;p)6=8-ief|`q$QZZ@efQQZp z9ylFwxlTQ!fsU^sdH|+`d8$5o78xUsYB6_*IUy7L7!ok23g)_U_p)LyQGV z<3sKpk+B{~{0)Eh;Rg|@0ljI~*}%CI4E6{BRa#{)S39AXKIh-e=fx)6Tp)nwak~0LV_F*h(iSrw{@W zYP2ih27Ndk2LsMG9GibmcdCb3bkq5`@zl3xhc%;eG}HNqkan-uY4ihdOWaZ&>x}Tk zKh{ZaavnvdEvDQ^n0h*A>X5zWT>JLR+mSeG&1cDEujTYy2Y>q^tyekAld4=z$}3LK znCszD*5G#BLBeX9-_S_DCiPS+=?m$eb|p_M&kO>NoGLIMq8Q5Rq4-6lo;x{71WIaT z@;~axpUYC+`}$2{}b2Jju%SO0f;d5%KnyuEUSH8gjs&W+dUf*3(}RZrDz>$6ww2+cGv z5v!>MM3dc0CrqzV?Nb`%@EK|VHC~F*mF#n0JLFRxC1)GR&BIsYXbYOMG8Us4>I~Hq zeV~M4>;iEfJe~!~pF={UPL51?U96A^vwrN8YGH3rj{fXD+nLX``O%oq^-FHu{!=8= zwv(@=5e%~{(Q~m`PiFYj+)2muUC!mSk?tF9XHGA?l33pDcXJwA zVs07#x!=7RI(*1LiR0&FwC5@w2nD1_Fs*($Mjx^!q0Ft0vk(tl$b)obCJt(DEkg-Tu%vIVHrstq1P~A~g59 z87i2g0K3k?Y9DABCzQNE_p3kl{3q-$?H}_1W61|FzP11-xl*OiAoSu0#^MJ2;Ll$E{wQz2y~QX@dbQD%8_Z*I(kX_4k)@AN#Fq6j@qQ4f7$cPW3&W3aGE ziQf_;N*@H)-GpLTWIm`A!cy$e7OY`mVX?U0m`9bv`pIt38rJym@Wtrer(_emZhS6o zmi-CV>ESPK%hO+yJSpHU_c>BT;~_jfyX<&9A80{7Bi&lx8qR&&m?FiX=kfklH3B!! z;+G=5+}yM4)&xrye()5&umclrj0G7=T6cupTy{?aH6-hX?`UU1AGj0m_V+8dvtXa4 z`mg*hI{|UF4PMtUmr*hso9iY`wQ~mOW7u%m{)}-(%zF1xH>XT#xhXY+&k2 z*Jh%VZ(ydXEANJ(xShR@EU>I)OSiC{mj1hHWBYx@r>|4=mrmidHq8{TbXsZk9(C^s zEQ_y@-^j-+NUXbsv|$lPOpVVu=;6O?zx1VU=QRmXYG$D~DGFJ9Yyv+^!Q*AWK4qcJ zSu>2?!DqM#PW&ARutuDjmMt3n86vrbbIZP$4l+?SsU4DEwKyiZS}2~*VBu^aU>sxu ztad$x^75r)c{y+2Y3M828<$3VyR!*hA7pw0mIOFsCmjTO&VsHw|Gz0z)#ORq2 z<~;uW6y;z(U`rX@9_`#b5 zw+C$`vaWNE>*^)7s^PVfyEPgo_f^s5mpH;5*oNa)yPfNTEkd^97yMr~{94R6h&XWz z4rfRg`puoySap>@-9RJ)TqsymmgiHnpo;rYb_;PO+jm&Z`m$=&$^NC9P@J|cxXc#q-096Jk@jLP$Lx~NR`nF>OH485`U zc?IA2hznf&u=1B#CcU$s$U3dtRCxT*FVe}^``Bm8=bd{ZN?yI`e7Zr}!|=%4$Y0~{ zZmu{NwWv?Xfy0n39sMLLPH>b#$GkApkmBi-!&NLeSPF2kxb{CyE4DTS^mVj6@-`Elh&Hy= zqzFIHMD=+$Ehxk*PJUFZ691w+Pm7xBZa$eaRgN;FM+(M=-nD{OeX65HS$$;zQQoTZ32Cp1Sq)#19ciz(0pbJmNWs!A}ZhN>vF4aHkR&1A=%rRuTkR`2k zmC5LHlJ>qh&0ISx#WsDo!@O~NA7Qcq(m^PaV==2malrW#b74*5_ojEw`iGi- z=?MOIA%06j*akHx6>pIUDw<@`@6UVPaor+B^Vn;mE!;HTYI5zfQ4(d?YgdKoO|B8!v8HkUrr44IrYwrrKj)2 zc=#AT+x<*Qx4=^Fn`HpOw2EJ4Mvgk~IX3fqEk@2kfOE&;%NGSUaSd$Z$Oq4YFjFj8 z&3S+Jq1;X4mrYeyEoF%RxKg{F@=AF7Olh43?zxK6E8gpA(MDR@I(c(hBSgw8_Gv2I z0+nov+L+bc;P#-31%+|^_vyKXak_le%Qn%7#2o%=QL>ecmc3a?Rks=AQlUIU2;+rD%`uRX4N+|1Xzm_fcP(|;Ld9gJU{y8JT zPST~u9`V0DdS`5mrbVV$_${ZU|4AJDfj%}#!gcN3v>nDK)&t;wZ~qXrVw zmz^P&84m`11kBCz1a*Sb}CmJJ3lvZpyt@_ptgFpShNbgbg=Z~8Xo@c z5-wT_b^B)#$tR1!HESo^wBr^OrQHYXe}UcImZADrH{55QobsL>{RMaJNz)SFox}!P zeP+$?@XLp%N@26sF=u5FmEy-?<&filnKs=ys{Ev<3VL$iRUCqC=NkZ^gNC=JiY7C@ z67ie)gjNgs;=rQbq7f>6eA?WC|9TAomWqZ=8E~PMh$)GivTmP_(q-s1xgQ^x zZ|2h;tw>m_VW!coV%cX_;F=}gou7YI7`IKgsoXdtTh3SqbmXqk_12jgI~0{#$mo*m z1d>W&xRXjZDHiHsE4W(i$Ud*9ifWLHXd~U=IQ^uvLpNXqZ&rJnT4Mc4;3$s&gojVJ zSA~kDK8oxWG&-VE(P{6H^@b9!`Q|FyZ4FJv{4_oc4FrKkvyAS*GTXv@5kg2-e`<5+ znOS)wSQOBtO+dfps*75P75Ef$i6Y$R$9&?8vnaOmn=MTI`Y}Wzs(mx9cnK{M&Fb=@ z-p;|lBF{qIl8`Ne6847*F`aILuDD2NC|n(xk~tv#9L-a$1Jjq~Va%7K=S0ty*(!Z^ zc?>qmmC{m7-3ov=e-ns#BD0Eo${`A-iA{dC0a{W_@6%$F;!Opa{F=^>mj#?j>;V<4 zkPh3EHzThO3>DTTP5dX{R%0}*wuztu4k63d4HOflBS?ksPy&h4)kk-}HRG*)-=s-} zC=MBin})1HH;5m1`21-+lc)Hr^Tn%~!yTm49r!REMVzduMynjz?RLi7Iqi05fM~JI zA>gK5Y%fT85TgBgJez-G5B`iI9NA4YN)}7LP?R03ec!USesgTCvZ;nlPNy3Yblx=j za2MsPIz^Puvu&J}OL~LY0K54$lwP6BPoTdgvDcG^3`y%xBUkz zS`9bXYE&wkJ%*(}=&3j|c79(!8KnN$jJHRWam3`9-E<1Km#=<7X1t(@VQ%6C6)h_@~zA0#TJb5Y1S+O=qS0K*OU` ztb1AJSo`Qke9!txFQw94{rZH>v@!hA)bwSYj+T>-a|O%P_yguLW}VVLh;I&-nX!v~ zUR9>PlW9`C7E3)jsLzBF0YO;gVoxa^mGszg+4!xku>X%h&cSvhGwGwbvUHcmODcv4 z@P)&yt?XR@_HA$^6q+91R-j{67zh)<{@w6yW$u3Z+zAu5FC;vaGPSlp&OGkTaPDbi z;S;}3gx{zNv#5986p**wH+*&Jc}z@_%1aO!6K;5a&)@631w-o=aIDhG``j)%EZK}h!--{(M+#BGxVY0!{9i|FRF+}Cj8^*u_PeI&K(1XS&NI&8ARhI3 z2+~Ci!7`U)k}p0_L$=d1Z7Ix9JVJ72aDDtG3Vv)DQ?BfrkZMjvlhuuLZG|hr8f36` zw}nTG0rn(`57dPY`%lpB3M}XVoycP0=s#ddv8<+hAu@5Xb**>ho0BpQ4 z7e5(7zIE0AKUhr>*Pc zS~F8NsW(kYz5ZEM+ipyW->h#gQ#a+O?k{IWMfason|mEKihA*;Oav83>-qyhMM*^Y_VW0{OE47C&b6wCT%zQ%^mvEpU^H39(i)FSd8xR! znw8!&hlSZL4W98O2?+`8K$^moLW^%YwwQfhs`0FdVMb0ja&YJMnsQ1CYEb0$le0d) zU}%-rJ)8}Jl=5n~N5#8=udh$t(z0a5j(qI6!#>X=qMlmoOW#MwUxL}vg|}HMmf^fl z{UjIV++s!;;l8v;4X>s7U(u?G=My!C>{+rRm2jFX`?@BZc?TPgM}~%_$R^yl)XTdh zK`4Wx`eFOu_dS4X`%)x;FuwE0er)+(qOn?%qCV(5xEh2>e-IN@K*O2bTs)vO#u$SR zCQI%sG?)BS9m?P?q6gR84`2?h=u7ekh%b>wFV_X?jn)}QwZ(}2=O^he_zpOFy!TbM zXvY*@FlNV6Qh(rcBNUFd;$7>Wp!gG^8#L-&kbYVSHJVR8YUiKuIf7#R9z7OO2_55P zEe^&}2K+$>BXmf>DFNGyLx$spg@4vIHHwpzicucz4jhwUkmF`KZ)Apwc1U?STlyOT zcnqt!X_tI`IABN}W8JWBvW5AeuVvmLcBDVN-6b4$2v*y6bAJQ}#C_Ct4$4ysLM|>Y zR<+LJ0jg?M^*RSul$#0;t|TBMR1hKTJn;8KhmAM+PwwxYY@*5SSPF=j^BnEuMJZ-( zT}2g(WY*5RsrN!Xp1|Q!=i3WIG%PMd+9}>f$zK~_oRw75)_N=KP= znhw96L!F0AZpi-y4H7;j*>*p8UaX!Guz3?UwmpB1!Y4j^z+cBl;k>th)#L7{VS zm<;iU*UlrDMlyAyzw{DoV*XO$`Gy2V@?a--kP;Q}A$|LzMJpK8(LLkVyjQDgxRMV7hc!Aeb7`ud7li~hUmK=CRUpwnYt3HkerdN75(?J-w zG*}@yC(BIH2yYY@AA0#r`n6H>NX*<<6-#D|gyg{8OQV+p7XfE_LAau`eo}f-30z_H z{yH77(n`Ho_I8xEv}UnxeU^U4U@?v#?Su@T-o7grtR@f$F8h|$f0vHAw-85N{8@1g zdHk_}@C%pqJ>++yMlGIob1xlZOYXNxstysUoZTlgIW{bhPeFeF&eieO)iu-gdBY`c z>a>+uM{Srs`681$?NY(E_D7D+O+EpwQ z?*4p?WkgRd@49B6WWK~L({sYGSAe2Y@!GdwelTvRgC9mGzrnq1sCKlCl6Ivj(O!ef z*n_TP*$CqrQG_0h$de`+s!yTyT4Zyfl3|tH?eD2&Xs=Td{;)%8vUbLV6N%(T!jcqJ zUmSPpOX;(70xw`HYI4i_OhkC2PN{n3*5w;4(`o(+-2`5%-zdL#stw9+F0$0{d2oVYpT1Wfo6~3>?`{bSH!Z}vHn8`A&eMxS#F|9y{g|jIFm-3!3|@yQgn2wd!e;>Z1?pY`S45r zcgxkzmxj%TdDe5-PCjk_kd*1ejyxISKTn2Bjr8({h%!O>?$G>7vQT*`07dw#tDv?z zj6MJ|E+avOjQn}T0ISD~tMc^P&W@}B6-#_k5iK_-zz=q!XL&tFO#UsG_+83QLRx{C z^2v|ik5yDP(4rv}pIz9Z&OcDgn@tWNMsNvIPEdEp%)(_Uk$JaMZZ;Qj{jw~b*;$Om#?X)MM-a zIx>eM!u@tQ3Es8c--Z=h-b&eHPtc|L!z03b#;NwV_VkqHtCw>o@S6_K>(Y2U71^MA zTFpITpouJSnijeHY^ch`$-wiHw>N7NP6_wwDQR1u7`nZh;ZAI|f3dJ{et02z&XRYO zEcdR19Xqn#bn;KTsacdn2OF~(_;MU>TNS6TI$)Dw^%#dWKCHc07$J6K&=&_~Dxs>T z-$@%8qs;h-IK#+=95MMsJnv%rL>BepxR;_pbvWM{FguGAl(9$B%=xMhMFOqwEB7_(NMboW;WwW{R z+kFB#c0EcY+-4jqNs3X;*HbSLYvVg@e-&ZgJcNxl`q}1C#Nzaww0wg4Ai+1blP=yh z)2IN25H@KDN~hOeyUGk@1c%RR0SM!rn98vMq?%JCjlk_M(zPU+G{+CX2hP=Yb8kbk3xPabR$AuhdD zQ++TJy>Z4}rGN>KBUO>FI$S{B^Xu^32TuITgA)~JyNx~LF8J*sW>da3o2aqwzNj`< zWGNf9wrV)rli1lZ*R7_t;Wejk8F)~LP-`t&ALH#Nqu*dwGuu`EYR8hJDMR^|8}o7}xS{Ya+8t!Tr^-XRFZiP>`2Sc6-5b4&eYFA_Leh5fLU&1@cJw(LAF|DTPFKyyx;$G`=w*L zt_E|+sOjhwr3nKblIipsc<^%HJW^EORj98krEb#R>IXG)n(7^2!8x?IT*O>^>qPFz zbyPXb)q}-zi}WllOmzawdSDgDxA?ovi@G$9>34sb z`=U(%;&k3PJqKs`Yl3&2TeD=>kyM>pq#XI(nJ;rRny=c?7ZW$^ozunZp+GLt&$z-Z z(|P@VndhbkqXRht)ul2j)v!xGjV^3+o_qt0m>=)pRIB7jDDXY(WzOjlmgnM0zEB}; z{prC+PqXt&z%l4}Jj*Ok@J;wVH@x7Nie%bn{{&Ia+m4RpBMToFpA!YO!CZ+q8b zwfmek$`L!=KNB+{Wx4gm%xCZZ%pRRx)=f^rJgX^3ocA(g>F^L9cAkmi%mcj(TBf@( z&c43k9{ttGHpC&aT?=9$3i6bY5MJMa3 zL*x;f6nYJtnD#1t#p~rTGsUlE>rf(xdt$J3DKHFfm~ndj1DLfNe52mE_fRV{vT)qd zKrF&|*sku9ZmSfTCoHJV@%iK^Enx!<#!}N|bDltWOs79j#uLb4>hl$#W`P_C)9kEm zl`r|MoirLsN&*+52jCUj%C+DmZ^V)ORrM?hnUwNQ^Xkd$7zD!H`C@gmL`( zJ-U-hW89oxR?bAp2-4^}=lDDX=Fq$p`U7)*Salp`pA+0`o!?kM_>xI}kIUje;S@if z-F0F#^oUVBKeAx%7o^$-Gs^~*-h@lJa>vKGHG@tED4 zXlb?|^JRQ?>U~^1S+%cq1p5YVS;Ju)267=pUh&A(vA{@!9sao{TI;2`J5af~n8WaAlL zq5wAMhmOcT!@OTcB4T5#BRAod<)Ju=@MQ+PHey8-h(o*K0Ev(Gc?W==J*^x(A<-v({VDPX+Cp^e+7& z>EfR}(@_lX0M-cYm25pS3f+U0IlA3&s@np%@Sj1YEDijai^Z+4V!2gh^oL(fjT8OoKcS5x))Y3gf z0-t$p4{&yFbSDUTyj=m4z>SD~<@*G0r(u@qk<+Bm?KQK{v6h5+CArKkyxU8psORTH$RCPQ*q;(233~w;0EKMLrg%b zZ+xOhUIBVrK~k=lFhJ6z4flRfovG!vuJcgvqdGPpIsrS2e(N4TylMVGccaKCKDb*W zeBYy4sx0tJed!A~p@7@a{oBocW%rAB z>2TGeu(A%m#rh5rRDq~5iasv*kx9BCH|_I@(cSAlia1x6JL6eE97Q#5zV!=IU{!eD zDQtBJ5EWlj$JsNrlYP$!ciUyCEmKA{NSM>54=i?rZ^Y^_ge`#cFHD_>rw(7JBFHeK zT#OvGGOZO6+Q!4fsLozL8LLHk_%xQXp`-~BAbd8{w(yUoa9%Z2W8Dt4R~8UhVuexs z!-O;vT6%gEn)9}@HAnrELBbFopgIW$9O3Sc;#*fu|0+7w)Q*|0o&N>|!84Lj+TtKz z9XQZYV7Q4^^>lCH-EHd<-}}x&aw{gD@?dY8qOEix=pSWwGpnAT$KU6w!lM;C={Uv8 zl$0Bp7D8-qWLAHUO8lGKUy~h4jHx{9!W5w&GR45^zs)#z>+jN^r@(0=jq!&Eq(F-} zujTh3AfYs2l)AjcstUiK511McqcfXh^4vC$_e(Re*~_pcE4<-(68|D33T_~FbeCNP z5nm^;S*FOZ5 zMfiSs#M1}HusmTPoG61@^`}3y>pxt9f!&lNW8eG+a9^Rz#g9SBGh}oq0^n}K`z1c4 z={f5?>lAnBJjY8ZyDNxSPnTaR=a^Dp!v5~r&u7MbPRz;v@~k}QC(zZ%wvR0n{ZDhR zp+?G66tOx%k|Mbz3(b&joqB~HEx9WAS8IRZK#WA7kFPA$FRnmNZ`eeZcdw4vZ#~U_ ztbNyk12*g?Q1h4Ah5_vzPfnbGvaW02Ua@NG$})!RzY|^n%65+100vNnUPTl$krl_e zpnhZB@|a;N^Up(y{O2L9qy3KJZXJ11m$g$EmR4XC#w4@!%IwK>ZcGmY?fi*_fe|nBc(9!&7kXt-7#(6ge2N zF(NPS$qukxd&(EeZD022jNDw5IEwM1=YfsEMgK$kt?Vl0tNhXcxwNdT+ZDstJY8vt z4Koc3*WozScahA)!+L`dP=CW_@~YO6UjLP)34b6=GP1mYQp#LZiZy5Fuyo)U24k-VcZXo(?L$M0Y%*=wjq}kZ$k5}Kr=?yJZ!=+?L zvQlKzOGf;Gcg3)PK?cU%WLD#;xH9+$e@@bcx%0o)^*KPA-HTSosr>#>J0> z15ZF81%-8_$>4Pwf4k9mS}@iDD0a3tf~&eL753z#^b|(V{i!^R)l*>X-ZA5RlJfVp zKy+O;R_|>7T)~F1L?LBApRp6PMz{Np2j?#`_!*-SVPh1Rq>^JJdhb^+$693bB zg|+jDT48E!t@+9#5ccc~ZHCvtuEHJs`~1Ha)`v&|yxN{T=AldTwk6N|NKH<|EJ4x% z`RvoHmy-<(WNV2b3(>?-g*4n14DNqEo&(6^nNK3i_yfXEe!a&lLV0OK2fN>`$luRl z&eSS{NW@w<$n8bNRb9@bxf{_?x=ZmWun!2myn42T!-p5nHkwOTJ}EQwR{&-pXq)(X z|8=T1BB$#6nB!g80fAEAtXK{8PyZ~d`YFZEHxdzUfz%~fjojaeU9$F+H>CpYyAm21 zvqn4zTl4PKOuEC~YHlCba{*AgkD?_GErNeg#YDv-9T5DU#sn)yQW7+&} zmYfXTbh0IV)Q-%~HhgLIEU>u^zcOhN+Nq!7NFxl!j_5Zvd>0ruBYX0#`JX?WvV{g| zG-mU?>sP)fg0x1^500I*NFJa6e4W*&VU$N5z_KLixSwe+EV+=D))hd9i@Ax&dfH%E zq?v0`T=nXVqfwdAYbC+4#9I}u8qHIblqPRiTEn@Cz@vGsBHcm0ei$bXAWuKG*ASUd`(HBEa}U$&fSQyM6+6 zg`179-A?O7$jH%SuuZTJIxZLT<#0E+rGqnLYOIkr%+n{P)+fE*>)UwyV~<@0xk4h5 zsm55$LvUTPARF5@&=j$OtkjE$y$Q_YdUV^6ndj1fe}#GB4aYrMTVRl7UD%iXbNwU` zvK-F>$@d+ys{&Oh`z=f$&e0zxq??;y4U{Xudsy_&3dimRgo|v9fjq@+*OU-%j1!$u z&{*ceRJP0i5qvb*5<-+nw<2A<7V^2~mAiMrWHYWy8mQWdtC31Y^R$f2Rv;)txzofi zvT`FYt3Y?2Ip#IfpaxA}fPjo8O$9kOOw(6N&MYN=wuF{92WfgnoJeMAqVz zIbR>zm+Geap^?j>v6Yv@t)5D2D3c+Od#q|~+1{8Pc@1!pw+5;G4dgK;Gs~y;(U%V3 zpkxrefO5Ke$)7FjFEzm5QGL`%SQ+8qr&O{k-B<&V$sFUjjiX@*1vv0V1Zj9r(U$J| zvTOG(=p3rcGXMyn?wZ>Grd{vW%#gaRu=4p2L2I-3Sv>=4+4dWVX&-et@{~1ULYv+fVEJI2q3*-o1 zahr_e;VX43X_msYHd5kvt)^)Fb2CEW?eUx%7%Tjkt*MUPkgX9esF(>YdB2l1tMKyS z*6roE-6D2zbJv~-sa<*0{rk4N`_!jdum*hN{ZCl%3PP&0;ra75L!2!_SM-zpB|{c9 zr>i<2xoP~waQrJa02ilnh=5-CRtcvCb=VvY!ZYA4Qiz_+62@^5M1J0?tUwq?3da!d z&Dw=73)eke=d5&^p|JMwcsoy%yhjW_`|?Jwan`cbWLUNS>G*PA2{yLOW2=pD zfaU%L5r(U~#qlah5utpP(f0q#*PzUKtRz&zXH+|Q7~4P{+FcVmUMf!yxpct{!Av536Hv!k1a4mhB%l_obGm7MZQV{zj2wl zS-Pc_$T5E_y51G6UshJ@Ber4Q>CyS&@U+}y7<`YKf1*FEx{qc(gN zLgj;6EhU>e-9rB7jdbRiY@zmX68-Cxr<>19@5qw_y<%xC?0SjxR)+aeki@udk@97$ zx{veT`Db;PE)32TItdbWiYj%UETRra?G>88S~MDZeLNG*lCzkZslF3itF(YoWP!oW z8@qpQV%z4HVr=_xc=q{Z|0=bLZS&DY&!MNw`B0ySSj(@uM{E-G7M%>ubh<`M#rmK4 zhAe22ybM@tg_(Kd%aflywV+8t{*f*US6=@8`D2gYOrD&q>+&vS=HvwL+~H`%3N1?K z(;w#YT#9Rj%;Q-XXKKAZi=jpES5vQZHl%8vz!nGBxx^ADBYC+}VKT3JD_S6Y`G|aLhopK@G$ zL14$9JNxKS=xAG(zP`T@rphhd6Svb@7%`83*qW}*XoF2EU!+@6whghokRrl}bMKmz zSe;^uVY9&$jq*3?x&DXa8t@lZ61Fdu-a>A}e7PJO+trYNt^+*`p^P0Lo3v3QEnTW- z2E04?w4%9yj`MihwZ07!)U`MPuxMI7zEUTbFkYAFoMs(KI$=I+$mBXRmy(0 z!auKf0+YIw23n3iir@0#W*(jC0xurl)u{>F@DBJhx{!@R%Xier=k+e%F){dCK&Lk9 zXe1ZG9OIcx1NM&J>}XdX0+Ks=LoE@oZN;qAldUq= zU0JDC@K3IYg3>>0K`(hlD1llBmZiRtSd!PAoa$fV>8T;;a(&34#QH1tRw+=I%gwid zluMYPvz!zx`0kZ!JMbf53D>7x#@s;@V6|gDUL4HLze@>>YVg-^$xD6XLSwi^#SQSz z_PETBTfo1t{W$kup;LIntOtt*!)D94jmGi4Tr?fnoY})TUNW5A2W1>2IJs`2!%|&R z{#)T|?)(<_$I5_>?e1#-j&v3Ul3lqfN>MdVjM*A06#K}HE$68YhaPn}oDDAZFRGlJ6NXo7{kIJ5{{eXX)um9lpq?~oAB#eoB_w2d$weslKb3OB$$(PX zbzyo0uk{;*>Bu<_S%T~3bSFG%$@)~3;ne@<2gB_->%VQC6>(|O%73Z2At*-+hUOsq zs4edR;>IV@gu9=N9?!$`f0cuQr`q{b@Eq$S?U2=NedVgKBLmCq6CcC#Dmc+JGT;P4g_ci?S z)c~#Izd9&2VgER?W4N2=RD-E#FUAVU=ID+mDgN!5Gb zDZucH8Xo0*dtv3b_ez{}t{J^#s2^ZKopuQl-~(Tz&Co?l+D50ojZ1;uLF0eC1y+$c zwb9lDzl9NNFev*3n;4H6c90BS7QmD{Xo)qq6*wN>46sL$%|LyNQ%ypMmsr-Rw>mEG z`yRUH7I)P0FTu)C$8P+&^K23?dPg-(wgk5b$ek{OyQV+zNKkxx zHMm&#QYz*_NAcD6OY?nuRw?T|tLlIMc7=kl)RGwB3eeQVu&Y@H?ks4^T%!$*YEa>b z5R(2!O+_A)&c_@0r#RtX5g>&HhTewVrH$0zHC5xErN z+Es_B6-c;l3W1&EU5ePhvg?j$;woIkRQGoq9=%)tGgtdpz?%))<#e7+l`&S~`L+4uf%PDmXvThvGAE45*43cl_N znHy-7XYK=l?S7V=#YBSl_(lQ*_4kxRFU;Q^konXD@`XEQ4hZ7aN2`g_M{g5==NIB6 zEnhR12-EPAh9^m!&7PRK`?DbwV>qm7KmK*$&-{ejxCdrb6_(;B-7+KFic-0_@W2&y z{r#(tc;down0#^1Z~lR3-IR8ne%2Zj&G@?8>a{$+?ar+_o&q~X_-_5oewfL<7Rz}K zU4lU`dH_?&LS(q^!0#mLR>mfmzgBStE@74Y4asHMW#(t}EcGAd zD2AF;!0JUkG+zsR8~I{f-At`G?s73hKji~r6>(SIk>Ambv3^6t)i+C7exHyjL$ReS z{T0)}ScELT#G=Cq4ACIxEQ#m6KVaC)%UdfdGVsFG_SNsRMd)oqrjVJH3I2Yc9&GGG zY-TJs8>*4b$P~)fZb?roxRB59$^7wP0qy9UKR8CmBjv@utyA}Ikw7wZ#IO>VZTC{l zgFvpHLG&)U#>~S_7BHu+j1v<#M)!)6>9FoyCtAd&DfWQ|q6Wx*tLI>l_wZcQI>ehu^I_Mf`H z@mEr?i1uO@O%wzHS(c{-daOhHpr>M@*SI&v`Qh2o{LeoeUXw5#PhFzudh7-e1qf7-6w@4$dzkGfKBF%El)mc6T}98^%&dREcJHd+$=R z73=f32!uPmzm?u>Y=VEn-3LCy){XvlmKp~F7tKNQwbUam3%kVmPTiFRB9cwNmN2!j z7wEJTMZMiyAX(dFm+b_WSg(+HN@UH#zSv3g)?D(W*4+BdhVt+w{&6JD`;B*S{5gf+(vl zb)oCscxDrh|8g51Z<>}tu6mgNJ#aBSJzQxKRy;WYgsMXBa`qnES{e@5TkGq;a*?CK z+IgQd&rWm+BJyEE;^S*Bf8LTJPqkyVD@WC17^!HtkBB>i)L~-Q(yivuriZWMyN&>* z=}r)BVPEv?Q$5+jXR$_i)9#b56~_MY+KO>Bt9m0bhlO2U10Av;RnZ@aH^l{(A$GNH ziGO&y(Kiwa$$@1sNLxclv?N{2RO)U#EQI|q4#07M+rLuG2fk<(B`d-XFVOI2O{%|8 z5iGbf_E<%5D0`$LYKrROHx*}q1>Ki0E~{Z?@59Y|zo)gd4rFRf4Hr+pWK%Tjjgff* z{TW*1CnQDzLMg0#jZwJN4E`zGnO3MH)0swB zZ`WNa=2?sNUB0l};`H+7U;$6y*L_D&n~B2u87~W80~JM+Tou1bS`E&nFwF%dC0%xQ)c@H8sZU= zpO$t=0sc_`6`N3_R(p3vv(63)jnM2m+rkO^^TpybRKynn6dsc4^cO#&?|(gXIL_%A zS>-{9djU)LCm}1IP2Bv;&)1=_poMz&`*S?cNgy3L`#G< zw)rrn^BaFVn-Zp|c>GPF?k$ApNiRRRpstE=T&>;R-F-IG(S8#lR$o?DU=e2;eb=d1 z_gJ9cs20FL61=nMV_z<0M$L9Tf(`%U%3w|}&slsdns6~%6NO6+{X?PbjZy-(U?2Ew z{6uA;l0FP(=j2T~`zLbU9<6XkpWo+;LlGUb$g1S>@^ZxlEfXd&E9)rCxi{D~z8>+- zZ45ha9Qpt;HFK}}22H{4Fn*c5w7#zG{pbOf9>N zZyBcHkF8v?(qghZXYd_wjfDMSY&6u}j`Pb|PD0YQoO9AG^i0Pis~b>I zT#1f$EMOk&h&SAb@FE4%aY{Y_nxMiq^Qw^BogGpBr8;nAYX2)9v}vuMOtlEg37Pg72E3;|n0MVj2rs$bI>`^1G-g(TFVlV(irc3W z8+!U00_FS`*@K1|5#2_!Qqgp%W)dBm=$mLW#53rE*%v5%hgkEVIDD>J5ZNf$>7~bsTjRJ7FjTdB=jQq$@Ub_9hS#?udhYmt2MWFlL+z)w|56|eF?R#KA>}Y4{ z&LdJ(u@_#0Zr{~qsfk+I{D*hq>ml)HjYU9p$^T8Jp%ZPvo83KQ&b$5)S`q}@21G}@ zCVDxHvwlu}`Vh#j&(I1==X&RH9Fal0)yZ#42JvOeR(;GnXQ|TS2Tq%%~K~W+~zo3{1E8F z-eWd0E=M-t0}b7J=6iAK*1d>`*OLbRqp>*|{U2gVKSs7Stiy-#cgFBXco=hh0dADj zczU3k_PN}#$olLb**{X6=Tb7(VksM}o3_@-YO?Aq5UZ152oiqdD5eLh&Lftev!~F!RbBt}D(7o3*`K<~7h5pkM3Y zzW0Nl&}3N|o#bZk9ebI^kHY+~?*yhLhg`ltRK*4f(w}=U>`NM~mgvS4Qyx(z$O`h0 zztr|$KP6^)?hV~xT@JTy`|YeNx6ww2$FeKZQ}C#3ygM`dyA016d=Kj`9>^P5CsDko zIwytVmwwPhKftEW9B_!24owd1^MGS0ExRZtT85u+WjE8lpQoFxIh@m9E%VNxD#TY3 z;VYJf-Mh-+r1>(vWsvLE*f6?$x4;~JOf9HvTpID0=qKHQbvMhc7tt~&_MNyMF!#Q7 z=<+@5AUxh&-=!3nQKi@^htzxKcxYYVkdFm&3cmDqDLHyBWd>0RmdVB9uce4lnoaa) z7b--&Jc4Y`ML?FZ%d5bL#wh;!z)mb#aFHae(*MSUeg3VtDO#2X;MB1=STS6a-Ajyq~3c|f_?ACCz zrxhk>=JlV-%E`}dPC4iVbhgjaR5`n0_2Y^O2eNWT@VpO2rBsKle6Ntxbp%qb*#RR% z3!*hh<|unom=U&K%|vl5cX>kmfGSyiXec!-OgY}HxPs|3kj*dtY{qA(3Zf?l9Tg(s zh{OQQ1>d2bsh5HjYlerd$hygr!4X2R<n^%N zTv)reaP4jC1`H_DWy+!vGhJuj+ZsQ!%Tt|T0;gSUq0Re+n3!9rqQ^vo+PX2f)$~XT zGthg-Q&m+n4cx2xilmXx2%jRmKRfQivjx8WWYb4kx5vgF&8r5M@t+nKE|BpynZZ7r zOYSdhp2AavFOkp7Z0dxcO{a`ZqV)rE`=yB1szcY!j5K-g9%AN#d~%3_&^ZYef{HC& z^OMkEJPHrJDWJ`dVqApv>W!M+vtJX=GcAoh+`}a1UiEYuJdW&wJa2(6G@s-{%5Azj zpT#9goQ;-ZFEGTsofRp~Hg!3--4wIF%)H%|o2JsMc;$?vs&Tp_N!$FIl?@}9BJ;}p!99A9Tr?CtH880@#-BnUip|)- z`3&_m6fIXD1M)W)BdVp6tJsOybTEP>Rf;yx1+jVj`ZOh8RrIbcyP@O{ug}fU^~3jY zuN`Zf^{Ui-Rg_e^ysTC0WMZX#=AH81w72{lzl94W0tJo~mu|Z6+1_m)DQZWV=VWdiB=gxc#_v2I_S=efVkj6N zd-_6deU$0Wq9rF26j~@JiNC`MODs8;F&oGKo%dZc_r{<$J1yH2k+a{9Hyn(7KC*se zso%+{d@FKej3Jpeu}2Q$;i<2oNC$5H#uh41=k;c-u(L3LJhj>n(8dE&$3;nkHAtjH!}ZW(&y%NVf(((D;9K7!DYO zZ2aOa!&}<(BxQ@A_AAG_(rgyCsaixq!@QG~FS++z?$AqymAA+}^{&GVqXR$04Hf4UuoO3q z1!Ak2<26S!XLKcD9M(;DM#L_C$g_)wW;?GUOvKFcGG@9|GJ*;M54V9d!8*O6NWdWF zEOlgr=kK|5+|nect#3Z{ibr*q_vZ69U>aJ|b&hdVt$maOU-r`Zt}nEPX|>SC(+_Vl ztIBYGrr9w8ZXwxSo1T?eDDEbfBxV_)$BV~2(i=@{xX+d(?Z+VQ7S+xO*ja9i^MfL`b%4nUgJMj)c+p(wU=%#um}pt*=V99Io75TRt0; z!a9xce<$kFLo)aHw?~6PqRs#A^y$#e*p9ge{Cx8*+_n z`?-2lD&*tmogbMyTpglcK`jL4;C zs>zhXTF7TtO3nC;-?S+AHydyDO(;`07rT5(P$(ZN+nDJMPY}yBEDDIC^ohMSB_O2d z-d%IVPtm`;Q1`o$w#@6IT>e*1SkNj4rPp|+JvGmpQCWtuQ)4bEnsHD4t7z3zbrRVP zg0gI0+tP3z2HJ-7S_>BtLYrGOEMKof3@!W@`-Q6XqcFC{jaGW$uQfjzqLdq+MJm{+ z*U5X|3~IU=>*^bfGA(YuIHoloa;=q{hTc+86{sW6I)`cFwkcU7fdzuOzaQx7W|k52 zub$02W0TSgHJ*7G!`}f4azCkc{_4=HynUpvP7V%F$fTinw>s^{B2|DPHnB;X(CFdCP=+1+v>ZXaM{{z`>=EV$MwVk&8qSQ&OGMT?GK3}eNn$u znyT?QQ*DyTjnLm{&dqzS&Q1mJdN`DLH5@nA4Hc(R!7KC{(Y3-m>;rh(4kxukjpm zO%wq)9-jLa3(i|rW1lNQ%KizNkPbHfI7ikb*WDCeY4I#3!(Od7+y4tCgj-`Nav=&` zn#28JyIuWD9-Wm}5AF{PZ>o@sQmK#&^pO>j29WIewy)fwB|8ERRk<7AchR1IT^9aF zR-DlDA^Ez}MvExjVXkL0D>YNJDE>V?N5|@XkEvm_6Ncc%FQZOeyQnDN$&I}!t1m42 z5%0WROs4a=Eu>YtJKC^;&6>=-BAlo|SLxHS6RB`ijKJ8P9j5p1^`xLl=KP*;SE?D2 zn>{J2C4oM6DYq$I`%ggL#wwV#i1sb6qyXKU2 zPS|p?SzuXXaEY!sb}X;=ZPMJz3IUUG@?HB(MXipGiyBYpkvIx>HUGMEy6e}>@a;Uqsr%@2(1yuRYUAReg9nXw zuz#yynFSk~E;2}z9ItLlX@cnd&Cl1`;h)yt6|3Ch$x*f2r_c<*#C#FRBmczvL+IpDx;@ zlaMh>tefgms$$DGs_pV7^02*$xDaf!Up1}>NIn1|P=h79ap`pXj{no%wT2~?u5H{+ zHG6bA?3&CxcCIP4JQE6*Q&whHR%WR*R+^bIYH0>YHfiHnVrH60GA;A0si30Jbdp3x zGo?hN6v7jbpb##B?_JHlzN@+R{=5H;KfEqQVXgOl)^mFA=f3@N>WnR>*;lOHIaC+z zB$@P9VjwKWwak+vpEmHB$2OU=g1<#w_;jL|=z^Ip@ydJaSd=^1h#%;kW8(ybFWQPn!Yw;nyE)2yy_jC`MFrnuXBL!debsW~KcgzgA($75*4zSzkf)3ra> zG*u-u`_pmu#1Hz|yPxkK?FW2wjuE;tBNj|rK1{2q^b+7|7YYH0S49?Bxj(9huD{VW z_5}ROz@$=wzIE(yWsr~=ncaaiGec?n&L=kATmj24NHN>^K7I;X0Lfs3hDb2n({ zhJQic)>KYZ6DT`x2xQmMQw2%9eJ47fM1o1A6e-R=GtakjR%79&Yo^S)oNCdgaQzwU zNY-JhkRV=HJfWS#Aw4$TEZ(^nu8es|JCrc?m7)h79BalCFGKVlLgK9*|AAQgc;vw5 zpU&QG3C{NKS0$$l+cIJ-CT+j;VF+f=Mn z(T4+A1^_b;4HVd2EZ)sI$>2K{`7xXD1J=Y*kM&A;j&xWPTeFA3Xeu;NxTNxg_$@lh zYL#54k#S~GnKMZe^&KMAvR3&~MFteWTl|)p z{+{q{*lR%UA~Vm51r+`8?P?OcKf;8#<(z6N-7_&sQ#fY(2`7tk8Q)(+iQJ}* z)*a_E<1R6x(VyZM-q2xm{6R*k&OY-+Z?tajI7wP+c%qzoXMxc6a2uC67|v2nz>6#Y zhR>^*V)3M}ml&B)IU+E>57bt*Q{7?kK%mz|4)vx9OWfbjmtDz?Sochw8@5VE5nrtF zU~fK>UnQLsLy!2({FdnooN0>y$e+Ah0!1e{L|Ra)TBM;X!7-;Sr@^yLHZ$w&fpj6z zNhK-Ztf8AoiEP`r1nRp_YZh4+LY(C2eqyL^fNQquHpNkb?l_M+V?hF4a?H6_W-{Yl zxtQEJIFv2dt>w5~%${+^#cKP-OA&p?|BIy`@4Ns~K~J#M@IdwFxLQ}96kF=iR~-?JwEC@f;--hG!s_D*^9=Y97}||mue9d!29?xFo)6cB^GmgHevm~M zQ6@sl1nb;qf+4ui9(M~QSteT|NaK9^;B@6=>+RNlDVA;1Fq)rZ@QnnMSs>Y7w zWr?|3x=yjVm>;gHs`JZn3ASWuf;Q9-lzb=-0}q(NJ~|Brm^IcZX&0aMu{<8F*+tt7fDpn1*S{^K~@Jjp0g16x1zZLIF%<4 z$ScrW^Ev^&Q8!h(L18BhEti1$aXCe@F8H4zs;XfAyVU`zCa&iM?}z?J@r1a}3D5@_ zR@J}J_mrdPbpL=0ePEfm41lDh;bnLMss?A-#@#N(U?^Z~j&v&DYs)YctSx*U?R##5WA#w2r5q+V`rJA}%0?%L$^`P>KiQ*h0}n%fPpY1FZXQHH!*7 z`vHNd(c@@+iC1i!_bzT%IIi|^a^9gPQo7L2y)}4upQ&jU@cGtUD?mxTGT3Eg|KdS^ zMYG^2fJL~M7YCyiS>AcCm7tMsyfEGN0Cr;c>+mP}@go57Xg4Fveb_?E@gt#mQA>#_ zhdM}As>Q@3vFN4`X9MiEbSQ2ugS6pnm9L`{8)Do4PA3{=M{_r!LA%G@{Sy@@u!iV` zPEmF+&;}im^WgZ{Ru%S_2p}=Be*#495$4IN*?3bWD=$=y1-0A}+&YjM`&( ziokR~E}ch9E0_TjE?Y124E%V+@gtpM-FcCuwbs@B--SH~2URkD^7GfI!O4^)-c-(X z{46+&x6yuvMcv|yvm3vGg&z(t!lg1L{cZJn#C?lXrp5(+c*k9O?&;O7WIs-4YRqyQsy3Q zrgQEPEUR{E#v>LI(T6&7Q}r&B8W_hkt0&>QD@g;GW%_}W>yl`x&N{vXJ9Xdido8;2 z;60@6^T20xF!XiNd4faX`bBj-4=a`Lcwn-T2u7YQFK@i2b=4XRKEHgfEj9ULpv5!5 z)#h}n08{oVl1u6oSJEYQOk?1JIkIcgFvX6lf=myVEL|$@zMVf+6uF3TaE{u1_Wk@} zfI6av1?ud;dTU=A<4j0lV*EYLwhnGwOyjS!xp~UNLVjy1l&?&1*(9l@XeLI8A43BR ztyMJ#D^#v%Ofv9Rlu3w{oYv2)>zDx*nx*zOWmcF(%pQ#%b45qaOsm!EV-fYZjSCTyQAgytrik$-+Ces>sy{*Okc&UhKH$5CTT2#T(cLm?r2F5XC*V zU`G?o_S9V;PhZWo*?n$)5VGweNT19l911(n3d#LlnwZI7{32wnTl@417E`#^+DL#q zK8DPGXmDsomGk1g(xE3^%rI^iMjdWBxk~h=3wiT$c;;N_+*#@m^W{cn(I99Ntfm{= z?)~_z50w1TQ-^3Wil(5<^oeqQnm=-^vZd!Q3c+lah>8&@KculDVs&I&fEw< zYh;Ps(Ah;JW!!|z$R)H_Jb>uqm}3&hSmL-?EjX0!nv_JnjNihGbZkxWWa!Ag5+JH&rloY^k<2CRQYv!)9wIeMs`d6{R zIy%r5KLMY}~n zy321gRvaV4eqv7sWqYjN&#JA$xyK}7(YwGYFGoLRhN&O5D^uxkq}CZ&TD}x%EFVe` zwQ)M7J9mXN8XgSsruEF1=QTDqdeMFzNhf(|z}tq1x%6}bLG8pNYYNbOv=5?su}vs0 zZat6)Lp(dvU2yETu63huFn$V%Ic6d__(8?XWTJ0_RK`v%1)7xORm?a7QIxJ1kaD?0 zU|j2z^M|_@#T}6@l-XW6asEJGUMK2IS6Zv$P8H!yT{Q(_pBw_HM03hjPi7w(apk`jbsJQ^D_qfW0%^0Rexn}ne#b$2tXUN~Fx>jS+R`I&gq zJAsaHW<&pi23tFcVBHbxOK%^^uf`itAdWjDQ(=EA-h-i2th!3zsF)=A(6uqv8v-sE zkp~QS^>iKfD z-$gR9Mi2#b8iY|VuPcKGQsq%)BuebcT`HG!_Q4A(3dQ|hU)&9KOSVK)B?c$x1cJFF z`S;Q$wt4fX1nb}cs3$@% zU{SoO>hX3fpOh`3UdcRbw>E>5{j{<+3x_$k4I(~@#jU(dW0v@=M#;!HXYal~`~k4L zu1XA{q)m~}tH<%`&E}{#KdL96D#2yQC)JyYo zWU}NNE<%`7mnnFGgCJRsEiQlLsk|w!xJx$goE+pNY7PX02xs590 zN^R~Do-WDX5@CMCD5ySj?b&g#8@%Q#_gW}aXCHMecaWQk26tfvY4TcAZ6CqwM_TzZ z(lTa>ms{jw&2sY}&2=9nQF9Q+8{y*Q_E*J8TI5e>V-E8o&z$XHXd*={dTw|FskEok zzJFwCzNRp(s%flra+uSdF40W07t1BB&4(oi6MNEM zywMUXUZh%xSZuB4hl-!vs$?a<*=ESLIM$LTo69=W(^4z#4 zJUu#<;+;*SWIkB2?PNt;Nqdw=Owa)ES-=u33AyB_locl1?tys0;t#VI|02<*uk?$_ z>8M*oA?XLP{E3*4<3qr`iS8F~myMaP6j0xSOOiA#L+xN-(HOP!#p08)%=nO$ZQ9qF z47=(23YeBZ0nqcEva=iAPZ!8i-4+;qpC0A=t1^ryuepHB>^UWdwps5Bna_{K#FCJa zjBPDCJJE(AXOgCNdl4aA5m+9Q@~NFOt&FNY#wHT$L@z7=j~LHz0RT-ViJjaph!a*B zDHo`-vc(`yvhzCbV*}Q7xA+Hq(+l6T{VKApb==*La}gT({oj6mH%o(T0S2`7pB$KUQ2so;m32+yq&$S)L&^Yz1 zC=^NIfO?c&y;We0G>y~dDznFp0$hd)e%=ph?tCE3!!-(W=N1upy?t>c8szAW9CK#Q zu|ag6%2V!KYV2=@i}6h~DBy7<<-JUkHl#S$wuV$MYTw4+_}O+AXFdOMniYU$PoC;r z8`-ZpPN#z03zOVr=pafkkZA9`!T4(egSU2Nobz5FM8V}tQ=yJm4w2a>A)uZB)@m?a z?v!ctTs%C>RU#2r^3GIdw`3aYA-?myuwmJ%HG4w+Qt~_Mx!n6oyWai=APy25n)yeR zs?mSq#`4-j465SkHD^QQ`0mcQuE8LC(Z28aQAEIZ2TF)Nnx0-SeDr)zAIB}6tev2& zI_UTb=2l#%tf(V+iW62e3QS%N=Jy6aFa^?*!_d?}p7`JQbV((HiKz<|kUUsRNB#)X zko*F=?s`Ab0T%xA;`gW{W?p7KW?1MhUNk%ti0)LLntvrP96|rmN-q-R?w&-4q!(==({yhF^TYQzpkbdTZ-Lt* zWNDO(S8bK96u*6^RaUq3L~;sxW~5sqe!Nw}xRU{m#YI>3`kK!am%&Wz>y@D%)KQT4 zNO&}Jdq+o=d56LKpGB`tVP@FU|^SW}Igm2vG`!qADvV2l53v zM8_JhwZj;k1Q^=$0d)M&2Y(FxQAJVRR%NPq=#2Xm(ePP}1LEzzkELHXK-1RzV8oKm z5XC5g?Rfuj{QPRZD!D|}8P=a9`U7+&&wznB>NEFgYLrW+PpCmXEe#l`{1*vH! zj7RkZe&zxgQ6O7~bXjLQp2g7*1GS^B=R{##)X^*@wI>>!b*0E`f7O~)@CJh(h~};} znu2wHLuZEmC7Gg5xH6)E6tPYP?2yCh=+FdjMPMK2z7PVg6>I~*^|)iX8{L#JSaT|v zW(h^n^@{IR&2XF<&YjAdIZuKd{%VzLN?5LO(QVZquFP3*494uQS9S!#73|ZM*G+6z zRMMct3t%|G$^?{o`f$s5y|UsV!0`o6X+D<+yM%rKsQRq8Rny}jJRZLU?!EcbBX^f` zp7Z1&Un(?A0jz-C8Y=BX2=X$~J~;YVIUKI0?h2+JI(km@WQ4O93Q<71=G`gKv(Pd@ z8imWv$-!4Izkxfw@MDBK^dU%##yg*~BF@a78bHrwT(g6=xZj`@~{+@;HT-*ZK|O zM2DaKSB>f2Kr%he&O?$mN8JbdYEwe6IXd3#>}(@SJKHxfFyN26d@pOgfh8`+M=CCW zAld*4LhGF@%P9+ziFP5b?D*1Og_YOSf=aTMvwW5%;gz8$#qIB7GoWN&!Jx5 zrYZ1s)0%{_wF6c(4zFG{7eT)t`PZdMTN9Fz{SIVC)ph^n6&oPSx%cZH3NY$5dtPro z17_FK|8k}QUrmv38xYvq@Rw>H)^p!en+`tUz>mTIarqnP#3Jq;?)=*G!T->42xvmP zmgN2={($$%eqbQfyYiPd|G!rgPQ)MleFJ~*031C3HlhFbeDLG__d|T`f9QpzEviA1 zHJl)SaZuV8jmie$n*L`Y@c~R{@pWI)XZY1DIc``fU?UI*|LyWX-lSu~$VydR^1tnN zw@L_L^2|&<#Qi`0-?B*_IB`SzUfHm0?UxVfze8WITNkd&GeC50{L`ndodwzwq;`N1 zRbjxJ4cf*`ZG^8UE&4-eJ2PH^`=AuGg304QT{%GEfG>lie_q6wAD*22`=u{Y=5cElcxO#S(bFW<|g-eiC(!PLI}l5c$p zXnWF*9t)Z@Vqs!hbTV{d){TK;Vvm>Dkkl!-nTZuXQ*F z=c%pzvi00qQO4nqJL43xe}mos;@g_|)Vp%mb?iNZ=MEm4$ujp067SW&5TCx;lsFi= zGu!oK__3AN@R5*HiFHX9k{wm6H50)j`})XPv6_XI@28@>KP+em1r6Qu_p=O{8d{26 z%_-^)(l465oU6NX`O6aPZHD|&+ailxUCT#BxM`kYZgh0C z;NHBsMM{x1@sn7^HM{!L#>dC!%Xc{K0fX89$Vgg1;Ht$z{jgg>wd7_Mvl;j}eVj72 z!D2=?+_-5;A*xxxiA3`@xqPU)CSfvU_Pc&3GpZAw!4xO?j%No~BW4uSL zb!*%M*=hA`s9s{P|BV|nUDrozOsul0XH(+^U1@8~v`#2vys3F$$ul5ek>-KD#uzrZ zP6NH~k>*ds+a2*K3pbu2%Z#@eDqsjP-xVUg5RFHAC!(x`SlV0_pR`xUsQrhbNke#_ zHAjpEV^F_oVCiV?%+tA(OQSpZ4Onk>_NlW*WWbJd9Q!y{<}Cby$n9Ejj7_c)bhL1~ zusYdtz~h4B3-nSoluTQ}&1>C^P~dycRQ#p|S9ejLXKqwQABJKsRNmfLHrJix6y=LD zI_L9Lhj!Umb*QPTj=3%!|5a8lyp$rfA~9M1A&qUghjLI^Ma6}tRki7SZ{b#(JsCJX zQX>;Lq}K16p=FUmxE9`>f=yWuEQv-FlDoUxXsRbP79P-9N^tZ@WI;rS#*wW6V)~5R~yOO z;hUekQ;0QrLz$Wu9EPV%Zte4aXP;z_PNC0iUq%1cL{!_==(kwciRiVQ5am^x@t21> zY;!$me(gw+)e?*A#X1YaKacC1eaWn7>aFNa)Xin-N>PcnGMJ`9Wu3}?=}OYTR+F>13#E9KDDS8UgNJ8GU}8$k_rPZ+h) z0xbI{A$(8I`71@4_RMMl<64AtkTG->3I|ThdY-&ZKp@lY#*K*b+4a9C^30HYXIyTe zvIzC+N~9D_krC8k+NoGoMqQ4)o@#`9L~_~ezsaT{`Vk)o{3TevDh5-lBkoPo@>_d8 zu0AO;;+DmE6Hwrh2nQKT7p-jbEwY=hR20jnye?EmznXP|UKtsnt<(^|o-Q*&29h0R zD8&DI>zDbEP}{^Ln6q;e!YEbMkNo4 z`(LQ_g%-%irH}Z@bw;2XJG~|4V~&I$E^~p9pS}@k^Vm0L$p~clqmLMBRadJdN$CXI zRB-665$SW?7(#=b!+9>}3L|oTWw$G{T#V7ViaRwb{Th3w>G7Bg@cW}Cn?rBj=0i}5 ztGD#JwlVSIZdFy&N3Y?HiX8MrU#85}`@W~NqT!++#c0cu_n9ph#YpiG-A?YC&`g3w zH(lFmB3=eUbDN9I7ag}vogBqb#m|%x3YL#Vs{}*5oTK3lIYDyWI`gAq0HU4~zHFN8 z#$MUj{L49QH{Rv{Iv;fWow|;mc}kWvm3UDGlAry$=3+t~=5xfdVvLDt>HGnC_ZRs+ z*?HS=S$cJ0O+)Hix(rxJy-|V)T z*~ZZYgPHBj0I|C12L~qgEkTDYij)Ru%LfS(#;!Gr`xMl z15!^rzrWTx??P+Lx`Jdxt}SSLDgdaus!Uk@r~jm`vSZ@e&JP2r$>N9*NQUs36K3pP}g#@z2aW;)h_5M3)_u9mGnTW3D6 zJB{~tuFsosIT2rWh?lFd4gC6zpc^j78hOt{?Z6@k)~T`QLy&p)?S_R4>v^guj8kzue&AAd{k?FIj0?P&015Ts=V24>i%+l39;l4 zS>i(%i?;1tHQM9883ktXg{?kijna!@i+XxJ3M?yO*79-jjAIsu2B|K5UqWnxVd2u% z(wnpMg8fZnGq=ZwI_6dKmGf^laCJ$k7=jV>;L66QKS;;$$*yNO<+{C%@1Vn7t7dA~ z{%B(qWd4F|-T0mtmog)0`A6(tiDQMuc=fJTa~M9YKKQ(}+stq=8ExHB#8h;eUdrc6 z{{qmmX2NUJyF{f+5E`Xh7Y}JPXcsy{R=6|OjoqHx!d|q8WH%Z?YcE>tuY^&$TC=@j-IYocR2OGvzx?Tr!sX1PznCM@1Uu-$cW8U$@Srl3@}d5BSut z-Ewnb=5F)0otzCl)v;u#M?4-pAk0eMhsC0=bYWfN4UC`G)}f(#=hz>~9=-VXjV@2w zxy}sFz zO2%hJPTs^3|C)Cga}5Z8SV4QmY_!A-9T>~`93f)UVXsf<=pH)<5TkHv?eb>VqPKYq zv9OPyLp~4s1;IKV?mxii2x?@DmLqXf)agQvh5Y`@9fnR7NZ4wlWyM8^BmL7C<${?r>U#TaMim7G$WlBw~#<5_i-#~Snb{jMEqB6XHC zF-u^VBfl7Ew2;A!OqJCc!#jN~2n9QvqQK0Ue+g*Z+#`iV28bVSp4Lw&C@4@u^YKtL zVdfh(cSd8zA)0fZ{h_8RhX?Pl<~ry4o=7As8AlNs2+;I7SxOS(&``#z-3Mv)uR4!h z(Fki2S|mz{wT6gI;R3$G$quyyYwMMs-H){e+@?r2X0@F+y~?-m)4PIbCv!o=f^C^jH=V_~M&`M| zaLmH|Z?$}q<=|}R@Cus@p?OzV_IfY-eDFv>L>72(OawvuAJBvos{sbABTi|EZ^II> zu%6}g6^}}fhQD;?-8<6uEw+CJIKhvd*Q7{ z+^`|UY~HWxyG{zR;#m&I$A8U@BR9{vhys*5hS%I=ljc!=wT-VWI}uJ~G-T^vxqGT8 zf6=Uj9i!oFw=QPfw6k~IYJfksf~2oB@zCH|{I|%!js~aBi_z*T-3~$|gAa-__72q+8%LooEpgq+t_X|S zD^e5U(t-f+8|FM{i|a33Gm4FnA5FCbZp6d|qu%K$0xLI2qc(%SLR&|oONqqYvG#8y zsBDoXK)qLSdpKoQq|-9^1`Bd3-0QQ|_{QzVQP_$4)iv!}`#B}CZZ@%wIU&Jhzoa6? zpSYSp!;@-1XBpvox3h4R4=*ZrmJ2=JUQcCF^x8?R8Yug->`9XUo@kDZJLi4ApA7Fx zTS&Ou=U~$dtHLuCNGaLHZ6hJyjGzb?`l~v6Yyb`*jKIfl|3K_TH&J+?^Xd(}HMn!K z-)+OXZNfQjH%^S%h#J}IIixU|c)7#g`P8ABcSil67>*i#KN6MpM3uvAgbC4ZONp zymp=9c=L@&v$~lKhKtKpYRp664FTxP79sm5 zk0dChv(0S{FF%uJkGv#duvf-1Jml6C= zNs@q;&Y!aN>5dOZ0&@%O{}Bt!Nxk)@Yu+>HHqn?2%iW_H*QgMpWGpxx1iw^1Rzx+p zRGV&TGK^W!-23){BGuh-X$!V9aJ|96$#!lZjJ8}ey-nHQrX{!}$5bZwG57kHSXqRH zkdABZuYB&^JQujFWgnxwcXg=9Fj0}WO-0tgYBH=1$JqeDR^kSaS$NJ)j7i2 zCgpSZ1Oi5bt1mcD#??E?H$EL8g!hItj*9mmUb&v@arUl#(T(F-M6t;PMvNp7b)0^DrvEqS>iSkYl_*NKDVYo ze8Ti@G^V6?V7Y$m4^+}#w^TeVVfTy}b0Z*;;Cs2_;q46xH4qftY5zHtJ^4Xt6IGRG z(yL|Vgg#y?%%KO(&t40<_Ic*xbV0JnjjWAuGBzmvYru2D8yacaktS#pys><{{Xw~Y z(enND6k*ng_btB!azwyK`sX?!R-OLoHq(RC?#sAPpjX}L+*Dh7p6;*CbIo427T!89 zo-bN8vr+-`UmK*G$T-+7_*WT0&(7o~-Np}EAApeZ@u8nrE|^4#xIDJM=mc9l*Y-x| zpbg1h#cOana{-Ot-}1XE1M{VE3Ehri8K(c9QaFSA`^T5@DB`hG9ty7au| zH?L+I3i5~5zU0{PCW}8Uh7YYwJ%n3mWWNoq*!@kT88HNfb_JPRo*HsE6?7&S(Mb7y zy9YM7ZFK}XPFp%X6mdWfxUPD+d&DN2DY;-`jnZo-t`?m!ryVSqzFUV}Q}6E=+0$)? z-HSS;@@wyug@kst3k7O6mAS8pdNtU_@lIKx-`)LfNG?*tv4ObJH`8fP&rqIz7T}kr zA>HAB0Zpc$X9y1!9!%5_^8bW{9*`tiSbCYP>5pQc!+HA6Nvuk%^XLkd{*(o^)`+5R zqQ#S#8&pfLZnUp;jYy&V!xCJf2YXnd_oRW&`21}{qD5+5CYNsICX{nQc-##^rufv$ZGq=3*=5NF7b zfAXEKT&a6TqHPp@=j}Rv2(@g2s^ScJVN@_WLB>Cnd`~UBHe!8wC+?ttKrsl`?-=hB z7w1LaLsY?+Kbhc~_Uz_gSy9$w=fee_#sN0^7d7#IAozOi?}xa$pI^5wui#_^1iCg` z;8HEQ)F=*5i?dv0=)#>;Ln+FIGe<+k7(WsVO9v>=1O*C!l=r7>n-LTj^VB(=Ar!v( zrriLW-vn$nBl@4u_~d$W^LC-|=%ydJ2L3I9VAFrPJG#lp^~YfNx9ETdKE@ci%BcN# z8UL0Xez(ucV3WoF^Nvdv0Q62gPqy!f|Ir?}MS;(&B&<4=s6Whl7Tl7~SJx92s6YG8 zS1!9i>~P2Uzv~{&wgc91`v$8uc5gR|LqIigx|FcWyzdVUossj^q{oIE%QpWWz^kYH zH)h?IK`oBAO@a)9ivMuc4V~~cER~6*GjFQVIIJbvQOkc1W*2{e9Y=&&!s4pRln}D7 zx6s;aEG~leK+^9@=hTPnhsOpC*S-q=`#l4j20iM~VaWO3@_K88=#n9Os8>Qo&1@~{ z-^RPJY2>tHRLea5ddEEf(S~4;D)`6n^%Xw`~od3LDN2lf<)Zr#h*?`{y!2oUMJJ3Wpt={T-$n!h#}_@ z*@s-?%NnT<@|OO053i1F+Q?Uo!CswrO7poL$x-GyLFr9PM0?}m(7rwcV-kuUNpS*E zW%=5_-D|(r=FGh)lYx+u=n1!Wvi8g1gJ}bkhMX2d=lTcmFX!R^p0t2X*E5flfrZ}u zZ@&0{>XZLJUo!tq_fq(iIkr>}JdQt^Svkt`k(S2ws1@r=~9=S>diB7imVSE4bJ#)Zv*S?OP2_0t!21dAH{{wPvTaGy?^2m zA9KLE2MhgZ@J?3v(|@po|FI-L5%vEGp8Pk)`F|Vk6!$UAre^s_ZTk-t@&~<>k9{Ys zm8k{DpGyT8_bP4^`Noj!dEU8ts3Ua!n=H&RHpb^oj(&I`Yn$QPI|c!Q@`(hHy4eap zxqE`KNPs{tmx*B7+S(@ZTpE70;8Bk+$V*pqmM}cHvQEJGeP7*nIHObkHThK6-vP?< zuJpvFi!j8>mr1H@fE>v==tEb{tA_ccgL-y;;ss3`<*wrfSEcB37{qGUyyD@*{JxEE zu1hasPWY-le*Ft0lHOb!n0Wg@4wHgHv9R1(Ec}{WP%e9+(ZBks&y&|>4PB=Wx<6MZ z*34_+Sszk_`@&o*CgC(E%J4_>iLMn6RC3aPXg&#Ih=UJ#WZ3Rw1mN`+>f9%TV==~` zcs$lH33uu-Gj+5vl$@uMqnt8dnc_}J8d5#X#}fs9c$Iioh8{1zTk&XI7BN$Z72~Um zqt<$h=H@HQ#!YYnja62)9A!{oXT**bmL#J#R!Agec`g|m>FGn47195GXWl{9s+goQ z5YH~jf}G{g$#+}6lLIG+sdDKc#Q2df%NWw4;Rzx19SW*qjQM>Gv>~@{Ugr=5x%M|h z%--3G-Te2rPx*Ye2JoYP=ZEX69S#O-%-8vhs|+4QisPr0lvML~G%peL>}$L@CpX_|J%`nMB3nAsXp+RAZr7qkNI2fo3AEm?^=?bQ%L zcGw(o0$&0Ht4-}N*j*udAwC746Pgy=C10Z;q){Yr8hfm_6lokeQ;;z*qQ%u~^mi82 zVY5jv6oU0`8^pODc0{O{gU^@*R_LZ|EQDszo0(%@*lq4~0Pd4vv!7qtROj`|W8f7H z7Oa&-wjqzR%UK!6{gB(V2lZ1)JOBx-lVcgl51q?r<%Cd<8EXxENWG^{gl+Q zqg^wuyopmiI)PuJ=@N~g(rS@@8qr}xzGJ`(zmQv@*&7>P7(@;H+s9{0Q-yKf3A!5qS)cwMyg`J$A0axJ#W{_?y@N?3EnO4G`KlYQ+{Fv+EMooS2r_8?D` z){aTsjN=$Yu9lQ|)ey_Mi~4S;(nb{q8#bcG^DoD=bDvNK7Q=e=mwFhnd*yGc7_P>L zp?i<_1c~yU=Fd%ER-m4{-VB_^uVNB4AxXKSLMp4DdU6tduv2`n&Fw^7iGnn}k&eTT z&?~xCUn@sH-=0WN87s=Xn0-pckU0`0i0K_`jwFq!nLV8#pw%ewr4KL%&-BvD%N-_* zVq2-U_AV!HMUI9|Bnk>+i!jJ_CGxSZW+%UTkFVZVwdzS8?I8=bO<`kv$G#%WqG9pK zl~d(tQm&(Zo;?@m5sN}2iit~T^3Gv={$NknR}Q^LS&U&z-y2Mc1mj&|OKnBW>JLUYV|7Hn}}dPC``IC4@EqHmZfG@SvhBXLEA)lAo;|uzDQky2$x0_xv6? z_##uy!tucJ{&G%n+K%-PcXrELuH}etE~y>-ZJqDk1Fw^N4UN-pYwS4=Q*GPcyT(>3 zt8@FX{ZoZo)s=R_#wq_XX9u{r@ZZV-m^y!lPBGc{Y_SU(jN>Twm1+1p36BtEJ+l{K z90x^ezB78>dPI6?Ns;Wj=&vDYH0moh>4lr?b!AsPuc$M;{AkgtD#T2vX*@9h&&1tz zxf)`Oa?WXTwRUyboCwP|bN-=+{GYAs#ya|ct;QC!_hm?u6)kEyD1LUrtU;`CIQ;+< zDp4y5+{tIJhkODRh3#_1kN}O1OzbkdB9T>B7a4V*bnCexlw68>nHO2n+)IojxWDf;8#vHFE z;w@Xf59AY;v9*7KG^-r!!k!6GyFea~(%dOkn!Q z8UOYTX>*6rAbNpZtk~Zz)O5NV6TO?^5U_vJ7jH%P=!e_8U>bd#RvMN6Ooz8^$idX7 z_mbE|imIpOx7rc6a7xxK8B77?#B@1ipO;fiMGbLIWTP+uJ^A?JyRu}6FGK|g&>-I` zDO6|@@r9Pv?C-(0P5)wxw{Oc5Hx5@T8}@RCbz=7a!M^$>;yPK@Q|wjcMqG6G5sR|f zT4I|uj-tTwiQ7;PhAM3WaPmK4QT+Mb3jOS)u))^9`Wn!?^HsXb{GE%E=~`~unDNge z!DS|{%8Qk>QIg{KS!YU}=@y-`WhH9?tyQK9(`Bz35( zPnY#%UTQuwLgujl!quVO8i{l}=RR4_h;O0yEVH9Ic?OX;4QkzDF+4;J2{+doxSBy8m-i2{yr^Q;`Li7B$u%F+nD=IOSzqMcqRBY}?tP{sZa~l~=xw z0;no&I+gpoIHTn#EXMw#jmwCg)#^@1KlA=vd~cacBQ7v|P()WY=cSdDoZ*ZSjuCz>zbEY%qbNE< zke2}2&!$?wn9HEx81)sJLdk})hpRE3$|ZRmFCHG-f|~Qo|)A{b)-e zXAi|DOp6-y8u>3{MVybwV3x~kxW9jC)a(<%XF z<#Vv3=YHBw*CQP7t&N`0c-~qZiPvqr4pMW(mD#1(Ph&#}_w^|&An{J=j`l;?r`it3*5Cu<;6%MNR8wg3Y{Z$JPM1KfPj7J_H-T0CflAOmai-4Obx+ zr)qqoFdVWRQRUEqZs;uwmBEj(zeVh0v|R{kT_I<~^8g<3DN~QcPtz4XONJEc7ds^+ zHEx%@&9f>rfTUMU4>*9@C$ozEuX6ByL0+w|+R4ZCmSh9EEuLgDjc}Udru&3gD?=uP zW|iS%)Oa@S4Q5-^0zcvg&8pA;1YxTV%d%wjr%6DaFU}h^`V6y)_k~%Rs~bc;dWkb3 zbM#Q58Tu1LFJ$hDP3pylxss(pz|1(HzxfM*D*}4S=kF_9ma~(T7Syex8V=9 zBZ1wsi2TbC`@6N$lb)kSP>Vwy=x>Rw+gWu}VdhS#@z&T^xw|-k1dwk7b)I3!~sp)h^cQUT=eL;{E~*%x~y-!6oMo0&=MHgY%_Olmd<@#9CebR5y19Ss&2X zT_w(lWG=W=5(ADCwJklZ`4m%HAT#7AhxSP~Lh`s9-V5S97p8{$@G1uZmQuJfbwYP8 zcjT`z5Mkab?j{0m82BL&Ep6cFT_3qRmlbcs#jzJ8Z|sY)8t{57%;Llfr;VA!cOz(} zwS~B3^gVq%agl8uIt1dAp{_`i5DEw!&Hx6>k5i^LgG%6{6`*KRA#I5n&!|{%hXT?m z*v$!7qPpJ>=bqA7hYy=TOtyd_iY^B~W`B(mA)b?gc^Rr)KuW9-cZf3JW05Zih6S&FU42YGajjA~I zu0A>%p6jrsurygMX%^32r`fyWPhC@E{>Z!n?RLq<@1v-{2E zYr^BE^!&DsQX=$8?xDT(Gk_n5O`c!^Rm4NS6ud+441T&DX}6m9`v2;gL+7L60lx;D zWAtC{P}&z{E9*EN(6!EaISBUnUCw@@(N^jq1Leu6^_e1)GP`~{Px5BNI)A_(-Fyk{ z!ILtarh7DJb)HO8<^dv4i)5S&ICba7pvktxRP+iF7767#hcq743n@{=(?mBwHOpWb zYp>Qg^-l3#!D3IJmrve3od;g~OAJY~ThhPj?;w6$BJlRo&$aW)rh^|DTzsbC(`9T^ zW+DSqF4euE2(ue+i}@Tj#v+e_{h%O!V!ApRePed1HvV2|vAX{4Zy%rBE2*^b@M?mx z$me3O)QpuAt=h#+9)@~0C8HS{sKaf1QhxkclaHPlN?cd-3h>(u7&lRC>!3OKMKaV7Zx&<6CPVTA^@S=CuY)V93a{T7yaHCN_SO! zzEt3Oy}$4x!h}L}mw|XVmA^^a{k_ zXc_v3m4DBf1l#fTK>358q_)CG)QlgQSV2$_cKBjzyu&f7tVZOSA^H;79PN;p{Fq)O zW@2%IG7t$dKyuc)BFz>Jj=E-t&4sDO&5SK&9Ev$R;~ENyWw%2i-CYB(=TarX#A&BI zt;3!jH#j6MYqqw=^r3X^A#*`AQ|yw-*JuHnnoIsf(^HNzm`4mWbp5ZHZ{I4;-qrdR zvDEe{KTUy}f8DP#x!3s1z61c}GK$o-^ zN(zwc`c#p6gw5RFrfZ%hE$cdgv`WvonB}Zx71P#1%#6cbaWyXAC;OK6_)NKUIkeoh z9BFGq*1DK(Iut_FatygNUhmO;;I{Rdn%uYouk=6-U7bQC`g!GALwn3nfZyx=i#aNK zam%M`(P;|LpDJ4vK+fGx*wDIj;isND)Op*)le4lWu>o@ zeb6A{_SgCRu*8i5Z8x35VDw5);U8$yt9~~b3~ID^HMTI8q#QTC=CU9fHy74CZcsY6 zQ99fDAPiASuBu0S%A?a0mC?)>nL~$MUpL7AdiI)hZ7(JP#8Yz=jUc0;s>MZUYUvV) z3%xPF?#6nQz{+#b6zrgV_Zai_<44Vq)`)hxdoH_;ZIR1-&+*pjp>2vicM^WmHwO9a ztC4|@)o@c$WO-u6FG#yR(Y__2PV#2vkL=4+Uqst!CfaU|Ec*j5t zk#JVKq`!0XhDU}=P2j;>WUI4$G!noU@I`69CKA(Qxd3*Xld@yjhS}mr-mQcV=6)T> z5D*F&2SZ27t=~@jH+qv)$(MdSx%KDf7Sq9@QajVSfspj}$@69lw-bB~!c#JClfpgS z)aC%O1lb)tAF;dn*(1gZ2?ld`Pr#oGM=gJ|BAfph!sVX|z}d4?dKwIavYnXTS2jgH zk|3V~26rjy=XCr>RR5VH`609O4f!(*^G{xePtg7c+yod^e0)5N`9V;i=M)&K&mR{q zT(GYxcmAo=cdQAqS{{n{UkE(ZDL(2K+NmWWpiTx;_$C0lOtEBG!HN6>3DC01V?WbM zPsA9kJ-F|qoJ!m$aDs#9$4}o&p3bp_t-%d3RKlVT<+_mme_rrC8jjfm#T3Eww+QeF z#3|@9Y$50lgjGeJ$7NFUt`*k)C(ZC#iR%6MJ1%>h0O+gwHpu!$phoASE0%ed5fl&b zXY;yVWrV!H2YIqHfYl6ouz9N_WF5UT@++o$=tz9CE1e8RN%~KRi-lQ7<=`^ppFQ|( zIilG_0{MILq;)EKoF@)ahW;}G#LB%KaGhp zROEHW3^5#zekVqrWtH%e9?~e%c7ka^3wj%J5$iz5|L z=RY~kp>H~1(}Nu$bQxMQ{EMnGv0W(hBsvd$gf55T(o-=MXdt!YA`Vph^Pz$#$h{uF zjpiTPI7+S{@JZ|Dl{1v3ca)M!ojfv4P?y{2r0(aCIx#%tp31M240PuN*M+fUKXZEx z520*rErH{LH(Tpz$~>j2^Rd~GwF8>W;k1DxNu-DMs6b4?$n@F_^({gMO6iYcS?y|7 zE9f4vhAaQa@3L~`2&?u-37^n%IvQ>=JkNkEa7b(6Jbc}tC9N}XUn<8T=M5x( z6_oNCR%@&v82eFa%4~F+A&+DhAplV7ZNr6K3I6Ay?)WrnSYqWMOq$@{9!&9;K98~F zp|18n_4toh6F;x-GDxaS(|<%=k|0d=*06HV=JZf#D_nIJ%Z_mcHEQI5x9*cSgvHxm~(gN)(cN+~l z#akYKpE*gTV>PXtry`o17q0|(a*3I`sKI}YAc1o*B0RjMvllOU#*`;wYH^N*fAi)$hEA@f2T~4i;j8Tr_IV*l+S?7XuWJ+rNZN0KO+@jo zi*hgS3j3MkJ?tfcdMHhp;)B7^ayrn9bAb%u@IU z3!i)xX?#FifWH(5>mUtnv=$dL5xa@u0H>o>yU+#ORv@j_eHxz(+Mw z-!6pwyV?PF@rI@7?983mwj(?*aN@E^MtD7Q56`RfI9F*>pKrV?CY^VOc7pM=Q7h^2 zM8SFpVQ6?WzTbot1uEk8aUK5A&-L$rx8N~U)I|p5q4G4UpSA+ML=*(Ba_9HBl!eZB zgV}QZed0m7We4$9Rkuq^3;)T70v?3LpLw`zbZ9<=M+J?bw65#$L^?OP!KvHQH|_Uy zEAXK)YS2RdmTg`c&r8s+KKW<>LnLTnK+caLD5C!+bsB?0w)mq#L#2LbkRGs{k60M0 z^a?gGx!AP2`e>cq^72(BBo~N;tSqlQ2OQul8Q8{!hDquK;v`7*Y%rokpmp%&Z=dQ% ziHjpo{H7bo(;#c(%1;nw_&2W%O!9-{U_Dqsn^-qr!(fEs*`trhYw%3s+;Fw`rofHATORV*N4(N@XjX3+0^o-o3BRHv!gr*0`wqiT(|^u6Gw2kT`al*unbctEyifbkrt zf*jPo^;Jm@Zo5!7kyNi7j{+47C&q~738&GOq4cpw!GL6njXx)#^ti z1>~?a5VtTp`MV9{CPzHzmsOIC< zO*z1S&IroYH+!HG0@`nWCd~4OPe{u8PKS<#7X`Ac)~DjXf-t;He~KTNtl|~2Ac*Bp zlOTgrI(C$+Ki4S=k~I{Np#hKB!w}VUcOME4v7({cI9D+VazBwCZ2WTH1tlKufTn0G zWfF!SoJLq|3SYfp063uO@KxmCe8|K41y0)$uwpR7_cm8pl}L-=Vt9sBLUT4%+UdIX z&(0$Epv7&9VL=~GN;V`znB4DxE0>72l+W##f$-EW2b0s}Ez8WED4k-=CC3iZff=Ze z+jTgS40M4=gx9?eOAo`B-^78hDNql%FmxJKSg5D&rd*6n7fUUTBLcE-bp!i;y&AL2 zNJixC1D^Uw6#$HQ6%C2aN5mMuUWBBB-p0GYp$_>n`!Q1!Z#+n^RWGDL-i>14+IL_L zvW_SXx<8K6uD|vX;YJP#)V#D-a)~c9<*lwnH1m{MJGhv>_std>JWH?&Nv1e&+LlZC zQG7m~Z^OUORfgi}w!Uofw**;;lNPYT~-cQEgSL=MIcZh1;~$Bx@Hh%2u)dN6=&i4B&1Uw+rYe_-!$J1-3z?t#SE^-yZxQiU z(-Qh}#lpE(+bJZWFX2-b%Y)>AFD5`i*&73>AC(Q9wV>QSg#i^Ozaxg@t3Z-EEa249) z(nX1p2wJJ&1r|`I2Q64e$IVz7t`Vj(hJ}-Uz_DMXYWG=nh&xP7R={ZkrLe3AdKW|wS=}P|=7-IFmP!&CmCYs0z?L(GFm{YTxOOoFI1-)`}w&jXcf`K=8TNqXz5OJFfcU3q(M_ptu~ z7F#3&X|>%}jNIaxv(?wG-K(3piZ|WIu-egPDht%TwI`pxr|?nw46*Q|oeZWKxyaU? zP1v{CSdfejWt{P$UsK)rM<+fsG2*y&Kh-iWtH2uh5m@BwUb;-V%MzX5Mk(iTp+3JM zJiRdUwy}h=NbzcadH`%VZok4KpNZoMMMJ0ipyB(gpgfSmt)&PAP^-rUeJ2c2W^ zF=3Y50a%f?PkyqR65b6JpY_YB*~y(iZl4I%S^cu6GrQhO&osj2wwhiXDv%gA@HQ~4 zWYBk3Uh0DA-u|Y92_?CNj&^z3_Shw>%}i*@Sgg)$VxXm(fTJHxtqMgD=)7Q0$h6GAmg>L<;=1R6WECaL|)FZC8*sw~Lo~Wx?Qt;rs5MuFjz20Vu z(VX>tUWjc@DCKp&iwLdkX4xNWrlD;*V6{FO6MPh^H%@2B$F%uQEFHs_X+)k5;pu9Q0lSJa zs`x);FiZ{Nz=9h`@vn7ma(QNcjq>%BM>W!KIiQM8U1{4X`$CMRxYDlcs%w(D_GH*DKC^cVP&c&{N|t>Ye{s&R1M6|M4Qw z!~+7&<^(N463O1|#HMM=u~gWSg5dNGJ*>S9guZi;E2$|q2MCYH3AlXdd&^vAPyxrE z0;%ZjIW3>85d$JkB9=yE_shDlQED9?VZ{1l7k>q!DI`hyI{r9A@*r9R)(m zgUY%(5Nl#4Afy8)K{SI*<8Uwt%vN;@2))glsb8rn)XH!1&~563G_p^1!N5Z!*Xy^Q zFMq)Kpx+-doUMg1Y-a2bEJ*)%&stDrf|?KRLe)cL$!s8Oc51vVA%Zf51@Zh&d4~>@ z(In&LaM^40A0MNsEk6P~-{SjSNW zqrF6op>epD7&2DvZU4G5veiSqSe33W5)E$>|2#wt@LelJJB4({h4EtEM@ng4^?6|p zHEcXT6l-lu-`Ftjuq;kiLx!|ZN8oOu`}DI<%CGjGmS2tq5c296?35fU!xUFy)x!f= zvXM>g6&Vf`2x4UcDtlE|MOk?y75*FI^YoobaHyiu=hX^uf&*n&ur@cRg_C{ERw~qZ z?xF~JEtT~*v`1=7-G!J1(Xxk<9!pO>jIBtW7n}7uQ%}PFIva4J2eBlt@LBN*1O14y zYV{z*Sh-%_79^}DUdOebzM;zq%NJ(^YcBZiWt+%{TK_q^H_o#<8Jlf27DVGpw^bAK zFG~lDE*mRN=3nU*q78<$_|(?DF!d4w5_FG#O6dj8LdFMu%{fz7K=-^Nnm}bM6P%Aj zxhy#@O@r_^h|k)G9}8xR0GeND7x8`2>%P9R0M&dX=wN?>!{q zly^4#F&_S>xq*RM)C#H)s0{Wano;#lk zM(AS-=_LL@XN9u%pX6b|4{xv}+Bp6VqkeS0+~ccrCkw>`HSOxnseAbSqm#_f04} zERkSID~TQ=X>-AGMm~d#BVAqlv$8hoecJD?s8R{G?X|%>K`!*R%NZP~+KK$sVy z-u71E94cV6s}Qz8?W(gH@CFqT-1WtaHq2ii!oyQNK*G|-{%ulaf_+CX3Y714t=&+f zR<=%`lRv0vkVx8rDYS;7emO(VxcpaRvRdPPqqMXpKs0)NVs?KA9P}$cv^kS#wIrWL z9`k>_rDq?XZG690-DZ~wex4)6vw#^PE|?3>7QgAnJOugqS3wMF=a-bl+$w$VRYPS++={_@~d?PIWR3^M12G#`;w@Ys^++p|k{9fZp(Lmg`ty4Fz7 z>x(=azD+27eSMEWC-4SPHdG(M02|#-{0`hC+!BYE*vp zcWh#+a?;hrVANEWmmQD&$pn(y^-G9zL6Z@ZE5vH>fX`_zHX1BkxYYv^ZQ$p87C?9k z9oSo#zKH(-5+L@ZX^@1{bm^D|ya%Dd(?NavD8sXq18XA6G@g}f%DtHA#-#vFa9VUp zpx+d5qO*KBTj7<5@}33eGXI`dJNw7(`zfbU+i$+yzU#H}`k6~M=9k{R+amt!sn5Ue z^%>ZbQP=wGHYvL;E0VAY@W&;sg)m}H{lb3HISE4btDT2KY7hSvRq^t2smt_~+00Fc z@|bgtG4z|_i1@BC0|>(Fb3VaqAty^uGZfi0_T4!4gds-L%Tu4eq%YsQ)MD%w@CUW? zopFxK4EL$@?oj7i$?pA3KW4PJ>!95n`x6>jC3_l5Ol&$%RsL9%7cu*oAD16Q@kZ%L z=Bn>GDa>st9KS$hlmx<0e@qZgs@Nn}e$tmQ?2Y{rAr&A!9rFUuUBMRZo7~E36JqR+ zx4%hDpc@pLstz?PoQ95xN7S+(Vc{MxY3=6pM+b6b481j=3BC8m+~b%nrepU09#6t} zSoUxnT_AXur~-s4CIjWF+S%3di-I>?I0rCUIQx`)`j64pnLNtP`z*<5-kF??v5qZo z=MI60t7rMrnG&@MuDp+o6uMmbQB!6!YbRNdG{D-O|%P4@_%7JXaC- zpMwhX(Y$(?Sde|;AJmrZcbca!c@6wUXUv2@a@UWzz}clI-ApbEsvks7K0S!>og{pW zgy*-W1t!M|?s)KfY>RSit}&}v@c6H+$?c4QKij+h=>9CsXc;2+jyKPMQwmZy2AD5I z)Spc6r)Z8XMNUY)#wSc@)^uSJ^WL?Dr^M9+L5=Z>D7$q2SW%A+^|~;^i(`6oq1#jM z>F;|8MhOF>L@DW)*VKeyQv~ningDUoJSU_Pfm(D3)L{99k98>jc28f26FA#)KOx3L zL$HzJGn1)Pf1Il0IYHnAUjD`mvnv#(cB4H$3jH!^yQS{{9Yc;z6?copOeMkBBr1GP9?Z*n>_ z>vYjke%bNOgI6C(Q*Boy60&$oXQWEbStk?RY=oA0x(Yqh;as}I=)LR31@!uKRu$jEd=GvZc{LpZ@awMIx;Ym98a^}NrdURK* zpOz{ND(~BKY%Y}bNO3D`dtx&?ZhFt%7nHe0*Af6EwQHp+gMol~i=xY={xa6_co*`V^L#5S(~8_U|7dr{ zBBu5brhTn}jMO^~b@kt!Y452#XK}nE!>jXQz^ws0C9hWNm1d7m_Uo-AMx^I{@(T(# zYau_XOb@MroBdk0zh(QllMB>B$=X%%XgiKLdwjB&fn;A)TgHCYe)$}pY>$^?P9P&O zzUBB`j-75w{Nh?NQ@q#XHGRjCt>Hafy5Fceud(6Un16u48_n$ufjhAueNKtA^(`Z~ zXTDnJTo_YO0si4YS=-WFn-fld_&r8)_twLy_ZRUK^sW?x_wVftr%Y}uz;Lr6vJz)= zR0(g^0`M?So@cV9?Ck`rU*q`d-D+m~nF}1Y-Gx0FXFANZ82(;46M?(y-jCJ8BPYaB z_SH8}`%guv-Nrky|Trgfo}{FDw~qnDeUpI7N^I{qFAtY=w)-{XC?;-ZM*5cUNY zV^Z*saaIOTWtZy#lFn!MxrYX$?@ru<-ygARufGXV>m4bT=q*i%va>VZ!I*UDX;J+f zT6ze=ey=dmWP2!)`6%!@n)!E_VbUX=F1l%eUb7(5u15Qi*OSvoS2y^VSK4mM6P5WK z?g5NaK=S1rsHew$LF+zJ!2Y{>TuFI9L%XaPWGl`P`2)nO7@U-+!bS2$(EQhmaNl^ zWsJeRpKG)|@Av1A=YHs1*E#32@0Y+k?!2_uR&?8t4| z)y|?&zmXR?_FCbZO@ev)vh_NiVr`$towUM~<=KQUCpbOlkdx|_-j?MqUQC?ME1XKy z(&`)YHaU6MJ8>G_6-A{yv{tB(xm@Wue*B}R>vj4Jb=B4)ITiIS)O3qOMe0$7>57es z2^=pUX0~tLJZ&*P^7!E_W%-PHZM{jIIuHAu8I|{r7Mkku?wE&hJZZU7XQRJZ@-mk9 z7q!?M-=nT_T`D1QKr5D{1}0md7DXKs^peuJXdJ{{M1nhSYLYpx-c-ok!~d*(bmGu8 zl*|K1ArQ26bN?3R{WzB<%}8ho$LO!YUOPytlC|^0j`lwIxVbN^JzXm}OwzqCuynV^ z7t<8KDvW22O14VMKkALMZxXF}?ka8J=VS^MZhmCk=cd{y-`XTARPx{B%$g?o!R!gz zV)hh%PkmQ2uEu>(7DRT^1Uo!((4eE17i@^Hk>%D#I!{!T)`CMz3^$^a)zq z`CQB57fqG#=4ZZ^&NrVRYM7Rb?|A1C^Q<~$No`8F#9;xu+kR)7ilyWYe8-jN#Le__ zh-+H~?3ww-;5krlFMHq?J>rmKGZT$X)#x4d^xmz6O1!AT3ByZzv*xMGrzu$X%(euE z0>693>-E&ZxhQn6{W>c}=d1m9dQ)!8%6oo^QFG0@o)lvD<0Wqqk6%o{z5f)Sj8;aq zcuPu~YUmY_cC}FDh;T=!)*3eth)K<46D^sp?%X}1Dee(@`DLSALod2(Y*p3J7<)=r zYKCCUtxeNjt+GsfodZev_*N7mMK=eQwG~bbsbjw9aWm%Wtf<^i}=p<(<3Rq+gV4L@Q+nZ@pt?p zq3U`^Tr+iV1J*pZe`0=A5?+EW)-{+qD07_{P})Pu5ajr>b=o|h|4Ok1(=aM?!mzY= zk`cv+LWEliQwCegz`8&G5yr`hTp|nEIj!~DEG3H~m_>$ApsTm)fqJ&IfBRgC?U#%D zU&>ml`qYAvS_{m_b&NLff?C;-!P}9B>e&wx*6Gehs*SeRI@?G7sc8!;RD< z+yw^%vO5+sj^D>WbTD^vahbG9Ux#}854~caP_qbW)Rb(4vrj7@TZa0NQpc;i zV;bn+Lec$vPE8l$R7g<7QYtPh`EX!pUxg<4^~B%f&~+wlt}NtT%0Ok$IDRYot#rU zzBNct8j`>txiFCtw1sJI%pbmYwyEesKS5E2s^+;je zJR^ce7w5*r=b2e-{JlqhEjfJT@@;wqFyMtxKqSGcC<$($T$4%y@!5Q^e>LD<<|qPi z*kZ@vjljtK$ff7S#l?P6dr+D-kU?`;M17~bCL8vz*Zc)4_RGtiip_F!3RG3x2e~<* zU`+wk&U;fv*`nFin+dzl|8-=ZTT^m#BUf(In+k%njMxP0H$icUjHhx+6*e_3cb@83 zG|wPJZTk&iTa|Y=A4@dZxRi`e(|s}Qt%Xs3VZcH1Fi@cU|yx60~1>$uD>U1=`gOx*9^Iw*v^6J=)c zdxSAm)!ad3+K?|=>-~1g|yIzk{GMyAz=O9 z@2e8MKqi_6NoP-bGXjNI{ej5z#aaDtQUAPIEGHgc#j>U9=I1|}`}FNH`~!*AH?u0y-LG{0)IVB0hSkwoDrCMF!mpoQb{sSZ8%2y=0u zo@rO~RpZ6#cBRTF|9<9%HX`!+O|pw^D7#1TPUdrI3<-N&A>c)J<<2HnG`s8raDE7MVW|za?s$`aoCCR> z-pM`x9;iF^8@i{(8xg(GI(vuAJUx$_qnC1}7&w)3t^ua1xmK---bF%$J4g!8P!M#|9*dwR=h*ZjFQO3#XcOy=Xsm{La9nhtBvq_1c4}duqS^q zbu(YV<^cQ;o5fz7*s^Mm(*{PVF-vaY8W;dX*Cq}=O;kFfNmf+i${D7Q#5-`5Sma#c{;+g1S)rOiHWgb|i!au= zyk=D-!lGxNR%qRm26ytOOkSn05y?N%>T8(Jh>~a$xB>!b#_|nl&s`*%bvgo!Al|3* zXSznKOH*a|{(3AyQQAMdL%Bn=oMn6^1QJfE880$yR-WncZ&$lpi7(+d+VGplYdlAD zFZezo>d#M+%M58s8O`GrIRG#<)KGGa|dS3L*)DrQ| z+~*K>m~f87`Z<<(o2h}Hwk57b8UBaey zA_0#GQGljKd2kN3Awr<9>D_jkf|!(tQXt1+7VZ+aU%7IHW|D0A-7$3}hL8WZOhP%z zCG$^sw9e0(m8(m&r-XTx4ag}RJcOJ|f273=mIP$*e@9UIBQg@MvC-JLrpMda8 zlT8H>(&u^tEn2ajB<2(iat636I(D zZJRC?uMSE%DE9}E%^aMcvQ3UoraCR37*+U2U?lr3p9G;qJh6J^p(kS(>j#>;FEw%f zQPKIYjS$^FCUuGVaJmr$RN~z=EInN}T`Qrs5vnT~YX5VM{`|?CCpl9 zoWxm-Pxr+?vOC|(NIlG9ECOF)?%osg^2J7$JpxA3FG}C*nZEd3*+_jE_pKwmDbUW# z_(<$7P;5cJSzYko3W=rOLqG|`Gj_EOd1emW+XeyIf3f2Uo_&pkO9rK8W6RGztlSy& z2|^TLprKA`-ES*=c~-uWJj(Thq&jW5`_z$Gngh&XJ4fv$F3-7ZRK_A}6TS!s{)38F zE=hUDHB^xh@O+>!$vnPl&kf?m)tl%7EXnerr@On`)Tbjx8hN5Y#B1qere4L;QItf$ z)!q9VHTqI`afBiJbpg#83Xf{uRA~TLoDNlNGt6r5xw1E?aX<6%ewGZgIx21b`s%lQ z%sSM}9oNz){_zg9%!HQd#eZG%4V@a(qKHqT_T|4PZvi^Ycy~s#c2`DwE#sT-H%;Ny z=Z@0@`i92Sz>JM6o&Ta{y>)dT)6MzBz2tklq^x{q+6^@h#c?0u`<#{&Mm2pAXeuS; z_nP50IwZZo&u6v=_~#kTu}2F1fk#K052oItCieF6oKF3hR%rwy98un>CfT!A#`oPo z>|`WF_57&C2b^)IUomd#V@qtJtpU+pBGgovC04yTMNSSL=+-@a_;Bh0c4Wd!vWyt~ zrN;UFNHTTYxak7{OCl+Zgf|hJrx)GRH#9FXZUE6QAvP5uAvJs`c#an)`M?Qw@7`^= zPkvD4I81OwC2lFt(hR5&Dol$(VZ7)UGCK3+E^r2|?4r4j{i zgpu!u`|1Oq3gxFg52tFzI}jGM=%xd6kzz79p&{OUw)h4qfB;3BY9 zKzY*#-0&U>pqeP1Pawaqb#OhmsJ>LPpQ9NK&_9P)sy;(;7||An;m1MdnusPs4Tnr! zewh%uVWJj~es1>PY^T>kOD?-i5^VLON1;wsJf2N?sQwsotnKg)7~`h#$|5J^mZ^B4 zpStWm0RD<(yWE;jNoK~UNz#z_s%^XKgS5&vKu)sDXi2L^DR{IJ- zT?!@qGCD5zy;RIvJiCl4o)+Y9@g9jwC4R7*YbSr~h~%f(*5l8UOhlSKJ$moX!ev_a&?5+r%;7 zfG7UV`5JZ?ZuA@lJ-NL$A@OaCR(VRH$!$U4!@!> zoVIP~Mh_BBh9BFl&(~8EB4IKWN(Kjr3%E57@7IbNH_@gifx5eV;l{%r0wRRqXLt*X zkj(ZB9DLy}FdzPUx%u(9qq(>KeRjuPtbalUDX|QC)XoS{uFon47x~Xu{rLWPd>Fgz ztbLytiB~ABXTS!Xi9l;s}6^)9P4F3PzQ8li3f$?xHWdCi`N8Du4kE=nqJ>h z?h3Yvi9~>OBb&-iK@Qsk&!$CK9H@X;JSbcDJ3%&_9hm3XKH(>-GV+Wjw2I9BM=1(`>6MM zydmlbj#Qs}o!2_c(55FgJ9^$|5Uyu4Gqb}kByy%zrdfj{&K`+y_|6+qQBmW-1~9y- zj|Cw!Rk6=~ISoz)F9TA>uZ!kc?;5)Cup0-6jL@WLKQX5a4H&UVS^K=bJ?V^6eO_K3 zdPSnyeY{+3kcr2FUZrm9(hvf86_P=_?2H-Es~6_h*;En*AB;fl+^|9n0(N&6rq0Y> zI*s!W>jlahC079T*FFK%NcWfK?jzfe7u>A+fH0d7qFGR=CT&mw#>s}uz7o0^+F<}( zIpA(5B}&q|WMo(da~#$LVOPXYd<=+a{o0KM3Cbz0{r|Y8%dzx5=eoM;Hsnl`dOIET^%hP{QVO(kvs)z|}N=Wo;Ul0 zytQeUfvEi8PXJy+;_$}JSMjnF2dsdM3z6Fe4@CSI(dvarRtF@6j6%gHskWi>5=EH0 z&5zMkZvewlSU8-Dq<9vz|DC`0ql9&>CxCQVUO!!FE_*&l{>>z4#eot5*~Xghto2A# ztJ>;*e~}acd{9^^q0A!Eps54aZBh2zJ?cj4@wFOu88<$FsVlL$PkN(iga%rU50;ui z^auWf(k$vxeSf()H}jtW#P>VzCSGn^D>n~}AOy&~g&2H?5gB2&6BJ;-1WN%b;)UTa z`5Esn6o7d?7p40gH}Yi$R<2_jP)K+3^kCttnd>qbo=&jZ+$7ldJY80tUUsr{JrnW`Zu}l zt0MOqxk*DjQ2V}yd?S7IhR7H6PeJE+cXoD`P4_Cgqv<#oJYptQD4}A)`9bG$AZP!y zDhwyBnpZIr=;r$=o_HOBi9UIUEFy%!qYF>imVHk(T(36)W%It}{W38!H zAhT+fGZ+T8uGNY>i1?8Z2K^Tkb^i7ur|<^kcZesW4H9w@Z`#N$4*)OeYOfYWmE8@1 z=s*xY)H3#9fUSxPJqJxYz)kNm^%A_@oSm(Tt<>Q6AS2MSweFJE=!1MwOSQ9kk<*87 zXdjPdmzjnTF8fKcj%m0wM-0mxlHe*BtQ;Cc&=q+U3^!}p>?L0y1(`9Ion0C{O+?XB ztb9|UPNd?GhfARIWTr7Yr1p_@$0;-x&i5>@gfZEHS+n-G4E3tb>cPjBnDtO}J z8@=!*TQ;OWjIETWrYTV4e8xW(ojWgxtF4EfY2Zlm-ca1Gfjko zxMF?B`I{o)iQ%vz_i$Ru?gqwt-IZI4I#&MN#`|Ki1*3cfE6rSo%K?|ND5W>bd=8t6 zx0YpNPENMgun+sEalxs->~7a-@H_1<+wFvG9ApUxx;6{{4^;yGc#KK2BhI6uba&A= zdlUa!7rfo4f|m$dQKv!+%EBEt8^jLV$1PA0uNR<@#<@s>pLdy67C0k2k8XLMQc3$_W@%Z`g$ZJSv-uBw_8wjt$3XxEK8RvTM`GVsJAyq zaNEef9MQmNT^Ji1lVTm+KfXQ7kR1NQwagbeLvJQHi6_#rS__bma<_~z)vs6CHS$Pd zfhG0ik5T?zJWUDoC}33E-#G>AZ8rrndWqE+SDq$4?zpUG%GpBbWEbBzbjytoE77nl zQqPvi51MESf)%pc;hCDwm!LTFS2)jon|LRfLx)F0Od*)lFWbM&;5J&urpIXivbGGs ztD3K0L1mpLgg`4sVx$$`%)NHih<_&SN{&0&xC_Rre;^302z``H7SNokYsjI7lz>e!%4ar4(h3qm@PGGODK^u66rL+|F0N(`6T9m|gcZ(h*_BVC2;Qmq~ zPEYlWEEn?{5`WudtBKPvbgw<1qh0_<-22|rqxZr>NCE{{P9{cNE-}fpoamsi#Ne8jp(5 z;Tt4{uAdQoQn}*1!=aj$k+=)QzLJKBg;Z5HgYSX4`&_7qG`%2h%L(+VA7$41)JLPt zYLTA!0b)ClfncR)K!-T0?@c}N=v#~KO}H%j1PPa18u&$?3VvJ7o9*aF1<9vI_m{WV zvQMlMW`nrGU%Sq@F}mVheJ*dOJ#gqb%dOXycBkXI%LV|h%zVhJxYR38A?LH|e>NKy z+gF!S5xUP4Ga9+r@_kduYS60P%5_9j_jA4N$JZe-hn1)qXv0Jo#O?x9SA-tLjMHtl zis_YbWu%Ai$2G?zrs`72V$UW2(`?8?2qGX2fg*wD=_J0d|I}bro*$~l*LP|G*yWW7 z5@&VN$Ux^Q-fIcnhh$4u;>Tc^$%rB%6hgyxR6pi}dB%pd%^`hfiScCeWe5flI+3le z2Ohx~w2DuIRrJ62krGokcbB3&iF)B=%cLFaL}}Q%jg0FHi%$h}1MfqAom!btdEo+*B3hx0GvHp8ZHdsyQqrsTOUn{7 zh+>50Ajmm$)}O~)Ec#yW6<8gZoUG>OJuS_oN-KcJ;bvLM{8T;#%K0#JA&==h9jdYT zZE`#}C&$I6(#L28_i*+1p{i|$h92?$uWk*fONr31ec{O2C8k3u-@?;7Qsv}=1T~~= zU}da=!7ISoyt9?6+@v|k=RQ++b^3Ii z>NX@<*L*G3FeaL@w^h;}Iqe>QS_QF6IF$@z5~r6LWIT5d^1T=FPc#xiW0}I=)dzj- z!%&jwhEZ_MUL@ldvT)_lHF0W%HXue`lX8R7cd7LrxqqacJ8qRq31Un(%{{&LYJiQR ziBKx(s}sxHq2|?6JuvdeZ*goYufYl5(WAqr4TF zk=s|@N~;C~g_Xkuh#a|t_<5yk@8ih6fgfqTDJeL$GGfFBQD<(1zHSeMxZ&a*40$)$ zQXWDJg0v}`>39F(EQay9>vp+~n@K>j{ZF9)gz@9ydmo`o;avy=9{56z8~r#7rh-d^ z?Qt3xVs}Qiz6xGMhNSjtF3*g%7w7G2YNO@SNNA?dGlnX(^5l%yrmb)oLcl6_<^?#_ zN5k7rk*cRv-AuITPA=Tde26^l-Wj)%TA=TL^G7Pwu2=DQ(#S*{0iPLP=0h2n97nng zipfkEU|ia2jJLbZO7bGFJa0#O(9zLh9al|M#00owM&cONJrK7kHI^YU!Vrx#CjVRz zJ#q&#dVA))WKnf>;CRWKd7>8`rslX3`_q_dUYwIeP<};Ylb=0u&A)H>Hl&s3i)So;4zvY(Mo3Gslp9kod z`mRHwB}1=kSL&lWiGat$%PY~%hn-4;!msl51!GMqOJp2#E?|j*W>U=DEPo5-ol&Z7 z99c%HO@-`PUd-BnDl6~@OC4l3t!OR@i&$n)TOcG7Vd70GmQHo}O$Iez_Xi$M$yCo_ zL_20{`GMHLvNh<)5x5zuSMlPwZ#P@eVK7tbrwgS(1 z-{$1B&LyaV@C#>D-c!AuO`(-+_1=yE!#P5G19gZ8jjLm(t@$lS^TRxyo?~?5bIAJB zvhO126M572?6~@wK3EV3dmmpqtiN(RB&Zj&7dj9U6`FWZepzBT{7h!JBcq$6g}` zgF}0AY<~SnHF_3F*zSask!>gOV5)wMn7HaiL~8X1`zzIj=D|3m;e#u&b%YSL_cawV zK8lbwrS;q(P)^j6d}>+GIwFZK<4UxZe*B|R9^NCdD^+{=`3U@XKUX>%`&MTGrE6Nh zW$|f^+i9mPNTMnfMNr{SjjHD>LY@Bs$T`k#A;}k!x;i_j4k7Z`P_x=KlEbdk-)i44 z8vvmA*gF;{vE>`$23^vKHWSlGxoGB7b~P;rBFQ!SMu$|?qb20!P{Rl6IkK?*3hrrrf8rNuJJL8z9K$}P*> zi0Xf+{`)`FmJDhC!m}|BNDv|HM}q{th;!WK007W?a}jCP#JN~$of*xok7PBPU5pQ` zBpE?r@uW`Cd&%=^63ebx0)`T2)6`SnkVa|5Q1lWk9yiNe=;r7d)LGrx|F3lnf!2Fi`U$ z1R3%6J2=SwlDF1<2;iP1*@1Oye+5}T$)OA9L{c}umfszfr;{J@Z_UtY&m0H2`Pl+c zqtDnfaKDFw7;(Que~mZdc4sK~%du@4d=Ng}fG#cus3wYmmvp9*Jy}6T;E2ZG>rJ#U zVIIYz@*g?KKkPrB1(MIWV-qDZ=^_i@dTM~!jXO~1{sAlLmp;6#)o?v-dH$n;##6=p zf@-G)p}fIGGLl{lv2j$;2hP7tutQG<<8*PAs+(fOn+om0EYxs`I3Jl8z!Ia;P>I9J z?*izbaf;9~i#}|MnV2D2Ak3l~E#E*YxAA#z@;1?ifoKOF{$G|VD5cZ#`hoWk)^ip8 zc>Snl_=f9EX=!U*=T2Bl`+u!fk2_eOEqg5BxIk|latizG^PBS||L-Y|ft4p3)eo>z zJoas-&vSGkQO&LCd{UnHUuzSZkO@B1;NZybWaYbLE+^}^b@it{AattPezmw(Q^P3X zE1^GH@li4~ZEX8LW5CvjD(MUu8$uZ-GM9)kwV=Ow+hrG!4>LqlqFfF&P9|&M`VT+i zB6*C%-0MY2LO^f9B%vU!*MMb*I3`InMT_uLEg(Xob}WYc+;b-myzt&@Jlrdi_+Y(< z;#%yrd_<2Qjwnqk@PR%<*n*dHX%lAtjZ+;Bs=ba8J58&p+`ShK7UMMNalO5lzm)R# z2JT_d3+xHb*&FtRaWY2H%iqxb3+*>JkQ#&Or{)No8{mzNn)ipDehYdH~&J ze%oaR>djn{HhmAqJQ0Q<-*L@ypCl3Kt=A{g4=o~!*?gqX{qZSmq>j>$+k1gVj%?rG zCW?*n{y`=-Sc=j#-Ph3a9{(ie5*8Ymfe37qms z>qVTi{q=E(WGvdgKdQE{%V zRQDf|9`%OH=L8GL9c7Ei9a=ON(lyFw1NY#RhqfYl)qHCRMOe9~&V>RVa&vR1UL-c) zklaJTTGrvN;?v~CP`CdHu0-3MFp#g`IY(;A4g;0nT#ZaJwCG2bwiys zQ`4)n_KF5T(MLF%34?^n0~i>3 zqv_!ow1#?#AUa0cu`z+EUgvg3Q+-OhPNXiYG|JbWzik@k1s132b@*&4C#NkAik9Yb z;hy#$j$cde8%8hwhyFrY^u-b7ZH^iD&cUS1Qt9bVOSjno>pG<>+(LWWT)<1&trW7m z0E4PnJ1%JBhV&D?VW;~nR~5Wulz*pHpLW7TO!6`{>ME~K&HmU8G@a9>m%?WJqQw47 z8<(M~JHbUj&3C5rKN*O_XcEWk0zdjC4+YF1Jli}@fts3}$|#?d&3rL|T@hVZR9pM) zqr1*Wo>I*%x94P-k(b-M{3hIp3!SAUv+73>6i=8vt4#I`w=bGkgqkll?vYB|hn-q2 zU1dNvqpeJY#>U80o!Qt#xz3sSQKb7Vv=q-qedII|=6jHEbBc~w zp>96DFy3APKa(l#f;E`C3LRIacAp-Pa8a&^Y{=rgZeQo?o5Y!4$35uRCKAveQqltr zJ$3)o*=JM28PNqio`T12{@3p{U`6(t(pZfxpDgt?2zkkuuE=Ab>3K3}z9Os=zVp!K zl#B8DdhCm%Rs&C{CJoIv@@`0bGZnu$B(33b zqsZ)on%)@Z@GSNuqVRj5?!<9>nPFR#ebm|21f^jY?N1l4^~qUYg(xXXS4;C;uxh^Z zOJM78RNBM{A!_q4*craH)EZh}B%b-0>xN8lcPKirTj8XRj2L15b<}H{o20;RDn~z^ z)Yb|gzcoboFpU)Q%GuPu9H9;gzt=`hEHM?|3%aVjnc5^>Dbp#4KE6YOX?b(VeJ$Om z{}RtuQrS$M#8Rn`vt^Ef%*l(t<f#$@58iR-6N(yJGublT91U)dkfc*)1Ax+YH6{-7rzOrPGZ06F)tmhjmctC;cuclc3+j7EM}v_3+=R`8B?FvLI7 z&}v^KLkd$uqp2|@nbv{UbtU61<gH z%lVq>%ey^9lzaqja6=Cnl?(0S+P&_(|9FEQ)KQ#6#VA1Q75umnvsbL^73>bXETLEJ{R@rscul zk&v7cqh!lKk%vYqIf5F|vDUNYk&i1noS8Ng6Ss)-9*LRX?T4>*+#3mAM0fUgEmXDo zimToa@zELzB=M7l#dRx*W3vKebXB|JJMW3>26WG%TjeA((Ru>o9K9w;k>^6TN3UrP zDmHcbUra0qDZnwCkSwsdo&0qdOK%a9Y8&>}Uw5QaAhGYQJX(Nw5h4Y(SFB>$R39_p*3PP!uoFu{J&y&M@3;&<`Py9i^3p?n)N>env#R`VKBhA5 zTx`tMM5*3>>C}!b)GF@vCgtorpEk5Z`<)60qjDWR?4_|@uPJXH(WixjFTLM+-~pee z=Of^U;W_6_m4bYm>6nDK@kVd#6HX2E}w3hC%$SLuL>7(H=+gcD{6*H|%|~NSSg40yyE$A=x(nfB zi!&NgH{;A+U{A+#*gsr&aA9=p#YGEI_%ik`z2Givvb)qcb@qkhc&i?K(l?*5Kb~Xe z`}H4<2SXP3&-KPU-`#?^_=nBJ}OC zLy9Q(V0P<`02u6aH`qVYh%RTDa;(aEk6?kE?d=J8e&)+J(yPiX1C&<#STc<-*)cY6 zx}Q^AVRHpXS3ni{0*J3WFW9z>Ri~Z1HGQz2p!9wGi#J{HMqr)`i^N8B6K+5fw0qCN zgtNLHWk`6S_t7(-ob}Y2?E#Mu#c{kULT~`)4B&vE-?(1>ZFvVavWdo7^o3nAbVNzs>3r95}l5}!!%OpiW}aBSTAGTiFV$REXO5Ts0(Xa|!~bEF6=-XX;< zt@?v??y^z(YTF7Z;mhJ59AB4rY0Zm+Gqu$3UbzW%CFhS_QIauM>sP)jGbP`8oxclx zK|(F1b&=oED=6_mMPY4O+Bm>@k>bwuiV|U%mY5wlFA(hiu5q%mj-=Wro30p7kM6=a zx5GHDY&qw)qp@g5jXmBPDHme%cDI_YTSMgIJTc!}I8>xYOS*Lk+ z42}oxgi|3xEy?y_?hn5JFE6jIJ)Q|pKsFk75klC2P1Kq~PQ9n^u1Qb-IKR$zj%8T( zZVC_=zS)Az9jkWL>M#oSU+89ks9t(L*k7v=algnFk%1|K8o6h8ol|SYuBWE28B_fJ z4L-|uEC&AU8;c$)Gg(X5WbbRXi#5cc-&UJ)_+oY-HY+NB#|LU-Wy&=LWj%^no2d0{ z@^bKCvE)zZ7gn@$P)D~j($~{E^do)L9S!U%2e4rJUSn(8wU-4zVpG5Fkw|Fu=SNnvDCmD)!L$gqoFY%ke= zGH)dk87*jdCKjzeQ;Q`wb!GdtF1SmXYvg#;yA_|qk&}sV1fS@19%fVpsGgEj5*{}2 zZRDu}t0hafDr0Q;P2~?~Ahlo$@jk=}D1?s>V^w1OM+?&Q1sEL=`RX#!rp>MdDp^o{ z8(KY?dPT`GftI^_#5y%W5Zy(G00@pS+Yd9ppvlkiT7op!h!(ob!~B(Cn!x-v_Mpvt z(wfUfbsJZUtLzxWQy=6xmu;+*SVwomF?z47<|)qGClZX+bF>%TG@*A4%H??_N2sb) z&15k}0XI5j1l#}0_(OmTw6vgXJ>jImi$DG)L&x}Qk}rID=kg>Y(g#!RDxsh*t*O2^ zbsg_Vn5_mIvQPP$t;3N|`XE;Pt=fj3XQlEfzgUKkSfw-wqO*kd6HRZnyx^rY?HSBo z?en1EC9`qsS~`qzr$#ruJFwnS4K$D$U6#PG>gxrqPA_*qeFuRxdr;<<1drI`Bp08)$q%o&weQ{tma6H9xuxv zb*Pjs$*}KiJ{fCBV0l2@PliCT%n066MA>&AQ3d+I*WQ<&PDd|Y90tqi&9)-CX-U}F zlB)Z_yP6Sk#1~s-d+E(kQiH^_)5uT(!FhQ=7NgHM&TGkygh0A?Lhwj4a9%J?DwJRE zeb=2D_gwn5=IH60I$u+>1kuQ+%#MKvF*P*(gyuJ8T-RLFH6q(B&ZXEvy);6^*S4)vzjR-8WP+k`Uv*jW*;jW<@3P-bWE-jJ&?NnC zXdL`rOci%ZX}Ljpq*rr%9@hpZ$$Hb25&z8NpCWtu#gFAmY?ED%fN)B@-UHl^|Jbj8 znSwrd)tOamEnOHhUp{-q$D(Jw9_Cj6h;s8!H+d&XAcBEEeqi+nA*v&yYw^3Y$ zXE58<@BQ{4l-DHN5Y1k78)8+{7Z}=LzlDl?{E5G4kW}+PGmqwpUq+h8u}VLQlS?XQ zZxnT)QY}=Xsoya5?GOY-37ytsUBy7UtWGyDGtfrLM?0P!mw9wc5REup(c?P$5sDVY zJ3QZwP#rk8*h>%M`Q6c;< z>J*lDm#Oxax0VHVPZrQ#8zoa%z4Yv)?k%KZ0k_zPYIs zEnk>zqrf>v`kLs;n9>5AT~^ws^L>g|9!ao{rnvV6_NoOmyTK>2_>DB;WAZG_|22rs zQ@*>B0aPBAS-a}t0p{%PZrEtEYYIPTh&kkepi>n@ zAHQA~txm%6h|c;**$Cd6QS2B=u3$43-wU61Gu4<@6dKm4iJ(OG)D2x^*=qfB?pvp+ zFTc$b-76?Qexrja0x~fhh3jhAt~kIfPhNYL)*S*e;PL0^6kbTJ@{Pkhz6 zn{&*iFEij2C?}zN4(3@u%nF!O@_Z`f2o+Tf8E5l^Q8g!5RS&uB=tI~-1ysdW16(m zGvO8PGH>!nVq>dsq}99Y{9tzs;WUxxgO)u&cPdN zzZ7u9$CQhymO*1#6J!G*=hL9On<78Z_BwLtzjj8L!(%_DO|j>^iLBactd+Eo&CMdC zG^gg9l5L4Lx{mL3PKZfMRy`;<=S8N!bN;S5@)X?>=3B*}|Hlz1^U+1iN}AXz^PfaD zxy~#5N#L5=ep2`kD9*H>SjaiKtv74es&*HR{afn}hjp1?vGYEWvK2};xY3Duo1lp( zJ^b`#4&PI?^BLkB-+AZ}_N@*iSAP_lZIUPZCEO|Cp^YDKyhw9pf`Q6~ZK)eY+ex(7 z@Y`?ieX^&hiM(k^z_2{8BVZ3jnK-8Qd~BABgwAW3*}=wHWxw`j_wA6aow^AT()d=A zH))QfR(iQ--e+k}z$5Zh-;zq5iU5Xh#7}<7UL)7TlCsRlu=s*gZH4QRd1)Hoi%+qP z-<=Rxe&E@7ePjl!8m}5tmOL3#;Hd(3Zw*IwLKEXEh1mx6aBXSUnBE7dclN414MO_7=GYpCH{`7vJJhsc^ zC8+2?CPE{oE#2?xe=Qk3dx~yBDTY8IIc1??re0RZ5}GerDGx*iMOzTcw9Ut=d=~Te z_6_?YWfCSk2f@HJxHB{ww?q?3U;U>$B?$Wu1VKJ3rzUlce1y{by1|A)dh)9Wtk<`3 zJbT+vUC{$otKiD7q&`?+Ga~yOHXp8%Z)?l)Sv1Uqj}?bWN`i4zvlwtBQztS-P7E?2 zND78!CyGKsfK8XIsLUVL;5g)4mh7lLi> z97&mr(Z;%da1S5xkTt)Dw`V;NJGGfEN~+JF+C2x=@PCoerfqU=@ktIqLPbZ~CL1yc zbsOtLUA&O;N%DJkRu}f_nuB0aA}B*h=xCpPz}*lpN^+~{sk!?()vG3 zsT<7_C&mB&Z`=+=WQ;gRY#?Xa$mh?Wt7<(ep0`Qu`=uRO*M(p7gOTElj}mzjS6{hg zwG~6+bWY4H%;o>QFIaXudOBNr?93Drgr_XJ?$w(?Pj55}>&pLSY#{GMjM5Et&3Z$w z2OB|BK731YEc+G4 zMpE4qY4Z5PiDu`@xwxD9s1LORs}ZlCvL|nE(V&XW1}OF%oyecOKvcc-H!{?PHT#ASoDNmjGe7%Yf zaL1J~AA~*FBb}!hql)@->z%5O>SdAH?9fbbf?7$kz4_LL6OPd^`I5YkF|^@-WR&(( zXpoN88g1A6bh}l=<@>3;u(B`Fz_IKqW7ThVM+dL|)1X%)ch{jOK(|yCuhpiOB7*Zk zrZnVjgpNK^9&K9t#pM_XS1&t+y;WV$p_>29 z7C`BTBZV!a5)=pDWyc2K(|!6#in0f-Q1t;iMt`%=o#0{qlnWcun6(!++fZI4W>1RN zvlZz>)9gOIyUB;dP>z2(P*MB#9L!6w)I}KdLL0LoqpyE|oh{z#RYuFG%RD#w zpZzU0?pQQrUK77F-6-8YO_u6SYrUuO?E(0O-TPofMfqkuiSv*F`y-VE>!mw*5=9^# zoLIBfSG8xC#{WoYvqGC|QcCbq@TSA-`pl`O_grW0nTEpVek$MTgKWbG{s&}8p1i$b zGo3x&b5H6izNuowFBOL#2$|J=!YKwjY^J6{6*keJ~VEo1Yx0W#*U ze-ggc21&}Iu-|QtD6Xl!qH)}}(3YJAGJ1hh82tZX72S9T{z)qSBgA~PZW`8+l=ANN zuv)JE8Wa$uD^$<1xzf~5$uIAIS&t3!l4mi0c8Sx9#m7O_eToQLug5R5`Txp;?V8ml zgNO7214~%dvtxg{vupNp4vGttf#@1ut4?;v#r2*<3P{uccLn2iKUc$RD=Summ!qr7 zhF`AoFO9f2*#8hBLTV+j_VV_S)`x=EKiHDdT|<|&&oieM;iC}YC!>sqWCxn|b`wHf z*BaCYcCAJw?g{qCA(?hNRo8d|tEI0QnRq6z1#rHy1Jw*w-n$ta^A;$#kX_3%a*@y6 zmtxkVY_F}S9*b$?O_x)FklDmUB*WM39u!wqAX6iZR>?>sg~j_DS%m-z@AaUcQgI?- z6)Mr^n3Az;0vJpe&n<^Q6W9Jr6|#Cz;Wtqk2*$^Tf<9pQHW79k30 zD+$VhX4CI`HT!XRHu%*{aSi>y9i(dqNA*E<*98j8bM-<4gZHC>E$)Vuvilf)AeE4U zZSivX0XJ4N${t`f_}K|v?68=$dFBIiV-P(dR!eF_(m@-UhL-MRzy8FuK3M-v`8kw~XhkS2n9X!u#B z8ThO~`R>6ikK+!6QmAg3*jpP~$JVgy-SG@r@GJz;FVNlqeF9xgl9`~P4vTdlrb3cu zRtsn^{N0`p$Z;n27N`akS_KgP_puXfMV!2fHspOxop_gX-kyGd_^srdyW$jTbync4 z3`l>O5VFW>j#>GW_OV!WG}Pzn*G)JgMr8d&_qZtlJ3QRsm@Bl9sImIem>Pa$w2(s? zlPSG-FZ+g&rDKY3?uM{$UbO#5=>(6@2^kqN1MOPQ&5_|_r(@BZRf(Ugxz}zuS=>@3 zpJcz^^-0;B$-!QA$@8O}nE_qiU!2pm=jzYw)LXWdeL!#aX#L`sTQ-;akdazOepp7v zs(#hYR4MYn(7cE=Pqo}}uT}HkpyZX*xsk5@3LzL2YVVz?sVSury?>2g#JOd0X7|~o z8$a@v+D1j4szjv~GiLOalF zbp#9;_&M@XH>=$`-cU(5dtNxMLE_b}P~~V3cFA@#)+II!qlMZo66gJ&9@4vGf{-n= ziYF_148J%qc!?AF6?KB|`MJxPqmsq^GC2cj{ze|_BKs7L1F26ls?Do`wuQT-j zu~;<4fLt&ai;pqcaQympTC#udDT~SZ&64drKet7pWG`I2crjXJFzeC^GEVSCllGKW z4sEm$QKWnKUMME*&-s{NqO$@>6zW~nhYugLApn(S%sRN>rJ1?8=%jwR2PY+;7zekv zw-*T#1KagoFP=mn|NYRGpCEa~7GHEBJ9pu8A<_4UsSX+k;l3bTG;D!f-5$^aLA)NNyf5CXQ7VdZx z3ou6{Bcr2pU)@~X_LCTOg;EUg&Pq+YEmB<0ioTTR?)!;^ zXWYL?h#!EY*mUCatY$AvB0Z=K5NfID_WpUW)8fDHHg|H$Q@QGq$@4Vl!z!g_A9}1r za2%3c<|{{BJZ2X*zQWCKR{upx*FSlR17RP?*>2HW?XZCku({w870Vv>C^a<|OCP`Z zxiS~Qg$2?ui$Yyq`|DYPO>K&yXwLSn(IknY&vTaz4ck^*?7J5j3D5F9I9-tY+~}uJ z82bhtGF61_RKK6>eqv*7ZS+&ihfj^)h!CH?1%yStI=Ocep1fFdYwl4oK{xy-5Be&4 z3^yyEtsjZY{7GyFGTKL_noOhLi+#K2)}Cc{`g5!|z)vfRq)5o&JJpg`Cr^I zcNfM~&_1l-3PU0Vp)8CxBMyoCwt(=2x?((F6=XUn*Y&)f*Jkzi zXESM`#)`Q$?&9ccL%cGKLQtSzvnwkryD5ogWd;p{@TlIkBjx^C$?t3I|52*w=1L-* zRv8+#3GkD@4foEUjcG|G*|;YeXFoUc zDaXvc4gPMk$?c42#{;6oN!!!5LZKO8e|P>jlTBJ^b6*6Q1lQ5|aOb~p9TEL5V@%~m zcU=I#)c^M{Rhs)eox>$$Sa*Ktr!Dr=$oM_?TA6{FB z({7L7-zY&6mC?PZg*r#J1MA0DT>fYMDoTmyh?kZ-Ciwn^9~Z9m-AiQbfKA>-@XMb6 z{_^t!VdvS#uV4APZvXvEpm23%M2I^7ern{i@e95rOxlmI(PqulTglt55`U}KTU^;* z^jkI@JAXWOnW2nqnSz6ZJ6=1dKe4ZH7>%)f|NaCx%Ufd?+Wppgc7AvN^rCIW7MR#m z6W6z6yYF9kdF|ao>82>pi;U;G0~@<+^4;zCq1K{4NoQZe-N>g_c53*H?e5wX^RnD>Sy( zeLD?yzJp6SdT3Y2g=BN7@_0-4XUhs#1~#gPxPbEDqh@p}_8GZz{%4t{XfOIq_q&v? zzyDIAWMD3=#mK?J0>BC?(2XgQwvIvoHrMPpKfJ$Qv2_8xa}Z2^05@RH z)1${PY}OggzRHko?jx`OD>%&I(OMm3`M0X#IzQ3eH?ptyg_Jf_DGox1k|ekBvwKC%Q}JdIfHN3s@D_N1F{l z4$fBdzx`V|NvSpWx&Cbyo*uUu&R3Xz>-6oUp3U39Z14tv73*tK&s!4?Ji7IJtN4Qk zHj0ajC;rxlpII}^1xl5ms}WmM z5ejcY4+^UNYTw>k*w%ngwx$I}azXTDsNjmO2vCg_G`1Ib%Gg9Axw`rp^B7wmKYl!U z7HF>P>-}TmhAVH~lKLK%tOl<7{eDs8>Zj=(3#RN748=-W$4d7Fvy7b@s_M-F|xX* zChY_Vlee~b0(BcPTRt`YEqDLTLpzUw=(XmlNl)xz^0*|M2TmjBqQl$0T4h&THa_@y z`u+5<0oJ)QpTqq{VB0I8{dYJ#eEpYcYvpePMT0duK=a-aJ)ET^C-Hj z+D&!WY*?)h>KElH5F9SqH%7zv!QT#m2?_`(r6DD=>AS1>^PF!e;OZ`qpk8Bl2SeOMc2d6}tbHN*d_wXl;yQ(yF=10X=Y83o1Hs zi1PQ2Fu>dWhxr1f&Apg67B(piv@uvQpaxp0gvYq^gZ*vjG-~vF1=|51%uIuOBh?^T zzjqVD3fzV4efm|ODKE_i&9ai+smtfxGArM?B^7vs_k+tgsEt2GVjLu6-+&Y`c_0$k zfY1@eLO|=zyoy`R1s7vAS(Ec6t zQ~n5{i|6@$BCOg#+3n#?%uJ5K7SNmA)B0c4`7Lh(ce1z4;L93>p$fIg!lZu|4q-rC z?Yjc5wG$^<+>?GGuDvtsqrze=B{_GTpr5-%;{LPCT#Q{}J$;(x%n@J$xKYcMUsWQU z{(qhe{{|l)3?3FZWe5b)EiDAufWzUwls#Aey;6? z84OhXe|+>V(w(o|RdU@@#cFZJ)*4WRrR0$1?+0hPuv3?omWIKco&YdyK#l|oeLD_t zauPN}=``x{)Ss*W*3_gQ5OxOW$#)iGPYil&HK5fyhJAbh{1V*r>#A*Bl=vybklVLpJ4&+-RF(4SnH{P1L(1VYe1Y; zWU~X)tCGO^bsuBuEIMb3H+)Ns*ru26*{F}=2#Dd6X>Q9<#(-IJuU@qR5~3}%)&aHt zVLPnh@c~xo-)AfWR(T(B9U9uA?E)kSR#I6=W-%>`c2yN2?efs(9<9E11ps$9-D8rZ z?WMSgM7>{`s=<@84%izMMc@!+VJsv=11vT{&^_b$v13wHXswl_qhnENX~5*vit3-c z^ZKd2rMbjYfaM2OkmKMbb-?xNfiQ4}y#xb%mYsURP2v6tDl264D0?~hcr9yKZjlGe zqX_M3itmIe((>S+(%TN2n&;0y{zH`VnH&9*tsN$A@A%@Mk7R0+PxxjM#LD&q?Ozx( zB{{1y!|>`vgfbC?=GEA-f>nTdR69Kz8yj66XrKicEwl|xB{*d*_FowVph_zvG%21k z89RQ*J?Zi*LPN3~EY>ou_X^m5grLCj-&-R_LWYbzL4&R#j zx7$@0F8^_%dh{61Dg(w%eoU1*)UEJr(RpompSF#&<#EQAi)3Eow1#X60uN*G(Ta9G#fmwbwK;1hichw}|oIdXM2hUq9u4IvMsV+ag|@;fT);Ut8Y+ z>RSNHXRpOfslfpHxGX_Z_UcE#NH29=a>B<|qamZ40jf3!d{4a|HF$DWK!?msMRZmMWDQ=+l7i@%VUGg*>3aI5}w(HfV5QXlIE2dQ($V zy#{6DoukIa^r^K!j)}GLy`56y=dyzIWc{9t@D_@Tty@z3nl}Cttc&4Y14r9Gq3KSt zXC1dPKvNp4bOq`*+Vf7U-z(=y+RUy?(#%W{oRTG;#W^G-WO5w{xEuoiUzNqsGh2o# zneeavQo8O*cW(LWBeoaD%h(};+*g2T*d~6Ljy^&k{{nv{nXG*=z2l>0iEVg|NmV`( z6F#*(kYH?pl-sr@puBYb6h7rJyx&(wOj>x@cyi`K{w+?Z=2c_kDPTMOjn$Se`v9=7 zsNf(y(Xi*A!(iN}^9e5-k_+vPQKIt#LrHm`KgtO@Mwkq1rfx6D8mVO~GciFl>_qBre~BIjSJ|+6)H4wK8QVPkV*~ zAJ&NYDanyeb2xI8nTeIUxK_a6d5dalRF##KqW(CleEZ8j#R9sT=y(vsc-?Qke(GYF zIvEC0Sa|R)@L|@m7x~`mq?KL0owuwqYsdLbiWTZ63|xG7zq)(m84d1==kv3((t3*^ z)ADRE3IFopFkY}U`Yk(x^3@zoj?Rn-6<9-cpS=uK|_ z7ZYd1MQ7a8K39LzSzFul$~RK&a^%|9>CromXOb4J!#@s>lRFfQTK8=$41nRo1FmHrp=gGzU zv^l{ZZ0B&VZG;2;+-8prIrNXvGc?e5W38Y;+ry}I1(}3j%cH(V_5FG%Vbbd>(PGoe z9@|fDTd#Z)o3waK2k9G8a)p}o6|-B;7kb)PR_@J%hUI4x8wip6EO_&a_iWuOF8RwW z@gvK9Q8uU%h216;zC78cShxIZY5b2(XA%N#f$N#|yTG^LSlaw3M&j%QGO_r~(&$J_ zrzhvHXW8+=Q|*~iC9^iGvLH*mc6jJO5}2V4OR@(8x%JS}GmVsi9Lm~&SCFg~Gt*}y zJkWu-5B2t#p%1q%WfK@fA}50n9ylQKhea;P4sVF@`AdKW7M%=UjQy;#V8&1}QrW%V zr~%t{8jpgk57nWF5x;&s83vsj&W_7OuDv6St|%4d)a4IcP5+SyW=|J!Gd+ETII=v| zA&2z=<18LHtT#(zKKv>9Obi%fXzd+wwWaJuSe8OZgi7Xoju98-rf^e%>5BIHLxRSn zBb+LRB06EC8SUWrY75<6-PCXM=yo^@`pK|TE%_**LOc_SE_nPa4~2?R|6?r=n;LVI z4f`RevRpb`b7?kI|EE|U?tkjCjv|y6l(_U&oO@r^nP;^$G)K6eVhF50^@&xbu1t&IX#BJH9 zg{>I5% z3{xJs^s&KzAD{tYFM)}%4Zj&byIX{4>4x0b=r?+O3L|b=uCjrDc`B;6YmS+7eruT+ zwrn)dxF$H9hNeHL@R%JUkF(bTDEA@grv5;vL)EKvR#%D(O1 zL|iQbSdL-P>C|-#K8l4_ycl2-7{Q@U(x&$Wvj{q}Fl>VidOWr~g7up|{?cZJ9f25?0 z1)^cX+tTH#-uy6;1Yl#!3Dux8>!7XLtwfP??U|}p2*W{2c62JT-IZfvZWkAYyzh@E zvhl_m55z3zrw-xXn7&W4j5w+T9HNAiV^&igy*I_!3c~AHSXcr8eNi<_z&Pm$D-_w+ zSoUvx2eXu`u8N!Kw|b7@wYFT70}eC)uk%vO8|%~;Jq z1Cbr-d-#ge_NXu^L3j*l))Z&(FaS)OjgpHjeEh`HT1ituA%1pY0b|(?KNI2P5SI$> z)t{c8O~ySH^*b+?>U21XCb~x+}={|W47To;`&y> z#>~vz`*}0prO$8T|EyI;a=b?E>sm^u0%C#1vk>mb4ZO3s1|uWbXHKg@A-J2{>GkCf zO(#|1^H;B3n~W8>XzGWAwiP+WL7D!?*~*@{JPziOQFqzwjSkQ49&OIHmp*lhG%hk$ zqt+bWdYR^ryx^Df!B|<#jtYim2OuN1pto-8@0G8U*j|sRk_JHFPe-9`-D>RuZu~-U zr^3yr)A7+n29FOB6d{`GsSPT|%pG1j)>G#{!5+lS{YX4nuhr^?e1rw9gK?w2%kH}W zKR)a^BZY%E6aYuGTf89krVMuTIO9>=cS;AS)bqrgt^*Db(;U;h8S6uw`i}A#)3w8E zDafu`sfgOviK74ew1b%5CGb6BGR&5m(1G-_rG1RYu}j>sH#rw-fNyxhIR&Rq9P!#$ z)+@LS@Wm}Ld5ph==SSH8S>^#A^rgP$DG{5!UIL9(js7Z+7{}R-zoWoGE;-<`Hb0V~ z8ayw+$2^$Kz$pYG(b2MX3WF>xFube0>wl#q=aTdf>l2*t(>@*cru3uWG=2N@PuEB} z?DqHa+7H`>nA%vKt@6cD#Vef}4_dY`mwiC!p0$dtJ;6fO`P-FXpw|nxFra+F%x14t zNT;Ny=X@07qZ$}IP%}E3SmA9ukHX-Z?Q4P#aB$q*!7fb+5`o>aH8vXC9oOa+nA#3e zL_zTJUv$XRmpAO3;(XmTp*H(=U;X}(h4FFb4Vpvh}eU0dd! z=JGMimsv#^X07u^S;@dLVs-P+ko+sSxJ~qk1h9L@hx%u49OmpS>!qNoICfob0Pzlo zO-hSg04OK$yA^S7OzzR6M^R+=qh%*abyYteA7|fv_PH8uuC&Zu4+?aQYxx4esSY=^ zPmsb73TfE+$Aa<({lUs8iN@i3-9|52sbH$RM55(Z8dCM}6*6qO&nZH5zL)_>K8QwqhWXapm3^qOUFp>}TOJx6e!9D# zUcoCaLRi^O-D(P%z(mlcy^ooS-l-kDA)WsS8`q4iY`HiHX1W$SFM)r#wwv`s9O{(| zXI~j`Y*h;W0?uzZ9b05r86L4sBX&QI++lgnMvbY!T5B;FUwIj34T*rO8FUE{pV9@& zt-G~5nb@x@IDp0}H>!*`%9<7YJ>F6i~7J2N0 zjRPvaxiDGi8W81=hQN@siJ+xP7Tor`E0aNUJC+A6?-Ra59IQ)S4nRini;H&wi=ns% zCM`F~R3K8$7EP#ZkHyG+)IeS4aq$7^_gWAKTl0@%z{)rpt8(v9cb}4;8CyHeb*Ei* z5s_iuwQ>FH+$Ba-fU)2E`L~rZ^f9Hoiwt9Dxa-*G&z~>f@?^z?PYikQ<6{C=j$49F zuZbGM3U#Kfky)W}fUlzQP~bZ9Y=Qyhs^qJzJ9LfB%*>2+Cpc2)7Z~5y&e`qyCwA7G z{=Up{^V27-dCEk~QPcbT6qS^chH7ETv}U0E*}$K2KSXRd2yI=b5E(`3VHTopEFu_% zEyn$pzC5w%?g{~%U*%JL#yj=5X778N$4*uR`mDGDHoc{6RT{0MnJrXSs5gA;1M2$jhs>c8XTvWY*@S7@lQq{q!MV^82K)n# z=Uwd}PX!Ed{F|$vW{O5G6)I-BiVKY>eSScJ4%(-S+190AwYVtu7Z7w=h)fiEzw zQmnrB)?8^v@~b!x6KHs4?dH6;!~Ad!>?=yHD#BL~sqv0B*#GlE=?!D(RjaA2zSQ?b4Ou^jCt#9B~JrQ|JIe3Qq$M!xdQwGMem|z(puYr zuor?|FZ&eegy{VIGX5{TngHC4!OVVUqJ8W{t1y|O=Z8T|>er|vuC zVi)T<)FOb~QIB;RxLRbMVJDz=IeW_RCzFy=o%bry@54JUm>*Ih_MPg39{q;wR=J*= zC_7_Z@caQopk&6CzOR50s<*Xv**q_G?MNQ75|rfJQ4TloL(*652SiPJZ;@l*4F{AH zpI+1#TVE(s8BWSuGw{>VoL!}@)`%j+Fsf2>O+|V+p-l>^F4T|{Pqwa_GCFy@TFr`g zzQqQmSBcA|M#!=q0T+BO@#>n2pkn1{sOOI`bC_nP)w)usqh_P;8t3|Oit1aBms({+ zM}LBkN;xSeT1k5J|o;>s=AN%kkFAvsD`~T47IAs>W$bm z@DAsDHt8`{Tw2;4Fcvpb(K{A+V1BS1MRF}LI@?vO?=h=rK?_$ougUZ1Ugk&4%bwsk z^x#5g$41({+r&!xuqT_yn~^9i$+q~-#|n=Vp7%r0i70A^pO$k6e`BstCufe1^bhqx z_+A<2z?Jvv$q2_d#tw>&1Lh^A=H3kVBu};ubt1*lpH8RiG2olXn-@{oJ#p|jnd&mm zk22TVkO{5dU?XA6ZDN#;B(;rex3+!sPwG3#J$pk)gT-Y~%>7$2H@aNQqF#+&Y7~7< z4h}4H6u~5+Do$foppV$0&s1S`p*rOGUKbS>n;C&1q0)|Ub%+CMn7(3&j;x^NwNEhI zp{DBrB~QcWSD|hCtZ*?HcO;hE#XWf0rkliLlwREN5^DS*FRZ-dwdcFx@a$ozx#oLa zJS<$c#@I?lv-({>Pr&e*8y`L`hpf2v7MYphXNgMCuQ-;(gk=Z9(H#wgvB#;zF5fKn z`elwDGmp7_ZeQ^CPY>$Vtr8ABdHk6D8&VSVNt3Azd291_mD)A4;&H`wnq}pY-Y_9i z%(%2{e~)Ay$oe8yGVDjX^CsxkaHAh{jL9aWB}MLtf$_-+;E+Tj)_5sJ*Au4W`wPsa zMw3h8HRkJ3n|^tRKWwO)ot3m{E3{~HnQ>2Yub3zxS>%-v-rk5m8n8EYYosH3DKrvG z0j&m;H%E}5p0ULH&}F=*^QO@Duf}*JA=^P&CDotM93W~5YPaer)%_cf0-wURtTUKOfzB8o+MXU^N2|q&)*cjO<%794ABIDbO_Mk%jSErO06Za7>snbiWUB495PaPiDLVdwT;A=tes4Mf-oZyTnP53Wfqdr0Hk##aXSiQxTurASJL zUZ2vc3aP~mZ1=z?ip*fU6U3#>r2;WcVw37-y?Rn7a>Z4rgHL&3{P1g?;C6Yv0P?`(eme)Ic)15;<%+js9c65O$G!nO>D!sbJnfP1Mo9)-0`G3ej( zLKIq+ROc{OI*6M}io{x?HU^kS?5H;Gd#m`-E@ak^nDQL%g$YqBUWmgtsX*H-=re;l zh=a6;QI$BP+9a)-)=is9@u=}9z!D)2b=_He#&tbBm1>as5)}yIM?a_D^}a|@ zkYwDyt_@+;uSNjw+a9C_JxbaGI5|}gp3U|w^`Rd5Mc@urEuOGFd_RnJfOfR}HBe{| zU;o@KxHT(k!6JNF9soLw7yv0)t4A_R(`WYbN6-QDPYEq5}{HxqU!<}ePv_EuKnGg)CS z$)F-bemz63(&K_GM5B6Q-OZ(TABu$!!Gl!T1MUAR4-z2SBeMU}Vj%xwt5#)e90e zw|+Sp#!eYsyT%d57g5q%7|Sd6!& z$5?oL*Wk5gPBWY!1GzklL&#P7_wt$B)c#yA9e|8>{JimH#8czx=YUd|w)A-7O!?1Y zK8iy<<`Bez=Xk4sPjqek00yCKb(rO%u8YM3fA13j_(^e^*gI|b4E=C&T(&$ynIQS+ zMq(>oE-sG_5^K}Fl&#WPW)|9bDQmS&o^qje3A|W?Zy6Aro$~_^dVw7gBmhKiwq97r zZmvJPs$tc_cJ&36fs=}lc6U#0ZZ3Cli1oAx#Ki`1Otdg=dowTUl4IGR%%v8sR6yG% z4m6h4?g5^&=A&jmlIj;O1;K3Zyv>7xNx!8#68kxkWYd|y$G@tpsUn+V#$Njhfhj{4 z^9LlsKwsSKwGUPV)VVM*{e1slCa;cYLPk-oxHoy$S;RO*%H@Up*I|`bGhrBuNk0&9 z%>+vw4A7W|I85LJ1;C=gPpL5w8 z_yF7=^~$eAEHQb@O(4hp*chN@b4NlwqH}A`4c$1O=$5l*mHmf;kUmaQR$8MXV`4Bf`-K_SB!zE!DsQBO@in z2CZ9QP=mrGI>-vLIYGGPSMcFs{DGK}lc zjTl5_gkz^u$=-yN!sSzJ-ul*(4)s7H*9UDk-e&luOS+PE@k5&3hy1OV->^fyEwb6f zC!3u$weiYUcv{-MZV!k9t%?xfxE$cf2&ZyUUcT_toU%v{>&Q~C0^#|~u?wKFWX0KC z?S^=dj+LO{oOs|IobHxOCMkOBca0YawBaQ#3zKRJJ^gqAF<>AdzrZ`&ytG+ccy zrd7X#jsUM+T9=<`4E)0ouiZO76BVdMeT}+@eWu32{;bW&b;VM-v+(> zvNSY7cBcW1_3kYI8k&Ij^}aLtoiVaV-=-n~p&7DxvpW)t^u+c?Zi0E;_LTKOJ`wy> z7yYj=I&e=I>|A76q+UMsX+{0fb!B2$x201UNH(Y?)MwN;Uqv6hM)`OE0Q&1X+_*`3 zYiIRSSzLZ~8Ruv_Y2lG!8SKzDc7u1_m)2gm-MhzoiLKKme@}j6O4$ju^9)1pH(N5OH(vNNKf-vqx{1@f_=1kF^=nExdxSe2?frZYG9b>SO0%a?>nwtjkip zH;o{qlud=)`&&Q^OxQx!l{om$u&zJ>6W~ZuEg!om3xS7(e7uXTuv-s^1&-KceD7%6 zywh6&FEJ5}`gj{bok~i0t>5y76HG8VU5dt^(l{8pmMoJ(ZC!<2=7f zYoOoD#(KjtEkAFBqwm~PN+T9P90nN9uKH+8_$Y`lq-?&jnxWb_70vZ7EG-`kc&H`K z2CXqJsAhs}Egata@%LhegND4t{B4tzZ0zxxfYY+b3$03RL^ZKGG{)>`p4r?RSz%p* z#J*B(ZtktpUss6o>UZX-ZxUtR0hL<7NT}3U3%Zd968g8#+t7VEz)gr`R9bj;uy<|a z?Qvmg61-X&%Pn$st%FXdx4&O#|JNEcetmxwPf%a{#H`dLhE9&lKvYg-IEwhjYzjj{ z2u1dXzm!=Qe~*jU1R$k!z06lk#MerI)y(Fr1%7A&y)dgybIXm|G?c3~H-k-2tqcUl zxtAd-D-Caydn94jD=_c;$xnBd;rZ_4SYS`Gmt*+qVP=?M;=o%|=awU1p|2hT{gZ!1 zB@@>%o=Uu($aCy8Nyw`b&CNwA^}Q@Nq?{8pVz`&dC3pL;l7&OmCyk+kukRyV7oz}6 zB6lR|_59g2YEebHIWq)w<`y!rY=bX-Ia16^kz#g_R@I!kA??!Uziy*5Yf(gO&+x@r z|FZW`r8{7d-y)yJN)0iY+n^nd@UwP-N5wXB0gf?eG=Dn6Ekg<%RW0=9mZERYkJPxX zwp`(WuCBMYx5s-NohS-kzA%D&tFa(9p(LMo>U;7&V1x+jCOqy1-cGOSlWnjcAWl2X zD}sSVZItJ*vuPX5^FZ{ZIjD>@2>|S#ko{0{b(`_KYT5I{)jpHlK%VHs3$foiIj32A zJ1;-FefWO7Q}1nyD;HlsfWXswSwMk^wCou zTWK9mybSHYorSQf3bIP=;g)OaIwOK1dPdvOVO2yK?ZTv?$%U@sMA!m=FwIVJ>U?_m zn)=qw0RwOG*Y7*rqPH3C_Lg0h`0K+Q%ga-Edte|O6x8QhBu*lG?-LbiTOa=DH(uDZ zyPO>w&Z*?M&X~XLRTaSIQ2s1jO`nIdcJcZ-w%2w_d(9%14e`<-!j~1eEv@|iGHf&h zX=@?WoEaPtv#;sya#sE`O_j(>MLcQ@#FkBJbkKt^$g zCR8u`godU|9AZj53z)r@I|^$lrTgPdw17d>3xQ}n?~l*3hB$y87{M-RUV?#-zN5Z; zlO%>R-)k`3sEs!?$dDeT!yS@l*15+#c*4cezk1n&0^)+LN~~;dc{OWTi5j@f(pPXB zc13PIFkv5P8T{YHE$4UtmIbH87v^GQ3fcZ1Do51f; zH~Fi!&)h_-F$eCPWmdxuQ3Qbf3v;IQ2+uJ5eO+Zoa5>J0SSk8t)uBM(`!()C5Meih zjAr)SymsDSA}5uQAN$vQu*b3is_VD8F&ZC?8#=iJy2G5AdwF2%sDQvqd@<%rtM86H zZQ%LheqxUEk3@>EHpUwq&>t1wE#mvV*irjO1lKMm>;=$gr%=w7%JS7;Fn1@pGcrsJ z>Kv2pZ<4m=iVUy#3Hz#zhmkoJ)|U%Z?hn>4Tugc1*Gx26kbK~7C9)U|zk*6^3t-%$ zU>Lgk{3(8cWW+k`O!Vh`nWqV-NzxY1AEGMnlo4r=9^hChIr_w~sKzh%8Vq?lSIe}L z`<>~JSgHON>Qd!Z;+M^(5B&yQ%yFK?*N2NHk6J`TL@5uz^*I}rt8TdwtskE zFB&$XkNd=6Ss@;AmXe0J$V0U$*0RI)@4dGUYSQ8}#PUW6y{B*%HXC^<4pP{-l+yuL z=Cs3?ZIou=MOKdCO7Y7%3u^NVh#r~Bg;Jp^pR8OD*tLuNf7UvdAu>zI?Fr>6q`u;hglb}VNASX^I_i0yWijdiwjI3@ zIi#EDpSRpLT{^8|q8d6vxOYZHyl(xV(bc;VbsH5#wD#tTH_h&+BJHAFBv)4f1ov_8 ztWH3f2LOIiKV!KBz{E~KT@<3FY{PrS8F1!+jA*HZ7fCT~<#1CcMu$6532jXByT-EhxQ02Vul@t z%P+&cX4T2+)w$0#>R@MHY}WeCDEfKwEQi6@23%hcdlpzASZO%ENhJ`FW2Fwb1)|i8 z)aB*>%C zoCZlYYJN{-+W@pavc)9XmJE?Sv$=*qVRs2720A z((;LhyO6G`m)QYyT%+X}Gb?qE<14BYtWC`_i3JOSuExii7QcWAW&R+axhhBsy?f_& z{mv&%mmrlp-}d!gczRJV&-;q78py1^8Mkhv=Tp%YvLEc|_lAg782%UGXj>$o_1W6t zpBW9T)JS$H`gZTA&}17$Zpe<2@I`ya{D|K|EnP#|CgJ1nVt~2Y-36%G7J)hrGFZ%@IHb(R)WvaYn#KED(9a&peUm3iz}TfKO%l9{^%;2|B(MH2FLNTfHbfp47-+8)^B)@0D`lPoCq4C~P?w9?ca% zpSyNsO+4Gp6u8u;Ozd|IYIkKwp5-5(Jp1~_CzFTk#XX*ZD=kL;$H7&3AjeN^rVTS6r3c&BtPEA~Qm8zk!)myfFAssoaCeC((p_vPw10D+oY8j@^da%ha zmIvPm4`vlXa)koTJRoK-YhMjA*BU_P1d@?w3uyvL#n7&b3oM+1t&Gf|4{>b(M7txz z6)s+MkC4nD75^cMj?!NgCKShw7rHU@xu8^4^FMCr6UctYh)gd{9lSNf03 z`{L0riMC>Kx`vw?NS|CwB{E`zl@Amckmqho?{{haDIav+%};8Vk7F@s2cc7y_= zb12jux~@?8XS0e2dik?h8JjXZp~I7SY&op-iN@}kK&u|@THGmrEa$y z85=7y5#BVXg3fSRGTK(kx91q!$n}N2^T^93#95Q@(YcNSrU!_)iy#jW7oJ-kM)exGZXu_kRTD*q&j<$qU_}PJlnm^JKwC z&lj}XKH)=#nr_SR>vPOj;8j{C_NGfBAjeq;-zd=NH!mOO3HXa=;ljeC@g~6LT=Zp2 z6H9AzAD`|qx<#JFenqh1VTg45OLdo`N+r30uur9XC=#Y zn5Ja-!N{i1e3Xv=5f09?StIV4r?vNHOdGyd4x^Q3pN*b6U2e|h%?lP-m4H%LS6@E4 zcFc&(QqXGStBEkjJibE%!QV_jG=v(C;-9{T)b6M*{5UYN*hGBnb(L05Ds*)PXQCU_H&UhBO@XJRBZRd(a#-MGPLk^x2b> zs`OkB^6>I1A1Y4s31jz?hp~)&6$IubFhJ_cuI;bVtlhb%dOw1W^@a|)^sZXc2izO< zjpCfS23t;-M!&EYA9@zZRZq#Ze#f5za$Lf+k6B$(T$yaov<(@_jnhz3^!pA%K)OF# z9?(H$KwFDC@R<+qT?eKkJi_l=)k-@39r4H3b6Qow>+r|()w4xujEvL4W%LKxX)9q7<%Guvj;Cv6$V&mb-8Dkw_}I5UbdAtWH5zE;Hv>wb zjCd%=0(v4?j5_z4`1N;nk7^G4y?Sv7_Tudtvl-s=d0jF*`-^81UqG7Ex<51Mt1ic% z(s#7(YkG=|t!0ewjO468$PteW zdodl8c&GH@sW!t8HG0_@$Qh7cy7p@Ck;~UGHsuA2=>~2V6@>lO{ttg87;CVVJq*8n z`()+4nXZBbnHfi)uMV99kq${GuFjw%FqTlQlcNg@W;J@FENL>RttHS4`d4U#(FeVp zL_&%-t%Wt)#&Ja&94aFrdos(H}4-|>mSaF99`|2i+%eKw4yhW^= zg=(DMNtlh0*;8mqwn*4Lj3hwHMOPnf!p^+Eo&!J2$UYF|=006OuuiZoVWl3;rK`3& z0gPdr)8ZU_F8fZcWlZp|)2gT3$wgW7r;D%^dkZbihot*g18l11+jF|-^lU|El_p&N z(*K%~u#dOa0cl%0Ga9i?e|YY^)l<*CbzAL##Lf@WEZwqC*gxD+Q1L;h_6?Tc+B+-y z?eH?kJB<{O4lrN04exly3B2^dks^)kfZUEw0>SFn+(wtv_VYoVQf@jsbbVE2U-;{; z$o=%^Thz`=oNeX?cXO8!=k8?{(x#z;=zn21E(+Y_3qZsAhxrrEklKm~AaQtmYrT$~ z^sO;hAlN-f^QkG`^HvIN^qBIRs$awEfn(d8)!tsxYma~)SB}VXtT>W%Y=M3SN1i&% z&Zd8PNWDM7n2RDW4m6%ZoI9XhSgBke!N?H9H)w*?UHv=DuA>oH2r126U2s4x*G7ivCWVKU)m0Bn{yfrKaN_eJS`5$s3d5uI+{ykfkaeGa zLj)tEtEyJ9;H3kMcTZ>31t13?MC6_J6BnFUvX=CKDO9(3xQbNtLbATaX!i%J?hNE>yZ6U!-C*c7%z5|MT{wO4apoq`Nl~uzui?pL}-E8-bt_<%sZT-o!YYW=yxg2k~>J_=m4#AP}SGXQ*kvq-G7e zZb!;aTv9bZ?js>m*RJ-~W%SLsD2c9dQ><3?dHh0r?PTi}ve>)@&aP`{xWOJ((GbF# z-gw>JI0R#{p5)-#GUG2c;9VAvYq()SbQ6)Il3nv^kV&f!76-jVFx+PFvn_p|^;%sQ z?tZ^7L$acT{E4@&FzT}c?B3VaY05(!#=lO6yq6wVIw&~?QU;ag3G8%X0})JfdFZzA z#LuWbxSGYn;p9Se4<{vpkk%2fw#IB(7O|Op8YRP2_MsuOr0B`D$gnWZdkN61ZG%>C z_#qCQV&PD>W8sn%=~A-#(5lwCy^8=_gg1>cj8&rCy-CL3> zXzD<&##NEJ2%u4<_QBtm$vj9w5EhmnS!=%@Zr-}E4D@tz*n7a>M~wezL>2-LlUqN= ze|9vD#9kEdHz_RiU>~@^3ia+CWCdBVjMX@D*zE5+^g+cZm!=H}+>C4QYA98hW{;3y zXS!bj3X;J=m7lG?5&y}_>$r%c|5Z@V;5@`iy%O$MY?VqogqEWEY!zBo5@M=cYb%mA`&X$__*S+pj?k0K(mP zU$j$aQc1gS*G!pHthDt^n`w-by9VrlsZhB8q0{ z*%lxyY6?h0a;vM!_EHVqo0;~PveZRKecTYtc~(uanw5NQD@{3Z#iPMnnq-`*5`~Dn z4}f$vDY#~0w&gWTh|I}K?s=SIkyDpkh^Im>KtM4-fuTI@;n`$*TvoNpCm zf&g(j1dq~Y%eI_N`Rkz)nTSTeEhiZo+q?q zP%f#BZ{*zpz%!uUf|ZK+HrL3=841-3O@f2S`s{0g#|SIx@yN}Hvxd7QgCvC`vC4xF z{|bG2Z|P6>g)^N;0{AAjtln&c`$dS);hkqh>TWeWuBWA1c&k45UzIS<@|u9(E&nL7 z_9LtUGz@uu=<aK;zMNX-e^^9FF#Y8YO{=OJHg}*7WC6w_X#hz5+&c62 z)!N{KTB|h_4h0I;&>?v7`(KaQp|G)rZ@IdjK4wXK3f3kBM7D)M5u7sy;rKcC@P9W- zZ)jd*JAM4ZfXBCv3B}I2Xv}0P5e&fOhzTnYd#+wPE=(dfr+x`oe~erP*TQkF^hub! z(E`{+D-hVCXLlvOZh!g_hPWWh-qRmZnui_Xq);^(wdDLVdsxq)kfrnQeSrfZ zO*)d+C~EQ;!O7WX84!UKe43k^D~2jiRaI55d#-;q18Fg);^i(l>7c-%x=qeHg2Jz^ z>mu7=Xlu$QJZY7!9@HATI)HpJaFvbc(q8`IQi-0Qg$Q=|Z0uGHXvNrl={OC7RK7is zSC)(;C)8tHa=*C5FP-?3L}@$Y*zxep{mwh9DzJDSh{jt+qWz@&#P)F!A?|e08mD`H z0XC6j#U3GhNcPae78P_PSDG!4Upb-CGDN6821udJvyoULKN93zfrz}pSDuO>zZ-!TbdSQQB5*qBR*Scxi zC^qO4NKxnr6PLMS7^(@{Y{ibNxlt40kzrWQ3esc7Y_Co(KglsxHtvczDv(On!-SIG}>h*j5z24eHwy z1L833!X(##AN6}}@o~#H{xAb^ExQ#X!LZvE$q&J4fQbUn;%mQ@+l)?vg5om+-S*N&(oJ?`UGoFzs|14pI#%OR8%RJc zfXm8lfhuj@&v&bm7Ak-SfB)FN2p3;?p6J-6c2&f;vJ@$2oPPCtMQKUM(rw3u7l@7t z03=cjH<1y>|9ZGL3pLZ$A)?&`%_agJYyD52gU38d+AlmV=1c0E;-XyOtGk}fhpWx$XleqTu8ACQRUXosNZ zB-n9mUDO5Y{ws4z>4Tg(+?2_nigNQR@3oKqxwKtc@x_%>dSiQ1D!3^#_f(t(37`^l z5P~Nhe`cHXq|z0mZxehJwP=CE3D~TTn%p{!y;F4=OI0nW*h>#7iD)gTgF?zwdDkt6 zXIuU#qIVT~y=QA`WA~41=R08q&v7zYE$FbyC@d{)0r+pjU|4~v+mUdG6LI3FQx!&0 zCs0QIowT0;Kf^~l-Z!z9vqI%TwVlF6NEPrZIdbeB?+*v{QNOW=FHfEK>i<65auKqn znXj3;ejHSXQvQ@K;J2&aiIvl5I!VfiYp+zAPkGVrd9GaOvUSPmiCMypvZ|+;W5*(b zHM>E>{~kU%lW-FNN;>+)-5=4BVOx)XWkc;i?GP&zS-cnJQkWJY_tK6{{c4+fYb|L7 z5L&KHV+JOYfoLtviYgMmG4rXh0ECB)WETf7jlR;m?r!=BS)#hpD#hVQri-?L^Z^LZ zQFD1=y$m;h?L4{5fZ3kwFU}=#SOWyz?({E(2`tN}@AQMfDFuv%F20iK7@@*Ix=x_@ zv%3ew{m2-qWwbWJIlB7fp`yIVot#YZSHVNvpfhZdVb2+f@i$Lc%>%{o4CMHT`XN$L zo#hn5rmDV29cRAB#8CM$JL!rx&IenS({vXga%?LYq1OF}mv3>=?4nn09Sjtnbvdzq@Vwr>8J<3I+GL|zJI zS5ZsnjljIUA+k2VTw+sSE^h5dUCNtr5Se~4Xl=4CaiXgZ=f#^@U3tY`9OZ|xQXSkcR%*C76 zL^~HaDN&u9!zz<+vf20bsjr-kGyB86zV9?(oaS`3w;=HfKq2!pKFr5NlPWF-N2G!B1bQ2-r#AMrW}Fu$iKLP0!Ukw8flC+uP~@0fOcDJ8uIx6w+#*7<0J`SM+-5l@ z>Yv`nV3$VN%itARy_O$e$PN*uz&-l`fe&Mg7(MxbxHh?zE|abK+6JBWa8VFy;37%T zTKakajv|RfB19(_e>6mO^11qhTju^_dsn&GFo^c^PnUz{KR!PKL)FP?ShtMJZ2Fl_ zI^0bQo?ynVX7@Wr_QNpfrF4nz6{@+a+HTeYxR}Ws-5{T|;cHbZS=`g8oUGJFHle>6 zaH4`zlhPw&n`rHm@7(EH6XUaF7Hx6UX^rikN$4?rUw!W;XVHzEq!&&+q&F z`RDy^ujlLedLEDaB!N7uy7BV#^zaZ`=-FFnL;f;ATrq9E>tyI@Qe{`_2?nOjfJXLm0s zu7~s%I2~}SLZFrOoB=EV&wChOZ7^zlB~1sOboZmoFUSp&|2pc$;rwZig#j)$9))oX z@M`dqAqj4wbgB3J6vzvFwSTatwYt*g`!S&n%i~G>8rW1~Hdo>PC?Ihq>CknpoA==s z3%@|_#?*TL$0!X%&&fTsU9n}pHsTj;y2UAHF5V1Z1Br2ImfwnQ=0_gMt~Ddo5b2Oc zv}R@A;;n*7J6giN9}Dc%p4^NJkt;%HS94_O}gae$SBy>rlS>sUKTQ_`X6 z9R_mw8~vAC;KY}R(J>WZLFDN@`LWGhZY5}NjF|B)!|!);_o{Jw`SluF)=SefX}+HC z&{;9(@AoDtTJMNlojkAa3^@B;Gfo}@D}v?N`I|;`37+b1(B)_p#40poS{D1jim`jm ztfyJ@?|ZDOL;_opMps6pm)3+eygZ`ouY2Rao+nFSNgQIq60}^s)x+z7QU&(7usQ5p z;qpu5WYRm->pS=4znT|X@eP&@4j+@;^$iurC2qv&*I~3OxW64Fh9`l5i7J<((QFW2 z1ZC*bk7xAvPO8kxBC>YUX}zF_M_W7eu2c3K~+1;&rtlyfyd{L*08%Q zD5ZB+ywAFOW~DtWYxR74IbXa$gmL7b?Sjlf%>_lh7c-~s?7(p&QqPdorQrxj+%8!S;PS= z75@Z;mf+WHCodvEAr3$&^`W>T+3ob{EIw@>qRU?L1Wi?asCD0)?erhGmjg+a!@fHW zMo-ngODG>wTA=}XkN-f#pb2EDd7FQoQ}UakeCLR}m2=tLbHN;V#43}@JE9SB-p~(5 zJ#-JD7{4W=HmnAb>4SZ0R)Fi)xF%KK&2WEHJs@!H?hg>9*j4wt+xWigv$c1g0Tihn(3zOr9c)|1fRViHJl_Ob1ph@ET-O#!{O~5*d)ljSpB|j& zCciNivaP)Mq5A4XvYUXxn6T}a#aYY5C9_9!ckUss@eIYb)diitmdGwC-bt%Gbf6-; zTFdA{ujsYWdK>Y+Erx!4p^AJvhKUwH?4`iZ_7e+r#z$x_!Wn(MWDxV@K0o^;uYdbD z3RD&<@5yuE&pl=|4MnJ|6Uy2aK;kKwz;D`Sp_1UIh&*=-T8B?!+!!}Nq=<88T6$0* z!(A|O%i<9;fj+6l?UIFjoE>)#+Jf*i5T#;PItbGA>kW{A?x_*c&h7lLM81ym2EdyL zY$e{8>VMYw&vAw*Tl)NH*aRHFlTeB;#9<{bRU~Hft-jO&a&31D%$$8vJqNVSCAZ!R zuk3K_y_k5N%=RN0$V)cIQp@i%{j_xfQQZ4(d&mm6LA`BODcTEuGe9o%UfeQ<&wmi) zF%>H8KRAAnuco@%WnpJ*oVT82as7{^Jg)AfMcswRW-*l@#uqIOvYMjd_R*YlP~eD< zx?_Yy^4T^m<>chlC`L;K#aXO}opSYoYntuA9=LIAc9q*bgg23g@pB0wzM~YWid< zH`x;ytzG@&h+0ux;zd>HX4{th(imMh2fVd1JC0_h{}FhIKhN53&jj9)eMKkS=e>>P ziw?X2`rKd8>f5f>L0FiZYhMLAqP82`OR4zy_%iBlVD(a_OmDe|&@KyOtr>6{7fya> zdu#T28m%sfi

LDI}O{z16V;A$FfbFGUV7$c&elp3jf`Fl+Al>g`Cc>ue~VOLtkK zGK4ZY3|ulhi1}-@$y9HC8APvETpq1&R*9xIhj>AZj`Q}EEOx)ha{*_ULd%YqHR0DS z?y4Hn7@o5Z6KHl#{`k-U*`%l$Xp3E3Dtv|qU4$>)TquA)TzNQ((?LCZvqCZR;2MeV zK;|;y7Yj{2++NO|^<2>H3E1=bPENjm`Qp%`&-B2{KrS-kn)p}ssSGU|>_SN|+u$(=VP?t`&U}SkVfxzmMt!;;kZyvcAIoX@7UwEYpk&X+`+~y!3T7RBX z$|?Y{|HDyQ$A>KaD&R!NDP{o!%E4lg8~^jUYOdY7x6y`?xc`qDP5Ky>}gL&m$9CbmE|8e$eXtmxUcwdmQmzBWDkspRX$!nZ{Z> z=d$~*&#nIH)n z1WqcA2k5-p&9}sXF77!k42<~o-ChQxwRY+^-e%BBiKn*Hzc!btO{OHQY#n<4pdAzh z*}0QeP=dZ#cvK7&p1ukqBQ~*t{0s5Q2f@R3Gbn`6@7Z?RJz`h zN^vV6k13FoLzd*r^oGz^SEXA(4n2!kN4#UM4OtYN&T(<&oqy;MNGZg3x<-V=m_KXn z%+tO)li@_uD!=-MaZ_Egn5toJm<-QxzjE!eWU&$dq|W!bkjqB3Ga~NYcX3Wz>bl%N zN636lV08UF+cI~&^BDCOyxh3_@s5?Q@7&$|`v8S!jQ+TE%Wnt($f!YmUkZ)#lJQnn zzeRpg=Q>vI9%7D@4yrkB9X$3;B)Pls=yp`rSrp(<@r4z8p&*8J4&`_jD)7ei$vBFF zgFL4y5Xu&lyN4~|HV}e`D?Eqhl^xl&RX0hBXQs&89o=4}@4MS$U_wwmESD{_<5f$gCwzKB)t1}fPYu28(XtL>C+a8h_SHVbEM1P2|aIU|o@(zCG&6Uzg-8SGD-#X)6Ja%3Dns`wA zm6~tZmGp6^(V!0eyGMr-7ftos@+(W@aCLnJO0PNh-O_`9z9*ySrWzj-nm>E4YU(kF zH&(ulhv5oC7MF-tLf)fUBi(OeV%w@yX$Oo%IUOj7xs(7CRYtVk)k`a8v#zr{i?pu} z<&Df2>iNg|rw@1*>S^H3L;DaibF^wtxz_w+<)~9QlPU&!&2Fk++i+>q(pGq4rEca4 zdb90MTdz4zH5XQ|`eFsze5fY=<9sV;V#cF8=sT4HH}A#a4shteI_Zu2)w=+RzIw%?w9~~(TrKSCq8|R&= z_3{{$_!Nl!JGg7lo67$DeWnU*H+`3;Ug@(vcqDUgOlSw4AMqs*T0lm>wFq z>e*l$xt!CGeDd7mI9%23rs(lV@#oHu10RL^GSK;j2fwT)y-NO}a^LKP(Holj)IYI zQCp7wCbVLt^ozbR7vt$xucMMV8HowcG6sRpBbS(>y&Iq4L}!8upq zP@U-vCo$`CIkv|#JSnPO*s_6n*TuOd_}qx>Xi~G+lHgLb)x8fPdzR=P+{A#;e6Hub zZcL^fWnk)(*)Ph4V*VhWhq`A|4!-}A&|j@Fy?XRU>s$t3uTEcB9;%*+i3iXkct zi94Y$l-<%#dG=|a`$Tqr$eze+3P-kDNZ&`iA%7L+_H6w+YcOhaVlpTqddpoc?o;d& zy$4{026aitV$UPXZyjxIM(8fvE)}fA zY@vVH4#I#-MWJr);c2;p9dN4@+JPX0Ec~Oua$W1ACzQ{rKmE8f#8wT-Fs$RH)K-LD zhUa6aiLedAZ7=y1*CKZC!4f2D|LA>4g^3FaJ{&og z_#d{Q^;oT~D-~0${IcT^J6mENEk)==TgN$2bSo;(e3&n6|Dg+yKbX2KY3#N%JbP6xXBJp z)6={)HX((y?bY}1n)yB;(J#8qKPFhos!vzXzrA8BTL3>5Rjv{GMs7!W8rG_k@b-HJ z5=tNAl^OQ4c9YLKB76GgP-M0--D<^9r@J-{Y@s#}{+%3piT9{Ks|S9XzRN$8YlRj6 z693b^%4N>e{T^bRovG#F6AZ;zl5g4HyxC&>xn6|#8b zRD9}E#)+9t*tb4N4gPUg%}*XdNzS?5w1QD2!_#|uw?4CAu~crdWb2EY)5lY~eZG?3 z2C>4Qe;5!*uBzKkuH%?|tJTK#yGE^)AgL#FcY>4LH2Rd}ViSUzeON$}v90C2Zr6nn zia><8xG))qP^M3eim$WtA8x^{eQcVFRoz*Lh&r@l6?d)mqkz$g!6GkZ|0?s zs*`eCn~?Y$n)y{CeNmRjLP7IZdcTnKL;~5D7Fn_Tu()gduCH!!;sH(Zb-kL(K;}+{_KHw83{0FuTJ}HXP~3 z69kWEY7g3Pc%~)F%5Y~ALikYJIEI`aLu%V4vO3>*F{@6+>-A&H9{Hg%W^QPVJT?wh zxPA7>DWq5g;!fnZmjv|CF1j1`P-fFEda#{*QUNSQLfpwR5I)7?EK0zmSE!Zf5hMsX zt*ydE87C`wo|zjDMF)XCRGrbwVljjUAJB0vg83Qv5q*rOs$l1dhoYm^!teabhppxf zr9Yk0T3nLmu^5&R|M@}WnfbF&^O}Y0I-L@*(Hg|J2&VRf%Jd!N$ofD9cI1#}Wq{7& zSm)~R6#3C#L|O`=_CW*_v4uX?$uR0)5PYa7pJaY%A+RtyMYhFU!{sgtF1DnFY7Z08 zlb_US$%T)i92G=umyV~7Kl$Z*RLpr`)wfnuLzm0X^RTXxSMBq0cdN!9pi0+w-Ik$K z^>+HY3P@zL-r0du$QK&9~KJmJ(wN!ZcNCi>bK(1eVpv%xewLC^h(1uepow$L|DJ`PudpG1Bip>g$dk zRm7f)5jsf93A-1o-)@?e{2;?AA^Lf~mgsmCr%qkckXV2vK4d5POYO`HrLA^|1&avH z^c&aq%#(;JYb3ZcTBDy3yg);=sod_bJHM4qPn8tMMFcAvs_SqNmgR~Y_x?PTv<0Q8 znYYNU)MCQYew?Y_&xr!rog>?Y*Boda{~N)NR-eQ zue4q0#T^6ZEg}#Tv@&rbzhh_I+K(sG%b`{6^(2m@Z1>}PL^#4h_ju)D37r>qafFL< zZ0*LwDk~$P+ZH?eNt0*}^62Jh(Q(JH@v)dUDW<9&!etY;kF_2WXrBbVk(Kqj-ZM}F z&Ax?AsZG)KQ3(2ysJ~zH%YnF=j;`%joA6B+cYV=DqNlFfbsbN7%s(!m+>(6CwAzOL z(J)+DOzZW@UduFsVVUMux^IDCz&0PWI~L$0S>26CEl=P?%h{8PVzOpug=o!H`rm@A z^y~Yt+(?^XB&)XwptNqPNBMZCJrOpT`&H%-o_%a?ma{0+41A0)8Jqg`A&i*PbkU6R z8(uE~i|KbzX)kr0fm@Y$RMj=I8lhg~f%(0&)OwhsDcN~k{eGUnd#SO1i6S9 zDR<}r_x9@d%^(#EABJ89ns8u^8aW@SusK?MJo>qvyse9rSq!#rlqttCkf-J#Ri8k6 zpJ^C}vOLPY>PYoGK}~S|6kDo5{Ftfdt-rPtw*0vq8zZdoV6}Pzi?WQFK+7j>LTN-2 zmIR%NU0zsO7k9oey?J4(7T-8Q`w;=b)74IXN7zE|CzdY{TWk*5-`=qY?vaoMXwC9| zF=JlTeg%Svvdf9)iw^NS=D=I+1a3XGIg#-%4yn%s<4w(;9>!l&o2KM~CmO1ID3ts? z`t`@LIZHN=F`2*Jttus8^`wCQ1;sWN{z%6O8)mF};RMZuX>B`4TOAE1#CQ!|eSnd6Q0`%<$FgHKy|@3gf>1rR=AvK!z=QSc&Zz{B zSs{W}{dBU5{RzM!fb%CgW?`vn;`j?COS=H{h@AIq5-qJ*RX$%kk^;vw>~IriXRGvI zF}DSsZaTw7CNa&=8^gIkHq`024;SQzh9t7TIeaG`c1hW@GE6qxF*B!y(ywO*U;^x1 zs3_j?cKu@&s)B(55A50nlhL_1PKD7^c*Z$|af~r~GchKsD||66i_FP;c{{xE>aGLB1s!JSIS`f2Sl{lD*}GTsZ0Ei)CNDTt6rP$n$dR zpG%g|3nIFTFObE|8M1nGBSkzVdO@H%=4{79yFS{g2uCdFJSs3Q5E~N{W3B1vW0b&g zOMpP&_+)3U4;@8_+mAfBWV6CBS%Hf5M)G;voUs?)*C)k>!88@L+!%eSL=+a{4*rUJ zG%!ahQ8Ctv5uMODENx((zRJ%?6v!0tzS7k*nnO7K$f3aOfyHLs=A%ikU^8VG{7842 zEUxdqG=a;(Qx0QYVh2*L!=lNmD`mTed?L?jCmRW(%BS^p>qrhMp)Ux7`*3Mq@|umE zLh^4sc^=qiSjCAiETQ~rXBFClS04|I`zR8rA)rTmdw$a{H8B!J7P+S>#^pMaU(p~= z8DGFx9MFrCYF03?BZXe8>bnTe&V2jhOyP)H3G_{UU8J%c3u(7B+2kO;Z0hA<{Qv-3 z61M&E=?Lbu|B$gZV&+ZqAe3u-i>YbbI!{&z*Eh%T}VsO$=sJ5iH*KYvEP%pDP3BXyEw106BRD4I4bf4 zqoizUyL54cjC<7ICr?fySQTHk$mkT**GQ^fq?J3)Fr=ie@7@~CGft>V_O5?Oc!O8r zDNAi{e{T3;n*UjwS}aFr*W>W3wVXCAoyym}Z$FxAc=?03 z_$-~dSl-qmwT=GU)kI_{vRT^evV3vB>U6Mef<)%14PP<+S&z)QLS%7+HQvBWD$&Y5{V3=IgEB|xw2 zXlkT8D=?dJG6D6L!`{t-`P{i?nmvMfY}|G>?v%`s$>)XW=(>Z1{d*-VMBYes zB)j6wcUN;eI94%&hl82H^TB>~+XqY1Jn0w9^SoybZ^vk~v|*)3J)RWvHlvfJZ!<%S zg`!AP6Q~#sR|4bVbDT1$;nqhJCHR4$x4F>^^3Be&Fsv8jX)^xyMV40rAGcIdlLtLG z-9ceYJr<`DarH!S^V~Og?{0F%rl!<6l8fi*yxXJpL|i#CpLkl)J2j*31KdU7SG!0T{Ql_6uYM?W` zIgCzhe(tP+)z{s8NgGEF#>DXXtST2}sf_wapP}EW>2|yx0|?w|bJoX2J`9YWlY`VV z&k0C-qj$CqAB2c8MaE_~`^o8Hj&B>Yc&Ks+xvjCk5vPRz#gB2Q%pCFAW3u9ke>r!R zv`o_K0liu)O9~wl6@6U-E?Rw;fUT|iq#PUu1e`$2G>wfx;<~-$8?vWv*rbl3+tG8) zG#)fNs#*v8dK-PYuJog12v2)2hNz;xQs-BMKLuK8ptFYHgN0`KtAp;v<)BKKo>DI( z6wO*C4gov+EpHDG|4?jk5$|n?(AmdE2Hf!+tZ~Ac#EJX-@LHfo%D>Jy#HFyO*5-t2{FB!^K`woywP_Q(a)J(29*iJcxI6DMzSX>Rm|PLVwrPp9)&!&UhIo3!v2$R^UV239zu$rNV~c zg^)l*2_;D5J3UkcqJ$|ui+4sss_%hg7MR$iV)uk&7I5h2;v|=#N)1m!XKso*uXj!& z-aq!adedlcq?n$=t&Y#86BVHpCn+VHgi#$LlF3q z1hQn5`I&tHj%j;$Q;P(K`7nMY9RD&fZ)(@SK8o;8Pdc0UiVL)I5~c<<)HzG>rW znQ-(>IdXJ%>f+p#XJa~9PR#B1N0vXyK?A$*+Vf`ec}y@h3m&s9ud61_NhSE zv#JxcGn^!1sKft&USD&<1ebkg7kR>RjB->Wkoz9WMJuShJFK97@>r zF&-`(;E`-D`u5Ysmpe&fE1(~HMi((E3Vync`c(StAZQM3(L!4Rp^KFP6w~6VKGN6O z*;ysx_w2%tvX z2bPV_pq4YcEUe1#Vq;&l?Gy+?c(`^{$fI9cH)>;>p8Zs*k55tDM-axG)^-sI>jD3d zryM|Wc8wnI8&g-P5ErB!e}su9NQ!y$U{pAY?_Ac!=F-*dO_8Jg1a6J+-8IS-RUwQ4 zJqUH?qoKf%Ut_0Eyv-|zZ|269*%B}Xb8(HJ&Yt<@bZstz)is-VnSdC(aS51*G|v?M zKj#*)fsD;2+EQa-ys55{hz zTbyusre9xcv-+Xlb*;5O*6D@5u32D;VH^vvRaNSF!I26j%Xc__qn$LdI|>7JBb$qU zKTh%C?Q4n_m|9$|vv@@XMKqilVQW~{fO3N!Xlneki!!`0@*gSUU@W=hZ0l>Kh0O}m zB)xN>_q2mH)Rf)Q+Prx^UB z0F9hq)*q6(t*W8d*r(PL%#=#QRH((@=}5VDZTL2?hV{kS2dTjYi7Oqkuoel}Ug9J5 z)Xt??bNHD~@6b7GYk7qx_(+K!?UJV+JsQSzklzzVNyX0#*h?$u-9X*`C+-}~{&sVC zSSVkkJJKaIv<{-dhhH`9!7I{19o_eH%C4X-^)%D3IA3sm`N_}g;*X3KkP0%nUq&B- zO*#H}mzz;t@qw0IDe~}5k95T)-zU)%vz@V-omZC6495=4_gI-BuV}b8QiYmG{H(O^ zNykXXo65&ZFk<=bbLd~hSD5TFh4$Db&NOSoEulb0tDw$iP%8?}i)`F7Px!gaSuCiu zPHJl5!`wqdS7nHO5CSxe?VWP>70VPD|CS8My-rAm_zd;bk0t@whhpvb?2SlL3EmV1 z`p4WAK4!XT)&>~X1`59x!@9UH5WM|9?cru zH3uTH0vyyTz&6q|SLa=ew=SNF+H-L{;0aF2>+PYgy8g%B&s221q#imtcLQS`0R{Kk zPS#Q-%@=|G-Lo&JEiV|tK{=X1kbSjcmJ$oREyI1ZA-2cts-}s#ac%d?@oLssTuXJLLFGWfFIB zpDrHiQujLg_>rpYrL>!@9=+8bGkcwY+3$T-d&7{+zkces$I>VU8B;M`dc@z0PyU)f z5Eo~ddq38w1twQ7l##J4CieW{BhC&&Sz_oG+i50GNKO7e2%?O9fBz7aJVDhgrW|i9 zm~h}E8EvJf_=x{>xPo^)ZC*wQa#4ST1^!`NQgP<#I24XdTw5f{P<5I+k7@w5@U&}l za&mt0!2I%?UF5AL)#Fr;nN!?GhEH;S%N!gBYV{jCZC~{r!F+&VHyFI$I4zLG|u7D;T_BR}slDCFjc(O1+ z&V_d-v6_^TuRdkV zV?mJxg5@if?P}jPY#wT?*aK>S%&5z+`C_7MEZH`^N0+5Ofl-wdTd+1wF7++G9*U}f;a9@WnlEdvK7tk=>8y1a*8IP{gwXB z%$vn*LJSu)b(c)h)INZD{MyB0wwh zokIE8M23m~6@9TXgwNu9aH)Ap*vd?9C2{}`POR5jVYg3KD`?7AA3!iFcGLqFrx-)R zF>}t1OL_&LzVFoZD|JgqN18&rZv3d|6)Fh4T>zz^+nEw$bOTzCP1EtB>UFABC-biWOjVrm$K~kPfI2g?&&&O<(u#RhLH0?!%TzBU9&r z)pz~kAfQm-aCdiyKNIt}jKkE5q>xr@7WtGNu?ryZry`6ogwLx>u|@*6^Z|Bf=8eUj zY}msvSu7=r@L->--Z~OO@XyZnUi;|&nACVBf4ex0_I-M2I&Pvh)_kS0g9=c1m0FBk zl3x<=`vOwHh9IS0;O7?r$$F!=%Drw^ux~ia_OnUOmATdeJIN`yBjUw4t<}v_ptryX zRT)W&rh(Jqc9Ro8DUs zqoa;%Hs~L809ZAlpbmTC#OJ$iex$Lc!Uf*?r9$uBJ4m^Xs9@usjjLIbz)~3TcK!fm z4C0&zT*vl2+qCHeB<57$fxU|gbmm+UM~7O*V$A~14qg}v5nFCu?fpS|C)_up#~tq7 z)x$BR3hta_iw{S{8A>9H!R4@hwlJ8txE`_=s&V42sJLfWI|RLj2WRBxcZ=J#Qfj}^ zrwY5SY=D!O75ciK-7x;~lDGmuH@}DM=Gr~zs>__zKo1~6LQ_T3evTCqNT;e)w)yxK z2^mxXbYC}M-d}KUw{tzX;mR&EBv_|`dG4hI>b?whYSgZ4?Oewdv3-}(lyoAnG5nm$lOaeJkgmmC zg*PlOT&a$H6D&_HLObahWH+k-l{c@CA(o-j2c_DmFzbtcnp=+r$X7m z*HMpRbG49%E6&|E+q40&1o!5_6f1LUWLfL`4Ww{wx2q^91Rh7zmEAJ>PEyDd~IBRb@38FAO@K8fmwdJ z7Ik&8mTIy`&9A;6z6PpX-9nR^g%@C~6`adg?9W}x76U&(_Zj?-UwpI(WriU}c5E`H zx3|}}i+|(9Un*MsjmHnxlTOBA>?@MX!wylm5rdsm!i5>JdVsQ88@~ii!bTNVL{nDR z0PIw*-xfdu#kzw!j~dtGs?ErPOS_j<1SV^nrX}sKrf$R z{GRDqNQNOp+$R}vaCENSY_PVO{zI*2BE4)I=zEUfJMlx6c?#`T5!#pU_FvV;QdYSG z35}1Q_c@*(Q*?Z^Bz-p4qjPyJH*6)h5O$k|WzqGljZ2i}eRvJD(fxC)pf2j5)glYD zZCh~72+7e|4EBO+njL@WJWY78=bO zt1^j*BC-H2x0c^}!585`g(o>TL$bV*G{H+ zq=#h;+Nsv*csiOa^`mtWKqjq}3ck_E1WBhhYA%GcN0gtmz}AQ<<#ub!Qh5T+WJVM2 zaq2b~5>vCjhvbBjrD&t^WXi_ROdh#{PU(n4TgP$abO6k&H_Y-ep9+S*C%js)9GP<2 zS1Qn&KV-d0WZ}s-b3*e22x~M!p;gl@8{uh_)Kb8Zoic^LJwkgj1A_ibpS7{X7-yW8 z*y8dn48>S%1dEy7Bx)_n70A3Wh4lilTq6^2**0ML`-Z10=c{5ADM?_Gq@NO_!ml)4 za2VAEQSn74jhDN$GP&mX2Ddimr^8>bXKE@Z|nKp_Gg5WYh6g`>Io}mVJ4j{P@T3np%Qe z?FFB2r!YrjxrDjd0!~B9&mURxr9+x-!WMd@dT>{S_K_Xj1g)v&L~>OraN1*9*xm|n z_$VLYH|ao2Sk5-AWgJKI@w;6I1Y(9_c7#`NIN!@9g|_E3e;59lP7Y|5MiIuRNH_+C%dvmY{)W&JJao|#J zNRj;(-%2OH1uK)?u(FkJx5@)$bqYnp%;J*{wXi#8oaT}VqKK$~J_h$TT$LX1^?MqH z>B6$0Q3N2vEVR;nyTA^3Hyr$G3%EHa*0N(j$RfBTnIU5jn~O>PA3uQ$+PPuem(w!} z?e$i;DL^B$($9GxnCeIetGC^-`suSC^t3H>cJagUz^^h0%<&sMLNNpM{V{}`R? zmytFfdhCAaXI| z5XapG*0Ey;jJjGt8<>v>&SD#!XT=`#%BMm ze|Q)HDR-)J(7(e&UIRha3pj1s7eYKe3(c(Sw*v_t{3%F4dI)%9w6%1enyrO4tyI|y zh!6O)IJpH746v?RUPhDb2z_RM>|JP!&`Kr$ENC(v@YjjOv?=Oh5AzEug6@72p^2LdQ-OVO_VbTzAbq07i_++UOd;E^Q%!#E(6>6g*9s4;mD2 z`1kv2B``#H8gA}5G?*UUPH3f5vezd%;`VoI+C3h}xMVx$U%iNp1VFN!U5z0NLzCph z{Ml-XD=?~8`Kq;p)A=*znOT0oDc?1ln7Z+pU0`Imk<{PANK~quZv%$hBF)(QV6v%3 z&8xam0F7)7w}NpE2SC@`j?M`QJSpw(ZrH)4$<1^Y_XQ|y39;7{cy3m@1*5-yHulf_ zImuHoJD|1Li`_hy3Oj#?60a_{6Og5&mPw-LBA6h=EHtfvr4JzEA){RK*axi%U;^T7 zUoJ8Z2t*D3Em#*Dn@h|p0sf!2KxQWu(%qE)qM$l33wg7a7yqH?p?_e|LaDv+|N0%k zqU*dk-p}LDO|bEE|Jm64o`S-{g|aY&_rC}G{yhMJWto50pmqR=;pvnaV;{-c;7<>s zPBO_2=CeY%cV z7oGup0Xm#LfZ^uGbbX(w%XE>U{{D|mE$ic(A=vfy@~U^Nx&!^tpbhXQ^U@1)mf@SZ z<6t3s(t?#`rut8<-73d!s5AzpgsJW!H-Fs$|MZ@_B;;~*Uf z(k0G8pMTp1_9^stpMenzoVm&EiXlJ(+p)6;>L-)D=xNJ;Yg9`6o27Lfz2*4YCm!QvvTk@)nwTqr; zFEtTLyz40Qmr9(2@LlZhYFv!U25QyaT9O@2LZsDh5C20{kaT-#{_(GW+bdXSH!c`) zHMzv*i~l4FNW5D6_-{EL24{W>tH ztHwHJOZb^FG>gUpr6YA{!(nuB79p&_?>!Xrp|J*j#&dZAS?T1naltjbD1IcC#B$I+ z_be?PO5gX^1Lf6~h}+rNZt)~4%dGbA{@IJU6vr`n_u(&a7x)wSJwdg@B!Hdvroq6z z!zu;>Crg>WdYAo=xoobma?qB_ItZx^N)K`&L8UBc8yj1D$I8lzXe&IGSWr|{eYj8x zkS|$aF&EaH8tf%kRf1^Q=%<^G5NkooCwvXZT7j{O8+2cQDo?++@vl!7oS<=4jO~3# zBl&kL;{`aES-@8j>2Ux_N3#sKHq`n-WD*LXh@O*PX_GGwraXpZSAk)R`cbVdY~cqN z&8OOkZZ4Kop)A$!%K#BY(&M=<;?=wuPPY8SLodOh@aonl!t8#ti>Bp>w;x?CaV;ssaSB(cu%b zn6u#Yh}qhfx-3nBYDj7iF$7_2(A1Ej+up4v5eyPP1xTc*?F7ciOlk95mW4AcECFGB#A2JXpakclFYy)p%c`3b4bQC*u3{wB|b{%*-Ug#_s z^M#l4ZCnKL?JZl1`TtC^6HM}f0gj_~-Am-V$8O;xu7xe-?Ej2Xk`gbqS#4|vzKqG= z>xL!Wu(oNF3CdsJ-uzlh=WTwNnVSa*ak5c53L-&=?o~WY01paR^wxt$qZOO)oL&iKP-FIuvnar2j?*dn z0~wHESN#bF90D^1@)p?py9hzm<;wYfXu&G#fCfXw)l##cRrk=E&#;jYhvefc*#@ovVF$1USaaWc$fYDLG zOa-*-bLRp5EY)u$zVW+f9D(GY^HDIct5f#Lw(xY9rx6JB|4a^i4#JfOY?p8OACgu( z0Yr|wH_NRw{JSs$##57tvGAB(;ptAM5r}ztn8J0ua>aj%$mJ{x=IQSHfKxm|l}KNkUT7G_h4bbrJlNpJC^1D09j8efjKV2F; z8y~8D3E;j~tJD@cM5yOLsC5`IYQrf47f(&R4D%9DUOoT5`1D~YXrrN4+uOp{e;8yZ zz<@Q}-3)=SYor1m`#S(%A8IXL1M=|a)|jAh@qdp>VK-!uy3-SH=u8F_-@#78%72$`@$6h}B_T0eV?jgps*t4?uJrxV-!7VwE;o2qWzur-9UclAt8 zVX+TJG{}ZFRr0&;zdJVOd1NB1vn-jVT3!O|P-hObmzw!zhyiskFd~GD{DnvDC&3+} zBv(Tae^3Mh?7(LhFLd25l=!dONvny1)AcbK)#{0Mh9o9HfYm{W@4DL>q8K}SQ!*}? z-OzQomZLcuq5Zx=_ScE_M{NB-U;i)8@kauSam|27y`%N`bE-Dj`n6I8t(3IFksf1;FA6(8e?Zy0H1Jwig%xnk-cdC0MjD7R}nH_BL^}?l0zL zgi;4eHX{Z=oes~?7*LxYMw^1D?tj-BEf$566tI-;Lzb!l z7n8ScIQ>JrGJC>$z(DRg8jOYL+N@ooh==JU9X#dH|&}Tgl6-2 zD!lt`$DaTDDFPDgG*UZ_TYZ;k`=1X$I(m2sh}r%RM@ShGWZHL!Dg()CQB_qfbT=fu z0(15T=ka!1bF!qq%ck4S0N&rh|9>xo`E-i@G@D)| zoHziq+gHVwvg*&9PV_^O zP77TVE>a+I6Pt4BNQPmGA_{;sdG+CTdSrqa1H2wMpqqnYS4~(mdY*NcdbX2& zke9}^!$7`%t=ZL&+|pe=VKm~JErTG=`iO^}gCv5E6GObf;1az2#3_jZ561c7L`;QOhPnHmm2Cn(*0Bfc@d1;`3hjFi z5Kq}b;a<*8fdI5DMxz&UpHY@)fs&yM#M185abXMPIIsfHu+JOv5mTD^PJEGIxrR|) zoBiALbrB#pV+&oWoq?HWSzNa_&HS<+;$Qqtn}Z(7!KHateprO;z1E3#3!8To2Qo3V zX9ZU_-Sk=k`dib1Z@5!&97)St^av3JQ(0^sX7rDoc9r?gy_+5zIy+Nh(XiD?ntrSDfG5UN_pGk^e0IR)1G$o!GfZEwOn zZlrmnhD1Fbump6RZbCiw_NYk%@;8 zYpo}9?E{fUsw0LLhk^`%!e2s}yfC#j9fKfkyWS}ZinWZwWtfB{-9dy!?Ge2dMlH)6 zxigPuwxd1tsQr$-J3-cvLk@zD6%QGI`feLNSjPe3kTwQi9+%Y{SYuA3D*e&qxHbeN_hLA*DN_KsItL@3Xl}wZmYC`)5d!4JlUcvGSYIjd z7@vn|)*O0m&YiFiV=ltsgJAvO(6d;Pfa#h57NFA?@T#rKOe8gI$viAzA>c7Zv51{i z_oNgXS__m}zmhQnQi@M)*rH$N&>c~RtuO&DUyuE0nj<(R>|IM@$2b-{zH1BiSBouP zUKbPNpSqTjZ+mOIYP)3ty}yK3`dh~T$eQ~#(F3!vkqB+3XG7@dxygWMuOgO%2`s^bK6f^g zmu@@8UBM<^oZI@`g0>_#->)r;He z^+Ij8KdyW)MK%}im!_t z!sg2Uv6}v&y8h&q?~uq0-mMFk|4HC2OH~$yW9rM2%V(x0>s)8<%3Mi+JQTx!=6A0R zJ-w{)T1LWyFb>3WB_&oT8z{BO1j2>_Pq^>6gBk#mV@I2&Q*3?hy{H~0uh|(SfbC4t ze@*6JFA!Iy{%A}vp1H#hgBP^eUJ3J znH8U5(Wp*NlQr|o0(IR*s2>+qS`mmXdCY8AjIUV_CJruR z*WoBOZ=39^=zkRNJLyvH)*QF+`OH+Ac#E)$@Vrm5kS9MYttht5DeB zPkFq;g0mWRkktw&+rBw@3WxPeRhBk58!_YB%OmQN5m8^4*wJbPs#3UStv;+%Kbu9< zVX5O)P&Uo`o%D0Q{p6ILxN@_&L?#id$sU=c(~>AF(pqwqOaLu06kTIEX*KeU=*u!e z{aWZ@N808t*AP2mb`9&+gMVx)I@^`)o)ve|d_OH>u#;f0&oxV(vhKTdrmO_KZ@&j+ zZc1mF)q`27ALOn@+(46qunBO{=yE12y;h#{{n7Q)ua)Jgr_`=dWPAcJtR!zvv{+hx zHQHK8XV%0^9Cma#n)P9V#dFkH1#Y>#BwXIV7KHhW5W{w z74`xvto;#txkg{-=Gh6=7%Uxeq`xKz39~W*^=WbV`h~&?RN;hjM=U2fZtH4WbTY%N zTfp*Kc3JaXFOHHUB;U((`hv4;m{r@XbIAJ9lpMQ8WkfkQtSjXZAnlz8ENM8YcnE0O zo+Xt#eDknBF#ARpfh_Ujo(;g8w!X-kU|?gV0*Q~LEHBU};R926c+CXYL`$ni-xbc& z;sHlV5$*cf50;kA_M3ww3B3<16xI-FH@*tFgW5pU(&UwDl<>40D1a>VQ)`3sRP8Cg zz*?yNP(Mi|j6Z1MIq&jM#MnycY@l2I$DVkZ%R2JiKA8=Q-Eg6MeG=W8rd;dw6|?He z9#slSie)z|Hac=qaR=yV+9{!~JM!H{SlzkruYIR_s&=iOB?_u2wdMrLTs&R1QDPcO zF^7aDAef-%#4H3ai|O0r?moOB_bul}|MCN1gu4NS+Ar6QbZDE48ZKw*^+ht0XqTQ{CUgDnY0D)K)!zRWtl_<4Z|ZzEJ!2hO$8aA`!Ljf2*sd@HSW= zhv*E|DWOApflHnoO;foqs7ZoW%$RYbm)9vqm3Nc^`VRjx-acQ#ClEwFf2c08F#BkD zHK*B(y$1=-P~gN|eyZ>ZNYj?hb*|GkR(?MPb5g^92r`w6r37CNcBxB0u%G;KcF&dx zH*5qdYIhZp%s8tU4Zql-_ychLv4~TAd1cgxH!0?!@LgYYK>Vr~eZK_g3L&vt=l(I* z<7$c}Y|eM)6Sw)?_!rj(a`K^X3MYvA56BnMt*dpKiocW*lrFkC?2O7`O(&^>Y5EM! zG=Pj*?+uU(0@E|1AsL3ttD?m;CVxmLHBVq7j8;NZR94Q|l=QztB28GudRrX&c7ei{ z9da5rI!c1={X>KK+c%mPvz}%&x>aq{YG8t2I_zq>>;k@vze&86ZVa7!)FJ0 zD|A1Yx@Tc?t$rWC&w3M(TcB&fg2U+w(><{nOe}z?FMC)u?5n7>&P=a=oOV*BaP*T* z^x*3SE-66|lH4&$k?j`fN5$pIcXK*(SnIl+Lw(ac-LvOb~0e?b!2O z(bw5}UB-s{Xb5lJt6-Ywkx|q;My%lQBWy7tpR<;KWzOB6Osi;%00o?LS5dyr(@Zz4 zYQktS6&cs%R)joG<1Uc4tLTaPuHTJV8F5w(TeGX6aLliM`UIHuElD@YezBPc97&z{ zAW$gFbq-guFAVS(kVSSruDPzT3Tved(gLaF$&@G-kkFU9kt{m~;k4Dyn5qFHw-GQx z?2AyHoCz@%CEKk+LS3^?a5A^@=TbUw-8Pc#jg`@A{ULs{g4`TXma7u<0zWR∨dU ziQK3LZ6~rA0!q0&%}!HZNo9Hmpc|~;?wr!FQG!wf?GT{pC~1s_M2uObEzLhd3f@Bn za|jM~9k9o-;iAP%_qV@dWLuvXgOb%OVCg>TTEY=yuwTv{)K~Bs&_}F_+VVq&Cgcx7 zA!i-{M3V8@S0+0Qd8~>{tO45>#K%;jRWZPJdV0&tV;FHXosGI%HQ8NUL>s>S6lHuB zs0g_siBn#G#o(-n(uF|et?MdE@JvJ5hv$#|1TFsBM=LivV;MhcXsf{E%>koRyd&*@ z6kk+N4r|zynTt}q$~f*j_u^qn>jeQK47*u9Rq0k|*Yl2$(rRAz_XK}Ww-Y={0#^TS zBQjEP@WO^^ibyw#d1J1erG#z|)P1nY8;=6gJvf)<1-jg9P8qyULvbHG6GeP$#BWS` zpigWB2IBZ&4Vw*wRS-i0Zwy(1vagN+;n5=^(_6U$+-t5r zz=e`PGkSy3ft>LXil_0Bh7{o_bU4pnw2hctZo1V_A+yVSltk+adO0sPp#$pB0YBar zmF=d{t|$3lUhqAUaf=IJxXrVAxpTOZrYv2jo+6sF=TLF!lOL&PfeZjHS1d;zXn27# zpq^6XyS31m-D5X|;>p)#+fpNZITS_l$^inI0{XFo`9dg`Em`?Gvyv6?6Bis|Fcd z+Uz}rL2fJexqlb(;J}rHPuiR$E=V)vYR=L z$zE<)5Jn~UEGGs?(yByKa&@ZIy?ORXQ42cBlbN@4a*YEnI+U{4X{H@(;u0+;FFxcWGE5p@jkuOHR5 zsmPyPhgv5euPFq7?G{!G0LjXC?;ynapezR2C7T1l@G-O@#em!GIB_uFf1Z?vNEJ_Q zT24oTolyEDbo0fkwB!}rUX9m+!A@%5;jbK-oE-%J_Nzl{?l#Y#A`qf;n93P9R#;~L?bVv0>rPvD z_jeWuOabqo1Fz{Bx_3#4;p5?jm zrYXa}Z>Y3R(EpQsTvyVzDm4`*+9hmh9oFT$BJQEYiHQiB%JY#`Eu7I*+nJ?~ujk2A zaFl!MGJ*lM{jzdhTkL}p*})ZFDhfqc)Z+Y23uUM}FmbCgmevpZOfRFO%#DcLFoH}= zI-erO^1H9N0AV~8`RXMtvGdmX1p=2$dI#ZD4hssQ@SKS1Smdng-&M3F5oTpk1kSTE zg&l?kGJAR_h~lFQq=f8zH_qFxMVHY2yLOf~Sdjg_Y%gmrEfEc1V-~+K zkXcA0Vvd9aRWZQynN|a~>W*Pkf~p2$Kn3zebGWL1JfX!q)435Sx$FQx>YrMjZ&(K} z8_>Ryvn5CsFVVpWfdf`&v}YIsBsJt5>nE^Xge#F)37rRe^EQ)9OjWqlKn9Yfez;2s z`|Gn+_+D(=eGvUwX}~KzmQ)et>+{K+nszPUa?!YUr<@)56HIe7oNG4Nt{1+6JBo!6 zcY*9zIsjGNk?T)}ip@1_#X)-HG)rjyr&hiTAlxPhPHvHN2RcGIiO4>)-9^*d1-g-! zlgYVPQ!bz4>=kFpnQ-;Sa|7?Bk8Szv8@`M#;ji0@r9D>ah|8@-w639>kGV$b6LPoZ zS~l%q)*W4jyv@E@hD^CV_)d?gf*C8*#?R|fJAnJ&Sw6NB_9$AI?RF4e4_PDzjloo46X7pH7(eYW^L zu#;+6%Eoj06J0@wnw6C*6zDB?qQ;}Bv7B#W;tl;8*Mz&A29E!w9~w;Xotnk*bNQrT zPg&hVOxaK6R&=BK@?vk2Hew8w`|s^1$=QWBl-(j`@j{yMZfM$W$QXg{fDKqWWoC?V z7x4SKAj``5EBQjP6^Ln^ZCA(u>hSY|r3OMyTgkScot26V<^b~3lqgyfRJ!yz&Kv=v z&I_I7Fe4&WxXORA$~q~(QW9_-0bL~*>$3op*6!tb`MXc%c?OGf|ApVScLdy$li$Bb z$$bcOJyi&CVF@4pB=yhVx`zhneudMaNsGzyHfx65G5(wy+xNj+28^}=BG>6Sw#Qx+ zB+232Kj6<6#fP>ytFWm*Hb8~|@i+yMVj}`@&3`^2;hD(^>%{qLN1i1t&#E&H&%}!@2tsX~Y=+n3NJ!uL81V$*+f%z_zv4fo*F{>PuA4 zz>|XV|Ke8vgCP8qTv}|)4G@S(!}go`0~M}o2hnYe47spB=&k_Jk)O?MQM;r{j#3KJ ztOSMk^KnIxFw zhCdyVYNsj?Ke}LTo&?gQcklf7*jK4j+)6uY2Ta?;HQej{(b%zA-gW4fT~k;}VT3J%sG{(n5TlLVsD z3rpK^K5Xf809GQlqK=Ei`MbRxahS5O4%ztw4eo!cgbw74)^6UBb+UFC9s;~+MP_W^ z;YGNAzH0ry&+broCUuDl z!IRxzXaN6xHFP-o1}u*v5x~ah$^$@YVvxHV1!VS?0W3T+9#0~F^2(ng@pv>P97=)x z_sIQJ$xHIIzd#eC(*m@K4)LkGoRRw+KsEpQ&_GRQmQKdv0)=M^y-|?blz@P#jgt!- ztbB(d>i+xsfBXUXS;kplP&Y;g$f-j*FF>9Bc?=S(an#V|zZ>7)_B*fU@u~QOW{i#^ z;3b`%JakZ(v|4iWyRJaMc4bNEz%#^dG@BGK%_;;}2yx!4PmRpwZz{LNTKmV>w#FJWXTE(_t zS7jtND2VMpieauz89^Cphy!9b)cGjL@;?hn@*LOh4m~J$a&nrqv<9)4Uw+Q-*XH&^ zjSK<0A!B_+l%4g+|9$rl3Pu~$@;eL}prLYR4H^or9r6vKwE-~@(g>#a@#X_(89@CQ z`s4e-oBPUo{lw|50~WozT8wlgzPl<+&uGCvV-Xh(1z*RvL#^I?_z8fllAwf%MWvwZaunxETbEN zZ`qu5G;i=g_bDo4_Iwq-sRzAFhb(TGP9rKlX|VX(km!Q7MO2zEGOLFB=yt5H6*epG4d4mIQ2vPEp}LHWNPd?Aw+8_Q7C z*_FeBoxb;0Z+b+q9e2GuI)d_HBvOfm_FDzC>ID|u8+&DQ_i-8cO5-{;lUlUNHH`rYA7@=&F+y!el(_5hn@@^9?NWM%W_6MHY>6T`Sk41=etZ%r(`j1 z&?h=YC3@`{;Bq-O*bN!!l}ju`0Xi=#FcR%JBDjDD4YmqCKX|A@(g_?Ul?8rD z3a@Mij)M!8{3m_A=QQK=1(PSL>BZ8s0D#4c&(5p$*DAVWzHh(1UsN`Dor2`{LKS5?K4*B9(R?m1G~HN;@H# z+!L2|J=O^$@rVY{*zC=S!vqm#Oi(EVOFM7dBh!mH&;z8_NXeJI^!J@i@b(x1Sm63# zAk>pgdY%bPJfWDKT{hJuaqGNDC^P;f7-q`l+OGRnMit>np$&xKbcbet{sNA?e-c7; zUgyRI^xJ2d7#lajdvi~PDTH|ODZOFaN?mK%{hXKr!9sfmvzXchaLPOLdD0LKk{&T%Dc%}pHD4+?%~GjIaT-mQUEWNt;?&cMK+Y>@J#uYEB7HDi$R>Cd_=s_Q(8nPbNON;@nKkr{(9w~G z);#G7JwyZ~ob?q18LDlomtfPWs0J>46Fjapa&Wgd7qu1%sbsJKW?29LeLG1{Vy}Tp z0;tw+>%QGFF7>|AoBQC`oTvm&t5P7S)Y>)1fs*FML2hn?tH$&AEQk%kCr$15sBA_8HRH12g z>UBFZLI0i4HZI-Fe|m3Y?;`bIJRo=l;M-w|J-)x@)mUU)>f(Y^{h=Y0+!G`cdMMip z(D;+(!-o%(44`L!y=eY9i9{*^=eJ2~#3~JtP$2x-vu7t_8M@3nZqyi;*6K%tXDvp5 z%`exdc;p9it>A}a&G=zs>cdKCFv=;ns>Z5>`=0_A9>tgrLmQW7^Ly~vwCz+;{h95y z)M|R_6W~bSb1|4$%l|S9FMv+8SP6%m=X`Nid|NKGh2ZSzCe#_1a`nnSuZng0B6scz zm~!N+dvD+2R&KE*mjNoYzjNQ)Ca`;`?!PdA=p53oS29unh_GePO22^M1L})fNJt1H zrTJ#$_YbZE`45iWmY!g;D@*sbx=83l6`-`L8G2kVnn7gyb#MkmqNAf_K*jc&Eb6h7 zjm;ce>8}T`zJOl*FTKLw)S8qUAaQ#iNS&RXBE~cy!@v=9yP}QB>7Oc!V}B1|z9B|W zDLWQI1n)FIt@lr$VXwtkh`1ZyYZMROv%(6E!DCca9{{pix=3|DAE_i)NFl*LT0joh z{>9q%pw|N2_CqC*k~g#gCg$S^F=yXjpf7)$`~@6?{Tc9Is`@OjS+_6fZ2S4<+0CRmptHMJ1F-8kBKe+USjt5MuO}23tJR%cv9mi*pa+QR>Dym+mvdk zR;iHl*Wnqz|5lGn#BhI8S0q$d6%Z?&;fwj{8>D5*w1??`owm}q1|>dSPTN`XSKrwD zeG<*%TuO|K3AmgL3_1*C8Tf~)vt#GyQSIsMNN}c4YCxw!5Xear?8j;X zKF}E2qpJ4j;I@<4toY!YCD1S0i>am_+%4XBG^SqkRAMGl6^5o=Du-4sCIm6^d%bR% z$~+3)`s4r=zCE>Z$r+F^M0q6s=9nRF3OD}ao-yJninHx%lUG&_P9A;l4^9B|2C*l< zDDyK%SXkKUjX?>@J#KAsc6K(_m}c?VZ>Bl|C;-hS7`SEdp44L3y_rBTBd`K!i1z>d z`EIF!&l$=A6PHy!MiFvU0|MQp%Nd~57TCrDo+>pih4(dl&W8@_BhHw^KvhGZ zQ{CV=1ZA8eDv$hnHWCtIRxh`+Fba-SzA=!9Pu~j}g+x-C=Pwqk>ih8FLwMS;9FGhZ z!04FjlU>Jv+UpYo>(s{v)ixP5e!ndOqS~zJ(L)svXTD2Ll5x$zfYaMYO z@SAdtv9rnh=W9wLfJz~5-$BpgkKtg|rrnWSaCfEJ0(FQ{b>wstTaAv%EUzk`J-<|Q zvWp2!Q+VoUb~k8NU%JWn>&Jx_0tgK0=SK#X8cONcO*=O?LYG60zcdCDe7P9sz!@V1 zQQ=iX_};fk^0H;Yy@p$hV0a5t=vT1$2NX!Ix5zQ*yTnM=pA7}}4|ccnRm(=-Uj>pN z?NUZQzJG4TZ8QmzCSQkK$98}opHDM@>Se?hI@kzDwTD-RB+^1WQUNQOKvLs0;t}i% zB-qY9*tukK0PGIqLg)qUYWGVGf=&PCU)DCJKIOg-PN*&M`&L+jC-`I9>79!vz%njaAdU&SX=87{umhGY zfJqGw^7A9vmWJMZ0;aPF16S^DHAxZ)Ch<@>g;rVfubjx2N+A(s0W3Q~p`#M}MaI-g)I1FBu|InP z;J61AM#ri#*erVKQHH(|wX^(7lU$O`0cS?iPf{UmdJ9OaR~Mh>Q>6KA&-=CexKBwb zmXsB{0kunWTwsvX+|clAu9sLOU^TJ2#0@k8dRe0u%QeJX1%+nQT+OG?L zgu7iDdQ7?QU%q?BY_o{YmhHG(mw%`PB5vC(vMV1vGoXxj zsbl;nuuG<%dSQL+Id%TSnrcOr8!*Jr_h(C?b7H}qmXp&~Y*5mo$Bj*`K3RD5m)s0F zmVaw($EOCe&q8hj#kH4rt*ebS558z&{7Vv1rHL6Qm%8p9oP;(V3N8epIYO`2c z0ZLY=ES4hoH^A9Z!tb#{Sf7vBR!!OeGA3ZnnK zeGX`zu0RIh{sX`5j>uCCQ4taA8GxxSDrqaxvCeGo+B*Z6L}DDV{q1=jC(!tUEq_rB z=)-m^0F{H^c!|xC@nD}{JOl^*d!B?`tP|KD8*ma_-;FrroJAz0Nc(M$*)0P4t0+Ej zF#P4T2nelm0TWfDO z1m(QzFVYOI&)k4IM;)&WJ_u5UQ&wOtm(RdS6}3C$b7s9D=bqPDNpDU-^Z^m)(I(Q{ z(f98XScrp6Pb^h?PW|@jAeZhhk>bzU_SRLS?}dR5yM_e06H`pRG8a1d)g#0w-)oB& zDcrbYe*ba4xG!+SgyRW#V6hpLhO#zu0g*7D3@MgOzMY|f@4$%Z1SGRPs+#?;3kD90 z1mNqy!8_ThgxJZqUSiSEybfa5`!z1(RxDHM`Iev zr3CPnbM2`yyT^N0vy1`%zxINRkg(?ec#i{F&E86)*!%<2MT@TT6X2cHkONkItp_$J zk>*Y7_nS(P87(=Z9Axq&rW^wV3fM=;NTI%g?d`N|6o{+AiPQbhz_!NH!0y#~5_6C+ zdI*}v#kIAy2U08PyBX$6?|6{uA@LV}JHC+RmMJVMI%CR@&Ch!`dT9SJG&H1AsU1;P z|4Ya|YxC_wz*fx`moQVtG~0K;*i-{7VG2B=|2o_u>8E1YO}e+u?K%I6TBKO*Emhg7 z`=F{|1LPn_a)S3sJD?=b;2>yc-TsdSo@3TMUkeQ1%Z8Hs1%{*gbca$Qt2LzcTupqN zFJZPAF#~QSZy^vL;6U^8=`-ktwSM_UfG@B@v%bLnyBsi~G;8Be+Zvk*glpoEQ86E_ zdz?haa`{W!{zf@V)OLfks?ux!CcI}4@Oo+gdr11OI9u<1+fG0GR}^IEUo(%n*L?t$ zpJDj@ZfsuEhpLTwZPA*ny9TO3*sj=;s>P~a}~hL30-Jud!AfHXn>g$z8-vbY_bd5 zbd&)Ab4&3Y5PL;^HcbB@+I;qWQyHY|toNA6Q zJcfoE`1Mqa?R$HB`ZdPO=gn=!PS9(22d@UqGzqgyI~gYbAlU8O*{7tY{y~$F7@DrX zz=;}-j3>tKE~=P2h%JC$p{06$=B#$I(*(kFzta~{F&;9T0>O`XMQ1%NHzgV#pZugRWj^b8^W0}#*W3XVP z)B-!kkX(a-m%!va-|T~Kd*%IcXxlzbY3Ff0AaSq$moy>vEa5y@^n4L@xO*Tp@br~} zJzaBeu}Gc7_#DUnzeO|DbKJn;+3{&zds%}*d7yKY@BEG-(E<+u+@c89w8aMeHVckN zHPT2?#dAIaD%~^S?%Wb|6DWh!E@#NmBBkB@<5z&J10TIKz;4%H>#<@^2RED1iQiWe zGH-LkcI|*Rt$%DmJb|jQWfT$v7jF3Juni01LSM@JlzmP_dVT-nF`Y>6=BfmbqvV0; zomWqun7e{=7{e~|de229)Xh5M83fNB4ch~kIB5T|A*b$?8Z?yyW4^oBH*lc+F%bS1 zI-hQmT8xiid#=zyC!fKS^Iu5@q)o`iYtZWY4fq8=_Q@cS-|gp4-D?GAf@&mpj3l^W z3baLr0Nn$8z%79z<2Cw_NV6n8Xc;#s6Fp zhxoS=<5Hyu+_P4NdmoKy&t3i{5!_ga2g_~bI;pqQ%fcjx7>Y8sV}A(qH2$+^&q@O? zL59wHj|754Cq$0W!@#klTJNlCbjf9#ebuZ z5c#4EnLz-7OC+9P$JTJ4?od83V5z7A#aC37>Op1T=<7Wo3gwjcXFH?8}{`se!O$Vo~}}o zO38#7P=QOc3AEfV4G5;K!F{me)c+LSyPYrY2&X&5*Cqgr#I(H3osSwamR|rvLJe9| z=O6|+gCp4O9L$jVeYBic!L6-h4Z%>21(Fr&nvYK;+wA5M4 z4l7-wyo(QjSs?sBsy@Hq-rGroQiD4z>ohr4S(n7%&>I5HJ6d0w+zFD3Jur_XsvFb( zkJkNEU{In6oNqL+qwfRbQI!f1{MH(eF|=)qmV|256p@A6NVau`8@U%Er5JVZ_b647oFxp$~!=4m{W#6A+-$5IU4}7!XNP0~^dmk0I;qBNUba zeilviP8%rwr)%&9+t{X3dx1R?O zWFNkb4Ki&c*QDw=&Q1@lk{3YB&zH5QnV{&y4KN+^5`z-EsGT@q@1nuHAp<<*w)t__ zXx$9sze+)jspHN}@Bw)T)J#+~YBYNGLp8w%peNu3P6G+I$i=-MCFNx@m&s3XpsDq6 z*OA0Q0cT`0dr464CmC@+WNBpSSRbPLv3=^R2R~Yn~B) zB2Rf$yBB?#(qk32COr-(5fT8}XwfUs3<#VG8|=Z|~QtK$l9W&QwHcz-G5yG5kIahOBmXG-L)C0IO{#g7v3}_1-CQ53t37;RI$cz5S^Oq~n>jZ%d zh*ROVJo0u>pGyZ#CU8{yP7mf7myDb>iP)Bm&2b*qYS-I63*^M(^Wtn(1ofYGBCY&f zW^j0`kq{3zPTlrFH!23cERoGy`Hou~>D(8SQ}w#Nk^iNvsX=$|KjnuPTJu7^&q5=6 z+Jdx}_Igq6yj`FNB^v)%Av+j(AO$2C%&{K-Al|2Tdgxl-qAtT!YAzoQ&WSq2A`v$^pdc~iAbk+Ajy#A4VXFzYgXuRlKrk@p zitHFz`3-2+FhXLGDrD)Sr3W9%IA(Uz*_lrjjskliI?ThnHn%wAzbLXSKf4$Od?b{j zoB2RLFK?9)?)qyKE|xKJ@WPkw>8>^gseOeJRk>PiolW050^TEbDJl{M#WEM{-(O)2 zy+6D2$ZaLZ7#vbFp+jK03{>;qwQ&i+(PXb-2D&6{kDED1gvU1<^egBcO-H78R0w!B zyWnV)w^hhcOWtubWdDue)rX{VvEtA*(PYqf);w^!4)oIo&oNf?p zZ}gvROc%+n(Qgb7tR4Xv&025zD(nohInIg+B@t)eh#pLFTN?H#$?=fhlnn0gazq8h z;MFoe&y6ag`>}az0@}^Do8bxq@U|&0c4XvMMy~X8d&oZ2V#$aYLaWK;*fQ> z_6n$oUH6X+)SlpP;v()!0_#W77To!uDAO~^mlsIHKQcWGHS{#VJYMx$-r93RE=@Lg zY_xuLfMK`0T01SEk3FOv%Qz$KuvPehFR#zYqb&C*Gp}jDzomaiJ!nkfbWW{W6@Z_q# zXOK);ek#2JaFn4VxDbkcE)qn#_W@Eks;#TI-a?dPc+4^J#Qk6#kaVp&8HLD(g~H6y zuzASn63S+OT9UkdOnjq2G;kpbk29Btm&era&9b!BZ#FaDAO!O$TCtOsHwDw4pT|L9 z(l}lv_%1M|oG0KFQxcZ@;p{Gk0k^yBmV8gw=%)Z9@(TmU)q!Ng6K}^{G83-S%+|=? z{J7`zP3KCNw?a|*w7H^BK&+!asi}nyoK|k6uCSJZ{6`bKLzt4YTrE#&WH#<}5^6MLY4o>H* zqinmMJ3%);4JCUX*L~67C92i>S(W*$vrtE%QG>KFQ#veSz@=TKPwNCLoZlmwS|#kt z;uWhafpFSo#t56Z>(yqg-(aZXq{-e3{gG*$leb7Kd58EtK0i68j&dxc;mJ`(M&WFO zW>ksZ9&xD&L=x-%@@spJ15fU2)gSqflWvG^RT=CiDG78CH#=KVzR@0A zUqN;TL}B|NcP95jUiCff+C%gAEPZRbJvwxsPlh#vZRo>9jO8uNNH#Fd$|;+Oi{k2B zrW!Z57@v$e?eI3RP4q_h#D69(h+J$`GDAU*%Wot(?0Mdy1J- zlMZbfmw2%)-)DlG(g}X7FlO;UWkT9lTfsM~JsPsx5)wk0pV$*cIvyLR$k}o|uh%hG z&Yp0gcI3$46aIQN#Z9N`2_s<-Dp-!%I*ZpRdC%;(@bV;Ygom_<&r43Mi`HnJG4CrD zo}5oV-*7XP=VW^f7Lts}gl+G+c5Ks(X<6~LCadI}m$$mj{gB<`7yC!jIJ0YQ=r2aD z@y*07Q|EWc#-|e8vWBCMyOnl%F@|P+cRzfU+NiRXohJwOf>ClSx_@jhr1W;E2Y^j@ zD|RRfOy3toV^_s#c}gEMNA4a5;&}KXF0il-nC5)qiy$CjK}H zbi zEv;3pnK;Xfwp4Xg9%(Unc5$s49)^$}$eU_^w%2gld9pZmh`7chHNjcZ+;JXfGQ&6P zzhKL)*0g&QUg^`A+7+|gV5 z_Jr%%9cCUswpra`x#>|v?xpK6kWdiq?TKiOhrcxyVzwZy3C5WfEqBSryEKhB5qKBO z3U7^Sce9jA<&+1-_aAqW`pQr3)aPY1t#oAd;xhz2N2K?qOz$lyi0B>qu<~^%&+KX` z_4vB`w5I*$o0S1A0fzhCC{pUllTq)F*}V1+dVISiuxG}~GWSN2bJ13JJ;Qoqbp#M< zR$q~8w(^5yD3%mtw}%hj$Cuf)G9*GZv?iQ=tRtpc5q`u|d_1O}!wg=h^b-v03B_AOxB#)`4h+QX0M|EAQbAOrg z7f60mQ2~iSEr7fJGwk#aX&zgXn+to6OTc`$<1x2A>q(2z8?7~=Ywa6f)77ea>EtLS ziD*%?j`))H#Q&f6Cqw1Q$A47v*3N%DTca=7JD&U*eS!K^UrpN4Y|)9S(j#$EhZaJj z_H=N~Sus-eDE;o#z*P`%4azYol{DAWhoWa7{4@%_=e$Ay^@ugeXj1Lv`(;5KVF-VQ zizb7wMx>akmM5H*sjZm6Hqe2i)(N0=R;B#2Gvuk6(v)X8YL`vx|85*bfFO?M=M+?k z+W2M~dD_7Mv1clD2=dgdA`^OmR@bSGXRw!9!q6^!iH>J*8;>>=Y=Q@tFi)ymI+S&c zFX;-%+h(WU9OQo1EF81Nw43-Hn8NREX8p^I9GaaX!Q}}C%UJH;^59gji{LF*&nlBg3y7A^seHnOl%*VfJ`?Ip39DwzWcPb*Cz>uA#U^ zackv@-L+gP@yJ8>7SK&^ZFM&li?-4#&lmy+F5Q~P93*k1S{GjmB}Ra&w_JZft^XH? z+Z#Oa1~g}@;|uWYeuk?j{Fj=VFWa`(8S#F5kn-~gw2@sYU82vnI{mdPRuUme25bQX z3$Mfo8|}ASLZv+lZ918AM;|qvZmDY)cEY%b^C^kQa0QDBB}9*EuS%&qUf&YLtu3dP z(Q)4MF6*G5ujG{$#rh{F0p5|X`BYC!azU!gOmO+|yrrO38))$E4-UzD9W_*PYs zP^FQ?Oau<}DdIswnmydWdd9t1Brv)=en?ziDVb=aw!!@jQ8ZRUrX}g!-sD3b^HUAF z_YBdN%u}e+&7znS&yrxoNc`+omIG)8nnV2bTHY!1)) zy2;7z_h)(c^MZ6J5{)-P_tU5e5NToYFd7~xxVT~ZRFOI7p$BJAa;kGxrA-ZzOHq!I zDLqG}$$q$S2iyzS$PAa6eEji8z>o7J5Xzt>8TKkol~>0S9i5dyPYyFq?8S{7CFRlA zIbJ+4yx-26ONt^lPLmG@U7jh_vxRJmM~g;QfNpGMn1tdcDWw`( zL1C1@z?AK6EOHU8wCj{`SCQ+3zUxWimEPflyf>9<-YZwi3MOg>AD4*&0OE<8YASlC zDd96F&u#Z68QTHJ^At6&OG^qmdY5%feo1;!Q*9bVP*N2|N3~tIwxRo$QWcfdwz+3C z%TQDAK$pnL7&f`bc0uCoPhEFph-$prEg+N|hkB zP=lWWn%`{Mm3GN9INCN430}lXFy9$Uy)0w~<1L@^ur$~+mAD>csJb5~zjBe>9RG7{ zO|`!+>A5)VtIWVC58eQmETPau=wJgk=kXXCf)r${tyI&I5JzKyntj8}gjo}#M$_N# zu46YHzJydD-asvb@UldyYAYe#!)~zSIdr#$z7|?S_rv}_??crC@8I*N)_?Rhb4NSk zZ$$5Z8nHRa)^JOkB7jb5#|S$kx)cU&YxllU@M=+%6{V>vDIeYeef}*Hng5@5ZM_M0gY~1$A;~FZqcND+vOWDI`BzjSBap(p%ix zPO`@OlfiwR=4AMTfmKff($1JQgm>wx2rf&GKsthWpJHwS1j`F~`-*VX$1!v84bNhZ zAr#0h0HTTq_nZf}W)s(|^l=9{L{uxQ&V*sC2`0m48dnM!W~K_1(HuE=J`W`SmO z1#tQ0uixza1MWjpuK0OW&FjtCxy5o! zlO+3<3pC3P1~)Fs!7k4~rwGTw6vOhj1iv+`w0XoGpa5MRFa5HF=}0&Fj-#^!Hbx%! z2v2a`lRYCZzFR#KGX^p=>dVtBf%i-zg(j0mtf9IUUi`iP+2(B}Hy##th%a^s~|9_n57`Z=A9cr@M2ZEYA1 zx#$nbb<#c)<;7mGG~p~$_SuPZ>!P3el>uIJSzfJ92KS#g>8atKc3<18bP$BqmeH%ys|ZLRV8ba#%cF=C0sf3 zrC}qtWTy1|HArA%Z*;F#N+`5Rd($?1m$NP>-E6%sjsi`}5qdmCKAWEt2*Fn%Kqrc`-G)x)Ex=(V)E{foyxmZxeZ-o5^r6lcDmD<)- zvQCxO!th$gL%}U!h(SM?&60^oFB9fYT%uXJBuC+`A6a}aEOKf^v(FCaY^5q&3Q+)|Qw(8ajAUc-Fa((eUj*kaH+^zFk z9Mx|)C3)@oruwlTdXsj{l~djq0F&8eqP;Hmz7$nf!el*RKaZDhR7r&kknu*kBE9FgkmIiO=?c59rs~z$96PZ62#} z#QgAkk@6PZHUrp3J=A$NE9xM6Gm0EXMyFzshfXgS-@w^b%zz|e2}+@iq*I8h4KT~* zvCY7*)`(xT0FI{P78bf9=)ok7Wm^>WGe}rCLke9fD>VwTLkuulnzGY~wa>ibyJ7I` z1)gHAD>P-MPCT>d&JNgNaf+ZwFKj3qJ~hUI*D9#IUIL9_rm7?=Gvc+ z$UA!|h9M$8!fQ{dii>_V`5Ye`_PCd>!rNX(UPiPkuhg>3B^}FzbiVM7xcCXLZeCJd z@;;Xc!KwFGR9DwA-hQd;ONe|~@r z$}{@5lZ8cgvjvzg4R0Ats3=PYM=^UbCS=2`K>l4eQ1Wfo_*LHa`1A%Lf#lKeye zg^yOBKrA^56S29d|5qo0)-7Y%)v0R4Y11=slaVAIQ1hn6G9`dx(RX#KyHZD|OO|Qb zjQ{)fpFYgr)g!G~CUmsp(Q~$nDA{l8t-qaJhu299c!>vwaztI#&#WUV245IdCgZ#BWkZ`_F0Gu7Qx&VkO0jIB z0c|(RYrI3x4DH%g+ofZ9dBYG4WIp_G>n;?R3R;ZZ3h$?S_AV z0P;=on5PMT{6kY%+F6tjT}Y>HYJKToJC@3R+i%DuG4%NwJ`zA?%ZpTk9kaBGX| zb`xAL=A*1KxUiKH?uMT>3x?_E+-@!Tlq?otSa-1*S80Yl?1rcfPyA?xjmWY;Ri47< zsa)jc9lneM$gNk^GeP$DZz0r>Z3_cvCtWojCkrDMPG`S8MJNLDq^{=dzYZg>#P9+? z&ZhDduhbc$_?l5u1PDx;8+W<(YImJ`7q%a%;!UbO?^>kMkrU}PYh|P(LJctER2Em; z-mJhOq?Qzr&Opc7kWUp%-{&#ci!xVJ3yW_{{GE-es75PMH$Hs4G}Cqv#X15KyzJ{c zF)%ma!f$Vn-Qm0r*-=y<$szLNd-P2J7#4Ik-?rvBltT_{ruXjJjpLNp5}jjQ9JE7i zftYe_Yb_KaI1f@l^2CB4pndScOLZ7GXjPc=qqn!$?=4{Z90HGR1IlSDZDaao$07|y zuZmgcy-O3tL69;=qQqp)ij2!-z5hFx`fuSoAYn4JNkA%YezmE>0wrF^sScJPs^TI2 z)8;QCFneqVo?oMv=-W7N=44%!4ddma!28Sg9?Q?uQJ_Cys-jR=ESsl_?ie$l5ucSw zBM=1(ZcTa4<^LwASESB#vmUxRa08&QuFFRO8qZv(*{?z?nH=Df?tES2dAu-GutO)> z9B-~2q>e^6Zmc>xRUhQ5DL@+)BL2FecATLX@enDxWgG*gNLAsDXehb{-4a>OxVFqJ zu@4mPP!KQhPf{&FqUe5&v0~1qT{FND_K_G#ZJ^sRTwI%i4sKD-w}P@t;Nq4Tn~M|c zi$;0OklJm(dbjemKB8fUvkm7U4$Ka4EK`)>j=dr05765*(@dN z*U5QUEo1|$!qqTRrU%BV>{s2dWc^rCE32WY$Jf2V`f~K}7YeQ&6t~T&e9%0YY>Gt$ zKoE@5U)=Jc6M^U|Xv0YdiGM8ytf{SQSGH~uMa2q8GZqv?5fG4;NRc84A_^i9lopj{ z=r!mD5u_>zA|-B$h%_NI2_zOEp+-P@iIPC11f+(LkenI(^?c7c*XMc8#kVfFAuB6u z&M`-Q$9O>|y;472%j&gUsGPv9&;al)V8<^&deeW`=JmG9Q4@047t2Cpv%2%mXpQp& zFX+XpMal};`u8gAG*jnEF||XpM(H3T=E0_Kme(&K_9$cqCCy?f3K086xb z!~nUSDFAs}CV}E_F%NfGHb6)KU0>y#tR@srqcHTg`AwW<;YeT6{=l+`h=fWCI;N6} zsC;{D!`LoqVo6jzNXw~+wG+RP8aRQHU3qg5K2zI$Gv;^?zZI`eym>QIQy!_JAXMN`+{pL zs#%K=-?|3oRubd(U>?=i?{Q52t_!_AT>4B^EaRmoS4|e7k8yTfl8eERi@^4 z2zT0^TZ`%eK&bh;%jqgTs&4)F8@XW&EV-CBTG}p;9V3rBZ!t~e0l~AU94VoavTFNq zqjGlK&mz~dtA#f7UZl=$XRPUO5EHP3UDjN^LI0nl!E?pwAjX|C*TD_x39MOyY_}Ur zK?4Q&EP3>ZU%~Y8nw1wPt+;@#(ChjaL_*xa5~U(O#H8YdqESWJd=_qmccG7gkfp!kS2p92LWyI)oyXx-cx^%!~V>N z>z|tzQJqB9L!|on-!ht3`)rxejbehSG-ehMYR<9HDkvLRm+l_#9N-C=(MV`}VF(wL zRFBKQA;rI6if)M`gXSn$4D?Mu`OM#J=ER~T+}5_vJVA2fwc1+vS3220s4g;CDHYVm z!P=~&$$!q)!)?q~mos4?2?d@7+K1e*JZvB~$YaJ}W!NI$w0KC4*B;rLyIfnT*mBG973&^xQ~Y=NdJ5HhGJ4OSWGQ6#h$|vaZD)K%gbw`|uKs%VZ24kOO1wv>1THa^l7|CdgW-*;jF@mVZb+DF?%i zxyWM6;DUKtv*dViz1r&0mOfbjd4|el=;jUkXw7{$I!chgp`f^?_WMarA&=O+kaBWv z5e&M|JOsf5mVm6hH2_D#uhrc!=6rgzV_KTZm?MW-hZ(mWlk(wS5^TBS=5LIVy5l?f z>2(0Cii*vw???2ccSKkaN%5Xv(Tu_nxD_>>MT;umx1J%E?KK0y2YaJFN2|yth>sc^tqsiqj4*fa7Qb=647{ za9Mgo)U}%{%8wYAlvp|B+yQ^DqJdPew=#rj-L}RFYFwVaq%?U$*=+jEx7Ju?fxcDjpha*B6LhKw4NsEd>IRZ$zu%RNm5q)Yev`jr zLuZ{m-f+kzj>J*=twD%u+crkRWvD^Wsq-LqeGAAL%Avb>yucC-NUfxOvsi%g+8hU) zv*jV@683|i$1^J!=Ed8Nv7h4YcRA|$f%Ju6d6V7uLkpdEUn%MTT81JBKIO!-%BE67 z3Jsg?`mA)h`LVdY8AQr~H>6*}du?g*VLhtI2Hmm>AisTtN9!zxy>wqXf&SP?s(EF? zWQCaW!#Mh+%4m_fJv4BF02q~th(9d#|Ozx_FK z4KNQ+QyPFDc|R@D3V4pc3n#yB)rknHyg8Dw(u`jni%~jCCD=9b1J?t9(3JoK7Vqu; zcoWik#8S{JlDZG41fibLZsPHXGb_K5CU^d|u}=^FC@Ucdd8P=TxY7!;*>~SQ3K10z z`~K-s&-#-L4Sx^2h>$vuj#TkJu`L@f^BWv`MA2G@<1{GGrNOv?_a21|q|N7>X5I|8 zogoMPB)~YJ2v7d{f8C?41B|f5CDyp^7PFkhxz{G^Ajm$Cn?wTd@>EdxrvKv=TqD`u zckyh3RG6kOFiFZ3f;Le~D`-iPSGz#HR^9f0EYCj?Az(u<4$4a%33#~y-)=2&VuON0 zKPf|=`S0lA4TA*a>6a_tqhBu+@d5B9-p-ns!zv+*- zZV_O*JYMgt@Z`13MX=SkGa2MCm^_s+De#{gA{q|5M+`L1?VCQ#+vDk#5K%I32;DN6 zKk1LQ>7v4mmQj0&$V$>Z5x zzlbNHdN(a z81{XK{Tp80p`%pB$Z!cjcWhNy%cY#D(%Qi$TaT3)VBeI^K9mf3fO4A#urnm?@}2C85W~fpLu&WGT_6v|YRf~~a`x)FsdhZq7K|{; z3u#ME*t-({Z!Ab(nzCpBeeLcSA`!*1FeP#g<^M>6ZJ9KU%%PJ@q+9-3!PWyRiDHja zoUgbfdubI7)rDwl*TEkP4RaR(!A}@QHU+noCtuv2g8d#TwpDS5nbVi%5*ljD9aXeK z_*zCyAI_z{;?%=%}W;BWncSD;1Pg{3s-= zvNNm&U2Icb&K!)<-y<{tlu_mhYhLmPx8uh{LgK1QgN1okq@X&~Bi&Ms|0puHI zeeL6J)Y*6RCbveD_@?#1gDIP%9xAVAiDj0MM23YJF^WS^2+K+$W58Rr8|eVqg~%@W z0Bz+k3Cn{8)^hox zBAlNl!v^GT4ODgS6(el}=tDD979u2spc^Jnz#fKhS0P)#>5<#(0a@P=v z%Lf(!_CL5J0mmr?omD2xZM;h1q9U}V$FpLC7 zY>uh(~gc^iwlU)>C9d2}02JcPlNZYgU z^v4N_-ZCK_Tok~@o}}lK@nJ9ytwo+&HI z!aBF60HiC6^fJ*5(QIQ3k33CHmsn+W;nq^&L3e!*s%|9#09kF29c`HCq4npPiU)O| z>Wu(dHn~PgfZ+zM#g$@#o}vGn{AL6sV($@p%@^pe%yV=V~=Lk-?MMzggGs=B-u+nvz6tFv7_B3~74rPT1wkV+wU})uztAH*- zFtpbd@5+vJy2N-t6s%WR2cV{fwEJ#Kv)TZmOZ`wK;f%x3o6w!J>lq|a;G{_IL7$jZ z2mvTen-bTNR<&oDee-I22?~SwRQE=OmMuQ=dD#5RM1x?Lx!WRSz9;4GLsdO}Sb#3w z#yqpH&#G#~qx7Lkkb%o(Vm>)K=ST!u%?VUuT@b1$tM@Nf`UumvfAW%Hfudm^U|fg# z|6ZH&lppIT@$X{N15AW~ygFqqUj{ofRlg#WNPEa2y@0@DdU)_%o_Q})bDtpxq% z9@A_FFdH`X8WPpWJbRz2-W4ppA-F|SO0mT5{h|=|;!u=tB!&?Cd5s#re?j5=(Uxrp z=ld~xk9%OBZii^**imd<{n=v(P*%CY=qejEuHA!Ry80w`oeq;^V2W!-2krXix%TT* zR#sA0mPdT=VNDb0KDY?E-3kkh@~E<(OyIEIOy_$k`B;$#*OYg%$Fj_d3T$0o=>(ND z;&r!H5Bm8*{r5UgE)TiaYFQ1s7otC^basH}jefbuLb_2z2xYVS9thTfBbqFNIMTFvD5?>$@+$sgkpOcE-cNs!8YiY&GLr9N zPBi#CYKB9e+m!2pPiUP1F3Jhc)j@kH^gdv#9lr1rPoP7tf)1#T9Zb8R(BIm}+3ryY zvF2KBWNr+4{Lx)v!V#pMC6QqAqfSKdeTwf^lJ5&q;p`JO2o-s(Ls$&e#PE@&*Xafu z0J_}SKT9+3s=TA`yt0V24)eL914V^J`GzmjMd`LnT!k9Q7F51yDzeTd`pc0tNt&_h z_%i_}x6V?r`HD~R{+*F``Z@qs3DUO6N*PI5==0w;yQJl}_xQzs&Uaw5y%lGT6g2QN z?^BvvP3huud3I{EM#2m8b-)I}%j#VsZ`N)fmycf#0e&jh& zEqK`8k>vyalQ0t`=FD8JxTIa}+=s9u8Z;)Y+D=)<<})&C{1E2E{Be#=DB(EJxZ33) z6qe~#G-J(BIFCOfd0DMk7zR}L;^0!hoz3?STLXN)x`@EpAaCLP(-NU(F(p!wpMOi*7aJRw{!L@*THY=WyydGkEDRY+&kx*vDZ^~of zD$HD;EW#$vK}@bTAEXbLT>1b&z4Brogq;6f951BI%}aJUN<=Rf%;55Aw}WPze80{P zPM&*p>sdsI>=w$6CT6DaPV@OA9N6=wVp;75-<0O8iaMk?cNKr_n@hswLW2e*F^l|m zN;_)62d$e}HAtIboA57I+>1F`oe4d&qSi686hH_RrUk5x>KImG(G!1r4|_X2xPSw^ zWn>>T#=GqL^(XAWG`KyzgWS*cXuS2($1hA?2RiCM*nwm((#08H?sPA)-F&(3p!)f7 zcPB@Ic&eV(KvF8p$~16p^+#-08DmmpsTkLj5^^ba)q(HD5{&0^kWd0sluI_+LQqTB zDz#XS)jokmkOAZ*g1v1BJH#i~eT+)MC5P_vJ9JnNAcHAH%?e^is>yRs$&>z>fL&*xFna|Q@wjsZ?s<#(x+KK#XR37ob zOyi~Q*#78RzcD2kMNxilx3W#}BvH};6d6x-r4cjr0*LQ?{O)7>VprlF_qsw;2U07t zb$n9%kG4HN-K3M-pq7+3)U}qmMK8rKyS#0X1ToZTUyX5cqZi5XRkwr)EcPJ^39pr^94}bp=N<3*s8=>uEbEr51BK^ws}CXLbLqqP zes%^GL(seQe^?S}u%iw?FXxvJAf*iFl+73L-O3p|2cuYqSc(W*X~4T>+sdj*O9x)N ztxdA=(8Ary7eaFv=VXevcgC?V=OL@dN&L&Wro5>(&;`3Xnu;o&8pm4uk$)ICRU4}$ zdiHy1urhuiE|`WG7{Txc)^ z%@nwwbc@Muv$Sp`&=qpDOUY+R)!yn@zeF!}cM5!~R;*5JoP|!7GtI|V$(igej+r^+ zdj0RC_G7BSA;V@1J!i^;O*CJ(ZHm1no+9yX51!%&z9$faCb%X)kC_ytS~7;O5&fUB zt;e99mo?0uB$^e9>0OK~caWEe+Cy{ioHr`{F7o9|!CnKEJIAzOSZ1B9h4brlmT886 zL9Xj_k8!sOq+DLty~CH)qfY0#$Z!5OCN8n8CAU?tZMi0knJd6NpW2!sRxj8#HKAcw z;VX|GLe{%%&e_U*Z|?&YbdZTw?3;NvhtVO@)EA{XmWMzNY2DYd-r$T~?KN_>r#-x> z57ZG=>H!1tuK=sOLOHuapqercJQd;(axCoN~uz$M^d9`Kxc% zIE9ds=t=uZN?q)5x%OyPbXo2b@E%@#A1aoUljXvqo{tUc{V!j&US&}N$6lZH2-){>oqaZ z(~I6&`-J73e~FL2b%e^VHD3DNql8kSsFP2sS;7q%zvq~;Y^Cc%s`3w9cDSHx8GS_J zR+7|NrCBe<6gY7(*TOjt=yqqNACyGKT&Q(aiw4C;Mz3*4@4NcS^$%LbWM&woNV?_NrFeMO%}b%%Xcn zJ%%^x~tBgPI9uKs{0^i>qt$j+5-y%CKYgXT#h$%-;3~>FCFrs z7l^5)_rK6%8?VKto?gtnG<=7=#NHta2dgq1UQYAD?h0BPK2iWpZM!;Kb-J5x`^D)y z01nx$E$!Sf36MaYD&ATh4IQ})wu)HXh;jy=Kec{EqaM9fM|Zv(>sKlt{#u5i@mv#GU{Gkrx?PI@%jM-gM}MDU_!)H z%FX2exZSaFAajF(+6Cjpo*v4?*LV2D&?=LZox3j8(pus9(|HIbnr;)qxzuq5AuVDN z{nb^5g9O6THUd9pDjVMF^Tog>^4uV#j;rNJb#UxgX)jI>wZ;<8 z6R>;w6~xp}J(XfSa(nHgYHZx#tJUW`$yf>@b)@?#x#zU#SJR)SVC4^8`C6Em;1q7v zl6;#78BHmafB79Q4H=l&p0cai{_}|7{;BK4-R11%H?ta((|Ok+K?mLstVGs(Fp73C z%}XKV(pZv}esr*Z+IHh`!;s$G1Lj*p?VJf9#xmc*+^EE&w3s}U0LPQN;%O2rV2Xy? z@p3_+Z&x4d@ul@Y#VE(ID!rUqznzJ4NzBI>Egq)?Pi`XZ$ho$fkI_&n6TN!I#i4!N zMIt}D20g%~9Ha93FiVUlt1cBTd_&?IV><$hO*kn#Az|4Sb#&E>4iz&uXT6Ubm(iTv z3cG&h$n6}Fz36(L0qTrzC7gSkd9Q3K^JDptF~2kQZ~LH~{ubK*T0vkxo-OCp%r#s{ z5gC4(g;`JDLt25&c1N&%Ku-p7wdjbh;2IH%r{Fs27v6g8BY!MsxreAUy6y^!3=v!b zXaInax>9h>!!-n5o47)Ofe36Fxcw1G&(9n9V0kK=Fu?2ZTmJcLRNe(*Yd-+)YDfkj zSTNW3*CGcG^1&6Zu0RK zE+O!FWTHI`LXLCVC7QJJR+?)^$DB*AQz;_{;3TuXOQj%axNFiGYPYML?Bk_V?-ol( z;%>|>2i_f6hm$`Ck^LRM7zTCd_dJDHKfi7)Ft0upd_%q8y+7OEG9pAUu{EWC(x8c! z3MSM0mDQgFJwwV=%-l|elbBTJnA(EeYp?HtfmNTgL4GVz9*YC0yR|&y)EA7uc$g3} z*54D}WN!;9GB$I&eutlJxruZ6GxS#oqOk7+L|(7s$_<|t7bR5AX6&1Y&`xgJ2eV)b?2d{@LD%e##U?Ms}i%sJPakmXty86qn+@$&d2CM^Fi zx%53!t}k9YS7E};!a*>5<6xx)%*gnv0l|MjTW~$g03%IRdM_~^@mNOw3H7R=C9}60 z*Rw1*;&a%rXrJbrP-BD^0kw0j9;iP`jnjA*=B+rdd!jl1J$NMPZL-fz9<&zvEV@y< zO;U0^^aS)MW+i57KXR^v8WI9s_L7QPm?++AD5x=@5f1-qIC}=u4 zj#DVg3sy8AB{7H|DSIY;zvY8=I|p7;2xM1a@-K5j>Xpa2;bF|wumWDH96|vmGaD}P z+i#ydrLg$MrfmOTYU+kDdJV?}nAcE`8vv!06UJQk>VB;-03S{DO++}~(4`_0qOFrA zp>4}*u3_Q;jlWYvHNx8GZm_RL>*?ae3q*egieI6-x;s=RNegKfHSp}|40I2yH6`Ru zDzA0*uya+6i>J$&M#T6l{*z0<9oi^>di&P(5L(otZ!+VZNo>k{m2J$AZLwx} zRUez{5Ui)5!@E0JI@MuGK`NruA9D&I?$X|cQ)R1+HKPXY1M@U zf$z$FwAe4m{R_xZC+Ber=|$iGy^XAm-f>sWM+fI!K7Md8bFN%5)-|@pUS&;GF9T{jR-B#pI-frwma`NEbfBl( zrJ}EnIsfhM<6vMTED-tQLi+UWfroCVZ|mT&xwQMLN*$E`#`ks;8K$YKC*SUU%BeG{ ze6)1lS4l~w!6L)I_$^;UaI;g`wx;sq^OU*-Z{<-N!D|5Z)tVA$T6jgz#^2%-Hui%t z|6yN^8*hN3+;#N{>1}zqY**J0^Tt;{0zt$)S+CSl2>c7A2Lc^q{uT;*Agjg5amPyB zdS3r{)lIyo{*;ZpW)~d{HLNccg-z=~v4r>qTVWlX+(p+G0~BkB+{;6?q$SP+`tmn( zWIW!m$=;26TTAV?i>X*)IxO_Lc*~Wjf}(x6o|m7Kq^XNuDh)UDMZ+LR6(2&a9IEc9 zC#mccrypw_-qtrMnU}a5lJa~N?V9pxw!-8ByX0y6Yr#ENj%i`gq~|XR#A$xwrEbBL zlhp2qJHki(YC(p1XM#7(wYo;w=jJ|*j_)UtnIo#|*S{Mg_POLu#dPE>t;KlfcDMB} zi3@0VU5Y>iE;OI$8%1bVKi^_{$}QslV)Z?E$qYn`0Cb=v^qCY~=f& zvR&%K6Y8lJxA!WZ)H6@!kKgt6$CbEUttR&?(v6^k5UJ7w5((B_qU8$v&aGRY(7xef z=^-tmhb{-C|F&C!;)*3u&-O zJLDxF;a+E1;e9OLKO?LlB8G2!aqdlAs3VNxpX?SqP_|=Fdiz>z-(|#?l*z;d?^B_q zyUO7Ks5K1gtynAupkO8Q`z}=IX5ijy&v2&JWC4XkWRzk8Ha{-({5#jxR7tF?th+^?YxhcJPROI{<>~tpdD^ z|5}~V9N)k?#w4h|iI-dM(b{TW0-bG~tQ;VP0!&Xbm`gY$MouSD8<$#IF0F&Qcq{VU{T3T3Bvs8lA2Fr+js2HPTX&GW1EUhNtE6@L&TH)+Yj=kpSqfB2zl{n|B2l5 zLcJrI=E6phY$4~56I){T%km{0(DVQM^ffutZ7&@@?oVRwVi7+tq~r0lYVO4HKdL&W zgn@wpJ0&zN(B+DPUc(2)7VDY$fF7<}-5d3pw)|ntN#l$HtvAS~k@JpfP3cHzet5@f z9O>i4DM3NmGs5t=0E*y3!P5$RwH%VE6g5Yrbb9mTyD=>q%P!FI3+3fnP}WkQ$mf7i zqLgLEaq-VfCld_B_g|G7;y-|wM{(bfD%<&YET7tCBH~y1Afpt$nkCE+k7a3!^}Zp^ zt%@Gt*N6?mDjZtTzy@modR|WZx%)2D=gHIhp>2=XV@KGm$Lnq)AKp_@2Z3PWe|h}mS-MnIoM-jbha&d=fZqwWe_%dmD$(e4u)}3W&*-P_~?GD zTMV)gEdR`H`%tq4#!Yhj*oS|fKYu>@aBD#VX2@)WyAo&RxvAfDYv88CG1@5qOc|*h zpL=&={#A!ZNct6g6EPXP*sY$Z4syZm zbDVe)(<#INfmU0~UGFF|)iN+BAP=yUG-oeog{HC8hS(W#tV4*ey`<#g-K6;p$rT>& zLfK=_=vn{a|G_XR ztmIH6CRPFqEAOd2Q|O^l6UGH+^(jtv6^c>quAi z^cxr9E{wO1lEP6^Hq}xH1OmU%vU3yIkq?JUPs_v4#|iJr5pnPvWTkmtL`wVD1z2e9 z`n*g33w5)BZAWELhT}J4U|HZIz483HI1;%S_eo!~V|h;Waz-?OOokz0)1;)^o-lpvX->rcOVRmf2PN66sf`jhc>p zFlUkauJk4xJ{tli1X>Bs0}l7;VO(hN7a^|K?c3jX!^`+S0OlGI>T#o&F7 z(`+kkr7O?aV*N(L1-MopZ_dUl-vMOflc_R~skchYtv#wtzaxWU;UVH%u8w%v@;MB* zE-_A(h@9ieI{V-g<7&^k75u1YTRe@yV$AsuZ<9*x4P&ji(?BgQJaUx_$TDEQu#VFD zo0}i-NQ#KY&zutbB*p$M#8gq_25Vjt&cP%V?paywjH(vDJ9SSQ`A&CP`Rmu?^V6w? z{(d3Mv0|CAviQxXE)8=!a}0v3rTCkZ&wrZ$xUM)m>zvy5s|k+;7uLZZOWd%vb@OL| ziGQrM<>~rUe2wEXl+eNI&j3lMQ3|i0k~nssK3J)(8zO$|XE@^t|L^5cB#KcP_vbAI zdX5(Z?B=<7R`XmVnBA`C{rV{*u2hoz`SEVmm8uWj4!5qs0MKO*3FT#aD_-vtHd+1=nBtL zD{#2cKn^=_?nBins}i5ck?PrX`+LCZu|1czZ|NDI%9Ow>H|7mc_R@PkNFbi5BC)ETqcdR647HU{;d1QyvI6vs zJo&5kVetC_VzPG;{4DwejTY9u&Rm|mP4WNgQ60?xs<^0VY3o`5i~)$m<3bOH3bFv( z!^}D}fSsio*!4b`;ekkIz3T+y4X58&IfISd3{Hy?*i3Z!Sou`XN%GgTH8wE`>j1f8 zpT$V3^9;z)vdvr;&k2cLygZ7Z@>=eQC)b{_$FavCSd%TY|F{O8v6nH4@ zD!IELx3cjmRpQ)-vTy##ra(rYeUnHNzM`VyD{IXL$hKy{&sU49^Ps@R`T70xDBrz# zJh=wx*gsC=Uw++luiZavy`xY82sz)T@VaA0ibON!H<8b`EK=J?={amL;53N;M8iO5 z5_}XpsYC%1mVkKo2ID}0A*z-969xj^itgE%H=cy5mo|%~$ zD=|bnx1YWoK?$_b@~pfW=2|_3U)e7BOL52>J&Vjz3!NWpgi9vWqm}H_Lp7x(7WofQ z+(WdQ##2M%tMbnikL-s5{{*h#J?i1G)9AbH^5?khTE4%+$ecmeq@)?WyLqV}rfX^h$%gM3pS<^5; zyc0fKDvvErP^;zoQ)U?aVyVsCe_7K~L-ZBx(uz&D0PKi&6v6%He8bs?!59KE8103^ zBHyzx$P`vn?@t<_^i}6DM3!h16Dxtre?PeE0B$Ph=?`$5BG~@Bzw8&B_btc5H8&-? z{PzR@T?g&|%ESLJ=b|-6Sl%@F`^Al8J|0Rt@Yklpjlc(RvbM7uA=8EBafZBqy{@2@ z+T%Hcr?zam@C4XsVpVPJnoZ7za=E)bxW1~&@9U|}n=Zh>d%fC&e9dkepXSQ)v_Kc! z)7_oU06DH9+5x^zw}gNe_;u~)X_$@c!C!))Q*q5e%zK&j#bd{GcpGSR(NwQQ=hi>}3yO#M Ab^rhX diff --git a/doc/leaf.adoc b/doc/leaf.adoc index 7e97d26e..1a21583b 100644 --- a/doc/leaf.adoc +++ b/doc/leaf.adoc @@ -629,21 +629,21 @@ enum class err2 { e1, e2 }; T f() { if( error_detected ) - throw leaf::exception(err1::e1, err2::e2); + leaf::throw_exception(err1::e1, err2::e2); // Produce and return a T. } ---- [.text-right] -<> +<> -The `leaf::exception` function handles the passed error objects just like `leaf::new_error` does, and then returns an object of a type that derives from `std::exception` (which the caller throws). Using this technique, the exception type is not important: `leaf::try_catch` catches all exceptions, then goes through the usual LEAF error handler selection procedure. +The `leaf::throw_exception` function handles the passed error objects just like `leaf::new_error` does, and then throws an object of a type that derives from `std::exception`. Using this technique, the exception type is not important: `leaf::try_catch` catches all exceptions, then goes through the usual LEAF error handler selection procedure. -If instead we want to use the legacy convention of throwing different types to indicate different failures, we simply pass an exception object (that is, an object of a type that derives from `std::exception`) as the first argument to `leaf::exception`: +If instead we want to use the legacy convention of throwing different types to indicate different failures, we simply pass an exception object (that is, an object of a type that derives from `std::exception`) as the first argument to `leaf::throw_exception`: [source,c++] ---- -throw leaf::exception(std::runtime_error("Error!"), err1::e1, err2::e2); +leaf::throw_exception(std::runtime_error("Error!"), err1::e1, err2::e2); ---- In this case the returned object will be of type that derives from `std::runtime_error`, rather than from `std::exception`. @@ -828,7 +828,7 @@ The following figure illustrates the slightly different error communication mode .LEAF Error Communication Model Using Exception Handling image::LEAF-2.png[] -The main difference is that the call to `new_error` is implicit in the call to the function template `leaf::exception`, which in this case takes an exception object of type `Ex`, and returns an exception object of unspecified type that derives publicly from `Ex`. +The main difference is that the call to `new_error` is implicit in the call to the function template `leaf::throw_exception`, which in this case takes an exception object of type `Ex`, and throws an exception object of unspecified type that derives publicly from `Ex`. [[tutorial-interoperability]] ==== Interoperability @@ -852,7 +852,7 @@ Note that if the above logic is nested (e.g. one function calling another), `new For a detailed tutorial see <>. -TIP: To avoid ambiguities, whenever possible, use the <> function template when throwing exceptions to ensure that the exception object transports a unique `error_id`; better yet, use the <> macro, which in addition will capture `pass:[__FILE__]` and `pass:[__LINE__]`. +TIP: To avoid ambiguities, whenever possible, use the <> function template to throw exceptions, to ensure that the exception object transports a unique `error_id`; better yet, use the <> macro, which in addition will capture `pass:[__FILE__]` and `pass:[__LINE__]`. ''' @@ -1015,20 +1015,20 @@ void read_file(FILE * f) { .... size_t nr1=fread(buf1,1,count1,f); if( ferror(f) ) - throw leaf::exception(); + leaf::throw_exception(); size_t nr2=fread(buf2,1,count2,f); if( ferror(f) ) - throw leaf::exception(); + leaf::throw_exception(); size_t nr3=fread(buf3,1,count3,f); if( ferror(f) ) - throw leaf::exception(); + leaf::throw_exception(); .... } ---- -Above, if a `throw` statement is reached, LEAF will invoke the function passed to `on_error` and associate the returned `e_errno` object with the exception. +Above, if `throw_exception` is called, LEAF will invoke the function passed to `on_error` and associate the returned `e_errno` object with the exception. The final argument type that can be passed to `on_error` is a function that takes a single mutable error object reference. In this case, `on_error` uses it similarly to how such functions are used by `load`; see <>. @@ -1564,7 +1564,7 @@ leaf::result file_read( FILE & f, void * buf, int size ) <2> In addition, this error is classified as `read_error`. <3> In addition, this error is classified as `eof_error`. -This technique works just as well if we choose to use exception handling, we just call `leaf::exception` instead of `leaf::new_error`: +This technique works just as well if we choose to use exception handling, we just call `leaf::throw_exception` instead of `leaf::new_error`: [source,c++] ---- @@ -1575,16 +1575,16 @@ void file_read( FILE & f, void * buf, int size ) int n = fread(buf, 1, size, &f); if( ferror(&f) ) - throw leaf::exception(read_error{}, leaf::e_errno{errno}); + leaf::throw_exception(read_error{}, leaf::e_errno{errno}); if( n!=size ) - throw leaf::exception(eof_error{}); + leaf::throw_exception(eof_error{}); } ---- [.text-right] -<> | <> | <> +<> | <> | <> -NOTE: If the type of the first argument passed to `leaf::exception` derives from `std::exception`, it will be used to initialize the returned exception object taken by `throw`. Here this is not the case, so the function returns a default-initialized `std::exception` object, while the first (and any other) argument is associated with the failure. +NOTE: If the type of the first argument passed to `leaf::throw_exception` derives from `std::exception`, it will be used to initialize the thrown exception object. Here this is not the case, so the function returns a default-initialized `std::exception` object, while the first (and any other) argument is associated with the failure. Now we can write a future-proof handler for any `input_error`: @@ -2389,7 +2389,7 @@ namespace boost { namespace leaf { else\ return <>.error() -#define BOOST_LEAF_NEW_ERROR <> ::boost::leaf::new_error +#define BOOST_LEAF_NEW_ERROR <> ---- [.text-right] @@ -2588,33 +2588,31 @@ Reference: <> | <> namespace boost { namespace leaf { template <1> - <> exception( Ex &&, E && ... ) noexcept; + [[noreturn]] void throw_exception( Ex &&, E && ... ); template <2> - <> exception( E1 &&, E && ... ) noexcept; + [[noreturn]] void throw_exception( E1 &&, E && ... ); - <> exception() noexcept; + [[noreturn]] void throw_exception(); template <1> - <> exception( error_id id, Ex &&, E && ... ) noexcept; + [[noreturn]] void throw_exception( error_id id, Ex &&, E && ... ); template <2> - <> exception( error_id id, E1 &&, E && ... ) noexcept; + [[noreturn]] void throw_exception( error_id id, E1 &&, E && ... ); - <> exception( error_id id ) noexcept; + [[noreturn]] void throw_exception( error_id id ); template <-deduced>> exception_to_result( F && f ) noexcept; } } -#define BOOST_LEAF_EXCEPTION <> ::boost::leaf::exception - -#define BOOST_LEAF_THROW_EXCEPTION <> ::boost::leaf::exception +#define BOOST_LEAF_THROW_EXCEPTION <> ---- [.text-right] -Reference: <> | <> | <> +Reference: <> | <> <1> Only enabled if std::is_base_of::value. <2> Only enabled if !std::is_base_of::value. @@ -3025,8 +3023,8 @@ TIP: See also <>. ''' -[[exception]] -=== `exception` +[[throw_exception]] +=== `throw_exception` [source,c++] .#include @@ -3034,57 +3032,57 @@ TIP: See also <>. namespace boost { namespace leaf { template <1> - <> exception( Ex && ex, E && ... e ) noexcept; + [[noreturn]] void throw_exception( Ex && ex, E && ... e ); template <2> - <> exception( E1 && e1, E && ... e ) noexcept; + [[noreturn]] void throw_exception( E1 && e1, E && ... e ); - <> exception() noexcept; <3> + [[noreturn]] void throw_exception(); <3> template <4> - <> exception( error_id id, Ex && ex, E && ... e ) noexcept; + [[noreturn]] void throw_exception( error_id id, Ex && ex, E && ... e ); template <5> - <> exception( error_id id, E1 && e1, E && ... e ) noexcept; + [[noreturn]] void throw_exception( error_id id, E1 && e1, E && ... e ); - <> exception( error_id id ) noexcept; <6> + [[noreturn]] void throw_exception( error_id id ); <6> } } ---- -The `exception` function is overloaded: it can be invoked with no arguments, or else there are several alternatives, selected using `std::enable_if` based on the type of the passed arguments: +The `throw_exception` function is overloaded: it can be invoked with no arguments, or else there are several alternatives, selected using `std::enable_if` based on the type of the passed arguments. All overloads throw an exception: -<1> Selected if the first argument is not of type `error_id` and is an exception object, that is, iff `Ex` derives publicly from `std::exception`. In this case the return value is of unspecified type which derives publicly from `Ex` *and* from class <>, such that: +<1> Selected if the first argument is not of type `error_id` and is an exception object, that is, iff `Ex` derives publicly from `std::exception`. In this case the thrown exception is of unspecified type which derives publicly from `Ex` *and* from class <>, such that: * its `Ex` subobject is initialized by `std::forward(ex)`; * its `error_id` subobject is initialized by `<>(std::forward(e)...`). -<2> Selected if the first argument is not of type `error_id` and is not an exception object. In this case the return value is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: +<2> Selected if the first argument is not of type `error_id` and is not an exception object. In this case the thrown exception is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: ** its `std::exception` subobject is default-initialized; ** its `error_id` subobject is initialized by `<>(std::forward(e1), std::forward(e)...`). -<3> If the fuction is invoked without arguments, the return value is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: +<3> If the fuction is invoked without arguments, the thrown exception is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: ** its `std::exception` subobject is default-initialized; ** its `error_id` subobject is initialized by `<>()`. -<4> Selected if the first argument is of type `error_id` and the second argument is an exception object, that is, iff `Ex` derives publicly from `std::exception`. In this case the return value is of unspecified type which derives publicly from `Ex` *and* from class <>, such that: +<4> Selected if the first argument is of type `error_id` and the second argument is an exception object, that is, iff `Ex` derives publicly from `std::exception`. In this case the thrown exception is of unspecified type which derives publicly from `Ex` *and* from class <>, such that: ** its `Ex` subobject is initialized by `std::forward(ex)`; ** its `error_id` subobject is initialized by `id.<>(std::forward(e)...)`. -<5> Selected if the first argument is of type `error_id` and the second argument is not an exception object. In this case the return value is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: +<5> Selected if the first argument is of type `error_id` and the second argument is not an exception object. In this case the thrown exception is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: ** its `std::exception` subobject is default-initialized; ** its `error_id` subobject is initialized by `id.<>(std::forward(e1), std::forward(e)...`). -<6> If `exception` is invoked with just an `error_id` object, the return value is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: +<6> If `exception` is invoked with just an `error_id` object, the thrown exception is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: ** its `std::exception` subobject is default-initialized; ** its `error_id` subobject is initialized by copying from `id`. -NOTE: The first three overloads return an exception object that is associated with a new `error_id`. The second three overloads return an exception object that is associated with the specified `error_id`. +NOTE: The first three overloads throw an exception object that is associated with a new `error_id`. The second three overloads throw an exception object that is associated with the specified `error_id`. .Example 1: [source,c++] ---- struct my_exception: std::exception { }; -throw leaf::exception(my_exception{}); <1> +leaf::throw_exception(my_exception{}); <1> ---- <1> Throws an exception of a type that derives from `error_id` and from `my_exception` (because `my_exception` derives from `std::exception`). @@ -3093,11 +3091,11 @@ throw leaf::exception(my_exception{}); <1> ---- enum class my_error { e1=1, e2, e3 }; <1> -throw leaf::exception(my_error::e1); +leaf::throw_exception(my_error::e1); ---- <1> Throws an exception of a type that derives from `error_id` and from `std::exception` (because `my_error` does not derive from `std::exception`). -NOTE: To automatically capture `pass:[__FILE__]`, `pass:[__LINE__]` and `pass:[__FUNCTION__]` with the returned object, use <> instead of `leaf::exception`. +NOTE: To automatically capture `pass:[__FILE__]`, `pass:[__LINE__]` and `pass:[__FUNCTION__]` with the returned object, use <> instead of `leaf::throw_exception`. ''' @@ -4315,7 +4313,7 @@ namespace boost { namespace leaf { } } ---- -The <>, <> and <> macros capture `pass:[__FILE__]`, `pass:[__LINE__]` and `pass:[__FUNCTION__]` into a `e_source_location` object. +The <> and <> macros capture `pass:[__FILE__]`, `pass:[__LINE__]` and `pass:[__FUNCTION__]` into a `e_source_location` object. ''' @@ -5524,16 +5522,16 @@ If `BOOST_LEAF_CFG_GNUC_STMTEXPR` is `1` (which is the default under `pass:[__GN ''' -[[BOOST_LEAF_EXCEPTION]] -=== `BOOST_LEAF_EXCEPTION` +[[BOOST_LEAF_THROW_EXCEPTION]] +=== `BOOST_LEAF_THROW_EXCEPTION` [source,c++] .#include ---- -#define BOOST_LEAF_EXCEPTION <> +#define BOOST_LEAF_THROW_EXCEPTION <> ---- -Effects: :: `BOOST_LEAF_EXCEPTION(e...)` is equivalent to `leaf::<>(e...)`, except the current source location is automatically passed, in a `<>` object (in addition to all `e...` objects). +Effects: :: `BOOST_LEAF_THROW_EXCEPTION(e...)` is equivalent to `leaf::<>(e...)`, except the current source location is automatically communicated with the thrown exception, in a `<>` object (in addition to all `e...` objects). ''' @@ -5543,24 +5541,11 @@ Effects: :: `BOOST_LEAF_EXCEPTION(e...)` is equivalent to `leaf::< [source,c++] ---- -#define BOOST_LEAF_NEW_ERROR <> +#define BOOST_LEAF_NEW_ERROR <> ---- Effects: :: `BOOST_LEAF_NEW_ERROR(e...)` is equivalent to `leaf::<>(e...)`, except the current source location is automatically passed, in a `<>` object (in addition to all `e...` objects). -''' - -[[BOOST_LEAF_THROW_EXCEPTION]] -=== `BOOST_LEAF_THROW_EXCEPTION` - -[source,c++] -.#include ----- -#define BOOST_LEAF_THROW_EXCEPTION throw BOOST_LEAF_EXCEPTION ----- - -Effects: :: Throws the exception object returned by <>. - [[rationale]] == Design @@ -5943,12 +5928,12 @@ https://www.boost.org/doc/libs/release/libs/exception/doc/exception_operator_shl | [source,c++,options="nowrap"] ---- -throw leaf::exception( my_exception(), +leaf::throw_exception( my_exception(), my_info{x}, my_info{y} ); ---- [.text-right] -<> +<> |==== .Augmenting exceptions in error neutral contexts diff --git a/example/asio_beast_leaf_rpc.cpp b/example/asio_beast_leaf_rpc.cpp index 8201a2ac..8fc357da 100644 --- a/example/asio_beast_leaf_rpc.cpp +++ b/example/asio_beast_leaf_rpc.cpp @@ -376,7 +376,7 @@ leaf::result execute_command(std::string_view line) { if (i2 == 0) { // In some cases this command execution function might throw, not // just return an error. - throw leaf::exception(std::runtime_error{"division by zero"}); + leaf::throw_exception(std::runtime_error{"division by zero"}); } response = std::to_string(i1 % i2); } else { diff --git a/example/capture_in_exception.cpp b/example/capture_in_exception.cpp index c203affa..3652ce7c 100644 --- a/example/capture_in_exception.cpp +++ b/example/capture_in_exception.cpp @@ -33,7 +33,7 @@ task_result task() if( succeed ) return { }; else - throw leaf::exception( + leaf::throw_exception( e_thread_id{std::this_thread::get_id()}, e_failure_info1{"info"}, e_failure_info2{42} ); diff --git a/example/lua_callback_eh.cpp b/example/lua_callback_eh.cpp index 4e87f267..00f62c3f 100644 --- a/example/lua_callback_eh.cpp +++ b/example/lua_callback_eh.cpp @@ -75,7 +75,7 @@ int do_work( lua_State * L ) } else { - throw leaf::exception(ec1); + leaf::throw_exception(ec1); } } @@ -127,7 +127,7 @@ int call_lua( lua_State * L ) // cur_err.assigned_error_id() will return a new leaf::error_id, // otherwise we'll be working with the original error reported // by a C++ exception out of do_work. - throw leaf::exception( cur_err.assigned_error_id().load( e_lua_pcall_error{err}, e_lua_error_message{std::move(msg)} ) ); + leaf::throw_exception( cur_err.assigned_error_id().load( e_lua_pcall_error{err}, e_lua_error_message{std::move(msg)} ) ); } else { diff --git a/example/print_file/print_file_eh.cpp b/example/print_file/print_file_eh.cpp index 69361e40..f89c9a5a 100644 --- a/example/print_file/print_file_eh.cpp +++ b/example/print_file/print_file_eh.cpp @@ -67,7 +67,7 @@ int main( int argc, char const * argv[] ) std::cout << buffer; std::cout.flush(); if( std::cout.fail() ) - throw leaf::exception(output_error, leaf::e_errno{errno}); + leaf::throw_exception(output_error, leaf::e_errno{errno}); return 0; }, @@ -152,7 +152,7 @@ char const * parse_command_line( int argc, char const * argv[] ) if( argc==2 ) return argv[1]; else - throw leaf::exception(bad_command_line); + leaf::throw_exception(bad_command_line); } @@ -162,7 +162,7 @@ std::shared_ptr file_open( char const * file_name ) if( FILE * f = fopen(file_name, "rb") ) return std::shared_ptr(f, &fclose); else - throw leaf::exception(open_error, leaf::e_errno{errno}); + leaf::throw_exception(open_error, leaf::e_errno{errno}); } @@ -172,14 +172,14 @@ int file_size( FILE & f ) auto load = leaf::on_error([] { return leaf::e_errno{errno}; }); if( fseek(&f, 0, SEEK_END) ) - throw leaf::exception(size_error); + leaf::throw_exception(size_error); int s = ftell(&f); if( s==-1L ) - throw leaf::exception(size_error); + leaf::throw_exception(size_error); if( fseek(&f,0,SEEK_SET) ) - throw leaf::exception(size_error); + leaf::throw_exception(size_error); return s; } @@ -191,8 +191,8 @@ void file_read( FILE & f, void * buf, int size ) int n = fread(buf, 1, size, &f); if( ferror(&f) ) - throw leaf::exception(read_error, leaf::e_errno{errno}); + leaf::throw_exception(read_error, leaf::e_errno{errno}); if( n!=size ) - throw leaf::exception(eof_error); + leaf::throw_exception(eof_error); } diff --git a/include/boost/leaf/capture.hpp b/include/boost/leaf/capture.hpp index 6455eb2d..b26be0fe 100644 --- a/include/boost/leaf/capture.hpp +++ b/include/boost/leaf/capture.hpp @@ -132,12 +132,12 @@ namespace leaf_detail catch( exception_base const & e ) { ctx->captured_id_ = e.get_error_id(); - throw_exception( capturing_exception(std::current_exception(), std::move(ctx)) ); + leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::move(ctx)) ); } catch(...) { ctx->captured_id_ = cur_err.assigned_error_id(); - throw_exception( capturing_exception(std::current_exception(), std::move(ctx)) ); + leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::move(ctx)) ); } } @@ -165,12 +165,12 @@ namespace leaf_detail catch( exception_base const & e ) { ctx->captured_id_ = e.get_error_id(); - throw_exception( capturing_exception(std::current_exception(), std::move(ctx)) ); + leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::move(ctx)) ); } catch(...) { ctx->captured_id_ = cur_err.assigned_error_id(); - throw_exception( capturing_exception(std::current_exception(), std::move(ctx)) ); + leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::move(ctx)) ); } } diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index b8c7685f..947792bb 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -99,39 +99,6 @@ namespace leaf_detail //////////////////////////////////////// -#ifdef BOOST_LEAF_NO_EXCEPTIONS - -namespace boost -{ -[[noreturn]] void throw_exception( std::exception const & ); // user defined -} - -namespace boost { namespace leaf { - -template -[[noreturn]] void throw_exception( T const & e ) -{ - ::boost::throw_exception(e); -} - -} } - -#else - -namespace boost { namespace leaf { - -template -[[noreturn]] void throw_exception( T const & e ) -{ - throw e; -} - -} } - -#endif - -//////////////////////////////////////// - namespace boost { namespace leaf { #if BOOST_LEAF_CFG_DIAGNOSTICS diff --git a/include/boost/leaf/exception.hpp b/include/boost/leaf/exception.hpp index bda4dd77..dc2ea564 100644 --- a/include/boost/leaf/exception.hpp +++ b/include/boost/leaf/exception.hpp @@ -8,48 +8,58 @@ #include #include - -#ifndef BOOST_LEAF_NO_EXCEPTIONS - #include -#define BOOST_LEAF_EXCEPTION ::boost::leaf::leaf_detail::inject_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::exception -#define BOOST_LEAF_THROW_EXCEPTION ::boost::leaf::leaf_detail::throw_with_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::exception +#ifdef BOOST_LEAF_NO_EXCEPTIONS -//////////////////////////////////////// +namespace boost +{ + [[noreturn]] void throw_exception( std::exception const & ); // user defined +} namespace boost { namespace leaf { namespace leaf_detail { - struct throw_with_loc + template + [[noreturn]] void throw_exception_impl( T && e ) { - char const * const file; - int const line; - char const * const fn; + ::boost::throw_exception(std::move(e)); + } - template - [[noreturn]] friend void operator+( throw_with_loc loc, Ex const & ex ) - { - ex.load_source_location_(loc.file, loc.line, loc.fn); - ::boost::leaf::throw_exception(ex); - } + class BOOST_LEAF_SYMBOL_VISIBLE exception_base + { + public: + + virtual error_id get_error_id() const noexcept = 0; + + protected: + + exception_base() noexcept { } + ~exception_base() noexcept { } }; } } } -//////////////////////////////////////// +#else + +#include namespace boost { namespace leaf { namespace leaf_detail { - inline void enforce_std_exception( std::exception const & ) noexcept { } + template + [[noreturn]] void throw_exception_impl( T && e ) + { + throw std::move(e); + } class BOOST_LEAF_SYMBOL_VISIBLE exception_base { std::shared_ptr auto_id_bump_; + public: virtual error_id get_error_id() const noexcept = 0; @@ -63,6 +73,44 @@ namespace leaf_detail ~exception_base() noexcept { } }; +} + +} } + +#endif + +//////////////////////////////////////// + +#define BOOST_LEAF_THROW_EXCEPTION ::boost::leaf::leaf_detail::throw_with_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::leaf_detail::make_exception + +namespace boost { namespace leaf { + +namespace leaf_detail +{ + struct throw_with_loc + { + char const * const file; + int const line; + char const * const fn; + + template + [[noreturn]] friend void operator+( throw_with_loc loc, Ex && ex ) + { + ex.load_source_location_(loc.file, loc.line, loc.fn); + ::boost::leaf::leaf_detail::throw_exception_impl(std::move(ex)); + } + }; +} + +} } + +//////////////////////////////////////// + +namespace boost { namespace leaf { + +namespace leaf_detail +{ + inline void enforce_std_exception( std::exception const & ) noexcept { } template class BOOST_LEAF_SYMBOL_VISIBLE exception: @@ -112,52 +160,62 @@ namespace leaf_detail { constexpr static const bool value = std::is_base_of::type>::value || at_least_one_derives_from_std_exception::value; }; -} -template -inline -typename std::enable_if::type>::value, leaf_detail::exception::type>>::type -exception( error_id err, Ex && ex, E && ... e ) noexcept -{ - static_assert(!leaf_detail::at_least_one_derives_from_std_exception::value, "Error objects passed to leaf::exception may not derive from std::exception"); - return leaf_detail::exception::type>( err.load(std::forward(e)...), std::forward(ex) ); -} + template + inline + typename std::enable_if::type>::value, exception::type>>::type + make_exception( error_id err, Ex && ex, E && ... e ) noexcept + { + static_assert(!at_least_one_derives_from_std_exception::value, "Error objects passed to leaf::exception may not derive from std::exception"); + return exception::type>( err.load(std::forward(e)...), std::forward(ex) ); + } -template -inline -typename std::enable_if::type>::value, leaf_detail::exception>::type -exception( error_id err, E1 && car, E && ... cdr ) noexcept -{ - static_assert(!leaf_detail::at_least_one_derives_from_std_exception::value, "Error objects passed to leaf::exception may not derive from std::exception"); - return leaf_detail::exception( err.load(std::forward(car), std::forward(cdr)...) ); -} + template + inline + typename std::enable_if::type>::value, exception>::type + make_exception( error_id err, E1 && car, E && ... cdr ) noexcept + { + static_assert(!at_least_one_derives_from_std_exception::value, "Error objects passed to leaf::exception may not derive from std::exception"); + return exception( err.load(std::forward(car), std::forward(cdr)...) ); + } -inline leaf_detail::exception exception( error_id err ) noexcept -{ - return leaf_detail::exception(err); -} + inline exception make_exception( error_id err ) noexcept + { + return exception(err); + } -template -inline -typename std::enable_if::type>::value, leaf_detail::exception::type>>::type -exception( Ex && ex, E && ... e ) noexcept -{ - static_assert(!leaf_detail::at_least_one_derives_from_std_exception::value, "Error objects passed to leaf::exception may not derive from std::exception"); - return leaf_detail::exception::type>( new_error().load(std::forward(e)...), std::forward(ex) ); -} + template + inline + typename std::enable_if::type>::value, exception::type>>::type + make_exception( Ex && ex, E && ... e ) noexcept + { + static_assert(!at_least_one_derives_from_std_exception::value, "Error objects passed to leaf::exception may not derive from std::exception"); + return exception::type>( new_error().load(std::forward(e)...), std::forward(ex) ); + } -template -inline -typename std::enable_if::type>::value, leaf_detail::exception>::type -exception( E1 && car, E && ... cdr ) noexcept -{ - static_assert(!leaf_detail::at_least_one_derives_from_std_exception::value, "Error objects passed to leaf::exception may not derive from std::exception"); - return leaf_detail::exception( new_error().load(std::forward(car), std::forward(cdr)...) ); + template + inline + typename std::enable_if::type>::value, exception>::type + make_exception( E1 && car, E && ... cdr ) noexcept + { + static_assert(!at_least_one_derives_from_std_exception::value, "Error objects passed to leaf::exception may not derive from std::exception"); + return exception( new_error().load(std::forward(car), std::forward(cdr)...) ); + } + + inline exception make_exception() noexcept + { + return exception(leaf::new_error()); + } } -inline leaf_detail::exception exception() noexcept +template +[[noreturn]] void throw_exception( E && ... e ) { - return leaf_detail::exception(leaf::new_error()); + // Warning: setting a breakpoint here will not intercept exceptions thrown + // via BOOST_LEAF_THROW_EXCEPTION or originating in the few other throw + // points elsewhere in LEAF. To intercept all of those exceptions as well, + // set a breakpoint inside boost::leaf::leaf_detail::throw_exception_impl. + leaf_detail::throw_exception_impl(leaf_detail::make_exception(std::forward(e)...)); } //////////////////////////////////////// @@ -223,5 +281,3 @@ exception_to_result( F && f ) noexcept } } #endif - -#endif diff --git a/include/boost/leaf/result.hpp b/include/boost/leaf/result.hpp index f2ad7e11..cd983f4b 100644 --- a/include/boost/leaf/result.hpp +++ b/include/boost/leaf/result.hpp @@ -7,7 +7,7 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include #include #include @@ -281,7 +281,7 @@ class result void enforce_value_state() const { if( !has_value() ) - ::boost::leaf::throw_exception(bad_result(get_error_id())); + ::boost::leaf::leaf_detail::throw_exception_impl(bad_result(get_error_id())); } public: diff --git a/test/accumulate_nested_error_exception_test.cpp b/test/accumulate_nested_error_exception_test.cpp index 163be9ac..a10dcbe2 100644 --- a/test/accumulate_nested_error_exception_test.cpp +++ b/test/accumulate_nested_error_exception_test.cpp @@ -38,7 +38,7 @@ struct info void f0() { auto load = leaf::on_error( []( info<0> & ) { } ); - throw leaf::exception(info<2>{2}); + leaf::throw_exception(info<2>{2}); } void f1() diff --git a/test/accumulate_nested_new_error_exception_test.cpp b/test/accumulate_nested_new_error_exception_test.cpp index 91b29971..7486e8e7 100644 --- a/test/accumulate_nested_new_error_exception_test.cpp +++ b/test/accumulate_nested_new_error_exception_test.cpp @@ -38,14 +38,14 @@ struct info void f0() { auto load = leaf::on_error( info<0>{-1} ); - throw leaf::exception(info<1>{-1}); + leaf::throw_exception(info<1>{-1}); } void f1() { auto load = leaf::on_error( []( info<0> & x ) { }, []( info<1> & x ) { ++x.value; }, []( info<2> & x ) { ++x.value; } ); try { f0(); } catch(...) { } - throw leaf::exception(); + leaf::throw_exception(); } leaf::error_id f2() diff --git a/test/capture_exception_async_test.cpp b/test/capture_exception_async_test.cpp index 57a5ea7b..5825a913 100644 --- a/test/capture_exception_async_test.cpp +++ b/test/capture_exception_async_test.cpp @@ -87,7 +87,7 @@ int main() if( res >= 0 ) return res; else - throw leaf::exception(info<1>{a}, info<2>{b}, info<3>{}); + leaf::throw_exception(info<1>{a}, info<2>{b}, info<3>{}); } ); for( auto & f : fut ) @@ -122,7 +122,7 @@ int main() if( res >= 0 ) return res; else - throw leaf::exception(info<1>{a}, info<2>{b}, info<3>{}); + leaf::throw_exception(info<1>{a}, info<2>{b}, info<3>{}); } ); for( auto & f : fut ) diff --git a/test/capture_exception_state_test.cpp b/test/capture_exception_state_test.cpp index 9e3b9cfa..a8a4eb22 100644 --- a/test/capture_exception_state_test.cpp +++ b/test/capture_exception_state_test.cpp @@ -69,7 +69,7 @@ int main() leaf::make_shared_context(error_handlers), [] { - throw leaf::exception(info<1>{}, info<3>{}); + leaf::throw_exception(info<1>{}, info<3>{}); } ); BOOST_TEST(false); } diff --git a/test/capture_exception_unload_test.cpp b/test/capture_exception_unload_test.cpp index c784c831..8bb548c6 100644 --- a/test/capture_exception_unload_test.cpp +++ b/test/capture_exception_unload_test.cpp @@ -194,13 +194,13 @@ int main() test, info<2>, info<3>>( [] { - throw leaf::exception(info<1>{1}, info<3>{3}); // Derives from leaf::leaf::error_id + leaf::throw_exception(info<1>{1}, info<3>{3}); // Derives from leaf::leaf::error_id } ); test, info<2>, info<3>>( [] { auto load = leaf::on_error( info<1>{1}, info<3>{3} ); - throw leaf::exception(); // Derives from leaf::leaf::error_id + leaf::throw_exception(); // Derives from leaf::leaf::error_id } ); test, info<2>, info<3>>( [] diff --git a/test/defer_nested_error_exception_test.cpp b/test/defer_nested_error_exception_test.cpp index b85d3b60..887064b4 100644 --- a/test/defer_nested_error_exception_test.cpp +++ b/test/defer_nested_error_exception_test.cpp @@ -38,7 +38,7 @@ struct info void f0() { auto load = leaf::on_error( [] { return info<0>{0}; } ); - throw leaf::exception(info<2>{2}); + leaf::throw_exception(info<2>{2}); } void f1() diff --git a/test/defer_nested_new_error_exception_test.cpp b/test/defer_nested_new_error_exception_test.cpp index 928d556a..2b5d82cb 100644 --- a/test/defer_nested_new_error_exception_test.cpp +++ b/test/defer_nested_new_error_exception_test.cpp @@ -38,14 +38,14 @@ struct info void f0() { auto load = leaf::on_error( [] { return info<0>{-1}; } ); - throw leaf::exception(info<1>{-1}); + leaf::throw_exception(info<1>{-1}); } void f1() { auto load = leaf::on_error( [] { return info<0>{0}; }, [] { return info<1>{1}; }, [] { return info<2>{2}; } ); try { f0(); } catch(...) { } - throw leaf::exception(); + leaf::throw_exception(); } leaf::error_id f2() diff --git a/test/diagnostic_info_test2.cpp b/test/diagnostic_info_test2.cpp index fbbae7af..ef50ee56 100644 --- a/test/diagnostic_info_test2.cpp +++ b/test/diagnostic_info_test2.cpp @@ -73,12 +73,12 @@ int main() leaf::try_catch( [] { - throw leaf::exception(info<1>{}); + leaf::throw_exception(info<1>{}); }, [] { } ); - throw leaf::exception(info<2>{}); + leaf::throw_exception(info<2>{}); }, []( info<1> ) { diff --git a/test/exception_test.cpp b/test/exception_test.cpp index 50949b54..91f912ec 100644 --- a/test/exception_test.cpp +++ b/test/exception_test.cpp @@ -118,92 +118,76 @@ int test( F && f ) int main() { BOOST_TEST_EQ(20, test>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); - BOOST_TEST_EQ(20, test>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); })); - BOOST_TEST_EQ(21, test>([]{ throw leaf::exception(my_exception(42), info{42}); })); - BOOST_TEST_EQ(21, test>([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); })); - BOOST_TEST_EQ(21, test>([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test>([]{ leaf::throw_exception(my_exception(42), info{42}); })); + BOOST_TEST_EQ(21, test>([]{ my_exception exc(42); leaf::throw_exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test>([]{ my_exception const exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(22, test>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); - BOOST_TEST_EQ(22, test>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); })); - BOOST_TEST_EQ(23, test>([]{ throw leaf::exception(my_exception(42)); })); - BOOST_TEST_EQ(23, test>([]{ my_exception exc(42); throw leaf::exception(exc); })); - BOOST_TEST_EQ(23, test>([]{ my_exception const exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(23, test>([]{ leaf::throw_exception(my_exception(42)); })); + BOOST_TEST_EQ(23, test>([]{ my_exception exc(42); leaf::throw_exception(exc); })); + BOOST_TEST_EQ(23, test>([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(20, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); - BOOST_TEST_EQ(20, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); })); - BOOST_TEST_EQ(21, test([]{ throw leaf::exception(my_exception(42), info{42}); })); - BOOST_TEST_EQ(21, test([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); })); - BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test([]{ leaf::throw_exception(my_exception(42), info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception exc(42); leaf::throw_exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(22, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); - BOOST_TEST_EQ(22, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); })); - BOOST_TEST_EQ(23, test([]{ throw leaf::exception(my_exception(42)); })); - BOOST_TEST_EQ(23, test([]{ my_exception exc(42); throw leaf::exception(exc); })); - BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(23, test([]{ leaf::throw_exception(my_exception(42)); })); + BOOST_TEST_EQ(23, test([]{ my_exception exc(42); leaf::throw_exception(exc); })); + BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(40, test([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); })); - BOOST_TEST_EQ(40, test([]{ throw BOOST_LEAF_EXCEPTION(info{42}); })); - BOOST_TEST_EQ(41, test([]{ throw leaf::exception(info{42}); })); - BOOST_TEST_EQ(41, test([]{ info inf{42}; throw leaf::exception(inf); })); - BOOST_TEST_EQ(41, test([]{ info const inf{42}; throw leaf::exception(inf); })); + BOOST_TEST_EQ(41, test([]{ leaf::throw_exception(info{42}); })); + BOOST_TEST_EQ(41, test([]{ info inf{42}; leaf::throw_exception(inf); })); + BOOST_TEST_EQ(41, test([]{ info const inf{42}; leaf::throw_exception(inf); })); BOOST_TEST_EQ(42, test([]{ BOOST_LEAF_THROW_EXCEPTION(); })); - BOOST_TEST_EQ(42, test([]{ throw BOOST_LEAF_EXCEPTION(); })); - BOOST_TEST_EQ(43, test([]{ throw leaf::exception(); })); - BOOST_TEST_EQ(23, test([]{ my_exception exc(42); throw leaf::exception(exc); })); - BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(43, test([]{ leaf::throw_exception(); })); + BOOST_TEST_EQ(23, test([]{ my_exception exc(42); leaf::throw_exception(exc); })); + BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(20, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); - BOOST_TEST_EQ(20, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); })); - BOOST_TEST_EQ(21, test([]{ throw leaf::exception(my_exception(42), info{42}); })); - BOOST_TEST_EQ(21, test([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); })); - BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test([]{ leaf::throw_exception(my_exception(42), info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception exc(42); leaf::throw_exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(22, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); - BOOST_TEST_EQ(22, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); })); - BOOST_TEST_EQ(23, test([]{ throw leaf::exception(my_exception(42)); })); - BOOST_TEST_EQ(23, test([]{ my_exception exc(42); throw leaf::exception(exc); })); - BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(23, test([]{ leaf::throw_exception(my_exception(42)); })); + BOOST_TEST_EQ(23, test([]{ my_exception exc(42); leaf::throw_exception(exc); })); + BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(40, test([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); })); - BOOST_TEST_EQ(40, test([]{ throw BOOST_LEAF_EXCEPTION(info{42}); })); - BOOST_TEST_EQ(41, test([]{ throw leaf::exception(info{42}); })); - BOOST_TEST_EQ(41, test([]{ info inf{42}; throw leaf::exception(inf); })); - BOOST_TEST_EQ(41, test([]{ info const inf{42}; throw leaf::exception(inf); })); + BOOST_TEST_EQ(41, test([]{ leaf::throw_exception(info{42}); })); + BOOST_TEST_EQ(41, test([]{ info inf{42}; leaf::throw_exception(inf); })); + BOOST_TEST_EQ(41, test([]{ info const inf{42}; leaf::throw_exception(inf); })); BOOST_TEST_EQ(42, test([]{ BOOST_LEAF_THROW_EXCEPTION(); })); - BOOST_TEST_EQ(42, test([]{ throw BOOST_LEAF_EXCEPTION(); })); - BOOST_TEST_EQ(43, test([]{ throw leaf::exception(); })); - BOOST_TEST_EQ(23, test([]{ my_exception exc(42); throw leaf::exception(exc); })); - BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(43, test([]{ leaf::throw_exception(); })); + BOOST_TEST_EQ(23, test([]{ my_exception exc(42); leaf::throw_exception(exc); })); + BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(20, test>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); - BOOST_TEST_EQ(20, test>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); })); - BOOST_TEST_EQ(21, test>([]{ throw leaf::exception(my_exception(42), info{42}); })); - BOOST_TEST_EQ(21, test>([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); })); - BOOST_TEST_EQ(21, test>([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test>([]{ leaf::throw_exception(my_exception(42), info{42}); })); + BOOST_TEST_EQ(21, test>([]{ my_exception exc(42); leaf::throw_exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test>([]{ my_exception const exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(22, test>([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); - BOOST_TEST_EQ(22, test>([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); })); - BOOST_TEST_EQ(23, test>([]{ throw leaf::exception(my_exception(42)); })); - BOOST_TEST_EQ(23, test>([]{ my_exception exc(42); throw leaf::exception(exc); })); - BOOST_TEST_EQ(23, test>([]{ my_exception const exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(23, test>([]{ leaf::throw_exception(my_exception(42)); })); + BOOST_TEST_EQ(23, test>([]{ my_exception exc(42); leaf::throw_exception(exc); })); + BOOST_TEST_EQ(23, test>([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(20, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42), info{42}); })); - BOOST_TEST_EQ(20, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42), info{42}); })); - BOOST_TEST_EQ(21, test([]{ throw leaf::exception(my_exception(42), info{42}); })); - BOOST_TEST_EQ(21, test([]{ my_exception exc(42); throw leaf::exception(exc, info{42}); })); - BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); throw leaf::exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test([]{ leaf::throw_exception(my_exception(42), info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception exc(42); leaf::throw_exception(exc, info{42}); })); + BOOST_TEST_EQ(21, test([]{ my_exception const exc(42); leaf::throw_exception(exc, info{42}); })); BOOST_TEST_EQ(22, test([]{ BOOST_LEAF_THROW_EXCEPTION(my_exception(42)); })); - BOOST_TEST_EQ(22, test([]{ throw BOOST_LEAF_EXCEPTION(my_exception(42)); })); - BOOST_TEST_EQ(23, test([]{ throw leaf::exception(my_exception(42)); })); - BOOST_TEST_EQ(23, test([]{ my_exception exc(42); throw leaf::exception(exc); })); - BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(23, test([]{ leaf::throw_exception(my_exception(42)); })); + BOOST_TEST_EQ(23, test([]{ my_exception exc(42); leaf::throw_exception(exc); })); + BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); leaf::throw_exception(exc); })); BOOST_TEST_EQ(40, test([]{ BOOST_LEAF_THROW_EXCEPTION(info{42}); })); - BOOST_TEST_EQ(40, test([]{ throw BOOST_LEAF_EXCEPTION(info{42}); })); - BOOST_TEST_EQ(41, test([]{ throw leaf::exception(info{42}); })); - BOOST_TEST_EQ(41, test([]{ info inf{42}; throw leaf::exception(inf); })); - BOOST_TEST_EQ(41, test([]{ info const inf{42}; throw leaf::exception(inf); })); + BOOST_TEST_EQ(41, test([]{ leaf::throw_exception(info{42}); })); + BOOST_TEST_EQ(41, test([]{ info inf{42}; leaf::throw_exception(inf); })); + BOOST_TEST_EQ(41, test([]{ info const inf{42}; leaf::throw_exception(inf); })); BOOST_TEST_EQ(42, test([]{ BOOST_LEAF_THROW_EXCEPTION(); })); - BOOST_TEST_EQ(42, test([]{ throw BOOST_LEAF_EXCEPTION(); })); - BOOST_TEST_EQ(43, test([]{ throw leaf::exception(); })); - BOOST_TEST_EQ(23, test([]{ my_exception exc(42); throw leaf::exception(exc); })); - BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); throw leaf::exception(exc); })); + BOOST_TEST_EQ(43, test([]{ leaf::throw_exception(); })); + BOOST_TEST_EQ(23, test([]{ my_exception exc(42); leaf::throw_exception(exc); })); + BOOST_TEST_EQ(23, test([]{ my_exception const exc(42); leaf::throw_exception(exc); })); { char const * wh = 0; @@ -283,7 +267,7 @@ int main() leaf::try_catch( [] { - throw leaf::exception( info{42} ); + leaf::throw_exception( info{42} ); }, []( info x ) { diff --git a/test/multiple_errors_test.cpp b/test/multiple_errors_test.cpp index da1e74ea..1e6718de 100644 --- a/test/multiple_errors_test.cpp +++ b/test/multiple_errors_test.cpp @@ -68,7 +68,7 @@ int main() { try { - throw leaf::exception(info<4>{4}); + leaf::throw_exception(info<4>{4}); } catch(...) { diff --git a/test/preload_exception_test.cpp b/test/preload_exception_test.cpp index 8008d140..231f4f6a 100644 --- a/test/preload_exception_test.cpp +++ b/test/preload_exception_test.cpp @@ -67,7 +67,7 @@ int main() leaf::try_catch( [] { - f1( [] { throw leaf::exception(); } ); + f1( [] { leaf::throw_exception(); } ); return 0; }, []( leaf::error_info const & err, info<1> ) @@ -88,7 +88,7 @@ int main() leaf::try_catch( [] { - f2( [] { throw leaf::exception(); } ); + f2( [] { leaf::throw_exception(); } ); return 0; }, []( info<1> ) diff --git a/test/preload_nested_error_exception_test.cpp b/test/preload_nested_error_exception_test.cpp index 301daae8..eae593fb 100644 --- a/test/preload_nested_error_exception_test.cpp +++ b/test/preload_nested_error_exception_test.cpp @@ -38,7 +38,7 @@ struct info void f0() { auto load = leaf::on_error( info<0>{0} ); - throw leaf::exception(info<2>{2}); + leaf::throw_exception(info<2>{2}); } void f1() diff --git a/test/preload_nested_new_error_exception_test.cpp b/test/preload_nested_new_error_exception_test.cpp index 4a593e86..bf4560e4 100644 --- a/test/preload_nested_new_error_exception_test.cpp +++ b/test/preload_nested_new_error_exception_test.cpp @@ -38,14 +38,14 @@ struct info void f0() { auto load = leaf::on_error( info<0>{-1} ); - throw leaf::exception(info<1>{-1}); + leaf::throw_exception(info<1>{-1}); } void f1() { auto load = leaf::on_error( info<0>{}, info<1>{1}, info<2>{2} ); try { f0(); } catch(...) { } - throw leaf::exception(); + leaf::throw_exception(); } leaf::error_id f2() diff --git a/test/try_catch_error_id_test.cpp b/test/try_catch_error_id_test.cpp index 5b32875c..27141594 100644 --- a/test/try_catch_error_id_test.cpp +++ b/test/try_catch_error_id_test.cpp @@ -38,7 +38,7 @@ int main() int r = leaf::try_catch( []() -> int { - throw leaf::exception( my_error(), info{42} ); + leaf::throw_exception( my_error(), info{42} ); }, []( my_error const & x, leaf::catch_ id ) { diff --git a/test/try_catch_system_error_test.cpp b/test/try_catch_system_error_test.cpp index 2ece5fd9..ad3abd58 100644 --- a/test/try_catch_system_error_test.cpp +++ b/test/try_catch_system_error_test.cpp @@ -38,7 +38,7 @@ int main() int r = leaf::try_catch( []() -> int { - throw leaf::exception( std::system_error(make_error_code(errc_a::a0)), info{42} ); + leaf::throw_exception( std::system_error(make_error_code(errc_a::a0)), info{42} ); }, []( std::system_error const & se, leaf::match_value ) { @@ -74,7 +74,7 @@ int main() int r = leaf::try_catch( []() -> int { - throw leaf::exception( std::system_error(make_error_code(errc_a::a0)), info{42} ); + leaf::throw_exception( std::system_error(make_error_code(errc_a::a0)), info{42} ); }, []( leaf::match, errc_a::a0> code, leaf::match_value ) { @@ -112,7 +112,7 @@ int main() int r = leaf::try_catch( []() -> int { - throw leaf::exception( std::system_error(make_error_code(errc_a::a0)), info{42} ); + leaf::throw_exception( std::system_error(make_error_code(errc_a::a0)), info{42} ); }, []( std::error_code const & ec, leaf::match_value ) { diff --git a/test/try_catch_test.cpp b/test/try_catch_test.cpp index d14740f4..2e3b2428 100644 --- a/test/try_catch_test.cpp +++ b/test/try_catch_test.cpp @@ -45,7 +45,7 @@ struct exc_val: std::exception { int value; explicit exc_val(int v): value(v) { template R failing( Ex && ex ) { - throw leaf::exception(std::move(ex), info<1>{1}, info<2>{2}, info<3>{3}); + leaf::throw_exception(std::move(ex), info<1>{1}, info<2>{2}, info<3>{3}); } template @@ -549,7 +549,7 @@ int main() int r = leaf::try_catch( [] { - throw leaf::exception(exc_val{42}); + leaf::throw_exception(exc_val{42}); return 0; }, []( leaf::match_value ) @@ -566,7 +566,7 @@ int main() int r = leaf::try_catch( [] { - throw leaf::exception(exc_val{42}); + leaf::throw_exception(exc_val{42}); return 0; }, []( leaf::match_value ) diff --git a/test/try_exception_and_result_test.cpp b/test/try_exception_and_result_test.cpp index 954ab091..57d62ef1 100644 --- a/test/try_exception_and_result_test.cpp +++ b/test/try_exception_and_result_test.cpp @@ -65,7 +65,7 @@ int main() leaf::result r = leaf::try_handle_some( []() -> leaf::result { - throw leaf::exception( my_exception(), info<1>{1} ); + leaf::throw_exception( my_exception(), info<1>{1} ); }, []( my_exception const &, info<1> const & x ) { @@ -79,7 +79,7 @@ int main() leaf::result r = leaf::try_handle_some( []() -> leaf::result { - throw leaf::exception( info<1>{1} ); + leaf::throw_exception( info<1>{1} ); }, []( info<1> const & x ) { @@ -132,7 +132,7 @@ int main() leaf::result r = leaf::try_handle_some( []() -> leaf::result { - throw leaf::exception( my_exception(), info<1>{1} ); + leaf::throw_exception( my_exception(), info<1>{1} ); }, error_handlers ); BOOST_TEST(r); @@ -142,7 +142,7 @@ int main() leaf::result r = leaf::try_handle_some( []() -> leaf::result { - throw leaf::exception( info<1>{1} ); + leaf::throw_exception( info<1>{1} ); }, error_handlers ); BOOST_TEST(r); @@ -178,7 +178,7 @@ int main() int r = leaf::try_handle_all( []() -> leaf::result { - throw leaf::exception( my_exception(), info<1>{1} ); + leaf::throw_exception( my_exception(), info<1>{1} ); }, []( my_exception const &, info<1> const & x ) { @@ -195,7 +195,7 @@ int main() int r = leaf::try_handle_all( []() -> leaf::result { - throw leaf::exception( info<1>{1} ); + leaf::throw_exception( info<1>{1} ); }, []( info<1> const & x ) { @@ -257,7 +257,7 @@ int main() int r = leaf::try_handle_all( []() -> leaf::result { - throw leaf::exception( my_exception(), info<1>{1} ); + leaf::throw_exception( my_exception(), info<1>{1} ); }, error_handlers ); BOOST_TEST_EQ(r, 1); @@ -266,7 +266,7 @@ int main() int r = leaf::try_handle_all( []() -> leaf::result { - throw leaf::exception( info<1>{1} ); + leaf::throw_exception( info<1>{1} ); }, error_handlers ); BOOST_TEST_EQ(r, 2); @@ -580,7 +580,7 @@ int main() leaf::result r = leaf::try_handle_some( []() -> leaf::result { - throw leaf::exception( my_exception(42) ); + leaf::throw_exception( my_exception(42) ); }, []( leaf::match_value m ) { @@ -606,7 +606,7 @@ int main() leaf::result r = leaf::try_handle_some( []() -> leaf::result { - throw leaf::exception( my_exception(42) ); + leaf::throw_exception( my_exception(42) ); }, []( leaf::match_value m ) { @@ -642,7 +642,7 @@ int main() int r = leaf::try_handle_all( []() -> leaf::result { - throw leaf::exception( my_exception(42) ); + leaf::throw_exception( my_exception(42) ); }, []( leaf::match_value m ) { @@ -674,7 +674,7 @@ int main() int r = leaf::try_handle_all( []() -> leaf::result { - throw leaf::exception( my_exception(42) ); + leaf::throw_exception( my_exception(42) ); }, []( leaf::match_value m ) { diff --git a/test/visibility_test_lib.cpp b/test/visibility_test_lib.cpp index 2c4a0ac3..a94d303b 100644 --- a/test/visibility_test_lib.cpp +++ b/test/visibility_test_lib.cpp @@ -21,7 +21,7 @@ leaf::result BOOST_SYMBOL_VISIBLE hidden_result() void BOOST_SYMBOL_VISIBLE hidden_throw() { auto load = leaf::on_error( my_info<1>{1}, my_info<3>{3} ); - throw leaf::exception( my_info<2>{2} ); + leaf::throw_exception( my_info<2>{2} ); } #endif From a5494d078e720407b97d536f4f2e6a3df77f5ebc Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sun, 26 Jun 2022 22:28:07 -0700 Subject: [PATCH 003/103] Documentation update --- doc/leaf.adoc | 152 +++++++++++++++++++++++++------------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/doc/leaf.adoc b/doc/leaf.adoc index 1a21583b..15872cce 100644 --- a/doc/leaf.adoc +++ b/doc/leaf.adoc @@ -3023,82 +3023,6 @@ TIP: See also <>. ''' -[[throw_exception]] -=== `throw_exception` - -[source,c++] -.#include ----- -namespace boost { namespace leaf { - - template <1> - [[noreturn]] void throw_exception( Ex && ex, E && ... e ); - - template <2> - [[noreturn]] void throw_exception( E1 && e1, E && ... e ); - - [[noreturn]] void throw_exception(); <3> - - template <4> - [[noreturn]] void throw_exception( error_id id, Ex && ex, E && ... e ); - - template <5> - [[noreturn]] void throw_exception( error_id id, E1 && e1, E && ... e ); - - [[noreturn]] void throw_exception( error_id id ); <6> - -} } ----- -The `throw_exception` function is overloaded: it can be invoked with no arguments, or else there are several alternatives, selected using `std::enable_if` based on the type of the passed arguments. All overloads throw an exception: - -<1> Selected if the first argument is not of type `error_id` and is an exception object, that is, iff `Ex` derives publicly from `std::exception`. In this case the thrown exception is of unspecified type which derives publicly from `Ex` *and* from class <>, such that: -* its `Ex` subobject is initialized by `std::forward(ex)`; -* its `error_id` subobject is initialized by `<>(std::forward(e)...`). - -<2> Selected if the first argument is not of type `error_id` and is not an exception object. In this case the thrown exception is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: -** its `std::exception` subobject is default-initialized; -** its `error_id` subobject is initialized by `<>(std::forward(e1), std::forward(e)...`). - -<3> If the fuction is invoked without arguments, the thrown exception is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: -** its `std::exception` subobject is default-initialized; -** its `error_id` subobject is initialized by `<>()`. - -<4> Selected if the first argument is of type `error_id` and the second argument is an exception object, that is, iff `Ex` derives publicly from `std::exception`. In this case the thrown exception is of unspecified type which derives publicly from `Ex` *and* from class <>, such that: -** its `Ex` subobject is initialized by `std::forward(ex)`; -** its `error_id` subobject is initialized by `id.<>(std::forward(e)...)`. - -<5> Selected if the first argument is of type `error_id` and the second argument is not an exception object. In this case the thrown exception is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: -** its `std::exception` subobject is default-initialized; -** its `error_id` subobject is initialized by `id.<>(std::forward(e1), std::forward(e)...`). - -<6> If `exception` is invoked with just an `error_id` object, the thrown exception is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: -** its `std::exception` subobject is default-initialized; -** its `error_id` subobject is initialized by copying from `id`. - -NOTE: The first three overloads throw an exception object that is associated with a new `error_id`. The second three overloads throw an exception object that is associated with the specified `error_id`. - -.Example 1: -[source,c++] ----- -struct my_exception: std::exception { }; - -leaf::throw_exception(my_exception{}); <1> ----- -<1> Throws an exception of a type that derives from `error_id` and from `my_exception` (because `my_exception` derives from `std::exception`). - -.Example 2: -[source,c++] ----- -enum class my_error { e1=1, e2, e3 }; <1> - -leaf::throw_exception(my_error::e1); ----- -<1> Throws an exception of a type that derives from `error_id` and from `std::exception` (because `my_error` does not derive from `std::exception`). - -NOTE: To automatically capture `pass:[__FILE__]`, `pass:[__LINE__]` and `pass:[__FUNCTION__]` with the returned object, use <> instead of `leaf::throw_exception`. - -''' - [[exception_to_result]] === `exception_to_result` @@ -3321,6 +3245,82 @@ TIP: See <> from the Tutorial. ''' +[[throw_exception]] +=== `throw_exception` + +[source,c++] +.#include +---- +namespace boost { namespace leaf { + + template <1> + [[noreturn]] void throw_exception( Ex && ex, E && ... e ); + + template <2> + [[noreturn]] void throw_exception( E1 && e1, E && ... e ); + + [[noreturn]] void throw_exception(); <3> + + template <4> + [[noreturn]] void throw_exception( error_id id, Ex && ex, E && ... e ); + + template <5> + [[noreturn]] void throw_exception( error_id id, E1 && e1, E && ... e ); + + [[noreturn]] void throw_exception( error_id id ); <6> + +} } +---- +The `throw_exception` function is overloaded: it can be invoked with no arguments, or else there are several alternatives, selected using `std::enable_if` based on the type of the passed arguments. All overloads throw an exception: + +<1> Selected if the first argument is not of type `error_id` and is an exception object, that is, iff `Ex` derives publicly from `std::exception`. In this case the thrown exception is of unspecified type which derives publicly from `Ex` *and* from class <>, such that: +* its `Ex` subobject is initialized by `std::forward(ex)`; +* its `error_id` subobject is initialized by `<>(std::forward(e)...`). + +<2> Selected if the first argument is not of type `error_id` and is not an exception object. In this case the thrown exception is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: +** its `std::exception` subobject is default-initialized; +** its `error_id` subobject is initialized by `<>(std::forward(e1), std::forward(e)...`). + +<3> If the fuction is invoked without arguments, the thrown exception is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: +** its `std::exception` subobject is default-initialized; +** its `error_id` subobject is initialized by `<>()`. + +<4> Selected if the first argument is of type `error_id` and the second argument is an exception object, that is, iff `Ex` derives publicly from `std::exception`. In this case the thrown exception is of unspecified type which derives publicly from `Ex` *and* from class <>, such that: +** its `Ex` subobject is initialized by `std::forward(ex)`; +** its `error_id` subobject is initialized by `id.<>(std::forward(e)...)`. + +<5> Selected if the first argument is of type `error_id` and the second argument is not an exception object. In this case the thrown exception is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: +** its `std::exception` subobject is default-initialized; +** its `error_id` subobject is initialized by `id.<>(std::forward(e1), std::forward(e)...`). + +<6> If `exception` is invoked with just an `error_id` object, the thrown exception is of unspecified type which derives publicly from `std::exception` *and* from class `error_id`, such that: +** its `std::exception` subobject is default-initialized; +** its `error_id` subobject is initialized by copying from `id`. + +NOTE: The first three overloads throw an exception object that is associated with a new `error_id`. The second three overloads throw an exception object that is associated with the specified `error_id`. + +.Example 1: +[source,c++] +---- +struct my_exception: std::exception { }; + +leaf::throw_exception(my_exception{}); <1> +---- +<1> Throws an exception of a type that derives from `error_id` and from `my_exception` (because `my_exception` derives from `std::exception`). + +.Example 2: +[source,c++] +---- +enum class my_error { e1=1, e2, e3 }; <1> + +leaf::throw_exception(my_error::e1); +---- +<1> Throws an exception of a type that derives from `error_id` and from `std::exception` (because `my_error` does not derive from `std::exception`). + +NOTE: To automatically capture `pass:[__FILE__]`, `pass:[__LINE__]` and `pass:[__FUNCTION__]` with the returned object, use <> instead of `leaf::throw_exception`. + +''' + [[to_variant]] === `to_variant` From e16e0cf417463ec992846078099d317495c2bc5e Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Tue, 28 Jun 2022 19:05:23 -0700 Subject: [PATCH 004/103] Explicit tests for the BOOST_LEAF_CFG_CAPTURE=0 configurations --- .github/workflows/ci.yml | 4 ++-- example/capture_in_exception.cpp | 1 + example/capture_in_result.cpp | 1 + include/boost/leaf/handle_errors.hpp | 2 ++ test/Jamfile.v2 | 10 +++++++--- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0d6acd5..96b2dd11 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,7 +136,7 @@ jobs: - name: Run tests run: | cd ../boost-root - ./b2 -j3 libs/leaf/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} link=shared,static variant=debug,release,leaf_debug_leaf_hpp,leaf_release_leaf_hpp,leaf_debug_diag0,leaf_release_diag0,leaf_debug_embedded,leaf_release_embedded + ./b2 -j3 libs/leaf/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} link=shared,static variant=debug,release,leaf_debug_capture0,leaf_release_capture0,leaf_debug_diag0,leaf_release_diag0,leaf_debug_embedded,leaf_release_embedded,leaf_debug_leaf_hpp,leaf_release_leaf_hpp windows: strategy: @@ -185,4 +185,4 @@ jobs: shell: cmd run: | cd ../boost-root - b2 -j3 libs/leaf/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release,leaf_debug_leaf_hpp,leaf_release_leaf_hpp,leaf_debug_diag0,leaf_release_diag0,leaf_debug_embedded,leaf_release_embedded + b2 -j3 libs/leaf/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release,leaf_debug_capture0,leaf_release_capture0,leaf_debug_diag0,leaf_release_diag0,leaf_debug_embedded,leaf_release_embedded,leaf_debug_leaf_hpp,leaf_release_leaf_hpp diff --git a/example/capture_in_exception.cpp b/example/capture_in_exception.cpp index 3652ce7c..f9facd34 100644 --- a/example/capture_in_exception.cpp +++ b/example/capture_in_exception.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace leaf = boost::leaf; diff --git a/example/capture_in_result.cpp b/example/capture_in_result.cpp index 94ced74c..04ed1970 100644 --- a/example/capture_in_result.cpp +++ b/example/capture_in_result.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace leaf = boost::leaf; diff --git a/include/boost/leaf/handle_errors.hpp b/include/boost/leaf/handle_errors.hpp index c3c4e68b..4410fc77 100644 --- a/include/boost/leaf/handle_errors.hpp +++ b/include/boost/leaf/handle_errors.hpp @@ -763,6 +763,7 @@ namespace leaf_detail { return std::forward(try_block)(); } +#if BOOST_LEAF_CFG_CAPTURE catch( capturing_exception const & cap ) { try @@ -792,6 +793,7 @@ namespace leaf_detail } ); } } +#endif catch( std::exception & ex ) { ctx.deactivate(); diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index bc872ada..9896c4e0 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -5,6 +5,9 @@ import testing ; +variant leaf_debug_capture0 : debug : BOOST_LEAF_CFG_CAPTURE=0 ; +variant leaf_release_capture0 : release : BOOST_LEAF_CFG_CAPTURE=0 ; + variant leaf_debug_diag0 : debug : BOOST_LEAF_CFG_DIAGNOSTICS=0 ; variant leaf_release_diag0 : release : BOOST_LEAF_CFG_DIAGNOSTICS=0 ; @@ -17,6 +20,7 @@ variant leaf_release_leaf_hpp : release : BOOST_LEAF_TEST_SINGLE_HEADER project : default-build 11 + multi : requirements BOOST_LEAF_BOOST_AVAILABLE single:BOOST_LEAF_NO_THREADS @@ -136,14 +140,14 @@ compile-fail _compile-fail-result_3.cpp ; compile-fail _compile-fail-result_4.cpp ; compile-fail _compile-fail-verbose_diagnostic_info.cpp ; -exe capture_in_exception : ../example/capture_in_exception.cpp : single:no off:no ; -exe capture_in_result : ../example/capture_in_result.cpp : single:no off:no ; +exe capture_in_exception : ../example/capture_in_exception.cpp : single:no off:no leaf_debug_capture0:no leaf_release_capture0:no ; +exe capture_in_result : ../example/capture_in_result.cpp : single:no leaf_debug_capture0:no leaf_release_capture0:no leaf_debug_embedded:no leaf_release_embedded:no ; exe error_log : ../example/error_log.cpp : off:no ; exe error_trace : ../example/error_trace.cpp : off:no ; exe exception_to_result : ../example/exception_to_result.cpp : off:no ; # exe lua_callback_result : ../example/lua_callback_result.cpp : off:no ; # exe lua_callback_eh : ../example/lua_callback_eh.cpp : off:no ; exe print_file_eh : ../example/print_file/print_file_eh.cpp : off:no ; -# exe print_file_outcome_result : ../example/print_file/print_file_outcome_result.cpp : off:no ; +# exe print_file_outcome_result : ../example/print_file/print_file_outcome_result.cpp : off:no 11:no ; exe print_file_result : ../example/print_file/print_file_result.cpp : off:no ; exe print_half : ../example/print_half.cpp : off:no ; From fc170d20edc209bbc7967330a7d30c3064148b08 Mon Sep 17 00:00:00 2001 From: Khalil Estell Date: Wed, 31 Aug 2022 08:33:52 -0700 Subject: [PATCH 005/103] Add local conanfile.py - Bump version to 0.4.0 --- conanfile.py | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 conanfile.py diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 00000000..c942e37f --- /dev/null +++ b/conanfile.py @@ -0,0 +1,80 @@ +from conan import ConanFile +from conan.tools.files import get, copy +from conan.tools.layout import basic_layout +from conan.tools.build import check_min_cppstd +from conan.errors import ConanInvalidConfiguration +import os + + +required_conan_version = ">=1.50.0" + + +class BoostLEAFConan(ConanFile): + name = "boost-leaf" + version = "0.4.0" + license = "BSL-1.0" + url = "https://github.com/conan-io/conan-center-index" + homepage = "https://github.com/boostorg/leaf" + description = ("Lightweight Error Augmentation Framework") + topics = ("multi-platform", "multi-threading", "cpp11", "error-handling", + "header-only", "low-latency", "no-dependencies", "single-header") + settings = "os", "compiler", "arch", "build_type" + exports_sources = "include/*", "LICENSE_1_0.txt" + no_copy_source = True + + def package_id(self): + self.info.clear() + + @property + def _min_cppstd(self): + return "11" + + @property + def _compilers_minimum_version(self): + return { + "gcc": "4.8", + "Visual Studio": "17", + "msvc": "141", + "clang": "3.9", + "apple-clang": "10.0.0" + } + + def requirements(self): + pass + + def validate(self): + if self.settings.get_safe("compiler.cppstd"): + check_min_cppstd(self, self._min_cppstd) + + def lazy_lt_semver(v1, v2): + lv1 = [int(v) for v in v1.split(".")] + lv2 = [int(v) for v in v2.split(".")] + min_length = min(len(lv1), len(lv2)) + return lv1[:min_length] < lv2[:min_length] + + compiler = str(self.settings.compiler) + version = str(self.settings.compiler.version) + minimum_version = self._compilers_minimum_version.get(compiler, False) + + if minimum_version and lazy_lt_semver(version, minimum_version): + raise ConanInvalidConfiguration( + f"{self.name} {self.version} requires C++{self._min_cppstd}, which your compiler ({compiler}-{version}) does not support") + + def layout(self): + basic_layout(self) + + def package(self): + copy(self, "LICENSE", dst=os.path.join( + self.package_folder, "licenses"), src=self.source_folder) + copy(self, "*.h", dst=os.path.join(self.package_folder, "include"), + src=os.path.join(self.source_folder, "include")) + copy(self, "*.hpp", dst=os.path.join(self.package_folder, + "include"), src=os.path.join(self.source_folder, "include")) + + def package_info(self): + self.cpp_info.set_property("cmake_target_name", "boost::leaf") + + self.cpp_info.bindirs = [] + self.cpp_info.frameworkdirs = [] + self.cpp_info.libdirs = [] + self.cpp_info.resdirs = [] From b2090ac95f364259b5f7959d7a9c25c64e27e81f Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Tue, 6 Sep 2022 14:49:00 -0700 Subject: [PATCH 006/103] Fixed warnings --- .github/workflows/ci.yml | 4 -- example/exception_to_result.cpp | 4 +- example/print_file/print_file_eh.cpp | 16 ++--- .../print_file/print_file_outcome_result.cpp | 14 ++-- example/print_file/print_file_result.cpp | 14 ++-- include/boost/leaf/capture.hpp | 2 +- include/boost/leaf/common.hpp | 4 +- include/boost/leaf/config/tls_array.hpp | 20 +++--- include/boost/leaf/config/tls_cpp11.hpp | 24 +++---- include/boost/leaf/config/tls_globals.hpp | 24 +++---- include/boost/leaf/context.hpp | 4 +- include/boost/leaf/detail/optional.hpp | 4 ++ include/boost/leaf/error.hpp | 25 +++---- include/boost/leaf/exception.hpp | 2 +- include/boost/leaf/handle_errors.hpp | 6 +- include/boost/leaf/on_error.hpp | 4 +- include/boost/leaf/result.hpp | 6 +- meson.build | 4 ++ test/BOOST_LEAF_ASSIGN_test.cpp | 2 +- test/BOOST_LEAF_AUTO_test.cpp | 2 +- test/BOOST_LEAF_CHECK_test.cpp | 2 +- ...mulate_nested_new_error_exception_test.cpp | 2 +- ...ccumulate_nested_new_error_result_test.cpp | 2 +- test/capture_exception_unload_test.cpp | 8 +-- test/capture_result_async_test.cpp | 2 +- test/context_activator_test.cpp | 8 +-- test/diagnostic_info_test.cpp | 4 +- test/diagnostic_info_test2.cpp | 2 +- test/exception_test.cpp | 8 +-- test/handle_all_other_result_test.cpp | 8 +-- test/handle_all_test.cpp | 2 +- test/handle_basic_test.cpp | 12 ++-- test/handle_some_other_result_test.cpp | 8 +-- test/handle_some_test.cpp | 66 +++++++++---------- test/match_test.cpp | 8 +-- test/optional_test.cpp | 4 +- test/result_bad_result_test.cpp | 24 +++---- test/result_implicit_conversion_test.cpp | 4 +- test/try_catch_error_id_test.cpp | 2 +- test/try_catch_test.cpp | 20 +++--- 40 files changed, 194 insertions(+), 187 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96b2dd11..80dcd723 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -143,10 +143,6 @@ jobs: fail-fast: false matrix: include: - - toolset: msvc-14.1 - cxxstd: "14,17,latest" - addrmd: 32,64 - os: windows-2016 - toolset: msvc-14.2 cxxstd: "14,17,latest" addrmd: 32,64 diff --git a/example/exception_to_result.cpp b/example/exception_to_result.cpp index 793f6777..98fdfcbb 100644 --- a/example/exception_to_result.cpp +++ b/example/exception_to_result.cpp @@ -68,12 +68,12 @@ int main() return { }; }, - []( error_a const & e ) + []( error_a const & ) { std::cerr << "Error A!" << std::endl; }, - []( error_b const & e ) + []( error_b const & ) { std::cerr << "Error B!" << std::endl; }, diff --git a/example/print_file/print_file_eh.cpp b/example/print_file/print_file_eh.cpp index f89c9a5a..cfd04fa8 100644 --- a/example/print_file/print_file_eh.cpp +++ b/example/print_file/print_file_eh.cpp @@ -40,10 +40,10 @@ char const * parse_command_line( int argc, char const * argv[] ); std::shared_ptr file_open( char const * file_name ); // Return the size of the file. -int file_size( FILE & f ); +std::size_t file_size( FILE & f ); // Read size bytes from f into buf. -void file_read( FILE & f, void * buf, int size ); +void file_read( FILE & f, void * buf, std::size_t size ); // The main function, which handles all errors. @@ -59,7 +59,7 @@ int main( int argc, char const * argv[] ) std::shared_ptr f = file_open(file_name); - int s = file_size(*f); + std::size_t s = file_size(*f); std::string buffer(1 + s, '\0'); file_read(*f, &buffer[0], buffer.size()-1); @@ -167,28 +167,28 @@ std::shared_ptr file_open( char const * file_name ) // Return the size of the file. -int file_size( FILE & f ) +std::size_t file_size( FILE & f ) { auto load = leaf::on_error([] { return leaf::e_errno{errno}; }); if( fseek(&f, 0, SEEK_END) ) leaf::throw_exception(size_error); - int s = ftell(&f); + long s = ftell(&f); if( s==-1L ) leaf::throw_exception(size_error); if( fseek(&f,0,SEEK_SET) ) leaf::throw_exception(size_error); - return s; + return std::size_t(s); } // Read size bytes from f into buf. -void file_read( FILE & f, void * buf, int size ) +void file_read( FILE & f, void * buf, std::size_t size ) { - int n = fread(buf, 1, size, &f); + std::size_t n = fread(buf, 1, size, &f); if( ferror(&f) ) leaf::throw_exception(read_error, leaf::e_errno{errno}); diff --git a/example/print_file/print_file_outcome_result.cpp b/example/print_file/print_file_outcome_result.cpp index 991a2e09..454ff5e9 100644 --- a/example/print_file/print_file_outcome_result.cpp +++ b/example/print_file/print_file_outcome_result.cpp @@ -52,10 +52,10 @@ result parse_command_line( int argc, char const * argv[] ); result> file_open( char const * file_name ); // Return the size of the file. -result file_size( FILE & f ); +result file_size( FILE & f ); // Read size bytes from f into buf. -result file_read( FILE & f, void * buf, int size ); +result file_read( FILE & f, void * buf, std::size_t size ); // The main function, which handles all errors. @@ -179,28 +179,28 @@ result> file_open( char const * file_name ) // Return the size of the file. -result file_size( FILE & f ) +result file_size( FILE & f ) { auto load = leaf::on_error([] { return leaf::e_errno{errno}; }); if( fseek(&f, 0, SEEK_END) ) return leaf::new_error(size_error).to_error_code(); - int s = ftell(&f); + long s = ftell(&f); if( s==-1L ) return leaf::new_error(size_error).to_error_code(); if( fseek(&f,0,SEEK_SET) ) return leaf::new_error(size_error).to_error_code(); - return s; + return std::size_t(s); } // Read size bytes from f into buf. -result file_read( FILE & f, void * buf, int size ) +result file_read( FILE & f, void * buf, std::size_t size ) { - int n = fread(buf, 1, size, &f); + std::size_t n = fread(buf, 1, size, &f); if( ferror(&f) ) return leaf::new_error(read_error, leaf::e_errno{errno}).to_error_code(); diff --git a/example/print_file/print_file_result.cpp b/example/print_file/print_file_result.cpp index bd733241..beeb702f 100644 --- a/example/print_file/print_file_result.cpp +++ b/example/print_file/print_file_result.cpp @@ -44,10 +44,10 @@ result parse_command_line( int argc, char const * argv[] ); result> file_open( char const * file_name ); // Return the size of the file. -result file_size( FILE & f ); +result file_size( FILE & f ); // Read size bytes from f into buf. -result file_read( FILE & f, void * buf, int size ); +result file_read( FILE & f, void * buf, std::size_t size ); // The main function, which handles all errors. @@ -171,28 +171,28 @@ result> file_open( char const * file_name ) // Return the size of the file. -result file_size( FILE & f ) +result file_size( FILE & f ) { auto load = leaf::on_error([] { return leaf::e_errno{errno}; }); if( fseek(&f, 0, SEEK_END) ) return leaf::new_error(size_error); - int s = ftell(&f); + long s = ftell(&f); if( s==-1L ) return leaf::new_error(size_error); if( fseek(&f,0,SEEK_SET) ) return leaf::new_error(size_error); - return s; + return std::size_t(s); } // Read size bytes from f into buf. -result file_read( FILE & f, void * buf, int size ) +result file_read( FILE & f, void * buf, std::size_t size ) { - int n = fread(buf, 1, size, &f); + std::size_t n = fread(buf, 1, size, &f); if( ferror(&f) ) return leaf::new_error(read_error, leaf::e_errno{errno}); diff --git a/include/boost/leaf/capture.hpp b/include/boost/leaf/capture.hpp index b26be0fe..08c3bcb4 100644 --- a/include/boost/leaf/capture.hpp +++ b/include/boost/leaf/capture.hpp @@ -102,7 +102,7 @@ namespace leaf_detail [[noreturn]] void unload_and_rethrow_original_exception() const { BOOST_LEAF_ASSERT(ctx_->captured_id_); - tls::write_uint32(ctx_->captured_id_.value()); + tls::write_uint(unsigned(ctx_->captured_id_.value())); ctx_->propagate(ctx_->captured_id_); std::rethrow_exception(ex_); } diff --git a/include/boost/leaf/common.hpp b/include/boost/leaf/common.hpp index 2069f55a..3ed7f7ea 100644 --- a/include/boost/leaf/common.hpp +++ b/include/boost/leaf/common.hpp @@ -50,7 +50,7 @@ struct BOOST_LEAF_SYMBOL_VISIBLE e_errno { int value; - explicit e_errno(int value=errno): value(value) { } + explicit e_errno(int val=errno): value(val) { } template friend std::basic_ostream & operator<<(std::basic_ostream & os, e_errno const & err) @@ -69,7 +69,7 @@ namespace windows { unsigned value; - explicit e_LastError(unsigned value): value(value) { } + explicit e_LastError(unsigned val): value(val) { } #if BOOST_LEAF_CFG_WIN32 e_LastError(): value(GetLastError()) { } diff --git a/include/boost/leaf/config/tls_array.hpp b/include/boost/leaf/config/tls_array.hpp index f194c56c..0d0e83c4 100644 --- a/include/boost/leaf/config/tls_array.hpp +++ b/include/boost/leaf/config/tls_array.hpp @@ -9,7 +9,7 @@ // LEAF requires thread local storage support for pointers and for uin32_t values. -// This header implements thread local storage for pointers and for uint32_t +// This header implements thread local storage for pointers and for unsigned int // values for platforms that support thread local pointers by index. namespace boost { namespace leaf { @@ -121,29 +121,29 @@ namespace tls //////////////////////////////////////// template - std::uint32_t read_uint32() noexcept + unsigned read_uint() noexcept { - static_assert(sizeof(std::intptr_t) >= sizeof(std::uint32_t), "Incompatible tls_array implementation"); - return (std::uint32_t) (std::intptr_t) (void *) read_ptr(); + static_assert(sizeof(std::intptr_t) >= sizeof(unsigned), "Incompatible tls_array implementation"); + return (unsigned) (std::intptr_t) (void *) read_ptr(); } template - void write_uint32( std::uint32_t x ) noexcept + void write_uint( unsigned x ) noexcept { - static_assert(sizeof(std::intptr_t) >= sizeof(std::uint32_t), "Incompatible tls_array implementation"); + static_assert(sizeof(std::intptr_t) >= sizeof(unsigned), "Incompatible tls_array implementation"); write_ptr((Tag *) (void *) (std::intptr_t) x); } template - void uint32_increment() noexcept + void uint_increment() noexcept { - write_uint32(read_uint32() + 1); + write_uint(read_uint() + 1); } template - void uint32_decrement() noexcept + void uint_decrement() noexcept { - write_uint32(read_uint32() - 1); + write_uint(read_uint() - 1); } } diff --git a/include/boost/leaf/config/tls_cpp11.hpp b/include/boost/leaf/config/tls_cpp11.hpp index dbc6711e..6b244b6a 100644 --- a/include/boost/leaf/config/tls_cpp11.hpp +++ b/include/boost/leaf/config/tls_cpp11.hpp @@ -8,7 +8,7 @@ // LEAF requires thread local storage support for pointers and for uin32_t values. -// This header implements thread local storage for pointers and for uint32_t +// This header implements thread local storage for pointers and for unsigned int // values using the C++11 built-in thread_local storage class specifier. #include @@ -47,36 +47,36 @@ namespace tls //////////////////////////////////////// template - struct BOOST_LEAF_SYMBOL_VISIBLE tagged_uint32 + struct BOOST_LEAF_SYMBOL_VISIBLE tagged_uint { - static thread_local std::uint32_t x; + static thread_local unsigned x; }; template - thread_local std::uint32_t tagged_uint32::x; + thread_local unsigned tagged_uint::x; template - std::uint32_t read_uint32() noexcept + unsigned read_uint() noexcept { - return tagged_uint32::x; + return tagged_uint::x; } template - void write_uint32( std::uint32_t x ) noexcept + void write_uint( unsigned x ) noexcept { - tagged_uint32::x = x; + tagged_uint::x = x; } template - void uint32_increment() noexcept + void uint_increment() noexcept { - ++tagged_uint32::x; + ++tagged_uint::x; } template - void uint32_decrement() noexcept + void uint_decrement() noexcept { - --tagged_uint32::x; + --tagged_uint::x; } } diff --git a/include/boost/leaf/config/tls_globals.hpp b/include/boost/leaf/config/tls_globals.hpp index 0dc92ffc..e8cca3bc 100644 --- a/include/boost/leaf/config/tls_globals.hpp +++ b/include/boost/leaf/config/tls_globals.hpp @@ -8,7 +8,7 @@ // LEAF requires thread local storage support for pointers and for uin32_t values. -// This header implements "thread local" storage for pointers and for uint32_t +// This header implements "thread local" storage for pointers and for unsigned int // values using globals, which is suitable for single thread environments. #include @@ -46,36 +46,36 @@ namespace tls //////////////////////////////////////// template - struct BOOST_LEAF_SYMBOL_VISIBLE tagged_uint32 + struct BOOST_LEAF_SYMBOL_VISIBLE tagged_uint { - static std::uint32_t x; + static unsigned x; }; template - std::uint32_t tagged_uint32::x; + unsigned tagged_uint::x; template - std::uint32_t read_uint32() noexcept + unsigned read_uint() noexcept { - return tagged_uint32::x; + return tagged_uint::x; } template - void write_uint32( std::uint32_t x ) noexcept + void write_uint( unsigned x ) noexcept { - tagged_uint32::x = x; + tagged_uint::x = x; } template - void uint32_increment() noexcept + void uint_increment() noexcept { - ++tagged_uint32::x; + ++tagged_uint::x; } template - void uint32_decrement() noexcept + void uint_decrement() noexcept { - --tagged_uint32::x; + --tagged_uint::x; } } diff --git a/include/boost/leaf/context.hpp b/include/boost/leaf/context.hpp index 0ac45d20..4fe1775b 100644 --- a/include/boost/leaf/context.hpp +++ b/include/boost/leaf/context.hpp @@ -329,7 +329,7 @@ class context tuple_for_each::value,Tup>::activate(tup_); #if BOOST_LEAF_CFG_DIAGNOSTICS if( unexpected_requested::value ) - tls::uint32_increment(); + tls::uint_increment(); #endif #if !defined(BOOST_LEAF_NO_THREADS) && !defined(NDEBUG) thread_id_ = std::this_thread::get_id(); @@ -348,7 +348,7 @@ class context #endif #if BOOST_LEAF_CFG_DIAGNOSTICS if( unexpected_requested::value ) - tls::uint32_decrement(); + tls::uint_decrement(); #endif tuple_for_each::value,Tup>::deactivate(tup_); } diff --git a/include/boost/leaf/detail/optional.hpp b/include/boost/leaf/detail/optional.hpp index 494ecedc..0a2cdb2d 100644 --- a/include/boost/leaf/detail/optional.hpp +++ b/include/boost/leaf/detail/optional.hpp @@ -140,24 +140,28 @@ namespace leaf_detail BOOST_LEAF_CONSTEXPR T const & value(int key) const & noexcept { BOOST_LEAF_ASSERT(has_value(key) != 0); + (void) key; return value_; } BOOST_LEAF_CONSTEXPR T & value(int key) & noexcept { BOOST_LEAF_ASSERT(has_value(key) != 0); + (void) key; return value_; } BOOST_LEAF_CONSTEXPR T const && value(int key) const && noexcept { BOOST_LEAF_ASSERT(has_value(key) != 0); + (void) key; return value_; } BOOST_LEAF_CONSTEXPR T value(int key) && noexcept { BOOST_LEAF_ASSERT(has_value(key) != 0); + (void) key; T tmp(std::move(value_)); reset(); return tmp; diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index 947792bb..fc21d551 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -112,8 +112,8 @@ namespace leaf_detail char const * (*first_type)(); int count; - BOOST_LEAF_CONSTEXPR explicit e_unexpected_count(char const * (*first_type)()) noexcept: - first_type(first_type), + BOOST_LEAF_CONSTEXPR explicit e_unexpected_count(char const * (*ft)()) noexcept: + first_type(ft), count(1) { } @@ -261,6 +261,9 @@ namespace leaf_detail diagnostic::print(os, value(k)); (os << '\n').flush(); } +#else + (void) os; + (void) key_to_print; #endif } @@ -314,7 +317,7 @@ namespace leaf_detail #if BOOST_LEAF_CFG_DIAGNOSTICS else { - int c = tls::read_uint32(); + int c = int(tls::read_uint()); BOOST_LEAF_ASSERT(c>=0); if( c ) load_unexpected(err_id, std::move(*this).value(err_id)); @@ -334,7 +337,7 @@ namespace leaf_detail #if BOOST_LEAF_CFG_DIAGNOSTICS else { - int c = tls::read_uint32(); + int c = int(tls::read_uint()); BOOST_LEAF_ASSERT(c>=0); if( c ) load_unexpected(err_id, std::forward(e)); @@ -379,20 +382,20 @@ namespace leaf_detail }; template - atomic_unsigned_int id_factory::counter(-3); + atomic_unsigned_int id_factory::counter(unsigned(-3)); inline int current_id() noexcept { - auto id = tls::read_uint32(); + unsigned id = tls::read_uint(); BOOST_LEAF_ASSERT(id==0 || (id&3)==1); - return id; + return int(id); } inline int new_id() noexcept { - auto id = id_factory<>::generate_next_id(); - tls::write_uint32(id); - return id; + unsigned id = id_factory<>::generate_next_id(); + tls::write_uint(id); + return int(id); } } @@ -444,7 +447,7 @@ namespace leaf_detail bool equivalent( int, std::error_condition const & ) const noexcept final override { return false; } bool equivalent( std::error_code const &, int ) const noexcept final override { return false; } char const * name() const noexcept final override { return "LEAF error"; } - std::string message( int condition ) const final override { return name(); } + std::string message( int ) const final override { return name(); } public: ~leaf_category() noexcept final override { } }; diff --git a/include/boost/leaf/exception.hpp b/include/boost/leaf/exception.hpp index dc2ea564..e28ba27f 100644 --- a/include/boost/leaf/exception.hpp +++ b/include/boost/leaf/exception.hpp @@ -227,7 +227,7 @@ class result; namespace leaf_detail { - inline error_id catch_exceptions_helper( std::exception const & ex, leaf_detail_mp11::mp_list<> ) + inline error_id catch_exceptions_helper( std::exception const &, leaf_detail_mp11::mp_list<> ) { return leaf::new_error(std::current_exception()); } diff --git a/include/boost/leaf/handle_errors.hpp b/include/boost/leaf/handle_errors.hpp index 4410fc77..68453f3f 100644 --- a/include/boost/leaf/handle_errors.hpp +++ b/include/boost/leaf/handle_errors.hpp @@ -197,7 +197,7 @@ namespace leaf_detail struct handler_argument_traits: handler_argument_always_available { template - BOOST_LEAF_CONSTEXPR static diagnostic_info_ get( Tup const & tup, error_info const & ei ) noexcept + BOOST_LEAF_CONSTEXPR static diagnostic_info_ get( Tup const &, error_info const & ei ) noexcept { return diagnostic_info_(ei); } @@ -307,7 +307,7 @@ namespace leaf_detail struct handler_argument_traits: handler_argument_always_available { template - BOOST_LEAF_CONSTEXPR static verbose_diagnostic_info_ get( Tup const & tup, error_info const & ei ) noexcept + BOOST_LEAF_CONSTEXPR static verbose_diagnostic_info_ get( Tup const &, error_info const & ei ) noexcept { return verbose_diagnostic_info_(ei); } @@ -932,7 +932,7 @@ namespace leaf_detail constexpr static bool always_available = false; template - BOOST_LEAF_CONSTEXPR static T * check( Tup & tup, error_info const & ei ) noexcept + BOOST_LEAF_CONSTEXPR static T * check( Tup &, error_info const & ei ) noexcept { using boost_exception = dependent_type_t; if( auto * be = get_exception(ei) ) diff --git a/include/boost/leaf/on_error.hpp b/include/boost/leaf/on_error.hpp index c41d7fc5..cd471829 100644 --- a/include/boost/leaf/on_error.hpp +++ b/include/boost/leaf/on_error.hpp @@ -114,7 +114,7 @@ namespace leaf_detail #if BOOST_LEAF_CFG_DIAGNOSTICS else { - int c = tls::read_uint32(); + int c = int(tls::read_uint()); BOOST_LEAF_ASSERT(c>=0); if( c ) load_unexpected(err_id, std::move(e_)); @@ -149,7 +149,7 @@ namespace leaf_detail #if BOOST_LEAF_CFG_DIAGNOSTICS else { - int c = tls::read_uint32(); + int c = int(tls::read_uint()); BOOST_LEAF_ASSERT(c>=0); if( c ) load_unexpected(err_id, std::forward(f_())); diff --git a/include/boost/leaf/result.hpp b/include/boost/leaf/result.hpp index cd983f4b..cb813014 100644 --- a/include/boost/leaf/result.hpp +++ b/include/boost/leaf/result.hpp @@ -95,7 +95,7 @@ namespace leaf_detail }; explicit result_discriminant( error_id id ) noexcept: - state_(id.value()) + state_(unsigned(id.value())) { BOOST_LEAF_ASSERT(state_==0 || (state_&3)==1); } @@ -122,7 +122,7 @@ namespace leaf_detail error_id get_error_id() const noexcept { BOOST_LEAF_ASSERT(kind()==no_error || kind()==err_id); - return make_error_id(state_); + return make_error_id(int(state_)); } }; } @@ -178,7 +178,7 @@ class result #if BOOST_LEAF_CFG_CAPTURE { error_id captured_id = r_.ctx_->propagate_captured_errors(); - tls::write_uint32(captured_id.value()); + tls::write_uint(unsigned(captured_id.value())); return captured_id; } #else diff --git a/meson.build b/meson.build index 0ac746f5..2b4ff64b 100644 --- a/meson.build +++ b/meson.build @@ -43,6 +43,10 @@ if not meson.is_subproject() '-Wno-dangling-else', '-Wno-non-virtual-dtor', '-Wno-delete-non-abstract-non-virtual-dtor', +# '-Wshadow-all', +# '-Wsign-conversion', +# '-Wextra', +# '-Werror', language:'cpp' ) elif compiler_id=='gcc' if get_option('buildtype')!='debug' diff --git a/test/BOOST_LEAF_ASSIGN_test.cpp b/test/BOOST_LEAF_ASSIGN_test.cpp index 2724636b..3ba9ae30 100644 --- a/test/BOOST_LEAF_ASSIGN_test.cpp +++ b/test/BOOST_LEAF_ASSIGN_test.cpp @@ -23,7 +23,7 @@ struct value { int x; - explicit value( int x ): x(x) { }; + explicit value( int x_ ): x(x_) { }; #ifndef BOOST_LEAF_NO_CXX11_REF_QUALIFIERS value( value const & ) = delete; diff --git a/test/BOOST_LEAF_AUTO_test.cpp b/test/BOOST_LEAF_AUTO_test.cpp index 5a53e7fa..debcf50f 100644 --- a/test/BOOST_LEAF_AUTO_test.cpp +++ b/test/BOOST_LEAF_AUTO_test.cpp @@ -23,7 +23,7 @@ struct value { int x; - explicit value( int x ): x(x) { }; + explicit value( int x_ ): x(x_) { }; #ifndef BOOST_LEAF_NO_CXX11_REF_QUALIFIERS value( value const & ) = delete; diff --git a/test/BOOST_LEAF_CHECK_test.cpp b/test/BOOST_LEAF_CHECK_test.cpp index 52510e15..d50186f6 100644 --- a/test/BOOST_LEAF_CHECK_test.cpp +++ b/test/BOOST_LEAF_CHECK_test.cpp @@ -24,7 +24,7 @@ struct value { int x; - explicit value( int x ): x(x) { }; + explicit value( int x_ ): x(x_) { }; #ifndef BOOST_LEAF_NO_CXX11_REF_QUALIFIERS value( value const & ) = delete; diff --git a/test/accumulate_nested_new_error_exception_test.cpp b/test/accumulate_nested_new_error_exception_test.cpp index 7486e8e7..322e9b08 100644 --- a/test/accumulate_nested_new_error_exception_test.cpp +++ b/test/accumulate_nested_new_error_exception_test.cpp @@ -43,7 +43,7 @@ void f0() void f1() { - auto load = leaf::on_error( []( info<0> & x ) { }, []( info<1> & x ) { ++x.value; }, []( info<2> & x ) { ++x.value; } ); + auto load = leaf::on_error( []( info<0> & ) { }, []( info<1> & x ) { ++x.value; }, []( info<2> & x ) { ++x.value; } ); try { f0(); } catch(...) { } leaf::throw_exception(); } diff --git a/test/accumulate_nested_new_error_result_test.cpp b/test/accumulate_nested_new_error_result_test.cpp index 59c8cef3..a13a9a94 100644 --- a/test/accumulate_nested_new_error_result_test.cpp +++ b/test/accumulate_nested_new_error_result_test.cpp @@ -29,7 +29,7 @@ leaf::error_id f0() leaf::error_id f1() { - auto load = leaf::on_error( []( info<0> & x ) { }, []( info<1> & x ) { ++x.value; }, []( info<2> & x ) { ++x.value; } ); + auto load = leaf::on_error( []( info<0> & ) { }, []( info<1> & x ) { ++x.value; }, []( info<2> & x ) { ++x.value; } ); (void) f0(); return leaf::new_error(); } diff --git a/test/capture_exception_unload_test.cpp b/test/capture_exception_unload_test.cpp index 8bb548c6..304318e7 100644 --- a/test/capture_exception_unload_test.cpp +++ b/test/capture_exception_unload_test.cpp @@ -139,7 +139,7 @@ void test( F f_ ) { std::rethrow_exception(ep); return true; }, - []( info<1> const & x, info<2> const & ) + []( info<1> const &, info<2> const & ) { return true; }, @@ -149,7 +149,7 @@ void test( F f_ ) BOOST_TEST_EQ(y.value, 3); return false; }, - []( info<1> const & x ) + []( info<1> const & ) { return true; }, @@ -167,7 +167,7 @@ void test( F f_ ) { std::rethrow_exception(ep); return false; }, - []( info<1> const & x, info<2> const & ) + []( info<1> const &, info<2> const & ) { return false; }, @@ -177,7 +177,7 @@ void test( F f_ ) BOOST_TEST_EQ(y.value, 3); return true; }, - []( info<1> const & x ) + []( info<1> const & ) { return false; }, diff --git a/test/capture_result_async_test.cpp b/test/capture_result_async_test.cpp index c6166dc5..a11e4c8a 100644 --- a/test/capture_result_async_test.cpp +++ b/test/capture_result_async_test.cpp @@ -68,7 +68,7 @@ int main() { int received_a, received_b; auto error_handlers = std::make_tuple( - [&received_a, &received_b]( info<1> const & x1, info<2> const & x2, info<4> const & x4 ) + [&received_a, &received_b]( info<1> const & x1, info<2> const & x2, info<4> const & ) { received_a = x1.value; received_b = x2.value; diff --git a/test/context_activator_test.cpp b/test/context_activator_test.cpp index 5639c067..4289821c 100644 --- a/test/context_activator_test.cpp +++ b/test/context_activator_test.cpp @@ -45,13 +45,13 @@ int main() [&] { auto ctx = leaf::make_context(error_handlers); - leaf::result r; + leaf::result r1; { auto active_context = activate_context(ctx); - r = f(ctx); + r1 = f(ctx); } - ctx.propagate(r.error()); - return r; + ctx.propagate(r1.error()); + return r1; }, error_handlers ); BOOST_TEST_EQ(r, 1); diff --git a/test/diagnostic_info_test.cpp b/test/diagnostic_info_test.cpp index cbc9afe0..29ccd922 100644 --- a/test/diagnostic_info_test.cpp +++ b/test/diagnostic_info_test.cpp @@ -39,7 +39,7 @@ struct my_exception: struct printable_payload { - friend std::ostream & operator<<( std::ostream & os, printable_payload const & x ) + friend std::ostream & operator<<( std::ostream & os, printable_payload const & ) { return os << "printed printable_payload"; } @@ -63,7 +63,7 @@ struct printable_info_non_printable_payload { non_printable_payload value; - friend std::ostream & operator<<( std::ostream & os, printable_info_non_printable_payload const & x ) + friend std::ostream & operator<<( std::ostream & os, printable_info_non_printable_payload const & ) { return os << "*** printable_info_non_printable_payload ***"; } diff --git a/test/diagnostic_info_test2.cpp b/test/diagnostic_info_test2.cpp index ef50ee56..7f36b87a 100644 --- a/test/diagnostic_info_test2.cpp +++ b/test/diagnostic_info_test2.cpp @@ -19,7 +19,7 @@ namespace leaf = boost::leaf; template struct info { - friend std::ostream & operator<<( std::ostream & os, info const & x ) + friend std::ostream & operator<<( std::ostream & os, info const & ) { return os << "printed info<" << I << '>'; } diff --git a/test/exception_test.cpp b/test/exception_test.cpp index 91f912ec..8a60e4de 100644 --- a/test/exception_test.cpp +++ b/test/exception_test.cpp @@ -43,7 +43,7 @@ struct my_exception: abstract_base_exception { int val;; - explicit my_exception(int val): val{val} { } + explicit my_exception(int v): val{v} { } int get_val() const { return val; } }; @@ -82,7 +82,7 @@ int test( F && f ) BOOST_TEST_EQ(get_val(ex), 42); return 20; }, - []( Ex ex, leaf::match_value, info x ) + []( Ex ex, leaf::match_value, info ) { BOOST_TEST_EQ(get_val(ex), 42); return 21; @@ -101,7 +101,7 @@ int test( F && f ) { return 40; }, - []( leaf::match_value, info x ) + []( leaf::match_value, info ) { return 41; }, @@ -278,7 +278,7 @@ int main() { throw std::exception(); }, - []( info x ) + []( info ) { return -1; }, diff --git a/test/handle_all_other_result_test.cpp b/test/handle_all_other_result_test.cpp index 5520dc25..8a0f5929 100644 --- a/test/handle_all_other_result_test.cpp +++ b/test/handle_all_other_result_test.cpp @@ -67,12 +67,12 @@ void test() int r = leaf::try_handle_all( [&] { - auto r = g(false); - BOOST_TEST(!r); - auto ec = r.error(); + auto r1 = g(false); + BOOST_TEST(!r1); + auto ec = r1.error(); BOOST_TEST_EQ(ec.message(), "LEAF error"); BOOST_TEST(!std::strcmp(ec.category().name(),"LEAF error")); - return r; + return r1; }, []( info<42> const & x, std::error_code const & ec ) { diff --git a/test/handle_all_test.cpp b/test/handle_all_test.cpp index 53d6c54d..57f02218 100644 --- a/test/handle_all_test.cpp +++ b/test/handle_all_test.cpp @@ -57,7 +57,7 @@ leaf::result f_errc_wrapped( Errc ec ) struct move_only { - explicit move_only( int value ): value(value) { } + explicit move_only( int val ): value(val) { } int value; #ifndef BOOST_LEAF_NO_CXX11_REF_QUALIFIERS diff --git a/test/handle_basic_test.cpp b/test/handle_basic_test.cpp index 053c6f0b..c9bdaf7c 100644 --- a/test/handle_basic_test.cpp +++ b/test/handle_basic_test.cpp @@ -275,7 +275,7 @@ int main() []( info<1> const & i1 ) { BOOST_TEST_EQ(i1.value, 42); - int r = leaf::try_handle_all( + int r1 = leaf::try_handle_all( []() -> leaf::result { return leaf::new_error( info<1>{43} ); @@ -284,7 +284,7 @@ int main() { return -1; } ); - BOOST_TEST_EQ(r, -1); + BOOST_TEST_EQ(r1, -1); BOOST_TEST_EQ(i1.value, 42); return 0; }, @@ -306,21 +306,21 @@ int main() []( info<1> const & i1 ) { BOOST_TEST_EQ(i1.value, 42); - int r = leaf::try_handle_all( + int r1 = leaf::try_handle_all( []() -> leaf::result { return leaf::new_error( info<1>{43} ); }, - []( info<1> const & i1 ) + []( info<1> const & i1_ ) { - BOOST_TEST_EQ(i1.value, 43); + BOOST_TEST_EQ(i1_.value, 43); return -1; }, []() { return -2; } ); - BOOST_TEST_EQ(r, -1); + BOOST_TEST_EQ(r1, -1); BOOST_TEST_EQ(i1.value, 42); return 0; }, diff --git a/test/handle_some_other_result_test.cpp b/test/handle_some_other_result_test.cpp index d42e0292..6a6a78c5 100644 --- a/test/handle_some_other_result_test.cpp +++ b/test/handle_some_other_result_test.cpp @@ -66,12 +66,12 @@ void test() ResType r = leaf::try_handle_some( [&] { - auto r = g(false); - BOOST_TEST(!r); - auto ec = r.error(); + auto r1 = g(false); + BOOST_TEST(!r1); + auto ec = r1.error(); BOOST_TEST_EQ(ec.message(), "LEAF error"); BOOST_TEST(!std::strcmp(ec.category().name(),"LEAF error")); - return r; + return r1; }, [&]( info<42> const & x, leaf::match, cond_x::x00> ec ) { diff --git a/test/handle_some_test.cpp b/test/handle_some_test.cpp index 4801f16a..195d24cf 100644 --- a/test/handle_some_test.cpp +++ b/test/handle_some_test.cpp @@ -953,7 +953,7 @@ int main() int r = leaf::try_handle_all( [] { - leaf::result r = leaf::try_handle_some( + leaf::result r1 = leaf::try_handle_some( []() -> leaf::result { BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); @@ -963,8 +963,8 @@ int main() { return 1; } ); - BOOST_TEST(!r); - return r; + BOOST_TEST(!r1); + return r1; }, []( my_error_code ec, info<1> const & x, info<2> y ) { @@ -986,7 +986,7 @@ int main() int r = leaf::try_handle_all( [] { - leaf::result r = leaf::try_handle_some( + leaf::result r1 = leaf::try_handle_some( []() -> leaf::result { BOOST_LEAF_AUTO(answer, f_errc(errc_a::a0)); @@ -996,8 +996,8 @@ int main() { return 1; } ); - BOOST_TEST(!r); - return r; + BOOST_TEST(!r1); + return r1; }, []( leaf::match, cond_x::x00> ec, info<1> const & x, info<2> y ) { @@ -1019,7 +1019,7 @@ int main() int r = leaf::try_handle_all( [] { - leaf::result r = leaf::try_handle_some( + leaf::result r1 = leaf::try_handle_some( []() -> leaf::result { BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); @@ -1029,8 +1029,8 @@ int main() { return 1; } ); - BOOST_TEST(!r); - return r; + BOOST_TEST(!r1); + return r1; }, []( leaf::match ec, info<1> const & x, info<2> y ) { @@ -1051,7 +1051,7 @@ int main() int r = leaf::try_handle_all( [] { - leaf::result r = leaf::try_handle_some( + leaf::result r1 = leaf::try_handle_some( []() -> leaf::result { BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); @@ -1061,8 +1061,8 @@ int main() { return 1; } ); - BOOST_TEST(!r); - return r; + BOOST_TEST(!r1); + return r1; }, []( leaf::match ec, info<1> const & x, info<2> y ) { @@ -1083,7 +1083,7 @@ int main() int r = leaf::try_handle_all( [] { - leaf::result r = leaf::try_handle_some( + leaf::result r1 = leaf::try_handle_some( []() -> leaf::result { BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); @@ -1093,8 +1093,8 @@ int main() { return 1; } ); - BOOST_TEST(!r); - return r; + BOOST_TEST(!r1); + return r1; }, []( leaf::match_value ec, info<1> const & x, info<2> y ) { @@ -1115,7 +1115,7 @@ int main() int r = leaf::try_handle_all( [] { - leaf::result r = leaf::try_handle_some( + leaf::result r1 = leaf::try_handle_some( []() -> leaf::result { BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); @@ -1125,8 +1125,8 @@ int main() { return 1; } ); - BOOST_TEST(!r); - return r; + BOOST_TEST(!r1); + return r1; }, []( leaf::match_value ec, info<1> const & x, info<2> y ) { @@ -1147,7 +1147,7 @@ int main() int r = leaf::try_handle_all( [] { - leaf::result r = leaf::try_handle_some( + leaf::result r1 = leaf::try_handle_some( []() -> leaf::result { BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); @@ -1160,8 +1160,8 @@ int main() BOOST_TEST_EQ(y.value, 2); return 1; } ); - BOOST_TEST(r); - return r; + BOOST_TEST(r1); + return r1; }, []( info<4> ) { @@ -1179,7 +1179,7 @@ int main() int r = leaf::try_handle_all( [] { - leaf::result r = leaf::try_handle_some( + leaf::result r1 = leaf::try_handle_some( []() -> leaf::result { BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); @@ -1192,8 +1192,8 @@ int main() BOOST_TEST_EQ(y.value, 2); return 1; } ); - BOOST_TEST(r); - return r; + BOOST_TEST(r1); + return r1; }, []( leaf::match ) { @@ -1211,7 +1211,7 @@ int main() int r = leaf::try_handle_all( [] { - leaf::result r = leaf::try_handle_some( + leaf::result r1 = leaf::try_handle_some( []() -> leaf::result { BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); @@ -1224,8 +1224,8 @@ int main() BOOST_TEST_EQ(y.value, 2); return 1; } ); - BOOST_TEST(r); - return r; + BOOST_TEST(r1); + return r1; }, []( leaf::match ) { @@ -1243,7 +1243,7 @@ int main() int r = leaf::try_handle_all( [] { - leaf::result r = leaf::try_handle_some( + leaf::result r1 = leaf::try_handle_some( []() -> leaf::result { BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); @@ -1256,8 +1256,8 @@ int main() BOOST_TEST_EQ(y.value, 2); return 1; } ); - BOOST_TEST(r); - return r; + BOOST_TEST(r1); + return r1; }, []( leaf::match_value ) { @@ -1275,7 +1275,7 @@ int main() int r = leaf::try_handle_all( [] { - leaf::result r = leaf::try_handle_some( + leaf::result r1 = leaf::try_handle_some( []() -> leaf::result { BOOST_LEAF_AUTO(answer, f(my_error_code::error1)); @@ -1288,8 +1288,8 @@ int main() BOOST_TEST_EQ(y.value, 2); return 1; } ); - BOOST_TEST(r); - return r; + BOOST_TEST(r1); + return r1; }, []( leaf::match_value ) { diff --git a/test/match_test.cpp b/test/match_test.cpp index 3592d982..2aed5f8c 100644 --- a/test/match_test.cpp +++ b/test/match_test.cpp @@ -164,7 +164,7 @@ int main() return 1; }, - []( my_error e ) + []( my_error ) { return 2; }, @@ -188,7 +188,7 @@ int main() return 1; }, - []( my_error e ) + []( my_error ) { return 2; }, @@ -246,7 +246,7 @@ int main() return leaf::new_error(e_my_error{42}); }, - []( leaf::match> m ) + []( leaf::match> ) { return 1; }, @@ -265,7 +265,7 @@ int main() return leaf::new_error(e_my_error{42}); }, - []( leaf::match> m ) + []( leaf::match> ) { return 1; }, diff --git a/test/optional_test.cpp b/test/optional_test.cpp index f3178c86..6661f71a 100644 --- a/test/optional_test.cpp +++ b/test/optional_test.cpp @@ -24,8 +24,8 @@ class my_info int value; - explicit my_info( int value ): - value(value) + explicit my_info( int val ): + value(val) { BOOST_TEST(++object_count>0); BOOST_TEST(++value_count>0); diff --git a/test/result_bad_result_test.cpp b/test/result_bad_result_test.cpp index 519c61ca..ed6bbedb 100644 --- a/test/result_bad_result_test.cpp +++ b/test/result_bad_result_test.cpp @@ -49,8 +49,8 @@ int main() int r = leaf::try_catch( [] { - leaf::result r = leaf::new_error(e_test{42}); - (void) r.value(); + leaf::result r1 = leaf::new_error(e_test{42}); + (void) r1.value(); return 0; }, check ); @@ -61,8 +61,8 @@ int main() int r = leaf::try_catch( [] { - leaf::result const r = leaf::new_error(e_test{42}); - (void) r.value(); + leaf::result const r1 = leaf::new_error(e_test{42}); + (void) r1.value(); return 0; }, check ); @@ -70,21 +70,21 @@ int main() } #endif { - leaf::result r = leaf::new_error(e_test{42}); - BOOST_TEST(r.operator->()==0); + leaf::result r1 = leaf::new_error(e_test{42}); + BOOST_TEST(r1.operator->()==0); } #if !BOOST_WORKAROUND( BOOST_GCC, < 50000 ) { - leaf::result const r = leaf::new_error(e_test{42}); - BOOST_TEST(r.operator->()==0); + leaf::result const r1 = leaf::new_error(e_test{42}); + BOOST_TEST(r1.operator->()==0); } #endif { int r = leaf::try_catch( [] { - leaf::result r = leaf::new_error(e_test{42}); - (void) r.value(); + leaf::result r1 = leaf::new_error(e_test{42}); + (void) r1.value(); return 0; }, check ); @@ -95,8 +95,8 @@ int main() int r = leaf::try_catch( [] { - leaf::result const r = leaf::new_error(e_test{42}); - (void) r.value(); + leaf::result const r1 = leaf::new_error(e_test{42}); + (void) r1.value(); return 0; }, check ); diff --git a/test/result_implicit_conversion_test.cpp b/test/result_implicit_conversion_test.cpp index 7ba7077c..b2ae9694 100644 --- a/test/result_implicit_conversion_test.cpp +++ b/test/result_implicit_conversion_test.cpp @@ -21,8 +21,8 @@ struct A { } - A( int x ) noexcept: - x(x) + A( int x_ ) noexcept: + x(x_) { } }; diff --git a/test/try_catch_error_id_test.cpp b/test/try_catch_error_id_test.cpp index 27141594..1d2bbf87 100644 --- a/test/try_catch_error_id_test.cpp +++ b/test/try_catch_error_id_test.cpp @@ -40,7 +40,7 @@ int main() { leaf::throw_exception( my_error(), info{42} ); }, - []( my_error const & x, leaf::catch_ id ) + []( my_error const &, leaf::catch_ id ) { BOOST_TEST(dynamic_cast(&id.matched)!=0 && dynamic_cast(&id.matched)->value()==1); return 1; diff --git a/test/try_catch_test.cpp b/test/try_catch_test.cpp index 2e3b2428..2ffe4285 100644 --- a/test/try_catch_test.cpp +++ b/test/try_catch_test.cpp @@ -427,7 +427,7 @@ int main() int r = leaf::try_catch( [] { - int r = leaf::try_catch( + int r1 = leaf::try_catch( [] { return failing(error1()); @@ -437,7 +437,7 @@ int main() return 1; } ); BOOST_TEST(false); - return r; + return r1; }, []( error1 const &, info<1> const & x, info<2> y ) { @@ -457,7 +457,7 @@ int main() int r = leaf::try_catch( [] { - int r = leaf::try_catch( + int r1 = leaf::try_catch( [] { return failing(error1()); @@ -467,7 +467,7 @@ int main() return 1; } ); BOOST_TEST(false); - return r; + return r1; }, []( leaf::catch_, info<1> const & x, info<2> y ) { @@ -487,7 +487,7 @@ int main() int r = leaf::try_catch( [] { - int r = leaf::try_catch( + int r1 = leaf::try_catch( [] { return failing(error1()); @@ -498,8 +498,8 @@ int main() BOOST_TEST_EQ(y.value, 2); return 1; } ); - BOOST_TEST_EQ(r, 1); - return r; + BOOST_TEST_EQ(r1, 1); + return r1; }, []( error1 const & ) { @@ -517,7 +517,7 @@ int main() int r = leaf::try_catch( [] { - int r = leaf::try_catch( + int r1 = leaf::try_catch( [] { return failing(error1()); @@ -528,8 +528,8 @@ int main() BOOST_TEST_EQ(y.value, 2); return 1; } ); - BOOST_TEST_EQ(r, 1); - return r; + BOOST_TEST_EQ(r1, 1); + return r1; }, []( error1 const & ) { From 538340ddf94f5b82cd6702964380809ad66affef Mon Sep 17 00:00:00 2001 From: Khalil Estell Date: Thu, 8 Sep 2022 06:28:51 -0700 Subject: [PATCH 007/103] Set conan veresion to 1.81.0-prerelease This version is the prerelease version of the offical 1.81.0 boost versino. In semver, version with tags have lower precedence over unlabled versions. To use this version in a conanfile the version range will have to look like this: boost-leaf/[>1.80.0, include_prerelease=True] or to simply get the latest boost-leaf/[x, include_prerelease=True] --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index c942e37f..9f2cdd7b 100644 --- a/conanfile.py +++ b/conanfile.py @@ -11,7 +11,7 @@ class BoostLEAFConan(ConanFile): name = "boost-leaf" - version = "0.4.0" + version = "1.81.0-prerelease" license = "BSL-1.0" url = "https://github.com/conan-io/conan-center-index" homepage = "https://github.com/boostorg/leaf" From 216393895f679907d0bd834e38c56dd121036303 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sat, 15 Oct 2022 17:57:21 -0700 Subject: [PATCH 008/103] Documentation update --- doc/leaf.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/leaf.adoc b/doc/leaf.adoc index 15872cce..5e066417 100644 --- a/doc/leaf.adoc +++ b/doc/leaf.adoc @@ -229,7 +229,7 @@ leaf::result r = leaf::try_handle_some( []( leaf::match ) -> leaf::result { - // Handle err::e1 + // Handle err::e1 or err1::e3 }, []( err1 e ) -> leaf::result @@ -432,7 +432,7 @@ leaf::result r = leaf::try_handle_some( An error handler is never dropped for lack of error objects of types which the handler takes as pointers; in this case LEAF simply passes `0` for these arguments. -TIP: Error handlers can take arguments by value, by const reference or pointer, and by mutable reference or pointer. It the latter case, changes to the error object state will be propagated up the call stack if the failure is not handled. +TIP: Error handlers can take arguments by value, by (`const`) reference or as a (`const`) pointer. It the latter case, changes to the error object state will be propagated up the call stack if the failure is not handled. [[tutorial-augmenting_errors]] === Augmenting Errors From 5dcf6054125b4b1ce0489f8caa8e97e2c4607fd4 Mon Sep 17 00:00:00 2001 From: Khalil Estell Date: Fri, 9 Sep 2022 17:44:54 -0700 Subject: [PATCH 009/103] [conan] Fix imports and license path - Bump version to 1.81.0 - Import fix is simply a cleanup step that has no impact on the conanfile as the import was not used - License path was incorrect meaning that the package was previously not included the local conan package cache. --- conanfile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conanfile.py b/conanfile.py index 9f2cdd7b..641a70c5 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,5 +1,5 @@ from conan import ConanFile -from conan.tools.files import get, copy +from conan.tools.files import copy from conan.tools.layout import basic_layout from conan.tools.build import check_min_cppstd from conan.errors import ConanInvalidConfiguration @@ -11,7 +11,7 @@ class BoostLEAFConan(ConanFile): name = "boost-leaf" - version = "1.81.0-prerelease" + version = "1.81.0" license = "BSL-1.0" url = "https://github.com/conan-io/conan-center-index" homepage = "https://github.com/boostorg/leaf" @@ -64,7 +64,7 @@ def layout(self): basic_layout(self) def package(self): - copy(self, "LICENSE", dst=os.path.join( + copy(self, "LICENSE_1_0.txt", dst=os.path.join( self.package_folder, "licenses"), src=self.source_folder) copy(self, "*.h", dst=os.path.join(self.package_folder, "include"), src=os.path.join(self.source_folder, "include")) From 2e72c5cf6b19cc4234b590e831724486721408e3 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Thu, 2 Mar 2023 16:19:13 -0800 Subject: [PATCH 010/103] GHA & Drone updates --- .drone.jsonnet | 242 ++++++++++++++++++++ .drone.star | 55 ----- .drone/drone.bat | 28 +++ .drone/drone.sh | 43 ++-- .github/workflows/ci.yml | 131 ++++++++--- .travis.yml | 422 ----------------------------------- appveyor.yml | 44 ---- include/boost/leaf/error.hpp | 8 +- 8 files changed, 387 insertions(+), 586 deletions(-) create mode 100644 .drone.jsonnet delete mode 100644 .drone.star create mode 100644 .drone/drone.bat delete mode 100644 .travis.yml delete mode 100644 appveyor.yml diff --git a/.drone.jsonnet b/.drone.jsonnet new file mode 100644 index 00000000..f475c163 --- /dev/null +++ b/.drone.jsonnet @@ -0,0 +1,242 @@ +# Copyright 2022 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +local library = "leaf"; + +local triggers = +{ + branch: [ "master", "develop", "feature/*" ] +}; + +local ubsan = { UBSAN: '1', UBSAN_OPTIONS: 'print_stacktrace=1' }; +local asan = { ASAN: '1' }; + +local linux_pipeline(name, image, environment, packages = "", sources = [], arch = "amd64") = +{ + name: name, + kind: "pipeline", + type: "docker", + trigger: triggers, + platform: + { + os: "linux", + arch: arch + }, + steps: + [ + { + name: "everything", + image: image, + environment: environment, + commands: + [ + 'set -e', + 'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -', + ] + + (if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) + + (if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) + + [ + 'export LIBRARY=' + library, + './.drone/drone.sh', + ] + } + ] +}; + +local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") = +{ + name: name, + kind: "pipeline", + type: "exec", + trigger: triggers, + platform: { + "os": "darwin", + "arch": arch + }, + node: { + "os": osx_version + }, + steps: [ + { + name: "everything", + environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" }, + commands: + [ + 'export LIBRARY=' + library, + './.drone/drone.sh', + ] + } + ] +}; + +local windows_pipeline(name, image, environment, arch = "amd64") = +{ + name: name, + kind: "pipeline", + type: "docker", + trigger: triggers, + platform: + { + os: "windows", + arch: arch + }, + "steps": + [ + { + name: "everything", + image: image, + environment: environment, + commands: + [ + 'cmd /C .drone\\\\drone.bat ' + library, + ] + } + ] +}; + +[ + linux_pipeline( + "Linux 14.04 GCC 4.9", + "cppalliance/droneubuntu1404:1", + { TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '11' }, + "g++-4.9", + [ "ppa:ubuntu-toolchain-r/test" ], + ), + + linux_pipeline( + "Linux 16.04 GCC 5*", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14' }, + ), + + linux_pipeline( + "Linux 18.04 GCC 6", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'gcc', COMPILER: 'g++-6', CXXSTD: '11,14' }, + "g++-6", + ), + + linux_pipeline( + "Linux 18.04 GCC 7* 32", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14', ADDRMD: '32' }, + ), + + linux_pipeline( + "Linux 18.04 GCC 7* 64", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14', ADDRMD: '64' }, + ), + + linux_pipeline( + "Linux 18.04 GCC 8", + "cppalliance/droneubuntu1804:1", + { TOOLSET: 'gcc', COMPILER: 'g++-8', CXXSTD: '11,14,17' }, + "g++-8", + ), + + linux_pipeline( + "Linux 20.04 GCC 9* 32", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '32' }, + ), + + linux_pipeline( + "Linux 20.04 GCC 9* 64", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '64' }, + ), + + linux_pipeline( + "Linux 20.04 GCC 9 ARM64 32/64", + "cppalliance/droneubuntu2004:multiarch", + { TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '11,14,17,2a', ADDRMD: '32,64' }, + arch="arm64", + ), + + linux_pipeline( + "Linux 20.04 GCC 10 32 ASAN", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '11,14,17,20', ADDRMD: '32' } + asan, + "g++-10-multilib", + ), + + linux_pipeline( + "Linux 20.04 GCC 10 64 ASAN", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'gcc', COMPILER: 'g++-10', CXXSTD: '11,14,17,20', ADDRMD: '64' } + asan, + "g++-10-multilib", + ), + + linux_pipeline( + "Linux 16.04 Clang 3.6", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'clang', COMPILER: 'clang++-3.6', CXXSTD: '11,14' }, + "clang-3.6", + ), + + linux_pipeline( + "Linux 16.04 Clang 3.7", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'clang', COMPILER: 'clang++-3.7', CXXSTD: '11,14' }, + "clang-3.7", + ), + + linux_pipeline( + "Linux 16.04 Clang 3.8", + "cppalliance/droneubuntu1604:1", + { TOOLSET: 'clang', COMPILER: 'clang++-3.8', CXXSTD: '11,14' }, + "clang-3.8", + ), + + linux_pipeline( + "Linux 20.04 Clang 13", + "cppalliance/droneubuntu2004:1", + { TOOLSET: 'clang', COMPILER: 'clang++-13', CXXSTD: '11,14,17,20' }, + "clang-13", + ["deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main"], + ), + + linux_pipeline( + "Linux 22.04 Clang 14 UBSAN", + "cppalliance/droneubuntu2204:1", + { TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '11,14,17,20' } + ubsan, + "clang-14", + ), + + linux_pipeline( + "Linux 22.04 Clang 14 ASAN", + "cppalliance/droneubuntu2204:1", + { TOOLSET: 'clang', COMPILER: 'clang++-14', CXXSTD: '11,14,17,20' } + asan, + "clang-14", + ), + + macos_pipeline( + "MacOS 10.15 Xcode 12.2 UBSAN", + { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + ubsan, + ), + + macos_pipeline( + "MacOS 10.15 Xcode 12.2 ASAN", + { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + asan, + ), + + windows_pipeline( + "Windows VS2017 msvc-14.1", + "cppalliance/dronevs2017", + { TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' }, + ), + + windows_pipeline( + "Windows VS2019 msvc-14.2", + "cppalliance/dronevs2019", + { TOOLSET: 'msvc-14.2', CXXSTD: '14,17,20,latest' }, + ), + + windows_pipeline( + "Windows VS2022 msvc-14.3", + "cppalliance/dronevs2022:1", + { TOOLSET: 'msvc-14.3', CXXSTD: '14,17,20,latest' }, + ), +] diff --git a/.drone.star b/.drone.star deleted file mode 100644 index 2d1b15aa..00000000 --- a/.drone.star +++ /dev/null @@ -1,55 +0,0 @@ -# Use, modification, and distribution are -# subject to the Boost Software License, Version 1.0. (See accompanying -# file LICENSE.txt) -# -# Copyright Rene Rivera 2020. - -# For Drone CI we use the Starlark scripting language to reduce duplication. -# As the yaml syntax for Drone CI is rather limited. -# -# -globalenv={} -linuxglobalimage="cppalliance/droneubuntu1404:1" -windowsglobalimage="cppalliance/dronevs2019" - -def main(ctx): - return [ - osx_cxx("UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD Job 1", "clang++", packages="", buildtype="boost", buildscript="drone", environment={'UBSAN': '1', 'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11,14', 'UBSAN_OPTIONS': 'print_stacktrace=1', 'DRONE_JOB_UUID': '356a192b79'}, globalenv=globalenv), - osx_cxx("UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD Job 2", "clang++", packages="", buildtype="boost", buildscript="drone", environment={'UBSAN': '1', 'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '1z,2a', 'UBSAN_OPTIONS': 'print_stacktrace=1', 'DRONE_JOB_UUID': 'da4b9237ba'}, globalenv=globalenv), - osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1 Job 3", "clang++", packages="", buildtype="boost", buildscript="drone", xcode_version="11.5", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': '77de68daec'}, globalenv=globalenv), - osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1 Job 4", "clang++", packages="", buildtype="boost", buildscript="drone", xcode_version="11.4", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': '1b64538924'}, globalenv=globalenv), - osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1 Job 5", "clang++", packages="", buildtype="boost", buildscript="drone", xcode_version="11.3", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': 'ac3478d69a'}, globalenv=globalenv), - osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1 Job 6", "clang++", packages="", buildtype="boost", buildscript="drone", xcode_version="11.2", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': 'c1dfd96eea'}, globalenv=globalenv), - osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1 Job 7", "clang++", packages="", buildtype="boost", buildscript="drone", xcode_version="11.1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': '902ba3cda1'}, globalenv=globalenv), - osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1 Job 8", "clang++", packages="", buildtype="boost", buildscript="drone", xcode_version="11", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': 'fe5dbbcea5'}, globalenv=globalenv), - osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1 Job 9", "clang++", packages="", buildtype="boost", buildscript="drone", xcode_version="10.3", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': '0ade7c2cf9'}, globalenv=globalenv), - osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1 Job 10", "clang++", packages="", buildtype="boost", buildscript="drone", xcode_version="10.2", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': 'b1d5781111'}, globalenv=globalenv), - osx_cxx("TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1 Job 11", "clang++", packages="", buildtype="boost", buildscript="drone", xcode_version="10.1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': '17ba079149'}, globalenv=globalenv), - linux_cxx("UBSAN=1 TOOLSET=gcc COMPILER=g++-9 CXXSTD=11, Job 12", "g++-9", packages="g++-9", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'UBSAN': '1', 'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '11,14', 'UBSAN_OPTIONS': 'print_stacktrace=1', 'LINKFLAGS': '-fuse-ld=gold', 'DRONE_JOB_UUID': '7b52009b64'}, globalenv=globalenv), - linux_cxx("UBSAN=1 TOOLSET=gcc COMPILER=g++-9 CXXSTD=17, Job 13", "g++-9", packages="g++-9", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'UBSAN': '1', 'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '17,2a', 'UBSAN_OPTIONS': 'print_stacktrace=1', 'LINKFLAGS': '-fuse-ld=gold', 'DRONE_JOB_UUID': 'bd307a3ec3'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++-9 CXXSTD=11,14,17,2a Job 14", "g++-9", packages="g++-9", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '11,14,17,2a', 'DRONE_JOB_UUID': 'fa35e19212'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++-8 CXXSTD=11,14,17 Job 15", "g++-8", packages="g++-8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': '11,14,17', 'DRONE_JOB_UUID': 'f1abd67035'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++-7 CXXSTD=11,14 Job 16", "g++-7", packages="g++-7", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '11,14', 'DRONE_JOB_UUID': '1574bddb75'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++-6 CXXSTD=11,14 Job 17", "g++-6", packages="g++-6", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': '11,14', 'DRONE_JOB_UUID': '0716d9708d'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++-5 CXXSTD=11,14 Job 18", "g++-5", packages="g++-5", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': '11,14', 'DRONE_JOB_UUID': '9e6a55b6b4'}, globalenv=globalenv), - linux_cxx("TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=11 Job 19", "g++-4.9", packages="g++-4.9", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-4.9', 'CXXSTD': '11', 'DRONE_JOB_UUID': 'b3f0c7f6bb'}, globalenv=globalenv), - linux_cxx("UBSAN=1 TOOLSET=clang COMPILER=clang++-8 CXXS Job 20", "clang++-8", packages="clang-8", llvm_os="trusty", llvm_ver="8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'UBSAN': '1', 'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '11,14', 'UBSAN_OPTIONS': 'print_stacktrace=1', 'DRONE_JOB_UUID': '91032ad7bb'}, globalenv=globalenv), - linux_cxx("UBSAN=1 TOOLSET=clang COMPILER=clang++-8 CXXS Job 21", "clang++-8", packages="clang-8", llvm_os="trusty", llvm_ver="8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'UBSAN': '1', 'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '17,2a', 'UBSAN_OPTIONS': 'print_stacktrace=1', 'DRONE_JOB_UUID': '472b07b9fc'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-10 CXXSTD=11,1 Job 22", "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu1604:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': '11,14,17,2a', 'DRONE_JOB_UUID': '12c6fc06c9'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-9 CXXSTD=11,14 Job 23", "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", buildscript="drone", image="cppalliance/droneubuntu1604:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': '11,14,17,2a', 'DRONE_JOB_UUID': 'd435a6cdd7'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-8 CXXSTD=11,14 Job 24", "clang++-8", packages="clang-8", llvm_os="trusty", llvm_ver="8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '11,14,17,2a', 'DRONE_JOB_UUID': '4d134bc072'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-7 CXXSTD=11,14 Job 25", "clang++-7", packages="clang-7", llvm_os="trusty", llvm_ver="7", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '11,14,17,2a', 'DRONE_JOB_UUID': 'f6e1126ced'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=11, Job 26", "clang++-6.0", packages="clang-6.0", llvm_os="trusty", llvm_ver="6.0", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': '11,14,17', 'DRONE_JOB_UUID': '887309d048'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=11, Job 27", "clang++-5.0", packages="clang-5.0", llvm_os="trusty", llvm_ver="5.0", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': 'bc33ea4e26'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=11, Job 28", "clang++-4.0", packages="clang-4.0", llvm_os="trusty", llvm_ver="4.0", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': '0a57cb53ba'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=11, Job 29", "clang++-3.9", packages="clang-3.9 libstdc++-4.9-dev", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.9', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': '7719a1c782'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=11, Job 30", "clang++-3.8", packages="clang-3.8 libstdc++-4.9-dev", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.8', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': '22d200f867'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=11, Job 31", "clang++-3.7", packages="clang-3.7", llvm_os="precise", llvm_ver="3.7", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.7', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': '632667547e'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=11, Job 32", "clang++-3.6", packages="clang-3.6 libstdc++-4.9-dev", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.6', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': 'cb4e5208b4'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=11, Job 33", "clang++-3.5", packages="clang-3.5 libstdc++-4.9-dev", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-3.5', 'CXXSTD': '11,14,1z', 'DRONE_JOB_UUID': 'b6692ea5df'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=/usr/bin/clang++ CXXST Job 34", "/usr/bin/clang++", packages="clang-3.4", llvm_os="precise", llvm_ver="3.8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': '/usr/bin/clang++', 'CXXSTD': '11', 'DRONE_JOB_UUID': 'f1f836cb4e'}, globalenv=globalenv), - linux_cxx("TOOLSET=clang COMPILER=/usr/bin/clang++ CXXST Job 35", "/usr/bin/clang++", packages="clang-3.3", llvm_os="precise", llvm_ver="3.8", buildtype="boost", buildscript="drone", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': '/usr/bin/clang++', 'CXXSTD': '11', 'DRONE_JOB_UUID': '972a67c481'}, globalenv=globalenv), - ] - -# from https://github.com/boostorg/boost-ci -load("@boost_ci//ci/drone/:functions.star", "linux_cxx","windows_cxx","osx_cxx","freebsd_cxx") diff --git a/.drone/drone.bat b/.drone/drone.bat new file mode 100644 index 00000000..86171967 --- /dev/null +++ b/.drone/drone.bat @@ -0,0 +1,28 @@ +@REM Copyright 2022 Peter Dimov +@REM Distributed under the Boost Software License, Version 1.0. +@REM https://www.boost.org/LICENSE_1_0.txt + +@ECHO ON + +set LIBRARY=%1 +set DRONE_BUILD_DIR=%CD% + +set BOOST_BRANCH=develop +if "%DRONE_BRANCH%" == "master" set BOOST_BRANCH=master +cd .. +git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root +cd boost-root +git submodule update --init tools/boostdep +xcopy /s /e /q %DRONE_BUILD_DIR% libs\%LIBRARY%\ +python tools/boostdep/depinst/depinst.py %LIBRARY% +cmd /c bootstrap +b2 -d0 headers + +echo "Generating single header" +cd libs/%LIBRARY% +python gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o test/leaf.hpp boost/leaf + +echo "Testing" +if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD% +if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD% +..\..\b2 -j3 test toolset=%TOOLSET% %CXXSTD% %ADDRMD% embed-manifest-via=linker link=shared,static variant=debug,release,leaf_debug_capture0,leaf_release_capture0,leaf_debug_diag0,leaf_release_diag0,leaf_debug_embedded,leaf_release_embedded,leaf_debug_leaf_hpp,leaf_release_leaf_hpp diff --git a/.drone/drone.sh b/.drone/drone.sh index 481bb8f1..baf7f521 100755 --- a/.drone/drone.sh +++ b/.drone/drone.sh @@ -1,42 +1,29 @@ #!/bin/bash -# Copyright 2020 Rene Rivera, Sam Darwin +# Copyright 2022 Peter Dimov # Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt) +# https://www.boost.org/LICENSE_1_0.txt -set -e -export TRAVIS_BUILD_DIR=$(pwd) -export DRONE_BUILD_DIR=$(pwd) -export TRAVIS_BRANCH=$DRONE_BRANCH -export VCS_COMMIT_ID=$DRONE_COMMIT -export GIT_COMMIT=$DRONE_COMMIT -export REPO_NAME=$DRONE_REPO -export PATH=~/.local/bin:/usr/local/bin:$PATH +set -ex -if [ "$DRONE_JOB_BUILDTYPE" == "boost" ]; then +DRONE_BUILD_DIR=$(pwd) -echo '==================================> INSTALL' +BOOST_BRANCH=develop +if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi cd .. -git clone -b master --depth 1 https://github.com/boostorg/boost.git boost-root +git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root cd boost-root -git submodule update --init tools/build -git submodule update --init tools/inspect -git submodule update --init libs/config git submodule update --init tools/boostdep -mkdir -p libs/leaf -cp -r $TRAVIS_BUILD_DIR/* libs/leaf -python tools/boostdep/depinst/depinst.py leaf -I example +cp -r $DRONE_BUILD_DIR/* libs/$LIBRARY +python tools/boostdep/depinst/depinst.py $LIBRARY ./bootstrap.sh -./b2 headers -cd libs/leaf +./b2 -d0 headers -echo '==================================> SCRIPT' +echo "Generating single header" +cd libs/$LIBRARY +python gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o test/leaf.hpp boost/leaf +echo "Testing" echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam -../../b2 test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release,leaf_debug_diag0,leaf_release_diag0 ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} -../../b2 exception-handling=off rtti=off test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release,leaf_debug_diag0,leaf_release_diag0 ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} -../../b2 threading=single test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release,leaf_debug_diag0,leaf_release_diag0 ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} -../../b2 threading=single exception-handling=off rtti=off test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release,leaf_debug_diag0,leaf_release_diag0 ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} - -fi +../../b2 -j3 test $LINKFLAGS toolset=$TOOLSET cxxstd=$CXXSTD ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+undefined-sanitizer=norecover debug-symbols=on} ${ASAN:+address-sanitizer=norecover debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} link=shared,static variant=debug,release,leaf_debug_capture0,leaf_release_capture0,leaf_debug_diag0,leaf_release_diag0,leaf_debug_embedded,leaf_release_embedded,leaf_debug_leaf_hpp,leaf_release_leaf_hpp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80dcd723..3061c0f0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,58 +19,80 @@ jobs: include: - toolset: gcc-4.8 cxxstd: "11" - os: ubuntu-18.04 - install: g++-4.8 + os: ubuntu-latest + container: ubuntu:18.04 + install: g++-4.8-multilib + address-model: 32,64 - toolset: gcc-5 cxxstd: "11,14,1z" - os: ubuntu-18.04 - install: g++-5 + os: ubuntu-latest + container: ubuntu:18.04 + install: g++-5-multilib + address-model: 32,64 - toolset: gcc-6 cxxstd: "11,14,1z" - os: ubuntu-18.04 - install: g++-6 + os: ubuntu-latest + container: ubuntu:18.04 + install: g++-6-multilib + address-model: 32,64 - toolset: gcc-7 cxxstd: "11,14" - os: ubuntu-18.04 + os: ubuntu-latest + container: ubuntu:18.04 + install: g++-7-multilib + address-model: 32,64 - toolset: gcc-8 cxxstd: "11,14,17,2a" - os: ubuntu-18.04 - install: g++-8 + os: ubuntu-20.04 + install: g++-8-multilib + address-model: 32,64 - toolset: gcc-9 cxxstd: "11,14,17,2a" os: ubuntu-20.04 + install: g++-9-multilib + address-model: 32,64 - toolset: gcc-10 cxxstd: "11,14,17,2a" os: ubuntu-20.04 - install: g++-10 + install: g++-10-multilib + address-model: 32,64 - toolset: gcc-11 - cxxstd: "11,14,17,2a" + cxxstd: "11,14,17,20" os: ubuntu-20.04 - install: g++-11 + install: g++-11-multilib + address-model: 32,64 + - toolset: gcc-12 + cxxstd: "11,14,17,20,2b" + os: ubuntu-22.04 + install: g++-12-multilib + address-model: 32,64 - toolset: clang compiler: clang++-3.9 cxxstd: "11,14" - os: ubuntu-18.04 + os: ubuntu-latest + container: ubuntu:18.04 install: clang-3.9 - toolset: clang compiler: clang++-4.0 cxxstd: "11,14" - os: ubuntu-18.04 + os: ubuntu-latest + container: ubuntu:18.04 install: clang-4.0 - toolset: clang compiler: clang++-5.0 cxxstd: "11,14,1z" - os: ubuntu-18.04 + os: ubuntu-latest + container: ubuntu:18.04 install: clang-5.0 - toolset: clang compiler: clang++-6.0 cxxstd: "11,14,17" - os: ubuntu-18.04 + os: ubuntu-20.04 install: clang-6.0 - toolset: clang compiler: clang++-7 cxxstd: "11,14,17" - os: ubuntu-18.04 + os: ubuntu-20.04 install: clang-7 - toolset: clang compiler: clang++-8 @@ -86,40 +108,67 @@ jobs: compiler: clang++-10 cxxstd: "11,14,17,2a" os: ubuntu-20.04 - install: clang-10 - toolset: clang compiler: clang++-11 cxxstd: "11,14,17,2a" os: ubuntu-20.04 - install: clang-11 - toolset: clang compiler: clang++-12 - cxxstd: "11,14,17,2a" + cxxstd: "11,14,17,20" os: ubuntu-20.04 - install: clang-12 + - toolset: clang + compiler: clang++-13 + cxxstd: "11,14,17,20,2b" + os: ubuntu-22.04 + install: clang-13 + - toolset: clang + compiler: clang++-14 + cxxstd: "11,14,17,20,2b" + os: ubuntu-22.04 + install: clang-14 - toolset: clang cxxstd: "11,14,17,2a" - os: macos-10.15 + os: macos-11 runs-on: ${{matrix.os}} + container: ${{matrix.container}} + + defaults: + run: + shell: bash steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + + - name: Setup container environment + if: matrix.container + run: | + apt-get update + apt-get -y install sudo python git g++ - name: Install packages if: matrix.install - run: sudo apt install ${{matrix.install}} + run: sudo apt-get -y install ${{matrix.install}} - name: Setup Boost run: | + echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY + LIBRARY=${GITHUB_REPOSITORY#*/} + echo LIBRARY: $LIBRARY + echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV + echo GITHUB_BASE_REF: $GITHUB_BASE_REF + echo GITHUB_REF: $GITHUB_REF REF=${GITHUB_BASE_REF:-$GITHUB_REF} + REF=${REF#refs/heads/} + echo REF: $REF BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true + echo BOOST_BRANCH: $BOOST_BRANCH cd .. git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root cd boost-root - cp -r $GITHUB_WORKSPACE/* libs/leaf + cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY git submodule update --init tools/boostdep - python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" leaf + python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY ./bootstrap.sh ./b2 -d0 headers @@ -136,7 +185,7 @@ jobs: - name: Run tests run: | cd ../boost-root - ./b2 -j3 libs/leaf/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} link=shared,static variant=debug,release,leaf_debug_capture0,leaf_release_capture0,leaf_debug_diag0,leaf_release_diag0,leaf_debug_embedded,leaf_release_embedded,leaf_debug_leaf_hpp,leaf_release_leaf_hpp + ./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} link=shared,static variant=debug,release,leaf_debug_capture0,leaf_release_capture0,leaf_debug_diag0,leaf_release_diag0,leaf_debug_embedded,leaf_release_embedded,leaf_debug_leaf_hpp,leaf_release_leaf_hpp windows: strategy: @@ -144,9 +193,18 @@ jobs: matrix: include: - toolset: msvc-14.2 - cxxstd: "14,17,latest" + cxxstd: "14,17,20,latest" addrmd: 32,64 os: windows-2019 + - toolset: msvc-14.3 + cxxstd: "14,17,20,latest" + addrmd: 32,64 + os: windows-2022 + - toolset: clang-win + cxxstd: "14,17,latest" + addrmd: 64 + os: windows-2022 + embedmanifest: embed-manifest-via=linker - toolset: gcc cxxstd: "11,14,17,2a" addrmd: 64 @@ -155,20 +213,27 @@ jobs: runs-on: ${{matrix.os}} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Boost shell: cmd run: | + echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY% + for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi + echo LIBRARY: %LIBRARY% + echo LIBRARY=%LIBRARY%>>%GITHUB_ENV% + echo GITHUB_BASE_REF: %GITHUB_BASE_REF% + echo GITHUB_REF: %GITHUB_REF% if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF% set BOOST_BRANCH=develop - if "%GITHUB_BASE_REF%" == "master" set BOOST_BRANCH=master + for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master + echo BOOST_BRANCH: %BOOST_BRANCH% cd .. git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root cd boost-root - xcopy /s /e /q %GITHUB_WORKSPACE% libs\leaf\ + xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\ git submodule update --init tools/boostdep - python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" leaf + python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY% cmd /c bootstrap b2 -d0 headers @@ -181,4 +246,4 @@ jobs: shell: cmd run: | cd ../boost-root - b2 -j3 libs/leaf/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release,leaf_debug_capture0,leaf_release_capture0,leaf_debug_diag0,leaf_release_diag0,leaf_debug_embedded,leaf_release_embedded,leaf_debug_leaf_hpp,leaf_release_leaf_hpp + b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} ${{matrix.embedmanifest}} variant=debug,release,leaf_debug_capture0,leaf_release_capture0,leaf_debug_diag0,leaf_release_diag0,leaf_debug_embedded,leaf_release_embedded,leaf_debug_leaf_hpp,leaf_release_leaf_hpp diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 68583bd3..00000000 --- a/.travis.yml +++ /dev/null @@ -1,422 +0,0 @@ -# Copyright 2016-2018 Peter Dimov -# Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) - -language: cpp - -sudo: false - -dist: trusty - -python: "2.7" - -os: - - linux - - osx - -branches: - only: - - master - - develop - - /^feature.*/ - -env: - matrix: - - BOGUS_JOB=true - -addons: - apt: - packages: - - g++-4.9 - - g++-5 - - g++-6 - - clang-3.6 - - clang-3.7 - - clang-3.8 - - ruby-full - - ninja-build - - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-precise - - llvm-toolchain-precise-3.6 - - llvm-toolchain-precise-3.7 - - llvm-toolchain-precise-3.8 - -matrix: - - exclude: - - env: BOGUS_JOB=true - - include: - - - os: linux - env: DOC=1 - install: - - gem install asciidoctor - - gem install asciidoctor-pdf --pre - - gem install rouge - - cd .. - - git clone -b master --depth 1 https://github.com/boostorg/boost.git boost-root - - cd boost-root - - git submodule update --init tools/build - - git submodule update --init libs/config - - mkdir -p libs/leaf - - cp -r $TRAVIS_BUILD_DIR/* libs/leaf - - ./bootstrap.sh - - cd libs/leaf - script: - - |- - echo "using asciidoctor ;" > ~/user-config.jam - - ../../b2 doc - deploy: - local-dir: ../boost-root/libs/leaf/doc/html - provider: pages - skip-cleanup: true - github-token: $GH_PAGES_TOKEN - keep-history: false - on: - branch: master - -################################### - - - os: osx - compiler: clang++ - env: UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD=11,14 UBSAN_OPTIONS=print_stacktrace=1 - - - os: osx - compiler: clang++ - env: UBSAN=1 TOOLSET=clang COMPILER=clang++ CXXSTD=1z,2a UBSAN_OPTIONS=print_stacktrace=1 - - - os: osx - osx_image: xcode11.5 - compiler: clang++ - env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z - - - os: osx - osx_image: xcode11.4 - compiler: clang++ - env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z - - - os: osx - osx_image: xcode11.3 - compiler: clang++ - env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z - - - os: osx - osx_image: xcode11.2 - compiler: clang++ - env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z - - - os: osx - osx_image: xcode11.1 - compiler: clang++ - env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z - - - os: osx - osx_image: xcode11 - compiler: clang++ - env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z - - - os: osx - osx_image: xcode10.3 - compiler: clang++ - env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z - - - os: osx - osx_image: xcode10.2 - compiler: clang++ - env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z - - - os: osx - osx_image: xcode10.1 - compiler: clang++ - env: TOOLSET=clang COMPILER=clang++ CXXSTD=11,14,1z - -################################### - - - os: linux - compiler: g++-9 - env: UBSAN=1 TOOLSET=gcc COMPILER=g++-9 CXXSTD=11,14 UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold - addons: - apt: - packages: - - g++-9 - sources: - - ubuntu-toolchain-r-test - - - os: linux - compiler: g++-9 - env: UBSAN=1 TOOLSET=gcc COMPILER=g++-9 CXXSTD=17,2a UBSAN_OPTIONS=print_stacktrace=1 LINKFLAGS=-fuse-ld=gold - addons: - apt: - packages: - - g++-9 - sources: - - ubuntu-toolchain-r-test - - - os: linux - compiler: g++-9 - env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=11,14,17,2a - addons: - apt: - packages: - - g++-9 - sources: - - ubuntu-toolchain-r-test - - - os: linux - compiler: g++-8 - env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=11,14,17 - addons: - apt: - packages: - - g++-8 - sources: - - ubuntu-toolchain-r-test - - - os: linux - compiler: g++-7 - env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=11,14 - addons: - apt: - packages: - - g++-7 - sources: - - ubuntu-toolchain-r-test - - - os: linux - compiler: g++-6 - env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=11,14 - addons: - apt: - packages: - - g++-6 - sources: - - ubuntu-toolchain-r-test - - - os: linux - compiler: g++-5 - env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=11,14 - addons: - apt: - packages: - - g++-5 - sources: - - ubuntu-toolchain-r-test - - - os: linux - compiler: g++-4.9 - env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=11 - addons: - apt: - packages: - - g++-4.9 - sources: - - ubuntu-toolchain-r-test - -################################### - - - os: linux - compiler: clang++-8 - env: UBSAN=1 TOOLSET=clang COMPILER=clang++-8 CXXSTD=11,14 UBSAN_OPTIONS=print_stacktrace=1 - addons: - apt: - packages: - - clang-8 - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-8 - - - os: linux - compiler: clang++-8 - env: UBSAN=1 TOOLSET=clang COMPILER=clang++-8 CXXSTD=17,2a UBSAN_OPTIONS=print_stacktrace=1 - addons: - apt: - packages: - - clang-8 - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-8 - - - os: linux - dist: xenial - compiler: clang++-10 - env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=11,14,17,2a - addons: - apt: - packages: - - clang-10 - sources: - - ubuntu-toolchain-r-test - - sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main' - key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' - - - os: linux - dist: xenial - compiler: clang++-9 - env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=11,14,17,2a - addons: - apt: - packages: - - clang-9 - sources: - - ubuntu-toolchain-r-test - - sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main' - key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' - - - os: linux - compiler: clang++-8 - env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=11,14,17,2a - addons: - apt: - packages: - - clang-8 - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-8 - - - os: linux - compiler: clang++-7 - env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=11,14,17,2a - addons: - apt: - packages: - - clang-7 - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-7 - - - os: linux - compiler: clang++-6.0 - env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=11,14,17 - addons: - apt: - packages: - - clang-6.0 - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-6.0 - - - os: linux - compiler: clang++-5.0 - env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=11,14,1z - addons: - apt: - packages: - - clang-5.0 - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-5.0 - - - os: linux - compiler: clang++-4.0 - env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=11,14,1z - addons: - apt: - packages: - - clang-4.0 - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-4.0 - - - os: linux - compiler: clang++-3.9 - env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=11,14,1z - addons: - apt: - packages: - - clang-3.9 - - libstdc++-4.9-dev - sources: - - ubuntu-toolchain-r-test - - - os: linux - compiler: clang++-3.8 - env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=11,14,1z - addons: - apt: - packages: - - clang-3.8 - - libstdc++-4.9-dev - sources: - - ubuntu-toolchain-r-test - - - os: linux - compiler: clang++-3.7 - env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=11,14,1z - addons: - apt: - packages: - - clang-3.7 - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.7 - - - os: linux - compiler: clang++-3.6 - env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=11,14,1z - addons: - apt: - packages: - - clang-3.6 - - libstdc++-4.9-dev - sources: - - ubuntu-toolchain-r-test - - - os: linux - compiler: clang++-3.5 - env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=11,14,1z - addons: - apt: - packages: - - clang-3.5 - - libstdc++-4.9-dev - sources: - - ubuntu-toolchain-r-test - - - os: linux - compiler: /usr/bin/clang++ - env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=11 - addons: - apt: - packages: - - clang-3.4 - - - os: linux - compiler: /usr/bin/clang++ - env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=11 - addons: - apt: - packages: - - clang-3.3 - -################################### - -install: - - cd .. - - git clone -b master --depth 1 https://github.com/boostorg/boost.git boost-root - - cd boost-root - - git submodule update --init tools/build - - git submodule update --init tools/inspect - - git submodule update --init libs/config - - git submodule update --init tools/boostdep - - mkdir -p libs/leaf - - cp -r $TRAVIS_BUILD_DIR/* libs/leaf - - python tools/boostdep/depinst/depinst.py leaf -I example - - ./bootstrap.sh - - ./b2 headers - - cd libs/leaf - -script: - - |- - echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam - - ../../b2 test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release,leaf_debug_diag0,leaf_release_diag0 ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} - - ../../b2 exception-handling=off rtti=off test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release,leaf_debug_diag0,leaf_release_diag0 ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} - - ../../b2 threading=single test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release,leaf_debug_diag0,leaf_release_diag0 ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} - - ../../b2 threading=single exception-handling=off rtti=off test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release,leaf_debug_diag0,leaf_release_diag0 ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} - -notifications: - email: - on_success: always diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 0b3a7bd3..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2016, 2017 Peter Dimov -# Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) - -version: 1.0.{build}-{branch} - -shallow_clone: true - -branches: - only: - - master - - develop - -environment: - matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - TOOLSET: msvc-14.1,clang-win - CXXSTD: 14,17 - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - TOOLSET: msvc-14.2 - CXXSTD: 14,17 - -install: - - set BOOST_BRANCH=develop - - if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master - - cd .. - - git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root - - cd boost-root - - git submodule update --init tools/build - - git submodule update --init tools/boost_install - - git submodule update --init libs/config - - git submodule update --init libs/headers - - git submodule update --init tools/boostdep - - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\leaf\ - - python tools/boostdep/depinst/depinst.py leaf - - cmd /c bootstrap - - b2 headers - -build: off - -test_script: - - if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD% - - b2 -j3 libs/leaf/test toolset=%TOOLSET% exception-handling=on,off variant=debug,release,leaf_debug_diag0,leaf_release_diag0 define=_CRT_SECURE_NO_WARNINGS %CXXSTD% diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index fc21d551..dac84a73 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -412,7 +412,7 @@ namespace leaf_detail template struct load_item { - BOOST_LEAF_CONSTEXPR static int load( int err_id, E && e ) noexcept + BOOST_LEAF_CONSTEXPR static int load_( int err_id, E && e ) noexcept { return load_slot(err_id, std::forward(e)); } @@ -421,7 +421,7 @@ namespace leaf_detail template struct load_item { - BOOST_LEAF_CONSTEXPR static int load( int err_id, F && f ) noexcept + BOOST_LEAF_CONSTEXPR static int load_( int err_id, F && f ) noexcept { return load_slot(err_id, std::forward(f)()); } @@ -430,7 +430,7 @@ namespace leaf_detail template struct load_item { - BOOST_LEAF_CONSTEXPR static int load( int err_id, F && f ) noexcept + BOOST_LEAF_CONSTEXPR static int load_( int err_id, F && f ) noexcept { return accumulate_slot(err_id, std::forward(f)); } @@ -546,7 +546,7 @@ class BOOST_LEAF_SYMBOL_VISIBLE error_id { if( int err_id = value() ) { - int const unused[ ] = { 42, leaf_detail::load_item::load(err_id, std::forward(item))... }; + int const unused[ ] = { 42, leaf_detail::load_item::load_(err_id, std::forward(item))... }; (void) unused; } return *this; From e02fc6ba222b1f4042ba862081f4b4ad46a4f66a Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Tue, 4 Apr 2023 21:30:18 -0700 Subject: [PATCH 011/103] Better includes for try_catch_test.cpp --- test/try_catch_test.cpp | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/test/try_catch_test.cpp b/test/try_catch_test.cpp index 2ffe4285..713cbbf2 100644 --- a/test/try_catch_test.cpp +++ b/test/try_catch_test.cpp @@ -3,27 +3,16 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#include -#include "lightweight_test.hpp" - -namespace leaf = boost::leaf; +#include #ifdef BOOST_LEAF_NO_EXCEPTIONS +#include + int main() { - int r = leaf::try_catch( - [] - { - return 42; - }, - [] - { - return 1; - } ); - BOOST_TEST_EQ(r, 42); - - return boost::report_errors(); + std::cout << "Unit test not applicable." << std::endl; + return 0; } #else @@ -31,9 +20,14 @@ int main() #ifdef BOOST_LEAF_TEST_SINGLE_HEADER # include "leaf.hpp" #else +# include # include #endif +#include "lightweight_test.hpp" + +namespace leaf = boost::leaf; + template struct info { int value; }; struct error1: std::exception { }; From 801e5e813ff9923d8d610b1b00597226369328d1 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Tue, 4 Apr 2023 21:30:36 -0700 Subject: [PATCH 012/103] Fix for Issue 53 --- include/boost/leaf/handle_errors.hpp | 4 +- meson.build | 2 + test/Jamfile.v2 | 2 + test/github_issue53_test.cpp | 77 +++++++++++++++++++++++ test/github_issue53x_test.cpp | 93 ++++++++++++++++++++++++++++ 5 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 test/github_issue53_test.cpp create mode 100644 test/github_issue53x_test.cpp diff --git a/include/boost/leaf/handle_errors.hpp b/include/boost/leaf/handle_errors.hpp index 68453f3f..0da2b376 100644 --- a/include/boost/leaf/handle_errors.hpp +++ b/include/boost/leaf/handle_errors.hpp @@ -733,7 +733,7 @@ try_handle_some( TryBlock && try_block, H && ... h ) noexcept using R = typename std::decay()())>::type; auto rr = ctx.template handle_error(id, std::forward(h)..., [&r]()->R { return std::move(r); }); if( !rr ) - ctx.propagate(id); + ctx.propagate(rr.error()); return rr; } } @@ -869,7 +869,7 @@ try_handle_some( TryBlock && try_block, H && ... h ) using R = typename std::decay()())>::type; auto rr = ctx.template handle_error(id, std::forward(h)..., [&r]()->R { return std::move(r); }); if( !rr ) - ctx.propagate(id); + ctx.propagate(rr.error()); return rr; } } diff --git a/meson.build b/meson.build index 2b4ff64b..a6b55868 100644 --- a/meson.build +++ b/meson.build @@ -143,6 +143,8 @@ if option_enable_unit_tests 'exception_test', 'exception_to_result_test', 'function_traits_test', + 'github_issue53_test', + 'github_issue53x_test', 'handle_all_other_result_test', 'handle_all_test', 'handle_basic_test', diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 9896c4e0..e8c02ac0 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -82,6 +82,8 @@ run error_id_test.cpp ; run exception_test.cpp ; run exception_to_result_test.cpp ; run function_traits_test.cpp ; +run github_issue53_test.cpp ; +run github_issue53x_test.cpp ; run handle_all_other_result_test.cpp ; run handle_all_test.cpp ; run handle_basic_test.cpp ; diff --git a/test/github_issue53_test.cpp b/test/github_issue53_test.cpp new file mode 100644 index 00000000..4ecd3017 --- /dev/null +++ b/test/github_issue53_test.cpp @@ -0,0 +1,77 @@ +// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_LEAF_TEST_SINGLE_HEADER +# include "leaf.hpp" +#else +# include +# include +# include +#endif + +#include "lightweight_test.hpp" + +namespace leaf = boost::leaf; + +enum class ErrorCode +{ + E_GENERIC_UNEXPECTED, + E_GENERIC_PARSE +}; + +leaf::result test1( int a ) +{ + if( a == 1 ) + return leaf::new_error(ErrorCode::E_GENERIC_UNEXPECTED); + return 32; +} + +leaf::result test2(int a) +{ + return leaf::try_handle_some( + [&]() -> leaf::result + { + BOOST_LEAF_AUTO(val, test1(a)); + (void) val; + return 4.5; + }, + [](leaf::match) -> leaf::result + { + return leaf::new_error(ErrorCode::E_GENERIC_PARSE); + } + ); +} + +void test3(int a) +{ + int x = 0; + leaf::try_handle_all( + [&]() -> leaf::result + { + BOOST_LEAF_AUTO(val, test2(a)); + (void) val; + return {}; + }, + [&](leaf::match) + { + x = 1; + }, + [&](ErrorCode e) + { + x = 2; + }, + [&]() + { + x = 3; + } + ); + BOOST_TEST_EQ(x, 1); +} + +int main() +{ + test3(1); + return boost::report_errors(); +} diff --git a/test/github_issue53x_test.cpp b/test/github_issue53x_test.cpp new file mode 100644 index 00000000..614d4179 --- /dev/null +++ b/test/github_issue53x_test.cpp @@ -0,0 +1,93 @@ +// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#include + +#ifdef BOOST_LEAF_NO_EXCEPTIONS + +#include + +int main() +{ + std::cout << "Unit test not applicable." << std::endl; + return 0; +} + +#else + +#ifdef BOOST_LEAF_TEST_SINGLE_HEADER +# include "leaf.hpp" +#else +# include +# include +#endif + +#include "lightweight_test.hpp" + +namespace leaf = boost::leaf; + +enum class ErrorCode +{ + E_GENERIC_UNEXPECTED, + E_GENERIC_PARSE +}; + +int test1( int a ) +{ + if( a == 1 ) + BOOST_LEAF_THROW_EXCEPTION(ErrorCode::E_GENERIC_UNEXPECTED); + return 32; +} + +float test2(int a) +{ + return leaf::try_catch( + [&] + { + auto val = test1(a); + (void) val; + return 4.5; + }, + [](leaf::match) + { + BOOST_LEAF_THROW_EXCEPTION(ErrorCode::E_GENERIC_PARSE); + return 0; + } + ); +} + +void test3(int a) +{ + int x = 0; + leaf::try_catch( + [&] + { + auto val = test2(a); + (void) val; + }, + [&](leaf::match) + { + x = 1; + }, + [&](ErrorCode e) + { + x = 2; + }, + [&]() + { + x = 3; + } + ); + BOOST_TEST_EQ(x, 1); +} + +int main() +{ + test3(1); + return boost::report_errors(); +} + +#endif From 333af1543c0213343a4e699bf9e6c3e93fc450e5 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sat, 19 Aug 2023 18:11:08 -0700 Subject: [PATCH 013/103] Issue 56 --- include/boost/leaf/error.hpp | 91 ++++++++++++++++--- meson.build | 3 +- test/Jamfile.v2 | 3 +- ...nfo_test.cpp => diagnostic_info_test1.cpp} | 0 test/diagnostic_info_test3.cpp | 54 +++++++++++ 5 files changed, 138 insertions(+), 13 deletions(-) rename test/{diagnostic_info_test.cpp => diagnostic_info_test1.cpp} (100%) create mode 100644 test/diagnostic_info_test3.cpp diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index dac84a73..bde19bfb 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -18,7 +18,7 @@ #if BOOST_LEAF_CFG_DIAGNOSTICS # include # include -# include +# include #endif #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR @@ -143,8 +143,73 @@ namespace leaf_detail class BOOST_LEAF_SYMBOL_VISIBLE e_unexpected_info { - std::string s_; - std::set already_; + class print_base + { + public: + virtual std::string print() const = 0; + virtual ~print_base() noexcept { }; + }; + + class print_base_ptr + { + print_base_ptr( print_base_ptr const & ) = delete; + print_base_ptr & operator=( print_base_ptr const & ) = delete; + print_base * p_; + public: + explicit print_base_ptr( print_base * p ) noexcept: + p_(p) + { + BOOST_LEAF_ASSERT(p_ != nullptr); + } + print_base_ptr( print_base_ptr && x ) noexcept + { + p_ = x.p_; + x.p_ = nullptr; + } + ~print_base_ptr() noexcept + { + delete p_; + } + print_base * get() const noexcept + { + BOOST_LEAF_ASSERT(p_ != nullptr); + return p_; + } + }; + + template + class print_impl: public print_base + { + print_impl( print_impl const & ) = delete; + print_impl & operator=( print_impl const & ) = delete; + E e_; + std::string print() const final override + { + if( diagnostic::is_invisible ) + return { }; + else + { + std::stringstream s; + diagnostic::print(s, e_); + (void) (s << '\n').flush(); + return s.str(); + } + } + public: + template + explicit print_impl( T && e ): + e_(std::forward(e)) + { + } + template + void set( T && e ) + { + e_.~E(); + (void) new (&e_) E(std::forward(e)); + } + }; + + std::vector> printers_; public: @@ -155,19 +220,23 @@ namespace leaf_detail template void add(E && e) { - if( !diagnostic::is_invisible && already_.insert(&type).second ) - { - std::stringstream s; - diagnostic::print(s,e); - (s << '\n').flush(); - s_ += s.str(); - } + using T = typename std::decay::type; + for( auto & p : printers_ ) + if( p.first == &type ) + { + print_base * pb = p.second.get(); + static_cast *>(pb)->set(std::forward(e)); + return; + } + printers_.emplace_back(&type, print_base_ptr(new print_impl(std::forward(e)))); } template void print( std::basic_ostream & os ) const { - os << "Unhandled error objects:\n" << s_; + os << "Unhandled error objects:\n"; + for( auto const & p : printers_ ) + os << p.second.get()->print(); } }; diff --git a/meson.build b/meson.build index a6b55868..84828c9d 100644 --- a/meson.build +++ b/meson.build @@ -134,8 +134,9 @@ if option_enable_unit_tests 'defer_nested_new_error_result_test', 'defer_nested_success_exception_test', 'defer_nested_success_result_test', - 'diagnostic_info_test', + 'diagnostic_info_test1', 'diagnostic_info_test2', + 'diagnostic_info_test3', 'e_errno_test', 'e_LastError_test', 'error_code_test', diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index e8c02ac0..f77ecd21 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -73,8 +73,9 @@ run defer_nested_new_error_exception_test.cpp ; run defer_nested_new_error_result_test.cpp ; run defer_nested_success_exception_test.cpp ; run defer_nested_success_result_test.cpp ; -run diagnostic_info_test.cpp ; +run diagnostic_info_test1.cpp ; run diagnostic_info_test2.cpp ; +run diagnostic_info_test3.cpp ; run e_errno_test.cpp ; run e_LastError_test.cpp ; run error_code_test.cpp ; diff --git a/test/diagnostic_info_test.cpp b/test/diagnostic_info_test1.cpp similarity index 100% rename from test/diagnostic_info_test.cpp rename to test/diagnostic_info_test1.cpp diff --git a/test/diagnostic_info_test3.cpp b/test/diagnostic_info_test3.cpp new file mode 100644 index 00000000..f2bef1af --- /dev/null +++ b/test/diagnostic_info_test3.cpp @@ -0,0 +1,54 @@ +// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_LEAF_TEST_SINGLE_HEADER +# include "leaf.hpp" +#else +# include +# include +# include +#endif + +#include "lightweight_test.hpp" +#include + +namespace leaf = boost::leaf; + +struct info { int value; }; + +leaf::result f1() +{ + return leaf::new_error(info{41}); +} + +leaf::result f2() +{ + auto load = leaf::on_error(info{42}); + return f1(); +} + +int main() +{ + leaf::try_handle_all( + []() -> leaf::result + { + return f2(); + }, + []( leaf::verbose_diagnostic_info const & di ) + { +#if BOOST_LEAF_CFG_STD_STRING + std::ostringstream st; + st << di; + std::string s = st.str(); +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_EQ(s.find("41"), s.npos); + BOOST_TEST_NE(s.find("42"), s.npos); +#endif + std::cout << s; +#endif + } ); + + return boost::report_errors(); +} From 422a5340bcf04ff7a4c3c67837a0b6f330d0cd5f Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sat, 26 Aug 2023 20:26:53 -0700 Subject: [PATCH 014/103] Added optional::put overload that uses T's default ctor --- include/boost/leaf/detail/optional.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/boost/leaf/detail/optional.hpp b/include/boost/leaf/detail/optional.hpp index 0a2cdb2d..93def2fc 100644 --- a/include/boost/leaf/detail/optional.hpp +++ b/include/boost/leaf/detail/optional.hpp @@ -107,6 +107,15 @@ namespace leaf_detail } } + BOOST_LEAF_CONSTEXPR T & put( int key ) + { + BOOST_LEAF_ASSERT(key); + reset(); + (void) new(&value_) T; + key_=key; + return value_; + } + BOOST_LEAF_CONSTEXPR T & put( int key, T const & v ) { BOOST_LEAF_ASSERT(key); From c3f61f154e6922fd2c9846f51833f5137bb32ddb Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sat, 26 Aug 2023 20:27:48 -0700 Subject: [PATCH 015/103] Fixed bugs in accumulate unit tests, error info object was not initialized correctly --- test/accumulate_nested_error_result_test.cpp | 2 +- test/accumulate_nested_new_error_exception_test.cpp | 2 +- test/accumulate_nested_new_error_result_test.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/accumulate_nested_error_result_test.cpp b/test/accumulate_nested_error_result_test.cpp index f5896b44..abccbfec 100644 --- a/test/accumulate_nested_error_result_test.cpp +++ b/test/accumulate_nested_error_result_test.cpp @@ -18,7 +18,7 @@ namespace leaf = boost::leaf; template struct info { - int value; + int value = 0; }; leaf::error_id f0() diff --git a/test/accumulate_nested_new_error_exception_test.cpp b/test/accumulate_nested_new_error_exception_test.cpp index 322e9b08..5ac07bfe 100644 --- a/test/accumulate_nested_new_error_exception_test.cpp +++ b/test/accumulate_nested_new_error_exception_test.cpp @@ -32,7 +32,7 @@ namespace leaf = boost::leaf; template struct info { - int value; + int value = 0; }; void f0() diff --git a/test/accumulate_nested_new_error_result_test.cpp b/test/accumulate_nested_new_error_result_test.cpp index a13a9a94..97bc2744 100644 --- a/test/accumulate_nested_new_error_result_test.cpp +++ b/test/accumulate_nested_new_error_result_test.cpp @@ -18,7 +18,7 @@ namespace leaf = boost::leaf; template struct info { - int value; + int value = 0; }; leaf::error_id f0() From 8b5cd796ead60c9953353c1bf6b2312d3db2fda4 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sat, 26 Aug 2023 20:44:28 -0700 Subject: [PATCH 016/103] One more accumulate test bug fixed --- test/accumulate_basic_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/accumulate_basic_test.cpp b/test/accumulate_basic_test.cpp index 928d7025..b32c97a4 100644 --- a/test/accumulate_basic_test.cpp +++ b/test/accumulate_basic_test.cpp @@ -18,7 +18,7 @@ namespace leaf = boost::leaf; template struct info { - int value; + int value = 0; }; leaf::error_id g() From 81b1141c64f1e83b8ada247d246d651e457022a3 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sun, 27 Aug 2023 16:37:55 -0700 Subject: [PATCH 017/103] Renamed meson bulid directory from bld to _bld --- .gitignore | 2 +- .vscode/launch.json | 2 +- .vscode/tasks.json | 25 +++++++++++-------------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index c589ffad..fd1a40a2 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ *.opensdf *.db *.opendb -bld/* +_bld/* doc/html/* snippets/* subprojects/*/ diff --git a/.vscode/launch.json b/.vscode/launch.json index 5f995048..0b2700e1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "(lldb) Launch", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/bld/debug/capture_exception_async_test", + "program": "${workspaceFolder}/_bld/debug/capture_exception_async_test", "args": [ ], "cwd": "${workspaceFolder}", "stopAtEntry": false, diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d844b069..7a705ffe 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -6,13 +6,13 @@ { "label": "Configure Meson build directories", "type": "shell", - "command": "cd ${workspaceRoot} && meson -D leaf_boost_examples=true -D leaf_lua_examples=true bld/debug && meson -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true bld/debug_leaf_hpp && meson -D leaf_boost_examples=true -D leaf_lua_examples=true bld/release --buildtype release && meson -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true bld/release_leaf_hpp --buildtype release && meson -D leaf_diagnostics=0 -D cpp_eh=none -D b_ndebug=true -D b_lto=true -D leaf_enable_benchmarks=true bld/benchmark --buildtype release", + "command": "cd ${workspaceRoot} && meson -D leaf_boost_examples=true -D leaf_lua_examples=true _bld/debug && meson -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true _bld/debug_leaf_hpp && meson -D leaf_boost_examples=true -D leaf_lua_examples=true _bld/release --buildtype release && meson -D leaf_boost_examples=true -D leaf_lua_examples=true -D leaf_hpp=true _bld/release_leaf_hpp --buildtype release && meson -D leaf_diagnostics=0 -D cpp_eh=none -D b_ndebug=true -D b_lto=true -D leaf_enable_benchmarks=true _bld/benchmark --buildtype release", "problemMatcher": [] }, { "label": "Configure Meson build directories (no Boost)", "type": "shell", - "command": "cd ${workspaceRoot} && meson -D leaf_lua_examples=true bld/debug && meson -D leaf_lua_examples=true -D leaf_hpp=true bld/debug_leaf_hpp && meson -D leaf_lua_examples=true bld/release --buildtype release && meson -D leaf_lua_examples=true -D leaf_hpp=true bld/release_leaf_hpp --buildtype release", + "command": "cd ${workspaceRoot} && meson -D leaf_lua_examples=true _bld/debug && meson -D leaf_lua_examples=true -D leaf_hpp=true _bld/debug_leaf_hpp && meson -D leaf_lua_examples=true _bld/release --buildtype release && meson -D leaf_lua_examples=true -D leaf_hpp=true _bld/release_leaf_hpp --buildtype release", "problemMatcher": [] }, { @@ -28,12 +28,12 @@ }, "label": "Build all unit tests and examples (debug)", "type": "shell", - "command": "cd ${workspaceRoot}/bld/debug && ninja", + "command": "cd ${workspaceRoot}/_bld/debug && ninja", "problemMatcher": { "base": "$gcc", "fileLocation": [ "relative", - "${workspaceRoot}/bld/debug" + "${workspaceRoot}/_bld/debug" ] } }, @@ -44,12 +44,12 @@ "dependsOn": [ "Generate leaf.hpp" ], - "command": "cd ${workspaceRoot}/bld/debug_leaf_hpp && ninja && meson test && cd ${workspaceRoot}/bld/debug && ninja && meson test", + "command": "cd ${workspaceRoot}/_bld/debug_leaf_hpp && ninja && meson test && cd ${workspaceRoot}/_bld/debug && ninja && meson test", "problemMatcher": { "base": "$gcc", "fileLocation": [ "relative", - "${workspaceRoot}/bld/debug" + "${workspaceRoot}/_bld/debug" ] } }, @@ -60,12 +60,12 @@ "dependsOn": [ "Generate leaf.hpp" ], - "command": "cd ${workspaceRoot}/bld/release && ninja && meson test && cd ${workspaceRoot}/bld/release_leaf_hpp && ninja && meson test", + "command": "cd ${workspaceRoot}/_bld/release && ninja && meson test && cd ${workspaceRoot}/_bld/release_leaf_hpp && ninja && meson test", "problemMatcher": { "base": "$gcc", "fileLocation": [ "relative", - "${workspaceRoot}/bld/release" + "${workspaceRoot}/_bld/release" ] } }, @@ -73,9 +73,6 @@ "group": "test", "label": "Run all unit tests (b2, all configurations)", "type": "shell", - "dependsOn": [ - "Generate leaf.hpp" - ], "command": "../../b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp exception-handling=on,off cxxstd=11,14,1z,17 && ../../b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=11,14,1z,17", "windows": { "command": "..\\..\\b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp exception-handling=on,off cxxstd=14,17,latest && ..\\..\\b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=14,17,latest", @@ -84,7 +81,7 @@ "base": "$gcc", "fileLocation": [ "relative", - "${workspaceRoot}/bld/release" + "${workspaceRoot}/_bld/release" ] } }, @@ -95,12 +92,12 @@ }, "label": "Test current editor file", "type": "shell", - "command": "cd ${workspaceRoot}/bld/debug && ninja && { meson test ${fileBasenameNoExtension} || cat ./meson-logs/testlog.txt }", + "command": "cd ${workspaceRoot}/_bld/debug && ninja && { meson test ${fileBasenameNoExtension} || cat ./meson-logs/testlog.txt }", "problemMatcher": { "base": "$gcc", "fileLocation": [ "relative", - "${workspaceRoot}/bld/debug" + "${workspaceRoot}/_bld/debug" ] } } From f56c3ec69d6d9c142998184b4c61970576b6d1c9 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sun, 27 Aug 2023 16:38:25 -0700 Subject: [PATCH 018/103] Much streamlined handling of diagnostics --- include/boost/leaf/context.hpp | 2 +- include/boost/leaf/error.hpp | 211 ++++++++++++------ include/boost/leaf/handle_errors.hpp | 5 +- include/boost/leaf/on_error.hpp | 47 +--- meson.build | 2 + test/Jamfile.v2 | 6 +- test/accumulate_nested_error_result_test.cpp | 18 +- ...mulate_nested_new_error_exception_test.cpp | 16 +- ...ccumulate_nested_new_error_result_test.cpp | 16 +- test/diagnostic_info_test1.cpp | 6 +- test/diagnostic_info_test2.cpp | 6 +- test/diagnostic_info_test3.cpp | 10 +- test/diagnostic_info_test4.cpp | 73 ++++++ test/diagnostic_info_test5.cpp | 134 +++++++++++ 14 files changed, 412 insertions(+), 140 deletions(-) create mode 100644 test/diagnostic_info_test4.cpp create mode 100644 test/diagnostic_info_test5.cpp diff --git a/include/boost/leaf/context.hpp b/include/boost/leaf/context.hpp index 4fe1775b..2e4633e8 100644 --- a/include/boost/leaf/context.hpp +++ b/include/boost/leaf/context.hpp @@ -177,7 +177,7 @@ namespace leaf_detail BOOST_LEAF_ASSERT(err_id != 0); auto & sl = std::get(tup); if( sl.has_value(err_id) ) - load_slot(err_id, std::move(sl).value(err_id)); + load_slot(err_id, std::move(sl).value(err_id)); tuple_for_each::propagate_captured(tup, err_id); } diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index bde19bfb..3d52a952 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -141,102 +141,120 @@ namespace leaf_detail BOOST_LEAF_CONSTEXPR static void print( std::basic_ostream &, e_unexpected_count const &) noexcept { } }; + template + class BOOST_LEAF_SYMBOL_VISIBLE slot; + class BOOST_LEAF_SYMBOL_VISIBLE e_unexpected_info { - class print_base - { - public: - virtual std::string print() const = 0; - virtual ~print_base() noexcept { }; - }; + e_unexpected_info( e_unexpected_info const & ) = delete; + e_unexpected_info & operator=( e_unexpected_info const & ) = delete; - class print_base_ptr + struct slot_base { - print_base_ptr( print_base_ptr const & ) = delete; - print_base_ptr & operator=( print_base_ptr const & ) = delete; - print_base * p_; public: - explicit print_base_ptr( print_base * p ) noexcept: - p_(p) - { - BOOST_LEAF_ASSERT(p_ != nullptr); - } - print_base_ptr( print_base_ptr && x ) noexcept - { - p_ = x.p_; - x.p_ = nullptr; - } - ~print_base_ptr() noexcept + slot_base * next_; + virtual void deactivate() noexcept = 0; + virtual void propagate( int err_id ) noexcept = 0; + virtual std::string print( int key_to_print ) const = 0; + virtual ~slot_base() noexcept { }; + protected: + BOOST_LEAF_CONSTEXPR slot_base(): + next_(nullptr) { - delete p_; - } - print_base * get() const noexcept - { - BOOST_LEAF_ASSERT(p_ != nullptr); - return p_; } }; template - class print_impl: public print_base + class slot_store: public slot_base, public slot { - print_impl( print_impl const & ) = delete; - print_impl & operator=( print_impl const & ) = delete; - E e_; - std::string print() const final override + slot_store( slot_store const & ) = delete; + slot_store & operator=( slot_store const & ) = delete; + using sl = slot; + void deactivate() noexcept final override { - if( diagnostic::is_invisible ) - return { }; - else - { - std::stringstream s; - diagnostic::print(s, e_); - (void) (s << '\n').flush(); - return s.str(); - } + sl::deactivate(); } - public: - template - explicit print_impl( T && e ): - e_(std::forward(e)) + void propagate( int err_id ) noexcept final override + { + sl::propagate(err_id); + } + std::string print( int key_to_print ) const final override { + std::stringstream st; + sl::print(st, key_to_print); + return st.str(); } + public: template - void set( T && e ) + BOOST_LEAF_CONSTEXPR slot_store( int err_id, T && e ) { - e_.~E(); - (void) new (&e_) E(std::forward(e)); + sl::put(err_id, std::forward(e)); } }; - std::vector> printers_; + slot_base * first_; + slot_base * * last_; public: - e_unexpected_info() noexcept + BOOST_LEAF_CONSTEXPR e_unexpected_info() noexcept: + first_(nullptr), + last_(&first_) { } + BOOST_LEAF_CONSTEXPR e_unexpected_info( e_unexpected_info && other ) noexcept: + first_(other.first_), + last_(other.last_ == &other.first_? &first_ : other.last_) + { + BOOST_LEAF_ASSERT(last_ != nullptr); + BOOST_LEAF_ASSERT(*last_ == nullptr); + other.first_ = nullptr; + other.last_ = nullptr; + } + + ~e_unexpected_info() noexcept + { + for( slot_base const * p = first_; p; ) + { + slot_base const * n = p -> next_; + delete p; + p = n; + } + } + template - void add(E && e) + BOOST_LEAF_CONSTEXPR typename std::decay::type & put(int err_id, E && e) { using T = typename std::decay::type; - for( auto & p : printers_ ) - if( p.first == &type ) - { - print_base * pb = p.second.get(); - static_cast *>(pb)->set(std::forward(e)); - return; - } - printers_.emplace_back(&type, print_base_ptr(new print_impl(std::forward(e)))); + BOOST_LEAF_ASSERT(last_ != nullptr); + BOOST_LEAF_ASSERT(*last_ == nullptr); + BOOST_LEAF_ASSERT(tls::read_ptr>() == nullptr); + slot_store * ss = new slot_store(err_id, std::forward(e)); + *last_ = ss; + last_ = &ss->next_; + ss->activate(); + return ss->value(err_id); + } + + void deactivate() noexcept + { + for( slot_base * p=first_; p; p=p->next_ ) + p->deactivate(); + } + + void propagate( int err_id ) noexcept + { + for( slot_base * p=first_; p; p=p->next_ ) + p->propagate(err_id); } template - void print( std::basic_ostream & os ) const + void print( std::basic_ostream & os, int key_to_print ) const { os << "Unhandled error objects:\n"; - for( auto const & p : printers_ ) - os << p.second.get()->print(); + for( slot_base const * p=first_; p; p=p->next_ ) + os << p->print(key_to_print); } }; @@ -300,18 +318,18 @@ namespace leaf_detail BOOST_LEAF_ASSERT(x.prev_==nullptr); } - BOOST_LEAF_CONSTEXPR void activate() noexcept + void activate() noexcept { prev_ = tls::read_ptr>(); tls::write_ptr>(this); } - BOOST_LEAF_CONSTEXPR void deactivate() noexcept + void deactivate() noexcept { tls::write_ptr>(prev_); } - BOOST_LEAF_CONSTEXPR void propagate( int err_id ) noexcept; + void propagate( int err_id ) noexcept; template void print( std::basic_ostream & os, int key_to_print ) const @@ -343,6 +361,22 @@ namespace leaf_detail #if BOOST_LEAF_CFG_DIAGNOSTICS + template <> + void slot::deactivate() noexcept + { + if( int const err_id = this->key() ) + if( e_unexpected_info * info = this->has_value(err_id) ) + info->deactivate(); + tls::write_ptr>(prev_); + } + + template <> + void slot::propagate( int err_id ) noexcept + { + if( e_unexpected_info * info = this->has_value(err_id) ) + info->propagate(err_id); + } + template BOOST_LEAF_CONSTEXPR inline void load_unexpected_count( int err_id ) noexcept { @@ -361,9 +395,21 @@ namespace leaf_detail if( slot * sl = tls::read_ptr>() ) { if( e_unexpected_info * unx = sl->has_value(err_id) ) - unx->add(std::forward(e)); + (void) unx->put(err_id, std::forward(e)); else - sl->put(err_id, e_unexpected_info()).add(std::forward(e)); + (void) sl->put(err_id).put(err_id, std::forward(e)); + } + } + + template + BOOST_LEAF_CONSTEXPR inline void accumulate_unexpected_info( int err_id, F && f ) noexcept + { + if( slot * sl = tls::read_ptr>() ) + { + if( e_unexpected_info * unx = sl->has_value(err_id) ) + (void) std::forward(f)(unx->put(err_id, E{})); + else + (void) std::forward(f)(sl->put(err_id).put(err_id, E{})); } } @@ -374,10 +420,17 @@ namespace leaf_detail load_unexpected_info(err_id, std::forward(e)); } + template + BOOST_LEAF_CONSTEXPR inline void accumulate_unexpected( int err_id, F && f ) noexcept + { + load_unexpected_count(err_id); + accumulate_unexpected_info(err_id, std::forward(f)); + } + #endif template - BOOST_LEAF_CONSTEXPR inline void slot::propagate( int err_id ) noexcept + inline void slot::propagate( int err_id ) noexcept { if( this->key()!=err_id && err_id!=0 ) return; @@ -394,7 +447,7 @@ namespace leaf_detail #endif } - template + template BOOST_LEAF_CONSTEXPR inline int load_slot( int err_id, E && e ) noexcept { static_assert(!std::is_pointer::value, "Error objects of pointer types are not allowed"); @@ -402,7 +455,10 @@ namespace leaf_detail using T = typename std::decay::type; BOOST_LEAF_ASSERT((err_id&3)==1); if( slot * p = tls::read_ptr>() ) - (void) p->put(err_id, std::forward(e)); + { + if( OverwriteAllowed || !p->has_value(err_id) ) + (void) p->put(err_id, std::forward(e)); + } #if BOOST_LEAF_CFG_DIAGNOSTICS else { @@ -429,6 +485,15 @@ namespace leaf_detail else (void) std::forward(f)(sl->put(err_id,E())); } +#if BOOST_LEAF_CFG_DIAGNOSTICS + else + { + int c = int(tls::read_uint()); + BOOST_LEAF_ASSERT(c>=0); + if( c ) + accumulate_unexpected(err_id, std::forward(f)); + } +#endif return 0; } } @@ -483,7 +548,7 @@ namespace leaf_detail { BOOST_LEAF_CONSTEXPR static int load_( int err_id, E && e ) noexcept { - return load_slot(err_id, std::forward(e)); + return load_slot(err_id, std::forward(e)); } }; @@ -492,7 +557,7 @@ namespace leaf_detail { BOOST_LEAF_CONSTEXPR static int load_( int err_id, F && f ) noexcept { - return load_slot(err_id, std::forward(f)()); + return load_slot(err_id, std::forward(f)()); } }; @@ -543,7 +608,7 @@ namespace leaf_detail else { err_id = new_id(); - (void) load_slot(err_id, ec); + (void) load_slot(err_id, ec); return (err_id&~3)|1; } } diff --git a/include/boost/leaf/handle_errors.hpp b/include/boost/leaf/handle_errors.hpp index 0da2b376..8517e7c2 100644 --- a/include/boost/leaf/handle_errors.hpp +++ b/include/boost/leaf/handle_errors.hpp @@ -235,11 +235,12 @@ class BOOST_LEAF_SYMBOL_VISIBLE verbose_diagnostic_info: public error_info friend std::basic_ostream & operator<<( std::basic_ostream & os, verbose_diagnostic_info const & x ) { os << "leaf::verbose_diagnostic_info for "; + int const err_id = x.error().value(); x.print(os); os << ":\n"; - x.print_(os, x.tup_, x.error().value()); + x.print_(os, x.tup_, err_id); if( x.e_ui_ ) - x.e_ui_->print(os); + x.e_ui_->print(os, err_id); return os; } }; diff --git a/include/boost/leaf/on_error.hpp b/include/boost/leaf/on_error.hpp index cd471829..f9250565 100644 --- a/include/boost/leaf/on_error.hpp +++ b/include/boost/leaf/on_error.hpp @@ -92,34 +92,18 @@ namespace leaf_detail class preloaded_item { using decay_E = typename std::decay::type; - slot * s_; decay_E e_; public: BOOST_LEAF_CONSTEXPR preloaded_item( E && e ): - s_(tls::read_ptr>()), e_(std::forward(e)) { } BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept { - BOOST_LEAF_ASSERT((err_id&3)==1); - if( s_ ) - { - if( !s_->has_value(err_id) ) - s_->put(err_id, std::move(e_)); - } -#if BOOST_LEAF_CFG_DIAGNOSTICS - else - { - int c = int(tls::read_uint()); - BOOST_LEAF_ASSERT(c>=0); - if( c ) - load_unexpected(err_id, std::move(e_)); - } -#endif + (void) load_slot(err_id, std::move(e_)); } }; @@ -127,34 +111,18 @@ namespace leaf_detail class deferred_item { using E = decltype(std::declval()()); - slot * s_; F f_; public: BOOST_LEAF_CONSTEXPR deferred_item( F && f ) noexcept: - s_(tls::read_ptr>()), f_(std::forward(f)) { } BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept { - BOOST_LEAF_ASSERT((err_id&3)==1); - if( s_ ) - { - if( !s_->has_value(err_id) ) - s_->put(err_id, f_()); - } -#if BOOST_LEAF_CFG_DIAGNOSTICS - else - { - int c = int(tls::read_uint()); - BOOST_LEAF_ASSERT(c>=0); - if( c ) - load_unexpected(err_id, std::forward(f_())); - } -#endif + (void) load_slot(err_id, f_()); } }; @@ -165,27 +133,18 @@ namespace leaf_detail class accumulating_item { using E = A0; - slot * s_; F f_; public: BOOST_LEAF_CONSTEXPR accumulating_item( F && f ) noexcept: - s_(tls::read_ptr>()), f_(std::forward(f)) { } BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept { - BOOST_LEAF_ASSERT((err_id&3)==1); - if( s_ ) - { - if( E * e = s_->has_value(err_id) ) - (void) f_(*e); - else - (void) f_(s_->put(err_id, E())); - } + accumulate_slot(err_id, std::move(f_)); } }; diff --git a/meson.build b/meson.build index 84828c9d..f351e97c 100644 --- a/meson.build +++ b/meson.build @@ -137,6 +137,8 @@ if option_enable_unit_tests 'diagnostic_info_test1', 'diagnostic_info_test2', 'diagnostic_info_test3', + 'diagnostic_info_test4', + 'diagnostic_info_test5', 'e_errno_test', 'e_LastError_test', 'error_code_test', diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f77ecd21..30a87d55 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -25,8 +25,8 @@ project BOOST_LEAF_BOOST_AVAILABLE single:BOOST_LEAF_NO_THREADS gcc:"-Wno-delete-non-virtual-dtor -Wno-parentheses" - clang:"-Wno-dangling-else" - darwin:"-Wno-unused-variable -Wno-delete-non-virtual-dtor -Wno-non-virtual-dtor -Wno-dangling-else" + clang:"-Wno-unused-variable -Wno-delete-non-virtual-dtor -Wno-non-virtual-dtor -Wno-delete-non-abstract-non-virtual-dtor -Wno-dangling-else" + darwin:"-Wno-unused-variable -Wno-delete-non-virtual-dtor -Wno-non-virtual-dtor -Wno-delete-non-abstract-non-virtual-dtor -Wno-dangling-else" msvc:"-wd 4267 -wd 4996 -wd 4244" ../../.. ; @@ -76,6 +76,8 @@ run defer_nested_success_result_test.cpp ; run diagnostic_info_test1.cpp ; run diagnostic_info_test2.cpp ; run diagnostic_info_test3.cpp ; +run diagnostic_info_test4.cpp ; +run diagnostic_info_test5.cpp ; run e_errno_test.cpp ; run e_LastError_test.cpp ; run error_code_test.cpp ; diff --git a/test/accumulate_nested_error_result_test.cpp b/test/accumulate_nested_error_result_test.cpp index abccbfec..67092d69 100644 --- a/test/accumulate_nested_error_result_test.cpp +++ b/test/accumulate_nested_error_result_test.cpp @@ -15,27 +15,35 @@ namespace leaf = boost::leaf; -template +template struct info { - int value = 0; + int value; + info(): + value(0) + { + } + explicit info(int value): + value(value) + { + } }; leaf::error_id f0() { auto load = leaf::on_error( []( info<0> & ) { } ); - return leaf::new_error( info<2>{2} ); + return leaf::new_error( info<2>(2) ); } leaf::error_id f1() { - auto load = leaf::on_error( info<0>{-1}, info<2>{-1}, []( info<1> & x ) {++x.value;} ); + auto load = leaf::on_error( info<0>(-1), info<2>(-1), []( info<1> & x ) {++x.value;} ); return f0(); } leaf::error_id f2() { - return f1().load( info<3>{3} ); + return f1().load( info<3>(3) ); } int main() diff --git a/test/accumulate_nested_new_error_exception_test.cpp b/test/accumulate_nested_new_error_exception_test.cpp index 5ac07bfe..57381580 100644 --- a/test/accumulate_nested_new_error_exception_test.cpp +++ b/test/accumulate_nested_new_error_exception_test.cpp @@ -32,13 +32,21 @@ namespace leaf = boost::leaf; template struct info { - int value = 0; + int value; + info(): + value(0) + { + } + explicit info(int value): + value(value) + { + } }; void f0() { - auto load = leaf::on_error( info<0>{-1} ); - leaf::throw_exception(info<1>{-1}); + auto load = leaf::on_error( info<0>(-1) ); + leaf::throw_exception(info<1>(-1)); } void f1() @@ -57,7 +65,7 @@ leaf::error_id f2() } catch( leaf::error_id const & err ) { - err.load( info<3>{3} ); + err.load( info<3>(3) ); throw; } catch(...) diff --git a/test/accumulate_nested_new_error_result_test.cpp b/test/accumulate_nested_new_error_result_test.cpp index 97bc2744..433dc90f 100644 --- a/test/accumulate_nested_new_error_result_test.cpp +++ b/test/accumulate_nested_new_error_result_test.cpp @@ -18,13 +18,21 @@ namespace leaf = boost::leaf; template struct info { - int value = 0; + int value; + info(): + value(0) + { + } + explicit info(int value): + value(value) + { + } }; leaf::error_id f0() { - auto load = leaf::on_error( info<0>{-1} ); - return leaf::new_error( info<1>{-1} ); + auto load = leaf::on_error( info<0>(-1) ); + return leaf::new_error( info<1>(-1) ); } leaf::error_id f1() @@ -36,7 +44,7 @@ leaf::error_id f1() leaf::error_id f2() { - return f1().load( info<3>{3} ); + return f1().load( info<3>(3) ); } int main() diff --git a/test/diagnostic_info_test1.cpp b/test/diagnostic_info_test1.cpp index 29ccd922..b57e7b80 100644 --- a/test/diagnostic_info_test1.cpp +++ b/test/diagnostic_info_test1.cpp @@ -12,8 +12,12 @@ # include #endif +#if BOOST_LEAF_CFG_STD_STRING +# include +#endif +#include + #include "lightweight_test.hpp" -#include namespace leaf = boost::leaf; diff --git a/test/diagnostic_info_test2.cpp b/test/diagnostic_info_test2.cpp index 7f36b87a..805b6a10 100644 --- a/test/diagnostic_info_test2.cpp +++ b/test/diagnostic_info_test2.cpp @@ -11,8 +11,12 @@ # include #endif +#if BOOST_LEAF_CFG_STD_STRING +# include +#endif +#include + #include "lightweight_test.hpp" -#include namespace leaf = boost::leaf; diff --git a/test/diagnostic_info_test3.cpp b/test/diagnostic_info_test3.cpp index f2bef1af..7a19401c 100644 --- a/test/diagnostic_info_test3.cpp +++ b/test/diagnostic_info_test3.cpp @@ -11,8 +11,12 @@ # include #endif +#if BOOST_LEAF_CFG_STD_STRING +# include +#endif +#include + #include "lightweight_test.hpp" -#include namespace leaf = boost::leaf; @@ -43,8 +47,8 @@ int main() st << di; std::string s = st.str(); #if BOOST_LEAF_CFG_DIAGNOSTICS - BOOST_TEST_EQ(s.find("41"), s.npos); - BOOST_TEST_NE(s.find("42"), s.npos); + BOOST_TEST_NE(s.find("41"), s.npos); + BOOST_TEST_EQ(s.find("42"), s.npos); #endif std::cout << s; #endif diff --git a/test/diagnostic_info_test4.cpp b/test/diagnostic_info_test4.cpp new file mode 100644 index 00000000..2e21070d --- /dev/null +++ b/test/diagnostic_info_test4.cpp @@ -0,0 +1,73 @@ +// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_LEAF_TEST_SINGLE_HEADER +# include "leaf.hpp" +#else +# include +# include +# include +#endif + +#if BOOST_LEAF_CFG_STD_STRING +# include +#endif +#include +#include + +#include "lightweight_test.hpp" + +namespace leaf = boost::leaf; + +struct my_error +{ + std::vector vec; + void append(int x) + { + vec.push_back(x); + } + friend std::ostream & operator<<( std::ostream & os, my_error const & x ) + { + for( auto const & e : x.vec ) + os << "appended: " << e << std::endl; + return os; + } +}; + +leaf::result f1() +{ + auto ctx_ = leaf::on_error([](my_error & e) {e.append(42);}); + return leaf::new_error("new_error"); +} + +leaf::result f2() +{ + auto ctx_ = leaf::on_error([](my_error & e) {e.append(43);}); + return f1(); +} + +int main() +{ + leaf::try_handle_all([]() -> leaf::result + { + return f2(); + }, + [](leaf::verbose_diagnostic_info const & e) + { +#if BOOST_LEAF_CFG_STD_STRING + std::ostringstream st; + st << e; + std::string s = st.str(); +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_NE(s.find("new_error"), s.npos); + BOOST_TEST_NE(s.find("appended: 42"), s.npos); + BOOST_TEST_NE(s.find("appended: 43"), s.npos); +#endif + std::cout << s; +#endif + } ); + + return boost::report_errors(); +} diff --git a/test/diagnostic_info_test5.cpp b/test/diagnostic_info_test5.cpp new file mode 100644 index 00000000..6dff6aea --- /dev/null +++ b/test/diagnostic_info_test5.cpp @@ -0,0 +1,134 @@ +// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_LEAF_TEST_SINGLE_HEADER +# include "leaf.hpp" +#else +# include +# include +# include +#endif + +#if BOOST_LEAF_CFG_STD_STRING +# include +#endif +#include + +#include "lightweight_test.hpp" + +namespace leaf = boost::leaf; + +namespace +{ + int counter = 0; +} + +template +struct info +{ + info(info const &) = delete; + info & operator=(info const &) = delete; + int acc = 0; + info() + { + ++counter; + } + info( info && x ): + acc(x.acc) + { + ++counter; + } + ~info() + { + --counter; + } + void accumulate() + { + ++acc; + } + friend std::ostream & operator<<( std::ostream & os, info const & x ) + { + return os << "info<" << N << ">: acc=" << x.acc; + } +}; + +leaf::result f1() +{ + return leaf::new_error(info<1>(), [](info<4> & x){ x.accumulate(); }); +} + +leaf::result f2() +{ + auto load = leaf::on_error(info<2>{}, [](){ return info<3>(); }, [](info<4> & x){ x.accumulate(); }); + return f1(); +} + +leaf::result f3() +{ + return leaf::try_handle_some( + []() -> leaf::result + { + return f2(); + }, + []( leaf::verbose_diagnostic_info const & e ) + { + return e.error(); + } ); +} + +int main() +{ + BOOST_TEST_EQ(counter, 0); + leaf::try_handle_all( + []() -> leaf::result + { + return f3(); + }, + []( info<1> const &, leaf::verbose_diagnostic_info const & di ) + { +#if BOOST_LEAF_CFG_STD_STRING + std::ostringstream st; + st << di; + std::string s = st.str(); +# if BOOST_LEAF_CFG_DIAGNOSTICS + auto const n1 = s.find("info<1>: acc=0"); + auto const n2 = s.find("info<2>: acc=0"); + auto const n3 = s.find("info<3>: acc=0"); + auto const n4 = s.find("info<4>: acc=2"); + auto const nd = s.find("Unhandled"); + BOOST_TEST_NE(n1, s.npos); + BOOST_TEST_NE(n2, s.npos); + BOOST_TEST_NE(n3, s.npos); + BOOST_TEST_NE(n4, s.npos); + BOOST_TEST_NE(nd, s.npos); + BOOST_TEST_LT(n1, nd); + BOOST_TEST_GT(n2, nd); + BOOST_TEST_GT(n3, nd); + BOOST_TEST_GT(n4, nd); + BOOST_TEST_EQ(counter, 4); +# else + BOOST_TEST_EQ(counter, 1); +# endif + std::cout << s; +#endif + }, + [] + { + std::abort(); + } ); + BOOST_TEST_EQ(counter, 0); + + leaf::try_handle_all( + []() -> leaf::result + { + return f2(); + }, + [] + { + BOOST_TEST_EQ(counter, 0); + } ); + + return boost::report_errors(); +} From 0b497c06e412617bff0b255c2f9595fbbc15d05d Mon Sep 17 00:00:00 2001 From: sdarwin Date: Mon, 28 Aug 2023 10:02:06 -0600 Subject: [PATCH 019/103] Upgrade MacOS drone tests --- .drone.jsonnet | 10 +++++----- .drone/drone.sh | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.drone.jsonnet b/.drone.jsonnet index f475c163..e84bfab0 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -44,7 +44,7 @@ local linux_pipeline(name, image, environment, packages = "", sources = [], arch ] }; -local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") = +local macos_pipeline(name, environment, xcode_version = "14.1", osx_version = "monterey", arch = "arm64") = { name: name, kind: "pipeline", @@ -213,13 +213,13 @@ local windows_pipeline(name, image, environment, arch = "amd64") = ), macos_pipeline( - "MacOS 10.15 Xcode 12.2 UBSAN", - { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + ubsan, + "MacOS 12.5.1 Xcode 14.1 UBSAN", + { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '14,17,20' } + ubsan, ), macos_pipeline( - "MacOS 10.15 Xcode 12.2 ASAN", - { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,1z' } + asan, + "MacOS 12.5.1 Xcode 14.1 ASAN", + { TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '14,17,20' } + asan, ), windows_pipeline( diff --git a/.drone/drone.sh b/.drone/drone.sh index baf7f521..daa71742 100755 --- a/.drone/drone.sh +++ b/.drone/drone.sh @@ -7,6 +7,7 @@ set -ex DRONE_BUILD_DIR=$(pwd) +export PATH=~/.local/bin:/usr/local/bin:$PATH BOOST_BRANCH=develop if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi From bcdf82f3a5ad60b5201bb490bff5630baa3e2f7c Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Mon, 28 Aug 2023 23:21:50 -0700 Subject: [PATCH 020/103] GHA update --- .github/workflows/ci.yml | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3061c0f0..7bd8c542 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,6 +66,12 @@ jobs: os: ubuntu-22.04 install: g++-12-multilib address-model: 32,64 + - toolset: gcc-13 + cxxstd: "11,14,17,20,2b" + os: ubuntu-latest + container: ubuntu:23.04 + install: g++-13-multilib + address-model: 32,64 - toolset: clang compiler: clang++-3.9 cxxstd: "11,14" @@ -126,9 +132,26 @@ jobs: cxxstd: "11,14,17,20,2b" os: ubuntu-22.04 install: clang-14 + - toolset: clang + compiler: clang++-15 + cxxstd: "11,14,17,20,2b" + os: ubuntu-22.04 + install: clang-15 + - toolset: clang + compiler: clang++-16 + cxxstd: "11,14,17,20,2b" + os: ubuntu-latest + container: ubuntu:23.04 + install: clang-16 - toolset: clang cxxstd: "11,14,17,2a" os: macos-11 + - toolset: clang + cxxstd: "11,14,17,20,2b" + os: macos-12 + - toolset: clang + cxxstd: "11,14,17,20,2b" + os: macos-13 runs-on: ${{matrix.os}} container: ${{matrix.container}} @@ -144,11 +167,13 @@ jobs: if: matrix.container run: | apt-get update - apt-get -y install sudo python git g++ + apt-get -y install sudo python3 git g++ - name: Install packages if: matrix.install - run: sudo apt-get -y install ${{matrix.install}} + run: | + sudo apt-get update + sudo apt-get -y install ${{matrix.install}} - name: Setup Boost run: | @@ -168,7 +193,7 @@ jobs: cd boost-root cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY git submodule update --init tools/boostdep - python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY + python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY ./bootstrap.sh ./b2 -d0 headers @@ -180,7 +205,7 @@ jobs: - name: Generate headers run: | cd ../boost-root/libs/leaf - python gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o test/leaf.hpp boost/leaf + python3 gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o test/leaf.hpp boost/leaf - name: Run tests run: | @@ -204,7 +229,6 @@ jobs: cxxstd: "14,17,latest" addrmd: 64 os: windows-2022 - embedmanifest: embed-manifest-via=linker - toolset: gcc cxxstd: "11,14,17,2a" addrmd: 64 @@ -240,7 +264,7 @@ jobs: - name: Generate headers run: | cd ../boost-root/libs/leaf - python gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o test/leaf.hpp boost/leaf + python3 gen/generate_single_header.py -i include/boost/leaf/detail/all.hpp -p include -o test/leaf.hpp boost/leaf - name: Run tests shell: cmd From 98288f52f2bd93def7d805d5c06e6163b4f03c2c Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Mon, 28 Aug 2023 23:22:32 -0700 Subject: [PATCH 021/103] Improved noexcept in load_slot --- include/boost/leaf/context.hpp | 2 +- include/boost/leaf/error.hpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/boost/leaf/context.hpp b/include/boost/leaf/context.hpp index 2e4633e8..dc0796a1 100644 --- a/include/boost/leaf/context.hpp +++ b/include/boost/leaf/context.hpp @@ -177,7 +177,7 @@ namespace leaf_detail BOOST_LEAF_ASSERT(err_id != 0); auto & sl = std::get(tup); if( sl.has_value(err_id) ) - load_slot(err_id, std::move(sl).value(err_id)); + (void) load_slot(err_id, std::move(sl).value(err_id)); tuple_for_each::propagate_captured(tup, err_id); } diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index 3d52a952..e718a923 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -329,7 +329,7 @@ namespace leaf_detail tls::write_ptr>(prev_); } - void propagate( int err_id ) noexcept; + void propagate( int err_id ) noexcept(!BOOST_LEAF_CFG_DIAGNOSTICS); template void print( std::basic_ostream & os, int key_to_print ) const @@ -362,7 +362,7 @@ namespace leaf_detail #if BOOST_LEAF_CFG_DIAGNOSTICS template <> - void slot::deactivate() noexcept + inline void slot::deactivate() noexcept { if( int const err_id = this->key() ) if( e_unexpected_info * info = this->has_value(err_id) ) @@ -371,7 +371,7 @@ namespace leaf_detail } template <> - void slot::propagate( int err_id ) noexcept + inline void slot::propagate( int err_id ) noexcept(!BOOST_LEAF_CFG_DIAGNOSTICS) { if( e_unexpected_info * info = this->has_value(err_id) ) info->propagate(err_id); @@ -414,14 +414,14 @@ namespace leaf_detail } template - BOOST_LEAF_CONSTEXPR inline void load_unexpected( int err_id, E && e ) noexcept + BOOST_LEAF_CONSTEXPR inline void load_unexpected( int err_id, E && e ) { load_unexpected_count(err_id); load_unexpected_info(err_id, std::forward(e)); } template - BOOST_LEAF_CONSTEXPR inline void accumulate_unexpected( int err_id, F && f ) noexcept + BOOST_LEAF_CONSTEXPR inline void accumulate_unexpected( int err_id, F && f ) { load_unexpected_count(err_id); accumulate_unexpected_info(err_id, std::forward(f)); @@ -430,7 +430,7 @@ namespace leaf_detail #endif template - inline void slot::propagate( int err_id ) noexcept + inline void slot::propagate( int err_id ) noexcept(!BOOST_LEAF_CFG_DIAGNOSTICS) { if( this->key()!=err_id && err_id!=0 ) return; @@ -448,7 +448,7 @@ namespace leaf_detail } template - BOOST_LEAF_CONSTEXPR inline int load_slot( int err_id, E && e ) noexcept + BOOST_LEAF_CONSTEXPR inline int load_slot( int err_id, E && e ) noexcept(!BOOST_LEAF_CFG_DIAGNOSTICS) { static_assert(!std::is_pointer::value, "Error objects of pointer types are not allowed"); static_assert(!std::is_same::type, error_id>::value, "Error objects of type error_id are not allowed"); @@ -472,7 +472,7 @@ namespace leaf_detail } template - BOOST_LEAF_CONSTEXPR inline int accumulate_slot( int err_id, F && f ) noexcept + BOOST_LEAF_CONSTEXPR inline int accumulate_slot( int err_id, F && f ) { static_assert(function_traits::arity==1, "Lambdas passed to accumulate must take a single e-type argument by reference"); using E = typename std::decay>::type; From 351a563de0f6ab1c7d0cb7216e6df7b5182a8663 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Fri, 15 Sep 2023 11:11:13 -0700 Subject: [PATCH 022/103] Copyright message update --- README.md | 2 +- benchmark/deep_stack_leaf.cpp | 2 +- benchmark/deep_stack_other.cpp | 2 +- doc/Jamfile | 2 +- example/capture_in_exception.cpp | 2 +- example/capture_in_result.cpp | 2 +- example/error_log.cpp | 2 +- example/error_trace.cpp | 2 +- example/exception_to_result.cpp | 2 +- example/lua_callback_eh.cpp | 2 +- example/lua_callback_result.cpp | 2 +- example/print_file/print_file_eh.cpp | 2 +- example/print_file/print_file_outcome_result.cpp | 2 +- example/print_file/print_file_result.cpp | 2 +- example/print_half.cpp | 2 +- gen/generate_single_header.py | 2 +- include/boost/leaf/config/tls.hpp | 2 +- include/boost/leaf/config/tls_array.hpp | 2 +- include/boost/leaf/config/tls_cpp11.hpp | 2 +- include/boost/leaf/config/tls_freertos.hpp | 2 +- include/boost/leaf/config/tls_globals.hpp | 2 +- include/boost/leaf/detail/all.hpp | 2 +- include/boost/leaf/detail/demangle.hpp | 2 +- include/boost/leaf/detail/function_traits.hpp | 2 +- include/boost/leaf/detail/mp11.hpp | 2 +- include/boost/leaf/detail/optional.hpp | 2 +- include/boost/leaf/exception.hpp | 2 +- include/boost/leaf/pred.hpp | 2 +- include/boost/leaf/to_variant.hpp | 2 +- test/BOOST_LEAF_ASSIGN_test.cpp | 2 +- test/BOOST_LEAF_AUTO_test.cpp | 2 +- test/BOOST_LEAF_CHECK_test.cpp | 2 +- test/_compile-fail-BOOST_LEAF_ASSIGN.cpp | 2 +- test/_compile-fail-BOOST_LEAF_AUTO.cpp | 2 +- test/_compile-fail-arg_boost_error_info_1.cpp | 2 +- test/_compile-fail-arg_boost_error_info_2.cpp | 2 +- test/_compile-fail-arg_catch_1.cpp | 2 +- test/_compile-fail-arg_catch_2.cpp | 2 +- test/_compile-fail-arg_match_1.cpp | 2 +- test/_compile-fail-arg_match_2.cpp | 2 +- test/_compile-fail-arg_rvalue_ref.cpp | 2 +- test/_compile-fail-diagnostic_info.cpp | 2 +- test/_compile-fail-error_info.cpp | 2 +- test/_compile-fail-exception_1.cpp | 2 +- test/_compile-fail-exception_2.cpp | 2 +- test/_compile-fail-new_error.cpp | 2 +- test/_compile-fail-result_1.cpp | 2 +- test/_compile-fail-result_2.cpp | 2 +- test/_compile-fail-result_3.cpp | 2 +- test/_compile-fail-result_4.cpp | 2 +- test/_compile-fail-verbose_diagnostic_info.cpp | 2 +- test/_hpp_capture_test.cpp | 2 +- test/_hpp_common_test.cpp | 2 +- test/_hpp_config_test.cpp | 2 +- test/_hpp_context_test.cpp | 2 +- test/_hpp_error_test.cpp | 2 +- test/_hpp_exception_test.cpp | 2 +- test/_hpp_handle_errors_test.cpp | 2 +- test/_hpp_leaf_test.cpp | 2 +- test/_hpp_on_error_test.cpp | 2 +- test/_hpp_pred_test.cpp | 2 +- test/_hpp_result_test.cpp | 2 +- test/_hpp_to_variant_test.cpp | 2 +- test/_test_ec.hpp | 2 +- test/_test_res.hpp | 2 +- test/accumulate_basic_test.cpp | 2 +- test/accumulate_nested_error_exception_test.cpp | 2 +- test/accumulate_nested_error_result_test.cpp | 2 +- test/accumulate_nested_new_error_exception_test.cpp | 2 +- test/accumulate_nested_new_error_result_test.cpp | 2 +- test/accumulate_nested_success_exception_test.cpp | 2 +- test/accumulate_nested_success_result_test.cpp | 2 +- test/boost_exception_test.cpp | 2 +- test/capture_exception_async_test.cpp | 2 +- test/capture_exception_result_async_test.cpp | 2 +- test/capture_exception_unload_test.cpp | 2 +- test/capture_result_async_test.cpp | 2 +- test/capture_result_unload_test.cpp | 2 +- test/context_activator_test.cpp | 2 +- test/context_deduction_test.cpp | 2 +- test/ctx_handle_all_test.cpp | 2 +- test/ctx_handle_some_test.cpp | 2 +- test/ctx_remote_handle_some_test.cpp | 2 +- test/defer_nested_error_exception_test.cpp | 2 +- test/defer_nested_error_result_test.cpp | 2 +- test/defer_nested_new_error_exception_test.cpp | 2 +- test/defer_nested_new_error_result_test.cpp | 2 +- test/defer_nested_success_exception_test.cpp | 2 +- test/error_code_test.cpp | 2 +- test/error_id_test.cpp | 2 +- test/exception_test.cpp | 2 +- test/exception_to_result_test.cpp | 2 +- test/function_traits_test.cpp | 2 +- test/github_issue53_test.cpp | 2 +- test/github_issue53x_test.cpp | 2 +- test/handle_all_other_result_test.cpp | 2 +- test/handle_all_test.cpp | 2 +- test/handle_basic_test.cpp | 2 +- test/handle_some_other_result_test.cpp | 2 +- test/handle_some_test.cpp | 2 +- test/lightweight_test.hpp | 2 +- test/match_member_test.cpp | 2 +- test/match_test.cpp | 2 +- test/match_value_test.cpp | 2 +- test/multiple_errors_test.cpp | 2 +- test/preload_exception_test.cpp | 2 +- test/preload_nested_error_exception_test.cpp | 2 +- test/preload_nested_error_result_test.cpp | 2 +- test/preload_nested_new_error_exception_test.cpp | 2 +- test/preload_nested_new_error_result_test.cpp | 2 +- test/preload_nested_success_exception_test.cpp | 2 +- test/preload_nested_success_result_test.cpp | 2 +- test/result_bad_result_test.cpp | 2 +- test/result_implicit_conversion_test.cpp | 2 +- test/result_load_test.cpp | 2 +- test/result_ref_test.cpp | 2 +- test/result_state_test.cpp | 2 +- test/tls_array_alloc_test1.cpp | 2 +- test/tls_array_alloc_test2.cpp | 2 +- test/tls_array_alloc_test3.cpp | 2 +- test/tls_array_test.cpp | 2 +- test/to_variant_test.cpp | 2 +- test/try_catch_error_id_test.cpp | 2 +- test/try_catch_system_error_test.cpp | 2 +- test/try_catch_test.cpp | 2 +- test/try_exception_and_result_test.cpp | 2 +- test/visibility_test_lib.cpp | 2 +- wasm.txt | 2 +- 128 files changed, 128 insertions(+), 128 deletions(-) diff --git a/README.md b/README.md index a8241876..3a75cd81 100644 --- a/README.md +++ b/README.md @@ -28,4 +28,4 @@ Besides GitHub, there are two other distribution channels: * LEAF is included in official [Boost](https://www.boost.org/) releases, starting with Boost 1.75. * For maximum portability, the library is also available in single-header format: simply download [leaf.hpp](https://boostorg.github.io/leaf/leaf.hpp) (direct download link). -Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. Distributed under the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0]. +Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. Distributed under the http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0]. diff --git a/benchmark/deep_stack_leaf.cpp b/benchmark/deep_stack_leaf.cpp index beea2c62..7940ab5f 100644 --- a/benchmark/deep_stack_leaf.cpp +++ b/benchmark/deep_stack_leaf.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/benchmark/deep_stack_other.cpp b/benchmark/deep_stack_other.cpp index aa61f67f..59f78310 100644 --- a/benchmark/deep_stack_other.cpp +++ b/benchmark/deep_stack_other.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/doc/Jamfile b/doc/Jamfile index e183454f..84edc47c 100644 --- a/doc/Jamfile +++ b/doc/Jamfile @@ -1,5 +1,5 @@ # Copyright 2017 Peter Dimov -# Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +# Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. # # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE_1_0.txt or copy at diff --git a/example/capture_in_exception.cpp b/example/capture_in_exception.cpp index f9facd34..a73d30d9 100644 --- a/example/capture_in_exception.cpp +++ b/example/capture_in_exception.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/example/capture_in_result.cpp b/example/capture_in_result.cpp index 04ed1970..c8c9ad7f 100644 --- a/example/capture_in_result.cpp +++ b/example/capture_in_result.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/example/error_log.cpp b/example/error_log.cpp index 3ae442b5..1c6df959 100644 --- a/example/error_log.cpp +++ b/example/error_log.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/example/error_trace.cpp b/example/error_trace.cpp index 603fc490..a2aabccf 100644 --- a/example/error_trace.cpp +++ b/example/error_trace.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/example/exception_to_result.cpp b/example/exception_to_result.cpp index 98fdfcbb..5ede8c35 100644 --- a/example/exception_to_result.cpp +++ b/example/exception_to_result.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/example/lua_callback_eh.cpp b/example/lua_callback_eh.cpp index 00f62c3f..5c27f942 100644 --- a/example/lua_callback_eh.cpp +++ b/example/lua_callback_eh.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/example/lua_callback_result.cpp b/example/lua_callback_result.cpp index f2b407cd..6cc3582b 100644 --- a/example/lua_callback_result.cpp +++ b/example/lua_callback_result.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/example/print_file/print_file_eh.cpp b/example/print_file/print_file_eh.cpp index cfd04fa8..2e07b582 100644 --- a/example/print_file/print_file_eh.cpp +++ b/example/print_file/print_file_eh.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/example/print_file/print_file_outcome_result.cpp b/example/print_file/print_file_outcome_result.cpp index 454ff5e9..5c642699 100644 --- a/example/print_file/print_file_outcome_result.cpp +++ b/example/print_file/print_file_outcome_result.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/example/print_file/print_file_result.cpp b/example/print_file/print_file_result.cpp index beeb702f..e42f4115 100644 --- a/example/print_file/print_file_result.cpp +++ b/example/print_file/print_file_result.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/example/print_half.cpp b/example/print_half.cpp index faab781c..efcd53e2 100644 --- a/example/print_half.cpp +++ b/example/print_half.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/gen/generate_single_header.py b/gen/generate_single_header.py index 623fddfb..571f20f8 100644 --- a/gen/generate_single_header.py +++ b/gen/generate_single_header.py @@ -1,6 +1,6 @@ """ - Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. + Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. Copyright (c) Sorin Fetche Distributed under the Boost Software License, Version 1.0. (See accompanying diff --git a/include/boost/leaf/config/tls.hpp b/include/boost/leaf/config/tls.hpp index 279bafb2..951da34d 100644 --- a/include/boost/leaf/config/tls.hpp +++ b/include/boost/leaf/config/tls.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED #define BOOST_LEAF_CONFIG_TLS_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/boost/leaf/config/tls_array.hpp b/include/boost/leaf/config/tls_array.hpp index 0d0e83c4..a78addc8 100644 --- a/include/boost/leaf/config/tls_array.hpp +++ b/include/boost/leaf/config/tls_array.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_CONFIG_TLS_ARRAY_HPP_INCLUDED #define BOOST_LEAF_CONFIG_TLS_ARRAY_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Copyright (c) 2022 Khalil Estell // Distributed under the Boost Software License, Version 1.0. (See accompanying diff --git a/include/boost/leaf/config/tls_cpp11.hpp b/include/boost/leaf/config/tls_cpp11.hpp index 6b244b6a..16c9b68f 100644 --- a/include/boost/leaf/config/tls_cpp11.hpp +++ b/include/boost/leaf/config/tls_cpp11.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_CONFIG_TLS_CPP11_HPP_INCLUDED #define BOOST_LEAF_CONFIG_TLS_CPP11_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/boost/leaf/config/tls_freertos.hpp b/include/boost/leaf/config/tls_freertos.hpp index a2678693..182bd1ad 100644 --- a/include/boost/leaf/config/tls_freertos.hpp +++ b/include/boost/leaf/config/tls_freertos.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_CONFIG_TLS_FREERTOS_HPP_INCLUDED #define BOOST_LEAF_CONFIG_TLS_FREERTOS_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Copyright (c) 2022 Khalil Estell // Distributed under the Boost Software License, Version 1.0. (See accompanying diff --git a/include/boost/leaf/config/tls_globals.hpp b/include/boost/leaf/config/tls_globals.hpp index e8cca3bc..0575aeb4 100644 --- a/include/boost/leaf/config/tls_globals.hpp +++ b/include/boost/leaf/config/tls_globals.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_CONFIG_TLS_GLOBALS_HPP_INCLUDED #define BOOST_LEAF_CONFIG_TLS_GLOBALS_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/boost/leaf/detail/all.hpp b/include/boost/leaf/detail/all.hpp index 8f5dcbd4..769cfd84 100644 --- a/include/boost/leaf/detail/all.hpp +++ b/include/boost/leaf/detail/all.hpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/boost/leaf/detail/demangle.hpp b/include/boost/leaf/detail/demangle.hpp index ed275241..3ad4ad33 100644 --- a/include/boost/leaf/detail/demangle.hpp +++ b/include/boost/leaf/detail/demangle.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED #define BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/boost/leaf/detail/function_traits.hpp b/include/boost/leaf/detail/function_traits.hpp index 3ef58ced..0a9acb03 100644 --- a/include/boost/leaf/detail/function_traits.hpp +++ b/include/boost/leaf/detail/function_traits.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED #define BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/boost/leaf/detail/mp11.hpp b/include/boost/leaf/detail/mp11.hpp index 6a1aee32..d0ad6117 100644 --- a/include/boost/leaf/detail/mp11.hpp +++ b/include/boost/leaf/detail/mp11.hpp @@ -2,7 +2,7 @@ #define BOOST_LEAF_DETAIL_MP11_HPP_INCLUDED // Copyright 2015-2017 Peter Dimov. -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // // Distributed under the Boost Software License, Version 1.0. // diff --git a/include/boost/leaf/detail/optional.hpp b/include/boost/leaf/detail/optional.hpp index 93def2fc..ac1c8a24 100644 --- a/include/boost/leaf/detail/optional.hpp +++ b/include/boost/leaf/detail/optional.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED #define BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/boost/leaf/exception.hpp b/include/boost/leaf/exception.hpp index e28ba27f..2de4a29a 100644 --- a/include/boost/leaf/exception.hpp +++ b/include/boost/leaf/exception.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_EXCEPTION_HPP_INCLUDED #define BOOST_LEAF_EXCEPTION_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/boost/leaf/pred.hpp b/include/boost/leaf/pred.hpp index 01ecf47e..1c5dbcb9 100644 --- a/include/boost/leaf/pred.hpp +++ b/include/boost/leaf/pred.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_PRED_HPP_INCLUDED #define BOOST_LEAF_PRED_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/boost/leaf/to_variant.hpp b/include/boost/leaf/to_variant.hpp index 83a23b4c..9c3b84ff 100644 --- a/include/boost/leaf/to_variant.hpp +++ b/include/boost/leaf/to_variant.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_TO_VARIANT_HPP_INCLUDED #define BOOST_LEAF_TO_VARIANT_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/BOOST_LEAF_ASSIGN_test.cpp b/test/BOOST_LEAF_ASSIGN_test.cpp index 3ba9ae30..f48fa867 100644 --- a/test/BOOST_LEAF_ASSIGN_test.cpp +++ b/test/BOOST_LEAF_ASSIGN_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/BOOST_LEAF_AUTO_test.cpp b/test/BOOST_LEAF_AUTO_test.cpp index debcf50f..748bb032 100644 --- a/test/BOOST_LEAF_AUTO_test.cpp +++ b/test/BOOST_LEAF_AUTO_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/BOOST_LEAF_CHECK_test.cpp b/test/BOOST_LEAF_CHECK_test.cpp index d50186f6..7264a8df 100644 --- a/test/BOOST_LEAF_CHECK_test.cpp +++ b/test/BOOST_LEAF_CHECK_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-BOOST_LEAF_ASSIGN.cpp b/test/_compile-fail-BOOST_LEAF_ASSIGN.cpp index effe3b2e..d8ec91f7 100644 --- a/test/_compile-fail-BOOST_LEAF_ASSIGN.cpp +++ b/test/_compile-fail-BOOST_LEAF_ASSIGN.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-BOOST_LEAF_AUTO.cpp b/test/_compile-fail-BOOST_LEAF_AUTO.cpp index 25be0027..eaafbbb8 100644 --- a/test/_compile-fail-BOOST_LEAF_AUTO.cpp +++ b/test/_compile-fail-BOOST_LEAF_AUTO.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-arg_boost_error_info_1.cpp b/test/_compile-fail-arg_boost_error_info_1.cpp index b3bc8fcb..5ae5a420 100644 --- a/test/_compile-fail-arg_boost_error_info_1.cpp +++ b/test/_compile-fail-arg_boost_error_info_1.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-arg_boost_error_info_2.cpp b/test/_compile-fail-arg_boost_error_info_2.cpp index b3bc8fcb..5ae5a420 100644 --- a/test/_compile-fail-arg_boost_error_info_2.cpp +++ b/test/_compile-fail-arg_boost_error_info_2.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-arg_catch_1.cpp b/test/_compile-fail-arg_catch_1.cpp index 6d0b3f62..35e782da 100644 --- a/test/_compile-fail-arg_catch_1.cpp +++ b/test/_compile-fail-arg_catch_1.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-arg_catch_2.cpp b/test/_compile-fail-arg_catch_2.cpp index d1aaf276..a2022b26 100644 --- a/test/_compile-fail-arg_catch_2.cpp +++ b/test/_compile-fail-arg_catch_2.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-arg_match_1.cpp b/test/_compile-fail-arg_match_1.cpp index 6ad721fc..b10b53f9 100644 --- a/test/_compile-fail-arg_match_1.cpp +++ b/test/_compile-fail-arg_match_1.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-arg_match_2.cpp b/test/_compile-fail-arg_match_2.cpp index 0d1ae1cb..c89eb773 100644 --- a/test/_compile-fail-arg_match_2.cpp +++ b/test/_compile-fail-arg_match_2.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-arg_rvalue_ref.cpp b/test/_compile-fail-arg_rvalue_ref.cpp index 458cf4ba..342ec681 100644 --- a/test/_compile-fail-arg_rvalue_ref.cpp +++ b/test/_compile-fail-arg_rvalue_ref.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-diagnostic_info.cpp b/test/_compile-fail-diagnostic_info.cpp index 59df9664..5149693f 100644 --- a/test/_compile-fail-diagnostic_info.cpp +++ b/test/_compile-fail-diagnostic_info.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-error_info.cpp b/test/_compile-fail-error_info.cpp index 39d7267c..2f04ff66 100644 --- a/test/_compile-fail-error_info.cpp +++ b/test/_compile-fail-error_info.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-exception_1.cpp b/test/_compile-fail-exception_1.cpp index 15fdc922..d7f9b857 100644 --- a/test/_compile-fail-exception_1.cpp +++ b/test/_compile-fail-exception_1.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-exception_2.cpp b/test/_compile-fail-exception_2.cpp index 540a6e61..47926525 100644 --- a/test/_compile-fail-exception_2.cpp +++ b/test/_compile-fail-exception_2.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-new_error.cpp b/test/_compile-fail-new_error.cpp index 6aca1ff5..62db0836 100644 --- a/test/_compile-fail-new_error.cpp +++ b/test/_compile-fail-new_error.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-result_1.cpp b/test/_compile-fail-result_1.cpp index c4bec3df..46cec4bf 100644 --- a/test/_compile-fail-result_1.cpp +++ b/test/_compile-fail-result_1.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-result_2.cpp b/test/_compile-fail-result_2.cpp index 1acdd95a..ec80ea29 100644 --- a/test/_compile-fail-result_2.cpp +++ b/test/_compile-fail-result_2.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Thanks @strager // Distributed under the Boost Software License, Version 1.0. (See accompanying diff --git a/test/_compile-fail-result_3.cpp b/test/_compile-fail-result_3.cpp index 47bd73cf..e74cf57d 100644 --- a/test/_compile-fail-result_3.cpp +++ b/test/_compile-fail-result_3.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Thanks @strager // Distributed under the Boost Software License, Version 1.0. (See accompanying diff --git a/test/_compile-fail-result_4.cpp b/test/_compile-fail-result_4.cpp index f25f6403..908a7712 100644 --- a/test/_compile-fail-result_4.cpp +++ b/test/_compile-fail-result_4.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_compile-fail-verbose_diagnostic_info.cpp b/test/_compile-fail-verbose_diagnostic_info.cpp index 61ecc650..fdbc0c92 100644 --- a/test/_compile-fail-verbose_diagnostic_info.cpp +++ b/test/_compile-fail-verbose_diagnostic_info.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_hpp_capture_test.cpp b/test/_hpp_capture_test.cpp index 4107de3e..3a58fdcc 100644 --- a/test/_hpp_capture_test.cpp +++ b/test/_hpp_capture_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_hpp_common_test.cpp b/test/_hpp_common_test.cpp index b3afd016..0c7b89d0 100644 --- a/test/_hpp_common_test.cpp +++ b/test/_hpp_common_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_hpp_config_test.cpp b/test/_hpp_config_test.cpp index a517cafb..49ba3ea5 100644 --- a/test/_hpp_config_test.cpp +++ b/test/_hpp_config_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_hpp_context_test.cpp b/test/_hpp_context_test.cpp index 667e244e..b9f5bfcd 100644 --- a/test/_hpp_context_test.cpp +++ b/test/_hpp_context_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_hpp_error_test.cpp b/test/_hpp_error_test.cpp index 1dc20a54..ed40b8bc 100644 --- a/test/_hpp_error_test.cpp +++ b/test/_hpp_error_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_hpp_exception_test.cpp b/test/_hpp_exception_test.cpp index bda12919..66bc3985 100644 --- a/test/_hpp_exception_test.cpp +++ b/test/_hpp_exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_hpp_handle_errors_test.cpp b/test/_hpp_handle_errors_test.cpp index 9e779013..0b2715ce 100644 --- a/test/_hpp_handle_errors_test.cpp +++ b/test/_hpp_handle_errors_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_hpp_leaf_test.cpp b/test/_hpp_leaf_test.cpp index 306c2bfe..a20facf6 100644 --- a/test/_hpp_leaf_test.cpp +++ b/test/_hpp_leaf_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_hpp_on_error_test.cpp b/test/_hpp_on_error_test.cpp index 578f299a..7dcffb22 100644 --- a/test/_hpp_on_error_test.cpp +++ b/test/_hpp_on_error_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_hpp_pred_test.cpp b/test/_hpp_pred_test.cpp index e7826451..0fa29d43 100644 --- a/test/_hpp_pred_test.cpp +++ b/test/_hpp_pred_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_hpp_result_test.cpp b/test/_hpp_result_test.cpp index 3cf95d65..73eb9ec1 100644 --- a/test/_hpp_result_test.cpp +++ b/test/_hpp_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_hpp_to_variant_test.cpp b/test/_hpp_to_variant_test.cpp index 3bedbe54..c5dcd6c9 100644 --- a/test/_hpp_to_variant_test.cpp +++ b/test/_hpp_to_variant_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_test_ec.hpp b/test/_test_ec.hpp index 77399c3c..6fd5e6d4 100644 --- a/test/_test_ec.hpp +++ b/test/_test_ec.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_TEST_EC_HPP_INCLUDED #define BOOST_LEAF_TEST_EC_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/_test_res.hpp b/test/_test_res.hpp index 089f85ae..aba66818 100644 --- a/test/_test_res.hpp +++ b/test/_test_res.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_TEST_RES_HPP_INCLUDED #define BOOST_LEAF_TEST_RES_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/accumulate_basic_test.cpp b/test/accumulate_basic_test.cpp index b32c97a4..2e6d7768 100644 --- a/test/accumulate_basic_test.cpp +++ b/test/accumulate_basic_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/accumulate_nested_error_exception_test.cpp b/test/accumulate_nested_error_exception_test.cpp index a10dcbe2..04a98078 100644 --- a/test/accumulate_nested_error_exception_test.cpp +++ b/test/accumulate_nested_error_exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/accumulate_nested_error_result_test.cpp b/test/accumulate_nested_error_result_test.cpp index 67092d69..569a9d4c 100644 --- a/test/accumulate_nested_error_result_test.cpp +++ b/test/accumulate_nested_error_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/accumulate_nested_new_error_exception_test.cpp b/test/accumulate_nested_new_error_exception_test.cpp index 57381580..3f28dd35 100644 --- a/test/accumulate_nested_new_error_exception_test.cpp +++ b/test/accumulate_nested_new_error_exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/accumulate_nested_new_error_result_test.cpp b/test/accumulate_nested_new_error_result_test.cpp index 433dc90f..48d070e3 100644 --- a/test/accumulate_nested_new_error_result_test.cpp +++ b/test/accumulate_nested_new_error_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/accumulate_nested_success_exception_test.cpp b/test/accumulate_nested_success_exception_test.cpp index ad8edc66..f01d27c4 100644 --- a/test/accumulate_nested_success_exception_test.cpp +++ b/test/accumulate_nested_success_exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/accumulate_nested_success_result_test.cpp b/test/accumulate_nested_success_result_test.cpp index fe068eb1..1ad3c020 100644 --- a/test/accumulate_nested_success_result_test.cpp +++ b/test/accumulate_nested_success_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/boost_exception_test.cpp b/test/boost_exception_test.cpp index 1ed1bb97..a45fa236 100644 --- a/test/boost_exception_test.cpp +++ b/test/boost_exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/capture_exception_async_test.cpp b/test/capture_exception_async_test.cpp index 5825a913..0e720721 100644 --- a/test/capture_exception_async_test.cpp +++ b/test/capture_exception_async_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/capture_exception_result_async_test.cpp b/test/capture_exception_result_async_test.cpp index 48df5ead..9471ea6c 100644 --- a/test/capture_exception_result_async_test.cpp +++ b/test/capture_exception_result_async_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/capture_exception_unload_test.cpp b/test/capture_exception_unload_test.cpp index 304318e7..31a66e3e 100644 --- a/test/capture_exception_unload_test.cpp +++ b/test/capture_exception_unload_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/capture_result_async_test.cpp b/test/capture_result_async_test.cpp index a11e4c8a..3b6dfba0 100644 --- a/test/capture_result_async_test.cpp +++ b/test/capture_result_async_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/capture_result_unload_test.cpp b/test/capture_result_unload_test.cpp index add325c0..6c256561 100644 --- a/test/capture_result_unload_test.cpp +++ b/test/capture_result_unload_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/context_activator_test.cpp b/test/context_activator_test.cpp index 4289821c..22a364ea 100644 --- a/test/context_activator_test.cpp +++ b/test/context_activator_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/context_deduction_test.cpp b/test/context_deduction_test.cpp index 893f5832..e7f1234d 100644 --- a/test/context_deduction_test.cpp +++ b/test/context_deduction_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/ctx_handle_all_test.cpp b/test/ctx_handle_all_test.cpp index 1357a8b6..03a77bae 100644 --- a/test/ctx_handle_all_test.cpp +++ b/test/ctx_handle_all_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/ctx_handle_some_test.cpp b/test/ctx_handle_some_test.cpp index 099ed215..bd6d0c5b 100644 --- a/test/ctx_handle_some_test.cpp +++ b/test/ctx_handle_some_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/ctx_remote_handle_some_test.cpp b/test/ctx_remote_handle_some_test.cpp index fd5f8bad..31f38dec 100644 --- a/test/ctx_remote_handle_some_test.cpp +++ b/test/ctx_remote_handle_some_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/defer_nested_error_exception_test.cpp b/test/defer_nested_error_exception_test.cpp index 887064b4..da94a0bb 100644 --- a/test/defer_nested_error_exception_test.cpp +++ b/test/defer_nested_error_exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/defer_nested_error_result_test.cpp b/test/defer_nested_error_result_test.cpp index 5d2a7dcc..c57bf91d 100644 --- a/test/defer_nested_error_result_test.cpp +++ b/test/defer_nested_error_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/defer_nested_new_error_exception_test.cpp b/test/defer_nested_new_error_exception_test.cpp index 2b5d82cb..7f702323 100644 --- a/test/defer_nested_new_error_exception_test.cpp +++ b/test/defer_nested_new_error_exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/defer_nested_new_error_result_test.cpp b/test/defer_nested_new_error_result_test.cpp index 9ba7f4d8..b3610608 100644 --- a/test/defer_nested_new_error_result_test.cpp +++ b/test/defer_nested_new_error_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/defer_nested_success_exception_test.cpp b/test/defer_nested_success_exception_test.cpp index 2e559890..6cdaad77 100644 --- a/test/defer_nested_success_exception_test.cpp +++ b/test/defer_nested_success_exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/error_code_test.cpp b/test/error_code_test.cpp index 1a3ec3e8..0ac0cfd9 100644 --- a/test/error_code_test.cpp +++ b/test/error_code_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/error_id_test.cpp b/test/error_id_test.cpp index 904aecd7..ce4e2609 100644 --- a/test/error_id_test.cpp +++ b/test/error_id_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/exception_test.cpp b/test/exception_test.cpp index 8a60e4de..8ecb7042 100644 --- a/test/exception_test.cpp +++ b/test/exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/exception_to_result_test.cpp b/test/exception_to_result_test.cpp index c5838755..139fdf43 100644 --- a/test/exception_to_result_test.cpp +++ b/test/exception_to_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/function_traits_test.cpp b/test/function_traits_test.cpp index e8b8ce5b..3fc153a7 100644 --- a/test/function_traits_test.cpp +++ b/test/function_traits_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/github_issue53_test.cpp b/test/github_issue53_test.cpp index 4ecd3017..efcbabc9 100644 --- a/test/github_issue53_test.cpp +++ b/test/github_issue53_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/github_issue53x_test.cpp b/test/github_issue53x_test.cpp index 614d4179..6c9870d9 100644 --- a/test/github_issue53x_test.cpp +++ b/test/github_issue53x_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/handle_all_other_result_test.cpp b/test/handle_all_other_result_test.cpp index 8a0f5929..9a7c988c 100644 --- a/test/handle_all_other_result_test.cpp +++ b/test/handle_all_other_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/handle_all_test.cpp b/test/handle_all_test.cpp index 57f02218..f8f89f70 100644 --- a/test/handle_all_test.cpp +++ b/test/handle_all_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/handle_basic_test.cpp b/test/handle_basic_test.cpp index c9bdaf7c..14bddbf1 100644 --- a/test/handle_basic_test.cpp +++ b/test/handle_basic_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/handle_some_other_result_test.cpp b/test/handle_some_other_result_test.cpp index 6a6a78c5..6bafbf4b 100644 --- a/test/handle_some_other_result_test.cpp +++ b/test/handle_some_other_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/handle_some_test.cpp b/test/handle_some_test.cpp index 195d24cf..e763a442 100644 --- a/test/handle_some_test.cpp +++ b/test/handle_some_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/lightweight_test.hpp b/test/lightweight_test.hpp index 46a31a8b..4aeac364 100644 --- a/test/lightweight_test.hpp +++ b/test/lightweight_test.hpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/match_member_test.cpp b/test/match_member_test.cpp index 350c3d6f..1fa4df71 100644 --- a/test/match_member_test.cpp +++ b/test/match_member_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/match_test.cpp b/test/match_test.cpp index 2aed5f8c..0ac5c3b8 100644 --- a/test/match_test.cpp +++ b/test/match_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/match_value_test.cpp b/test/match_value_test.cpp index 41054235..5dc194c8 100644 --- a/test/match_value_test.cpp +++ b/test/match_value_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/multiple_errors_test.cpp b/test/multiple_errors_test.cpp index 1e6718de..1465f389 100644 --- a/test/multiple_errors_test.cpp +++ b/test/multiple_errors_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/preload_exception_test.cpp b/test/preload_exception_test.cpp index 231f4f6a..6cfb3277 100644 --- a/test/preload_exception_test.cpp +++ b/test/preload_exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/preload_nested_error_exception_test.cpp b/test/preload_nested_error_exception_test.cpp index eae593fb..db24377a 100644 --- a/test/preload_nested_error_exception_test.cpp +++ b/test/preload_nested_error_exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/preload_nested_error_result_test.cpp b/test/preload_nested_error_result_test.cpp index 1689e921..1642fa9c 100644 --- a/test/preload_nested_error_result_test.cpp +++ b/test/preload_nested_error_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/preload_nested_new_error_exception_test.cpp b/test/preload_nested_new_error_exception_test.cpp index bf4560e4..62c8b778 100644 --- a/test/preload_nested_new_error_exception_test.cpp +++ b/test/preload_nested_new_error_exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/preload_nested_new_error_result_test.cpp b/test/preload_nested_new_error_result_test.cpp index 3066c349..40b0af06 100644 --- a/test/preload_nested_new_error_result_test.cpp +++ b/test/preload_nested_new_error_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/preload_nested_success_exception_test.cpp b/test/preload_nested_success_exception_test.cpp index 86f509e6..9e88f05d 100644 --- a/test/preload_nested_success_exception_test.cpp +++ b/test/preload_nested_success_exception_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/preload_nested_success_result_test.cpp b/test/preload_nested_success_result_test.cpp index f5026872..427b03f8 100644 --- a/test/preload_nested_success_result_test.cpp +++ b/test/preload_nested_success_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/result_bad_result_test.cpp b/test/result_bad_result_test.cpp index ed6bbedb..58bff44e 100644 --- a/test/result_bad_result_test.cpp +++ b/test/result_bad_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/result_implicit_conversion_test.cpp b/test/result_implicit_conversion_test.cpp index b2ae9694..6e71f719 100644 --- a/test/result_implicit_conversion_test.cpp +++ b/test/result_implicit_conversion_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/result_load_test.cpp b/test/result_load_test.cpp index 45c8555b..e758a95f 100644 --- a/test/result_load_test.cpp +++ b/test/result_load_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/result_ref_test.cpp b/test/result_ref_test.cpp index 819ddef9..f7be0cf9 100644 --- a/test/result_ref_test.cpp +++ b/test/result_ref_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/result_state_test.cpp b/test/result_state_test.cpp index 591721f5..8588afbc 100644 --- a/test/result_state_test.cpp +++ b/test/result_state_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/tls_array_alloc_test1.cpp b/test/tls_array_alloc_test1.cpp index d550bd19..ebb0eef0 100644 --- a/test/tls_array_alloc_test1.cpp +++ b/test/tls_array_alloc_test1.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/tls_array_alloc_test2.cpp b/test/tls_array_alloc_test2.cpp index 870d6229..2b922433 100644 --- a/test/tls_array_alloc_test2.cpp +++ b/test/tls_array_alloc_test2.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/tls_array_alloc_test3.cpp b/test/tls_array_alloc_test3.cpp index cfcafbfe..c7ce6bff 100644 --- a/test/tls_array_alloc_test3.cpp +++ b/test/tls_array_alloc_test3.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/tls_array_test.cpp b/test/tls_array_test.cpp index 5e6e650f..ae36eed8 100644 --- a/test/tls_array_test.cpp +++ b/test/tls_array_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/to_variant_test.cpp b/test/to_variant_test.cpp index f2d6fc29..ac13b12d 100644 --- a/test/to_variant_test.cpp +++ b/test/to_variant_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/try_catch_error_id_test.cpp b/test/try_catch_error_id_test.cpp index 1d2bbf87..fa83568c 100644 --- a/test/try_catch_error_id_test.cpp +++ b/test/try_catch_error_id_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/try_catch_system_error_test.cpp b/test/try_catch_system_error_test.cpp index ad3abd58..5c13eafc 100644 --- a/test/try_catch_system_error_test.cpp +++ b/test/try_catch_system_error_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/try_catch_test.cpp b/test/try_catch_test.cpp index 713cbbf2..f3ed55fb 100644 --- a/test/try_catch_test.cpp +++ b/test/try_catch_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/try_exception_and_result_test.cpp b/test/try_exception_and_result_test.cpp index 57d62ef1..088ade9a 100644 --- a/test/try_exception_and_result_test.cpp +++ b/test/try_exception_and_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/visibility_test_lib.cpp b/test/visibility_test_lib.cpp index a94d303b..0cfbc9c1 100644 --- a/test/visibility_test_lib.cpp +++ b/test/visibility_test_lib.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/wasm.txt b/wasm.txt index 82e568fe..af95800b 100644 --- a/wasm.txt +++ b/wasm.txt @@ -1,4 +1,4 @@ -# Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +# Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) From 48319b4197c571c0d236286a00f28aa0f4aea977 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Fri, 15 Sep 2023 11:11:42 -0700 Subject: [PATCH 023/103] Deleted test for GCC 4.8 --- .github/workflows/ci.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7bd8c542..1aedba33 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,12 +17,6 @@ jobs: fail-fast: false matrix: include: - - toolset: gcc-4.8 - cxxstd: "11" - os: ubuntu-latest - container: ubuntu:18.04 - install: g++-4.8-multilib - address-model: 32,64 - toolset: gcc-5 cxxstd: "11,14,1z" os: ubuntu-latest From 87c6ba405d2e41127fbab1b78cb699c4c8ae85fb Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Fri, 15 Sep 2023 11:12:29 -0700 Subject: [PATCH 024/103] Changed b2 invocation order for .vscode integration b2 --- .vscode/tasks.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 7a705ffe..d82a8e16 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -73,9 +73,9 @@ "group": "test", "label": "Run all unit tests (b2, all configurations)", "type": "shell", - "command": "../../b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp exception-handling=on,off cxxstd=11,14,1z,17 && ../../b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=11,14,1z,17", + "command": "../../b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=11,14,1z,17 && ../../b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp exception-handling=on,off cxxstd=11,14,1z,17", "windows": { - "command": "..\\..\\b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp exception-handling=on,off cxxstd=14,17,latest && ..\\..\\b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=14,17,latest", + "command": "..\\..\\b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp,leaf_debug_embedded,leaf_release_embedded exception-handling=off rtti=off cxxstd=14,17,latest && ..\\..\\b2 test link=shared,static variant=debug,release,leaf_debug_diag0,leaf_release_diag0,leaf_debug_leaf_hpp,leaf_release_leaf_hpp exception-handling=on,off cxxstd=14,17,latest", }, "problemMatcher": { "base": "$gcc", From 9e39b70c5a12043d052913ac72eadec6b5c403dd Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Fri, 15 Sep 2023 11:14:10 -0700 Subject: [PATCH 025/103] Improved configuration validation --- include/boost/leaf/config.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/boost/leaf/config.hpp b/include/boost/leaf/config.hpp index 48df7527..bf3118f7 100644 --- a/include/boost/leaf/config.hpp +++ b/include/boost/leaf/config.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_CONFIG_HPP_INCLUDED #define BOOST_LEAF_CONFIG_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -114,6 +114,10 @@ # error BOOST_LEAF_CFG_GNUC_STMTEXPR must be 0 or 1. #endif +#if BOOST_LEAF_CFG_STD_SYSTEM_ERROR && !BOOST_LEAF_CFG_STD_STRING +# error BOOST_LEAF_CFG_STD_SYSTEM_ERROR != 0 requires BOOST_LEAF_CFG_STD_STRING != 0 +#endif + //////////////////////////////////////// // Configure BOOST_LEAF_NO_EXCEPTIONS, unless already #defined From 87efaf7380454d5218506cbbd93cf4cc116e88fe Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Fri, 15 Sep 2023 11:15:10 -0700 Subject: [PATCH 026/103] Improved diagnostics --- doc/LEAF-1.png | Bin 119490 -> 0 bytes doc/LEAF-2.png | Bin 159860 -> 0 bytes doc/leaf.adoc | 133 +++++++++----------- include/boost/leaf.hpp | 2 +- include/boost/leaf/capture.hpp | 50 ++++---- include/boost/leaf/common.hpp | 10 +- include/boost/leaf/context.hpp | 13 +- include/boost/leaf/detail/print.hpp | 8 +- include/boost/leaf/error.hpp | 146 +++++++++++++--------- include/boost/leaf/handle_errors.hpp | 13 +- include/boost/leaf/on_error.hpp | 8 +- include/boost/leaf/result.hpp | 110 +++++++++++++++- meson.build | 3 +- test/Jamfile.v2 | 3 +- test/capture_exception_state_test.cpp | 33 ++++- test/capture_result_state_test.cpp | 31 ++++- test/ctx_remote_handle_all_test.cpp | 4 +- test/defer_basic_test.cpp | 13 +- test/defer_nested_success_result_test.cpp | 2 +- test/diagnostic_info_test1.cpp | 28 +++-- test/diagnostic_info_test2.cpp | 10 +- test/diagnostic_info_test3.cpp | 6 +- test/diagnostic_info_test4.cpp | 7 +- test/diagnostic_info_test5.cpp | 12 +- test/e_LastError_test.cpp | 12 +- test/e_errno_test.cpp | 14 ++- test/optional_test.cpp | 2 +- test/preload_basic_test.cpp | 13 +- test/print_test.cpp | 51 ++++---- test/result_print_test.cpp | 117 +++++++++++++++++ test/visibility_test.cpp | 33 ++++- test/visibility_test_lib.hpp | 4 +- 32 files changed, 624 insertions(+), 267 deletions(-) delete mode 100644 doc/LEAF-1.png delete mode 100644 doc/LEAF-2.png create mode 100644 test/result_print_test.cpp diff --git a/doc/LEAF-1.png b/doc/LEAF-1.png deleted file mode 100644 index 9aa55b7b9623de0271f37598a46bf4791ae052b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 119490 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

H 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≷C{c7euSlCn&n?h^FQ2i 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%0A$mCVhyS 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 becomes extremely lightwei === Reporting Errors -A function that reports an error is pretty straight-forward: +A function that reports an error: [source,c++] ---- @@ -240,11 +240,11 @@ leaf::result r = leaf::try_handle_some( [.text-right] <> | <> | <> | <> -LEAF considers the provided error handlers in order, and calls the first one for which it can supply arguments, based on the error objects currently being communicated. Above: +LEAF considers the provided error handlers in order, and calls the first one for which it is able to supply arguments, based on the error objects currently being communicated. Above: -* The first error handler uses the predicate `leaf::match` to specify that it should only be considered if an error object of type `err1` is available, and its value is either `err1::e1` or `err1::e3`. +* The first error handler will be called iff an error object of type `err1` is available, and its value is either `err1::e1` or `err1::e3`. -* Otherwise the second error handler will be called if an error object of type `err1` is available, regardless of its value. +* Otherwise the second error handler will be called iff an error object of type `err1` is available, regardless of its value. * Otherwise `leaf::try_handle_some` fails. @@ -347,7 +347,7 @@ leaf::result r = leaf::try_handle_some( [.text-right] <> | <> | <> -Recall that error handlers are always considered in order: +Error handlers are always considered in order: * The first error handler will be used if an error object of type `err1` is available; * otherwise, the second error handler will be used if an error object of type `err2` is available; @@ -430,9 +430,9 @@ leaf::result r = leaf::try_handle_some( [.text-right] <> | <> | <> -An error handler is never dropped for lack of error objects of types which the handler takes as pointers; in this case LEAF simply passes `0` for these arguments. +An error handler is never dropped for lack of error objects of types which the handler takes as pointers; in this case LEAF simply passes `nullptr` for these arguments. -TIP: Error handlers can take arguments by value, by (`const`) reference or as a (`const`) pointer. It the latter case, changes to the error object state will be propagated up the call stack if the failure is not handled. +TIP: When an error handler takes arguments by mutable reference or pointer, changes to their state are preserved when the error is communicated to the caller. [[tutorial-augmenting_errors]] === Augmenting Errors @@ -469,7 +469,7 @@ leaf::result process_file( FILE * f ) [.text-right] <> | <> -Because `process_file` does not handle errors, it remains neutral to failures, except to attach the `current_line` if something goes wrong. The object returned by `on_error` holds a copy of the `current_line` wrapped in `struct e_line`. If `parse_line` succeeds, the `e_line` object is simply discarded; but if it fails, the `e_line` object will be automatically "attached" to the failure. +Because `process_file` does not handle errors, it remains neutral to failures, except to attach the `current_line` if something goes wrong. The object returned by `on_error` holds a copy of the `current_line` wrapped in `struct e_line`. If `parse_line` succeeds, the `e_line` object is simply discarded; if it fails, the `e_line` object will be automatically "attached" to the failure. Such failures can then be handled like so: @@ -530,7 +530,7 @@ leaf::result r = leaf::try_handle_some( [[tutorial-exception_handling]] === Exception Handling -What happens if an operation throws an exception? Not to worry, both `try_handle_some` and `try_handle_all` catch exceptions and are able to pass them to any compatible error handler: +What happens if an operation throws an exception? Both `try_handle_some` and `try_handle_all` catch exceptions and are able to pass them to any compatible error handler: [source,c++] ---- @@ -596,9 +596,9 @@ leaf::try_catch( [.text-right] <> -Remarkably, we did not have to change the error handlers! But how does this work? What kind of exceptions does `process_file` throw? +We did not have to change the error handlers! But how does this work? What kind of exceptions does `process_file` throw? -LEAF enables a novel technique of exception handling, which does not use an exception type hierarchy to classify failures and does not carry data in exception objects. Recall that when failures are communicated via `leaf::result`, we call `leaf::new_error` in a `return` statement, passing any number of error objects which are sent directly to the correct error handling scope: +LEAF enables a novel exception handling technique, which does not require an exception type hierarchy to classify failures and does not carry data in exception objects. Recall that when failures are communicated via `leaf::result`, we call `leaf::new_error` in a `return` statement, passing any number of error objects which are sent directly to the correct error handling scope: [source,c++] ---- @@ -637,7 +637,7 @@ T f() [.text-right] <> -The `leaf::throw_exception` function handles the passed error objects just like `leaf::new_error` does, and then throws an object of a type that derives from `std::exception`. Using this technique, the exception type is not important: `leaf::try_catch` catches all exceptions, then goes through the usual LEAF error handler selection procedure. +The `leaf::throw_exception` function handles the passed error objects just like `leaf::new_error` does, and then throws an object of a type that derives from `std::exception`. Using this technique, the exception type is not important: `leaf::try_catch` catches all exceptions, then goes through the usual LEAF error handler selection routine. If instead we want to use the legacy convention of throwing different types to indicate different failures, we simply pass an exception object (that is, an object of a type that derives from `std::exception`) as the first argument to `leaf::throw_exception`: @@ -799,39 +799,8 @@ lib3::result r = leaf::try_handle_some( ''' -[[tutorial-model]] -=== Error Communication Model - -==== `noexcept` API - -The following figure illustrates how error objects are transported when using LEAF without exception handling: - -.LEAF noexcept Error Communication Model -image::LEAF-1.png[] - -The arrows pointing down indicate the call stack order for the functions `f1` through `f5`: higher level functions calling lower level functions. - -Note the call to `on_error` in `f3`: it caches the passed error objects of types `E1` and `E3` in the returned object `load`, where they stay ready to be communicated in case any function downstream from `f3` reports an error. Presumably these objects are relevant to any such failure, but are conveniently accessible only in this scope. - -_Figure 1_ depicts the condition where `f5` has detected an error. It calls `leaf::new_error` to create a new, unique `error_id`. The passed error object of type `E2` is immediately loaded in the first active `context` object that provides static storage for it, found in any calling scope (in this case `f1`), and is associated with the newly-generated `error_id` (solid arrow); - -The `error_id` itself is returned to the immediate caller `f4`, usually stored in a `result` object `r`. That object takes the path shown by dashed arrows, as each error neutral function, unable to handle the failure, forwards it to its immediate caller in the returned value -- until an error handling scope is reached. - -When the destructor of the `load` object in `f3` executes, it detects that `new_error` was invoked after its initialization, loads the cached objects of types `E1` and `E3` in the first active `context` object that provides static storage for them, found in any calling scope (in this case `f1`), and associates them with the last generated `error_id` (solid arrow). - -When the error handling scope `f1` is reached, it probes `ctx` for any error objects associated with the `error_id` it received from `f2`, and processes a list of user-provided error handlers, in order, until it finds a handler with arguments that can be supplied using the available (in `ctx`) error objects. That handler is called to deal with the failure. - -==== Exception Handling API - -The following figure illustrates the slightly different error communication model used when errors are reported by throwing exceptions: - -.LEAF Error Communication Model Using Exception Handling -image::LEAF-2.png[] - -The main difference is that the call to `new_error` is implicit in the call to the function template `leaf::throw_exception`, which in this case takes an exception object of type `Ex`, and throws an exception object of unspecified type that derives publicly from `Ex`. - [[tutorial-interoperability]] -==== Interoperability +=== Interoperability Ideally, when an error is detected, a program using LEAF would always call <>, ensuring that each encountered failure is definitely assigned a unique <>, which then is reliably delivered, by an exception or by a `result` object, to the appropriate error handling scope. @@ -852,14 +821,12 @@ Note that if the above logic is nested (e.g. one function calling another), `new For a detailed tutorial see <>. -TIP: To avoid ambiguities, whenever possible, use the <> function template to throw exceptions, to ensure that the exception object transports a unique `error_id`; better yet, use the <> macro, which in addition will capture `pass:[__FILE__]` and `pass:[__LINE__]`. - ''' [[tutorial-loading]] === Loading of Error Objects -To load an error object is to move it into an active <>, usually local to a <>, a <> or a <> scope in the calling thread, where it becomes uniquely associated with a specific <> -- or discarded if storage is not available. +To load an error object is to move it into an active <> object, usually contained within a <>, a <> or a <> scope in the calling thread, where it becomes uniquely associated with a specific <> -- or discarded if storage is not available. Various LEAF functions take a list of error objects to load. As an example, if a function `copy_file` that takes the name of the input file and the name of the output file as its arguments detects a failure, it could communicate an error code `ec`, plus the two relevant file names using <>: @@ -969,7 +936,7 @@ leaf::result operation( char const * file_name ) noexcept It is not typical for an error reporting function to be able to supply all of the data needed by a suitable error handling function in order to recover from the failure. For example, a function that reports `FILE` failures may not have access to the file name, yet an error handling function needs it in order to print a useful error message. -Of course the file name is typically readily available in the call stack leading to the failed `FILE` operation. Below, while `parse_info` can't report the file name, `parse_file` can and does: +The file name is typically readily available in the call stack leading to the failed `FILE` operation. Below, while `parse_info` can't report the file name, `parse_file` can and does: [source,c++] ---- @@ -993,18 +960,18 @@ leaf::result parse_file( char const * file_name ) noexcept [.text-right] <> | <> | <> -<1> `parse_info` parses `f`, communicating errors using `result`. -<2> Using `on_error` ensures that the file name is included with any error reported out of `parse_file`. All we need to do is hold on to the returned object `load`; when it expires, if an error is being reported, the passed `e_file_name` value will be automatically associated with it. +<1> `parse_info` parses `f`, communicating errors using `leaf::result`. +<2> Using `on_error` ensures that the file name is included with any error reported out of `parse_file`. When the `load` object expires, if an error is being reported, the passed `e_file_name` value will be automatically associated with it. -TIP: `on_error` -- like `load` -- can be passed any number of arguments. +TIP: `on_error` -- like `new_error` -- can be passed any number of arguments. When we invoke `on_error`, we can pass three kinds of arguments: . Actual error objects (like in the example above); . Functions that take no arguments and return an error object; -. Functions that take an error object by mutable reference. +. Functions that take a single error object by mutable reference. -If we want to use `on_error` to capture `errno`, we can't just pass <> to it, because at that time it hasn't been set (yet). Instead, we'd pass a function that returns it: +For example, if we want to use `on_error` to capture `errno`, we can't just pass <> to it, because at that time it hasn't been set (yet). Instead, we'd pass a function that returns it: [source,c++] ---- @@ -1028,16 +995,16 @@ void read_file(FILE * f) { } ---- -Above, if `throw_exception` is called, LEAF will invoke the function passed to `on_error` and associate the returned `e_errno` object with the exception. +Above, if an exception is thrown, LEAF will invoke the function passed to `on_error` and associate the returned `e_errno` object with the exception. -The final argument type that can be passed to `on_error` is a function that takes a single mutable error object reference. In this case, `on_error` uses it similarly to how such functions are used by `load`; see <>. +Finally, if `on_error` is passed a function that takes a single error object by mutable reference, the behavior is similar to how such functions are used by `load`; see <>. ''' [[tutorial-predicates]] === Using Predicates to Handle Errors -Usually, LEAF error handlers are selected based on the type of the arguments they take and the type of the available error objects. When an error handler takes a predicate type as an argument, the <> is able to also take into account the _value_ of the available error objects. +Usually, the compatibility between error handlers and the available error objects is determined based on the type of the arguments they take. When an error handler takes a predicate type as an argument, the <> is able to also take into account the _value_ of the available error objects. Consider this error code enum: @@ -1163,7 +1130,7 @@ NOTE: See also <>. ''' [[tutorial-binding_handlers]] -=== Binding Error Handlers in a `std::tuple` +=== Reusing Common Error Handlers Consider this snippet: @@ -1222,7 +1189,7 @@ leaf::try_handle_all( }); ---- -That works, but it is better to bind our error handlers in a `std::tuple`: +That works, but it may be better to bind the error handlers in a `std::tuple`: [source,c++] ---- @@ -1280,9 +1247,9 @@ Error handling functions accept a `std::tuple` of error handlers in place of any [[tutorial-async]] === Transporting Error Objects Between Threads -Error objects are stored on the stack in an instance of the <> class template in the scope of e.g. <>, <> or <> functions. When using concurrency, we need a mechanism to collect error objects in one thread, then use them to handle errors in another thread. +Like exceptions, error objects are local to a thread. When using concurrency, sometimes we need to collect error objects in one thread, then use them to handle the error in another thread. -LEAF offers two interfaces for this purpose, one using `result`, and another designed for programs that use exception handling. +LEAF offers two interfaces for this purpose, one using `result`, and another using exception handling. [[tutorial-async_result]] ==== Using `result` @@ -1294,7 +1261,7 @@ Let's assume we have a `task` that we want to launch asynchronously, which produ leaf::result task(); ---- -Because the task will run asynchronously, in case of a failure we need it to capture the relevant error objects but not handle errors. To this end, in the main thread we bind our error handlers in a `std::tuple`, which we will later use to handle errors from each completed asynchronous task (see <>): +Because the task will run asynchronously, in case of a failure we need it to capture the relevant error objects but not handle errors. To this end, in the main thread we bind our error handlers in a `std::tuple`, which we will later use to handle errors from each completed asynchronous task (see <>): [source,c++] ---- @@ -1365,8 +1332,6 @@ return leaf::try_handle_some( [.text-right] <> | <> | <> -The reason this works is that in case the `leaf::result` communicates a failure, it is able to hold a `shared_ptr` object. That is why earlier instead of calling `task()` directly, we called `leaf::capture`: it calls the passed function and, in case that fails, it stores the `shared_ptr` we created in the returned `result`, which now doesn't just communicate the fact that an error has occurred, but also holds the `context` object that `try_handle_some` needs in order to supply a suitable handler with arguments. - NOTE: Follow this link to see a complete example program: https://github.com/boostorg/leaf/blob/master/example/capture_in_result.cpp?ts=4[capture_in_result.cpp]. [[tutorial-async_eh]] @@ -1440,8 +1405,6 @@ return leaf::try_catch( [.text-right] <> -This works similarly to using `result`, except that the `std::shared_ptr` is transported in an exception object (of unspecified type which <> recognizes and then automatically unwraps the original exception). - NOTE: Follow this link to see a complete example program: https://github.com/boostorg/leaf/blob/master/example/capture_in_exception.cpp?ts=4[capture_in_exception.cpp]. ''' @@ -1584,7 +1547,7 @@ void file_read( FILE & f, void * buf, int size ) [.text-right] <> | <> | <> -NOTE: If the type of the first argument passed to `leaf::throw_exception` derives from `std::exception`, it will be used to initialize the thrown exception object. Here this is not the case, so the function returns a default-initialized `std::exception` object, while the first (and any other) argument is associated with the failure. +NOTE: If the type of the first argument passed to `leaf::throw_exception` derives from `std::exception`, it will be used to initialize the thrown exception object. Here this is not the case, so the function throws a default-initialized `std::exception` object, while the first (and any other) argument is associated with the failure. Now we can write a future-proof handler for any `input_error`: @@ -1666,7 +1629,7 @@ leaf::result print_answer() noexcept [.text-right] <> | <> -Finally, here is a scope that handles the errors -- it will work correctly regardless of whether `error_a` and `error_b` objects are thrown as exceptions or not. +Finally, here is the scope that handles the errors -- it will work correctly regardless of whether `error_a` and `error_b` objects are thrown as exceptions or not. [source,c++] ---- @@ -1856,7 +1819,7 @@ int main() noexcept NOTE: Follow this link to see the complete program: https://github.com/boostorg/leaf/blob/master/example/lua_callback_result.cpp?ts=4[lua_callback_result.cpp]. -TIP: When using Lua with {CPP}, we need to protect the Lua interpreter from exceptions that may be thrown from {CPP} functions installed as `lua_CFunction` callbacks. Here is the program from this section rewritten to use a {CPP} exception to safely communicate errors out of the `do_work` function: https://github.com/boostorg/leaf/blob/master/example/lua_callback_eh.cpp?ts=4[lua_callback_eh.cpp]. +TIP: When using Lua with {CPP}, we need to protect the Lua interpreter from exceptions that may be thrown from {CPP} functions installed as `lua_CFunction` callbacks. Here is the program from this section rewritten to use a {CPP} exception (instead of `leaf::result`) to safely communicate errors out of the `do_work` function: https://github.com/boostorg/leaf/blob/master/example/lua_callback_eh.cpp?ts=4[lua_callback_eh.cpp]. '''' @@ -1926,7 +1889,7 @@ struct e_errno The `e_errno` type above is designed to hold `errno` values. The defined `operator<<` overload will automatically include the output from `strerror` when `e_errno` values are printed (LEAF defines `e_errno` in ``, together with other commonly-used error types). -Using `verbose_diagnostic_info` comes at a cost. Normally, when the program attempts to communicate error objects of types which are not used in any error handling scope in the current call stack, they are discarded, which saves cycles. However, if an error handler is provided that takes `verbose_diagnostic_info` argument, before such objects are discarded, they are printed and appended to a `std::string` (this is the case with `e_file_name` in our example above). Such objects appear under `Unhandled error objects` in the output from `verbose_diagnostic_info`. +Using `verbose_diagnostic_info` comes at a cost. Normally, when the program attempts to communicate error objects of types which are not used in any error handling scope in the current call stack, they are discarded, which saves cycles. However, if an error handler is provided that takes `verbose_diagnostic_info` argument, such objects are stored on the heap instead of being discarded. They appear under `Unhandled error objects` in the output from `verbose_diagnostic_info`. If handling `verbose_diagnostic_info` is considered too costly, use `diagnostic_info` instead: @@ -1960,7 +1923,7 @@ leaf::diagnostic_info for Error ID = 1: Detected 1 attempt to communicate an unexpected error object of type [with Name = boost::leaf::e_file_name] ---- -Notice how the diagnostic information for `e_file_name` changed: LEAF no longer prints it before discarding it, and so `diagnostic_info` can only inform about the type of the discarded object, but not its value. +Notice how the diagnostic information for `e_file_name` changed: because it was discarded, LEAF is unable to print it, and so `diagnostic_info` can only inform about its type, but not its value. TIP: The automatically-generated diagnostic messages are developer-friendly, but not user-friendly. Therefore, `operator<<` overloads for error types should only print technical information in English, and should not attempt to localize strings or to format a user-friendly message; this should be done in error handling functions specifically designed for that purpose. @@ -1971,7 +1934,7 @@ TIP: The automatically-generated diagnostic messages are developer-friendly, but ==== Introduction -The relationship between `std::error_code` and `std::error_condition` is not easily understood from reading the standard specifications. This section explains how they're supposed to be used, and how LEAF interacts with them. +The relationship between `std::error_code` and `std::error_condition` is not easily understood from reading the standard specification. This section explains how they're supposed to be used, and how LEAF interacts with them. The idea behind `std::error_code` is to encode both an integer value representing an error code, as well as the domain of that value. The domain is represented by a `std::error_category` [underline]#reference#. Conceptually, a `std::error_code` is like a `pair`. @@ -2341,6 +2304,9 @@ namespace boost { namespace leaf { virtual void propagate( error_id ) noexcept = 0; virtual void print( std::ostream & ) const = 0; + + template + friend std::ostream & operator<<( std::basic_ostream & os, polymorphic_context const & ctx ); }; ////////////////////////////////////////// @@ -2498,6 +2464,9 @@ namespace boost { namespace leaf { template error_id load( Item && ... item ) noexcept; + + template + friend std::ostream & operator<<( std::basic_ostream & os, result const & r ); }; template <> @@ -2533,6 +2502,9 @@ namespace boost { namespace leaf { template error_id load( Item && ... item ) noexcept; + + template + friend std::ostream & operator<<( std::basic_ostream & os, result const & r ); }; struct bad_result: std::exception { }; @@ -2672,6 +2644,9 @@ namespace boost { namespace leaf { void print( std::ostream & os ) const; + template + friend std::ostream & operator<<( std::basic_ostream & os, context const & ctx ); + template R handle_error( R &, H && ... ) const; }; @@ -3816,6 +3791,13 @@ namespace boost { namespace leaf { template void context::print( std::ostream & os ) const; + template + friend std::ostream & context::operator<<( std::basic_ostream & os, context const & ctx ) + { + ctx.print(os); + return os; + } + } } ---- @@ -4397,6 +4379,13 @@ namespace boost { namespace leaf { virtual void propagate( error_id ) noexcept = 0; virtual void print( std::ostream & ) const = 0; + + template + friend std::ostream & operator<<( std::basic_ostream & os, polymorphic_context const & ctx ) + { + ctx.print(os); + return os; + } }; } } diff --git a/include/boost/leaf.hpp b/include/boost/leaf.hpp index 743221b6..ede7549c 100644 --- a/include/boost/leaf.hpp +++ b/include/boost/leaf.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_HPP_INCLUDED #define BOOST_LEAF_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/boost/leaf/capture.hpp b/include/boost/leaf/capture.hpp index 08c3bcb4..9235a824 100644 --- a/include/boost/leaf/capture.hpp +++ b/include/boost/leaf/capture.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_CAPTURE_HPP_INCLUDED #define BOOST_LEAF_CAPTURE_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -34,19 +34,19 @@ namespace leaf_detail namespace leaf_detail { - template + template inline decltype(std::declval()(std::forward(std::declval())...)) - capture_impl(is_result_tag, context_ptr && ctx, F && f, A... a) noexcept + capture_impl(is_result_tag, ContextPtr && ctx, F && f, A... a) noexcept { auto active_context = activate_context(*ctx); return std::forward(f)(std::forward(a)...); } - template + template inline decltype(std::declval()(std::forward(std::declval())...)) - capture_impl(is_result_tag, context_ptr && ctx, F && f, A... a) noexcept + capture_impl(is_result_tag, ContextPtr && ctx, F && f, A... a) noexcept { auto active_context = activate_context(*ctx); if( auto r = std::forward(f)(std::forward(a)...) ) @@ -54,7 +54,7 @@ namespace leaf_detail else { ctx->captured_id_ = r.error(); - return std::move(ctx); + return std::forward(ctx); } } @@ -90,9 +90,10 @@ namespace leaf_detail public: - capturing_exception(std::exception_ptr && ex, context_ptr && ctx) noexcept: + template + capturing_exception(std::exception_ptr && ex, ContextPtr && ctx) noexcept: ex_(std::move(ex)), - ctx_(std::move(ctx)) + ctx_(std::forward(ctx)) { BOOST_LEAF_ASSERT(ex_); BOOST_LEAF_ASSERT(ctx_); @@ -106,18 +107,12 @@ namespace leaf_detail ctx_->propagate(ctx_->captured_id_); std::rethrow_exception(ex_); } - - template - void print( std::basic_ostream & os ) const - { - ctx_->print(os); - } }; - template + template inline decltype(std::declval()(std::forward(std::declval())...)) - capture_impl(is_result_tag, context_ptr && ctx, F && f, A... a) + capture_impl(is_result_tag, ContextPtr && ctx, F && f, A... a) { auto active_context = activate_context(*ctx); error_monitor cur_err; @@ -132,19 +127,19 @@ namespace leaf_detail catch( exception_base const & e ) { ctx->captured_id_ = e.get_error_id(); - leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::move(ctx)) ); + leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::forward(ctx)) ); } catch(...) { ctx->captured_id_ = cur_err.assigned_error_id(); - leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::move(ctx)) ); + leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::forward(ctx)) ); } } - template + template inline decltype(std::declval()(std::forward(std::declval())...)) - capture_impl(is_result_tag, context_ptr && ctx, F && f, A... a) + capture_impl(is_result_tag, ContextPtr && ctx, F && f, A... a) { auto active_context = activate_context(*ctx); error_monitor cur_err; @@ -155,7 +150,7 @@ namespace leaf_detail else { ctx->captured_id_ = r.error(); - return std::move(ctx); + return std::forward(ctx); } } catch( capturing_exception const & ) @@ -165,12 +160,12 @@ namespace leaf_detail catch( exception_base const & e ) { ctx->captured_id_ = e.get_error_id(); - leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::move(ctx)) ); + leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::forward(ctx)) ); } catch(...) { ctx->captured_id_ = cur_err.assigned_error_id(); - leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::move(ctx)) ); + leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::forward(ctx)) ); } } @@ -210,6 +205,15 @@ namespace leaf_detail #endif +template +inline +decltype(std::declval()(std::forward(std::declval())...)) +capture(context_ptr const & ctx, F && f, A... a) +{ + using namespace leaf_detail; + return capture_impl(is_result_tag()(std::forward(std::declval())...))>(), ctx, std::forward(f), std::forward(a)...); +} + template inline decltype(std::declval()(std::forward(std::declval())...)) diff --git a/include/boost/leaf/common.hpp b/include/boost/leaf/common.hpp index 3ed7f7ea..55ae517a 100644 --- a/include/boost/leaf/common.hpp +++ b/include/boost/leaf/common.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_COMMON_HPP_INCLUDED #define BOOST_LEAF_COMMON_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,10 +10,12 @@ #include #include +#include + #if BOOST_LEAF_CFG_STD_STRING # include #endif -#include + #if BOOST_LEAF_CFG_WIN32 # include # include @@ -53,7 +55,7 @@ struct BOOST_LEAF_SYMBOL_VISIBLE e_errno explicit e_errno(int val=errno): value(val) { } template - friend std::basic_ostream & operator<<(std::basic_ostream & os, e_errno const & err) + friend std::ostream & operator<<(std::basic_ostream & os, e_errno const & err) { return os << type() << ": " << err.value << ", \"" << std::strerror(err.value) << '"'; } @@ -75,7 +77,7 @@ namespace windows e_LastError(): value(GetLastError()) { } template - friend std::basic_ostream & operator<<(std::basic_ostream & os, e_LastError const & err) + friend std::ostream & operator<<(std::basic_ostream & os, e_LastError const & err) { struct msg_buf { diff --git a/include/boost/leaf/context.hpp b/include/boost/leaf/context.hpp index dc0796a1..57238f55 100644 --- a/include/boost/leaf/context.hpp +++ b/include/boost/leaf/context.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_CONTEXT_HPP_INCLUDED #define BOOST_LEAF_CONTEXT_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,7 +10,7 @@ #include #if !defined(BOOST_LEAF_NO_THREADS) && !defined(NDEBUG) -# include +# include #endif namespace boost { namespace leaf { @@ -177,7 +177,7 @@ namespace leaf_detail BOOST_LEAF_ASSERT(err_id != 0); auto & sl = std::get(tup); if( sl.has_value(err_id) ) - (void) load_slot(err_id, std::move(sl).value(err_id)); + (void) load_slot(err_id, std::move(sl).value(err_id)); tuple_for_each::propagate_captured(tup, err_id); } @@ -370,6 +370,13 @@ class context leaf_detail::tuple_for_each::value,Tup>::print(os, &tup_, 0); } + template + friend std::ostream & operator<<( std::basic_ostream & os, context const & ctx ) + { + ctx.print(os); + return os; + } + template BOOST_LEAF_CONSTEXPR R handle_error( error_id, H && ... ) const; diff --git a/include/boost/leaf/detail/print.hpp b/include/boost/leaf/detail/print.hpp index d37c75f6..eb05b30e 100644 --- a/include/boost/leaf/detail/print.hpp +++ b/include/boost/leaf/detail/print.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_DETAIL_PRINT_HPP_INCLUDED #define BOOST_LEAF_DETAIL_PRINT_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,8 +9,6 @@ #include #include -#if BOOST_LEAF_CFG_DIAGNOSTICS - #include #include #include @@ -96,7 +94,7 @@ namespace leaf_detail template static void print( std::basic_ostream & os, Wrapper const & ) { - os << type() << ": {Non-Printable}"; + os << type() << ": {not printable}"; } }; @@ -127,5 +125,3 @@ namespace leaf_detail } } #endif - -#endif diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index e718a923..34fed80b 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -1,24 +1,18 @@ #ifndef BOOST_LEAF_ERROR_HPP_INCLUDED #define BOOST_LEAF_ERROR_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include #include -#include #include #include -#include -#include - #if BOOST_LEAF_CFG_DIAGNOSTICS -# include -# include -# include +# include #endif #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR @@ -47,25 +41,25 @@ #if BOOST_LEAF_CFG_GNUC_STMTEXPR #define BOOST_LEAF_CHECK(r)\ - ({\ - auto && BOOST_LEAF_TMP = (r);\ - static_assert(::boost::leaf::is_result_type::type>::value,\ - "BOOST_LEAF_CHECK requires a result object (see is_result_type)");\ - if( !BOOST_LEAF_TMP )\ - return BOOST_LEAF_TMP.error();\ - std::move(BOOST_LEAF_TMP);\ - }).value() + ({\ + auto && BOOST_LEAF_TMP = (r);\ + static_assert(::boost::leaf::is_result_type::type>::value,\ + "BOOST_LEAF_CHECK requires a result object (see is_result_type)");\ + if( !BOOST_LEAF_TMP )\ + return BOOST_LEAF_TMP.error();\ + std::move(BOOST_LEAF_TMP);\ + }).value() #else #define BOOST_LEAF_CHECK(r)\ - {\ - auto && BOOST_LEAF_TMP = (r);\ - static_assert(::boost::leaf::is_result_type::type>::value,\ - "BOOST_LEAF_CHECK requires a result object (see is_result_type)");\ - if( !BOOST_LEAF_TMP )\ - return BOOST_LEAF_TMP.error();\ - } + {\ + auto && BOOST_LEAF_TMP = (r);\ + static_assert(::boost::leaf::is_result_type::type>::value,\ + "BOOST_LEAF_CHECK requires a result object (see is_result_type)");\ + if( !BOOST_LEAF_TMP )\ + return BOOST_LEAF_TMP.error();\ + } #endif @@ -155,7 +149,7 @@ namespace leaf_detail slot_base * next_; virtual void deactivate() noexcept = 0; virtual void propagate( int err_id ) noexcept = 0; - virtual std::string print( int key_to_print ) const = 0; + virtual void print( std::ostream &, int key_to_print ) const = 0; virtual ~slot_base() noexcept { }; protected: BOOST_LEAF_CONSTEXPR slot_base(): @@ -169,26 +163,23 @@ namespace leaf_detail { slot_store( slot_store const & ) = delete; slot_store & operator=( slot_store const & ) = delete; - using sl = slot; void deactivate() noexcept final override { - sl::deactivate(); + slot::deactivate(); } void propagate( int err_id ) noexcept final override { - sl::propagate(err_id); + slot::propagate(err_id); } - std::string print( int key_to_print ) const final override + void print( std::ostream & os, int key_to_print ) const final override { - std::stringstream st; - sl::print(st, key_to_print); - return st.str(); + slot::print(os, key_to_print); } public: template BOOST_LEAF_CONSTEXPR slot_store( int err_id, T && e ) { - sl::put(err_id, std::forward(e)); + slot::put(err_id, std::forward(e)); } }; @@ -254,7 +245,7 @@ namespace leaf_detail { os << "Unhandled error objects:\n"; for( slot_base const * p=first_; p; p=p->next_ ) - os << p->print(key_to_print); + p->print(os, key_to_print); } }; @@ -284,7 +275,7 @@ struct BOOST_LEAF_SYMBOL_VISIBLE e_source_location char const * function; template - friend std::basic_ostream & operator<<( std::basic_ostream & os, e_source_location const & x ) + friend std::ostream & operator<<( std::basic_ostream & os, e_source_location const & x ) { return os << leaf::type() << ": " << x.file << '(' << x.line << ") in function " << x.function; } @@ -344,7 +335,7 @@ namespace leaf_detail return; } else - os << '[' << k << ']'; + os << '[' << k << "] "; diagnostic::print(os, value(k)); (os << '\n').flush(); } @@ -371,7 +362,7 @@ namespace leaf_detail } template <> - inline void slot::propagate( int err_id ) noexcept(!BOOST_LEAF_CFG_DIAGNOSTICS) + inline void slot::propagate( int err_id ) { if( e_unexpected_info * info = this->has_value(err_id) ) info->propagate(err_id); @@ -390,7 +381,7 @@ namespace leaf_detail } template - BOOST_LEAF_CONSTEXPR inline void load_unexpected_info( int err_id, E && e ) noexcept + BOOST_LEAF_CONSTEXPR inline void load_unexpected_info( int err_id, E && e ) { if( slot * sl = tls::read_ptr>() ) { @@ -402,7 +393,7 @@ namespace leaf_detail } template - BOOST_LEAF_CONSTEXPR inline void accumulate_unexpected_info( int err_id, F && f ) noexcept + BOOST_LEAF_CONSTEXPR inline void accumulate_unexpected_info( int err_id, F && f ) { if( slot * sl = tls::read_ptr>() ) { @@ -413,18 +404,48 @@ namespace leaf_detail } } - template - BOOST_LEAF_CONSTEXPR inline void load_unexpected( int err_id, E && e ) + template + inline void load_unexpected( int err_id, E && e ) noexcept(OnError) { load_unexpected_count(err_id); - load_unexpected_info(err_id, std::forward(e)); + if( OnError ) + { +#ifndef BOOST_LEAF_NO_EXCEPTIONS + try + { +#endif + load_unexpected_info(err_id, std::forward(e)); +#ifndef BOOST_LEAF_NO_EXCEPTIONS + } + catch(...) + { + } +#endif + } + else + load_unexpected_info(err_id, std::forward(e)); } - template - BOOST_LEAF_CONSTEXPR inline void accumulate_unexpected( int err_id, F && f ) + template + inline void accumulate_unexpected( int err_id, F && f ) noexcept(OnError) { load_unexpected_count(err_id); - accumulate_unexpected_info(err_id, std::forward(f)); + if( OnError ) + { +#ifndef BOOST_LEAF_NO_EXCEPTIONS + try + { +#endif + accumulate_unexpected_info(err_id, std::forward(f)); +#ifndef BOOST_LEAF_NO_EXCEPTIONS + } + catch(...) + { + } +#endif + } + else + accumulate_unexpected_info(err_id, std::forward(f)); } #endif @@ -442,13 +463,13 @@ namespace leaf_detail int c = int(tls::read_uint()); BOOST_LEAF_ASSERT(c>=0); if( c ) - load_unexpected(err_id, std::move(*this).value(err_id)); + load_unexpected(err_id, std::move(*this).value(err_id)); } #endif } - template - BOOST_LEAF_CONSTEXPR inline int load_slot( int err_id, E && e ) noexcept(!BOOST_LEAF_CFG_DIAGNOSTICS) + template + BOOST_LEAF_CONSTEXPR inline int load_slot( int err_id, E && e ) noexcept(OnError) { static_assert(!std::is_pointer::value, "Error objects of pointer types are not allowed"); static_assert(!std::is_same::type, error_id>::value, "Error objects of type error_id are not allowed"); @@ -456,7 +477,7 @@ namespace leaf_detail BOOST_LEAF_ASSERT((err_id&3)==1); if( slot * p = tls::read_ptr>() ) { - if( OverwriteAllowed || !p->has_value(err_id) ) + if( !OnError || !p->has_value(err_id) ) (void) p->put(err_id, std::forward(e)); } #if BOOST_LEAF_CFG_DIAGNOSTICS @@ -465,14 +486,14 @@ namespace leaf_detail int c = int(tls::read_uint()); BOOST_LEAF_ASSERT(c>=0); if( c ) - load_unexpected(err_id, std::forward(e)); + load_unexpected(err_id, std::forward(e)); } #endif return 0; } - template - BOOST_LEAF_CONSTEXPR inline int accumulate_slot( int err_id, F && f ) + template + BOOST_LEAF_CONSTEXPR inline int accumulate_slot( int err_id, F && f ) noexcept(OnError) { static_assert(function_traits::arity==1, "Lambdas passed to accumulate must take a single e-type argument by reference"); using E = typename std::decay>::type; @@ -491,7 +512,7 @@ namespace leaf_detail int c = int(tls::read_uint()); BOOST_LEAF_ASSERT(c>=0); if( c ) - accumulate_unexpected(err_id, std::forward(f)); + accumulate_unexpected(err_id, std::forward(f)); } #endif return 0; @@ -548,7 +569,7 @@ namespace leaf_detail { BOOST_LEAF_CONSTEXPR static int load_( int err_id, E && e ) noexcept { - return load_slot(err_id, std::forward(e)); + return load_slot(err_id, std::forward(e)); } }; @@ -557,7 +578,7 @@ namespace leaf_detail { BOOST_LEAF_CONSTEXPR static int load_( int err_id, F && f ) noexcept { - return load_slot(err_id, std::forward(f)()); + return load_slot(err_id, std::forward(f)()); } }; @@ -566,7 +587,7 @@ namespace leaf_detail { BOOST_LEAF_CONSTEXPR static int load_( int err_id, F && f ) noexcept { - return accumulate_slot(err_id, std::forward(f)); + return accumulate_slot(err_id, std::forward(f)); } }; } @@ -574,6 +595,7 @@ namespace leaf_detail //////////////////////////////////////// #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR + namespace leaf_detail { class leaf_category final: public std::error_category @@ -608,7 +630,7 @@ namespace leaf_detail else { err_id = new_id(); - (void) load_slot(err_id, ec); + (void) load_slot(err_id, ec); return (err_id&~3)|1; } } @@ -623,6 +645,7 @@ inline bool is_error_id( std::error_code const & ec ) noexcept BOOST_LEAF_ASSERT(!res || !ec.value() || ((ec.value()&3)==1)); return res; } + #endif //////////////////////////////////////// @@ -718,7 +741,7 @@ class BOOST_LEAF_SYMBOL_VISIBLE error_id } template - friend std::basic_ostream & operator<<( std::basic_ostream & os, error_id x ) + friend std::ostream & operator<<( std::basic_ostream & os, error_id x ) { return os << x.value_; } @@ -774,8 +797,15 @@ class polymorphic_context virtual void deactivate() noexcept = 0; virtual void propagate( error_id ) noexcept = 0; virtual bool is_active() const noexcept = 0; - inline virtual void print( std::ostream & ) const { }; + virtual void print( std::ostream & ) const { }; error_id captured_id_; + + template + friend std::ostream & operator<<( std::basic_ostream & os, polymorphic_context const & ctx ) + { + ctx.print(os); + return os; + } }; #if BOOST_LEAF_CFG_CAPTURE diff --git a/include/boost/leaf/handle_errors.hpp b/include/boost/leaf/handle_errors.hpp index 8517e7c2..90cefd7e 100644 --- a/include/boost/leaf/handle_errors.hpp +++ b/include/boost/leaf/handle_errors.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_HANDLE_ERRORS_HPP_INCLUDED #define BOOST_LEAF_HANDLE_ERRORS_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,7 +9,6 @@ #include #include #include -#include namespace boost { namespace leaf { @@ -89,7 +88,7 @@ class BOOST_LEAF_SYMBOL_VISIBLE error_info } template - friend std::basic_ostream & operator<<( std::basic_ostream & os, error_info const & x ) + friend std::ostream & operator<<( std::basic_ostream & os, error_info const & x ) { os << "leaf::error_info: "; x.print(os); @@ -123,7 +122,7 @@ class BOOST_LEAF_SYMBOL_VISIBLE diagnostic_info: public error_info public: template - friend std::basic_ostream & operator<<( std::basic_ostream & os, diagnostic_info const & x ) + friend std::ostream & operator<<( std::basic_ostream & os, diagnostic_info const & x ) { os << "leaf::diagnostic_info for "; x.print(os); @@ -173,7 +172,7 @@ class BOOST_LEAF_SYMBOL_VISIBLE diagnostic_info: public error_info public: template - friend std::basic_ostream & operator<<( std::basic_ostream & os, diagnostic_info const & x ) + friend std::ostream & operator<<( std::basic_ostream & os, diagnostic_info const & x ) { os << "leaf::diagnostic_info requires #define BOOST_LEAF_CFG_DIAGNOSTICS 1\n" @@ -232,7 +231,7 @@ class BOOST_LEAF_SYMBOL_VISIBLE verbose_diagnostic_info: public error_info public: template - friend std::basic_ostream & operator<<( std::basic_ostream & os, verbose_diagnostic_info const & x ) + friend std::ostream & operator<<( std::basic_ostream & os, verbose_diagnostic_info const & x ) { os << "leaf::verbose_diagnostic_info for "; int const err_id = x.error().value(); @@ -283,7 +282,7 @@ class BOOST_LEAF_SYMBOL_VISIBLE verbose_diagnostic_info: public error_info public: template - friend std::basic_ostream & operator<<( std::basic_ostream & os, verbose_diagnostic_info const & x ) + friend std::ostream & operator<<( std::basic_ostream & os, verbose_diagnostic_info const & x ) { os << "leaf::verbose_diagnostic_info requires #define BOOST_LEAF_CFG_DIAGNOSTICS 1\n" diff --git a/include/boost/leaf/on_error.hpp b/include/boost/leaf/on_error.hpp index f9250565..0144385d 100644 --- a/include/boost/leaf/on_error.hpp +++ b/include/boost/leaf/on_error.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_LEAF_ON_ERROR_HPP_INCLUDED #define BOOST_LEAF_ON_ERROR_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -103,7 +103,7 @@ namespace leaf_detail BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept { - (void) load_slot(err_id, std::move(e_)); + (void) load_slot(err_id, std::move(e_)); } }; @@ -122,7 +122,7 @@ namespace leaf_detail BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept { - (void) load_slot(err_id, f_()); + (void) load_slot(err_id, f_()); } }; @@ -144,7 +144,7 @@ namespace leaf_detail BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept { - accumulate_slot(err_id, std::move(f_)); + accumulate_slot(err_id, std::move(f_)); } }; diff --git a/include/boost/leaf/result.hpp b/include/boost/leaf/result.hpp index cb813014..958ab1a1 100644 --- a/include/boost/leaf/result.hpp +++ b/include/boost/leaf/result.hpp @@ -1,12 +1,13 @@ #ifndef BOOST_LEAF_RESULT_HPP_INCLUDED #define BOOST_LEAF_RESULT_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include +#include #include #include @@ -34,6 +35,40 @@ class bad_result: //////////////////////////////////////// +namespace leaf_detail +{ + template ::value> + struct result_value_printer; + + template + struct result_value_printer + { + template + static void print( std::basic_ostream & s, T const & x ) + { + (void) (s << x); + } + }; + + template + struct result_value_printer + { + template + static void print( std::basic_ostream & s, T const & ) + { + (void) (s << "{not printable}"); + } + }; + + template + void print_result_value( std::basic_ostream & s, T const & x ) + { + result_value_printer::print(s, x); + } +} + +//////////////////////////////////////// + namespace leaf_detail { template @@ -257,11 +292,20 @@ class result error_id get_error_id() const noexcept { - BOOST_LEAF_ASSERT(what_.kind()!=result_discriminant::val); + BOOST_LEAF_ASSERT(what_.kind() != result_discriminant::val); #if BOOST_LEAF_CFG_CAPTURE - return what_.kind()==result_discriminant::ctx_ptr ? ctx_->captured_id_ : what_.get_error_id(); + if( what_.kind() == result_discriminant::ctx_ptr ) + { + BOOST_LEAF_ASSERT(ctx_ && ctx_->captured_id_); + return ctx_->captured_id_; + } + else + { + BOOST_LEAF_ASSERT(what_.kind() == result_discriminant::err_id); + return what_.get_error_id(); + } #else - BOOST_LEAF_ASSERT(what_.kind()!=result_discriminant::ctx_ptr); // Possible ODR violation. + BOOST_LEAF_ASSERT(what_.kind() != result_discriminant::ctx_ptr); // Possible ODR violation. return what_.get_error_id(); #endif } @@ -365,10 +409,18 @@ class result #endif #if BOOST_LEAF_CFG_CAPTURE + result( context_ptr const & ctx ) noexcept: + ctx_(ctx), + what_(result_discriminant::kind_ctx_ptr{}) + { + BOOST_LEAF_ASSERT(ctx_ && ctx_->captured_id_); + } + result( context_ptr && ctx ) noexcept: ctx_(std::move(ctx)), what_(result_discriminant::kind_ctx_ptr{}) { + BOOST_LEAF_ASSERT(ctx_ && ctx_->captured_id_); } #endif @@ -517,6 +569,35 @@ class result { return error_id(error()).load(std::forward(item)...); } + + template + void print( std::basic_ostream & os ) const + { + switch(what_.kind()) + { + case result_discriminant::val: + leaf_detail::print_result_value(os, value()); + break; + case result_discriminant::ctx_ptr: +#if BOOST_LEAF_CFG_CAPTURE + BOOST_LEAF_ASSERT(ctx_ && ctx_->captured_id_); + os << "Error ID " << ctx_->captured_id_ << ", captured error objects:\n" << *ctx_; + break; +#else + BOOST_LEAF_ASSERT(0); // Possible ODR violation. +#endif + default: + os << "Error ID " << what_.get_error_id(); + } + } + + + template + friend std::ostream & operator<<( std::basic_ostream & os, result const & r ) + { + r.print(os); + return os; + } }; //////////////////////////////////////// @@ -574,6 +655,11 @@ class result: #endif #if BOOST_LEAF_CFG_CAPTURE + result( context_ptr const & ctx ) noexcept: + base(ctx) + { + } + result( context_ptr && ctx ) noexcept: base(std::move(ctx)) { @@ -604,6 +690,22 @@ class result: BOOST_LEAF_ASSERT(has_value()); } + template + void print( std::basic_ostream & os ) const + { + if( what_.kind() == result_discriminant::val ) + os << "No error"; + else + os << *static_cast(this); + } + + template + friend std::ostream & operator<<( std::basic_ostream & os, result const & r ) + { + r.print(os); + return os; + } + using base::operator=; using base::operator bool; using base::get_error_id; diff --git a/meson.build b/meson.build index f351e97c..96416ed1 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -# Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +# Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -170,6 +170,7 @@ if option_enable_unit_tests 'result_bad_result_test', 'result_implicit_conversion_test', 'result_load_test', + 'result_print_test', 'result_ref_test', 'result_state_test', 'tls_array_alloc_test1', diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 30a87d55..d6a922e0 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -1,4 +1,4 @@ -# Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +# Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -109,6 +109,7 @@ run print_test.cpp ; run result_bad_result_test.cpp ; run result_implicit_conversion_test.cpp ; run result_load_test.cpp ; +run result_print_test.cpp ; run result_ref_test.cpp ; run result_state_test.cpp ; run context_deduction_test.cpp ; diff --git a/test/capture_exception_state_test.cpp b/test/capture_exception_state_test.cpp index a8a4eb22..78edfcb6 100644 --- a/test/capture_exception_state_test.cpp +++ b/test/capture_exception_state_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -25,13 +25,18 @@ int main() # include #endif +#if BOOST_LEAF_CFG_STD_STRING +# include +# include +#endif + #include "lightweight_test.hpp" namespace leaf = boost::leaf; int count = 0; -template +template struct info { info() noexcept @@ -48,6 +53,12 @@ struct info { --count; } + + template + friend std::ostream & operator<<( std::basic_ostream & os, info const & ) + { + return os << "info<" << N << "> instance"; + } }; int main() @@ -63,10 +74,11 @@ int main() } ); BOOST_TEST_EQ(count, 0); std::exception_ptr ep; + leaf::context_ptr ctx = leaf::make_shared_context(error_handlers); try { leaf::capture( - leaf::make_shared_context(error_handlers), + ctx, [] { leaf::throw_exception(info<1>{}, info<3>{}); @@ -78,6 +90,20 @@ int main() ep = std::current_exception(); } BOOST_TEST_EQ(count, 2); + +#if BOOST_LEAF_CFG_STD_STRING + { + std::ostringstream st; + st << *ctx; + std::string s = st.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_NE(s.find("info<1> instance"), s.npos); + BOOST_TEST_NE(s.find("info<3> instance"), s.npos); +#endif + } +#endif + int r = leaf::try_catch( [&]() -> int { @@ -87,6 +113,7 @@ int main() BOOST_TEST_EQ(r, 1); ep = std::exception_ptr(); BOOST_TEST_EQ(count, 0); + return boost::report_errors(); } diff --git a/test/capture_result_state_test.cpp b/test/capture_result_state_test.cpp index 1d116231..6b6e054e 100644 --- a/test/capture_result_state_test.cpp +++ b/test/capture_result_state_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -25,13 +25,18 @@ int main() # include #endif +#if BOOST_LEAF_CFG_STD_STRING +# include +# include +#endif + #include "lightweight_test.hpp" namespace leaf = boost::leaf; int count = 0; -template +template struct info { info() noexcept @@ -48,6 +53,12 @@ struct info { --count; } + + template + friend std::ostream & operator<<( std::basic_ostream & os, info const & ) + { + return os << "info<" << N << "> instance"; + } }; int main() @@ -63,14 +74,28 @@ int main() } ); { + leaf::context_ptr ctx = leaf::make_shared_context(error_handlers); auto r = leaf::capture( - leaf::make_shared_context(error_handlers), + ctx, []() -> leaf::result { return leaf::new_error( info<1>{}, info<3>{} ); } ); BOOST_TEST_EQ(count, 2); +#if BOOST_LEAF_CFG_STD_STRING + { + std::ostringstream st; + st << *ctx; + std::string s = st.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_NE(s.find("info<1> instance"), s.npos); + BOOST_TEST_NE(s.find("info<3> instance"), s.npos); +#endif + } +#endif + int answer = leaf::try_handle_all( [&r] { diff --git a/test/ctx_remote_handle_all_test.cpp b/test/ctx_remote_handle_all_test.cpp index 71ceb345..50ba9ed7 100644 --- a/test/ctx_remote_handle_all_test.cpp +++ b/test/ctx_remote_handle_all_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -49,6 +49,8 @@ int main() leaf::result r1 = f(ctx); BOOST_TEST(!r1); + std::cout << "ctx contents:" << std::endl << ctx; + int r2 = ctx.handle_error( r1.error(), std::move(handlers)); diff --git a/test/defer_basic_test.cpp b/test/defer_basic_test.cpp index 0f460f80..1cb616fd 100644 --- a/test/defer_basic_test.cpp +++ b/test/defer_basic_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -11,8 +11,12 @@ # include #endif +#if BOOST_LEAF_CFG_STD_STRING +# include +# include +#endif + #include "lightweight_test.hpp" -#include namespace leaf = boost::leaf; @@ -53,9 +57,10 @@ int main() { BOOST_TEST_EQ(i42.value, 42); #if BOOST_LEAF_CFG_STD_STRING - std::stringstream ss; ss << di; + std::stringstream ss; + ss << di; std::string s = ss.str(); - std::cout << s; + std::cout << s << std::endl; #if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST(s.find("info<-42>")!=s.npos); #else diff --git a/test/defer_nested_success_result_test.cpp b/test/defer_nested_success_result_test.cpp index 37c3c282..e6941c09 100644 --- a/test/defer_nested_success_result_test.cpp +++ b/test/defer_nested_success_result_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/diagnostic_info_test1.cpp b/test/diagnostic_info_test1.cpp index b57e7b80..a2f8c06b 100644 --- a/test/diagnostic_info_test1.cpp +++ b/test/diagnostic_info_test1.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -14,8 +14,8 @@ #if BOOST_LEAF_CFG_STD_STRING # include +# include #endif -#include #include "lightweight_test.hpp" @@ -112,8 +112,10 @@ int main() std::ostringstream st; st << unmatched; std::string s = st.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST_NE(s.find("leaf::error_info: Error ID = "), s.npos); - std::cout << s; +#endif #endif }, []() @@ -150,13 +152,14 @@ int main() std::ostringstream st; st << unmatched; std::string s = st.str(); + std::cout << s << std::endl; #if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST_NE(s.find("leaf::diagnostic_info for Error ID = "), s.npos); BOOST_TEST_NE(s.find("e_source_location"), s.npos); BOOST_TEST_NE(s.find("*** printable_info_printable_payload printed printable_payload ***"), s.npos); BOOST_TEST_NE(s.find("*** printable_info_non_printable_payload ***"), s.npos); BOOST_TEST_NE(s.find(": printed printable_payload"), s.npos); - BOOST_TEST_NE(s.find(": {Non-Printable}"), s.npos); + BOOST_TEST_NE(s.find(": {not printable}"), s.npos); BOOST_TEST_NE(s.find("enum_class_payload"), s.npos); BOOST_TEST_NE(s.find("Detected 2 attempts"), s.npos); BOOST_TEST_NE(s.find("unexpected_test<1>"), s.npos); @@ -165,7 +168,6 @@ int main() BOOST_TEST_NE(s.find("leaf::diagnostic_info requires #define BOOST_LEAF_CFG_DIAGNOSTICS 1"), s.npos); BOOST_TEST_NE(s.find("leaf::error_info: Error ID = "), s.npos); #endif - std::cout << s; #endif }, []() @@ -202,13 +204,14 @@ int main() std::ostringstream st; st << di; std::string s = st.str(); + std::cout << s << std::endl; #if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST_NE(s.find("leaf::verbose_diagnostic_info for Error ID = "), s.npos); BOOST_TEST_NE(s.find("e_source_location"), s.npos); BOOST_TEST_NE(s.find("*** printable_info_printable_payload printed printable_payload ***"), s.npos); BOOST_TEST_NE(s.find("*** printable_info_non_printable_payload ***"), s.npos); BOOST_TEST_NE(s.find(": printed printable_payload"), s.npos); - BOOST_TEST_NE(s.find(": {Non-Printable}"), s.npos); + BOOST_TEST_NE(s.find(": {not printable}"), s.npos); BOOST_TEST_NE(s.find("enum_class"), s.npos); BOOST_TEST_NE(s.find("Unhandled error objects:"), s.npos); BOOST_TEST_NE(s.find("unexpected_test<1>"), s.npos); @@ -219,7 +222,6 @@ int main() BOOST_TEST_NE(s.find("leaf::verbose_diagnostic_info requires #define BOOST_LEAF_CFG_DIAGNOSTICS 1"), s.npos); BOOST_TEST_NE(s.find("leaf::error_info: Error ID = "), s.npos); #endif - std::cout << s; #endif }, []() @@ -260,10 +262,12 @@ int main() std::ostringstream st; st << unmatched; std::string s = st.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST_NE(s.find("leaf::error_info: Error ID = "), s.npos); BOOST_TEST_NE(s.find("Exception dynamic type: "), s.npos); BOOST_TEST_NE(s.find("std::exception::what(): my_exception"), s.npos); - std::cout << s; +#endif #endif } ); @@ -296,6 +300,7 @@ int main() std::ostringstream st; st << unmatched; std::string s = st.str(); + std::cout << s << std::endl; #if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST_NE(s.find("leaf::diagnostic_info for Error ID = "), s.npos); BOOST_TEST_NE(s.find("Exception dynamic type: "), s.npos); @@ -304,7 +309,7 @@ int main() BOOST_TEST_NE(s.find("*** printable_info_printable_payload printed printable_payload ***"), s.npos); BOOST_TEST_NE(s.find("*** printable_info_non_printable_payload ***"), s.npos); BOOST_TEST_NE(s.find(": printed printable_payload"), s.npos); - BOOST_TEST_NE(s.find(": {Non-Printable}"), s.npos); + BOOST_TEST_NE(s.find(": {not printable}"), s.npos); BOOST_TEST_NE(s.find("enum_class_payload"), s.npos); BOOST_TEST_NE(s.find("Detected 2 attempts"), s.npos); BOOST_TEST_NE(s.find("unexpected_test<1>"), s.npos); @@ -315,7 +320,6 @@ int main() BOOST_TEST_NE(s.find("Exception dynamic type: "), s.npos); BOOST_TEST_NE(s.find("std::exception::what(): my_exception"), s.npos); #endif - std::cout << s; #endif } ); @@ -348,6 +352,7 @@ int main() std::ostringstream st; st << di; std::string s = st.str(); + std::cout << s << std::endl; #if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST_NE(s.find("leaf::verbose_diagnostic_info for Error ID = "), s.npos); BOOST_TEST_NE(s.find("Exception dynamic type: "), s.npos); @@ -356,7 +361,7 @@ int main() BOOST_TEST_NE(s.find("*** printable_info_printable_payload printed printable_payload ***"), s.npos); BOOST_TEST_NE(s.find("*** printable_info_non_printable_payload ***"), s.npos); BOOST_TEST_NE(s.find(": printed printable_payload"), s.npos); - BOOST_TEST_NE(s.find(": {Non-Printable}"), s.npos); + BOOST_TEST_NE(s.find(": {not printable}"), s.npos); BOOST_TEST_NE(s.find("enum_class_payload"), s.npos); BOOST_TEST_NE(s.find("Unhandled error objects:"), s.npos); BOOST_TEST_NE(s.find("unexpected_test<1>"), s.npos); @@ -369,7 +374,6 @@ int main() BOOST_TEST_NE(s.find("Exception dynamic type: "), s.npos); BOOST_TEST_NE(s.find("std::exception::what(): my_exception"), s.npos); #endif - std::cout << s; #endif } ); diff --git a/test/diagnostic_info_test2.cpp b/test/diagnostic_info_test2.cpp index 805b6a10..0aab481a 100644 --- a/test/diagnostic_info_test2.cpp +++ b/test/diagnostic_info_test2.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -13,8 +13,8 @@ #if BOOST_LEAF_CFG_STD_STRING # include +# include #endif -#include #include "lightweight_test.hpp" @@ -57,10 +57,10 @@ int main() std::ostringstream st; st << di; std::string s = st.str(); + std::cout << s << std::endl; #if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST_NE(s.find("info<2>"), s.npos); #endif - std::cout << s; #endif } ); @@ -94,10 +94,10 @@ int main() std::ostringstream st; st << di; std::string s = st.str(); + std::cout << s << std::endl; #if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST_NE(s.find("info<2>"), s.npos); #endif - std::cout << s; #endif } ); @@ -131,10 +131,10 @@ int main() std::ostringstream st; st << di; std::string s = st.str(); + std::cout << s << std::endl; #if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST_NE(s.find("info<2>"), s.npos); #endif - std::cout << s; #endif } ); diff --git a/test/diagnostic_info_test3.cpp b/test/diagnostic_info_test3.cpp index 7a19401c..686c0360 100644 --- a/test/diagnostic_info_test3.cpp +++ b/test/diagnostic_info_test3.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -13,8 +13,8 @@ #if BOOST_LEAF_CFG_STD_STRING # include +# include #endif -#include #include "lightweight_test.hpp" @@ -46,11 +46,11 @@ int main() std::ostringstream st; st << di; std::string s = st.str(); + std::cout << s << std::endl; #if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST_NE(s.find("41"), s.npos); BOOST_TEST_EQ(s.find("42"), s.npos); #endif - std::cout << s; #endif } ); diff --git a/test/diagnostic_info_test4.cpp b/test/diagnostic_info_test4.cpp index 2e21070d..5d152381 100644 --- a/test/diagnostic_info_test4.cpp +++ b/test/diagnostic_info_test4.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -13,8 +13,9 @@ #if BOOST_LEAF_CFG_STD_STRING # include +# include #endif -#include + #include #include "lightweight_test.hpp" @@ -60,12 +61,12 @@ int main() std::ostringstream st; st << e; std::string s = st.str(); + std::cout << s << std::endl; #if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST_NE(s.find("new_error"), s.npos); BOOST_TEST_NE(s.find("appended: 42"), s.npos); BOOST_TEST_NE(s.find("appended: 43"), s.npos); #endif - std::cout << s; #endif } ); diff --git a/test/diagnostic_info_test5.cpp b/test/diagnostic_info_test5.cpp index 6dff6aea..7fce88ee 100644 --- a/test/diagnostic_info_test5.cpp +++ b/test/diagnostic_info_test5.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -13,8 +13,8 @@ #if BOOST_LEAF_CFG_STD_STRING # include +# include #endif -#include #include "lightweight_test.hpp" @@ -92,7 +92,8 @@ int main() std::ostringstream st; st << di; std::string s = st.str(); -# if BOOST_LEAF_CFG_DIAGNOSTICS + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS auto const n1 = s.find("info<1>: acc=0"); auto const n2 = s.find("info<2>: acc=0"); auto const n3 = s.find("info<3>: acc=0"); @@ -108,10 +109,9 @@ int main() BOOST_TEST_GT(n3, nd); BOOST_TEST_GT(n4, nd); BOOST_TEST_EQ(counter, 4); -# else +#else BOOST_TEST_EQ(counter, 1); -# endif - std::cout << s; +#endif #endif }, [] diff --git a/test/e_LastError_test.cpp b/test/e_LastError_test.cpp index ff8ffc03..1f9b334f 100644 --- a/test/e_LastError_test.cpp +++ b/test/e_LastError_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -25,8 +25,12 @@ int main() # include #endif +#if BOOST_LEAF_CFG_STD_STRING +# include +# include +#endif + #include "lightweight_test.hpp" -#include namespace leaf = boost::leaf; @@ -36,7 +40,11 @@ int main() #if BOOST_LEAF_CFG_STD_STRING std::stringstream ss; ss << leaf::windows::e_LastError{}; + std::string s = ss.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST(ss.str().find("The system cannot find the file specified") != std::string::npos); +#endif #endif int r = leaf::try_handle_all( diff --git a/test/e_errno_test.cpp b/test/e_errno_test.cpp index f8e60a15..e9faa8fb 100644 --- a/test/e_errno_test.cpp +++ b/test/e_errno_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -11,8 +11,12 @@ # include #endif +#if BOOST_LEAF_CFG_STD_STRING +# include +# include +#endif + #include "lightweight_test.hpp" -#include namespace leaf = boost::leaf; @@ -22,7 +26,11 @@ int main() #if BOOST_LEAF_CFG_STD_STRING std::stringstream ss; ss << leaf::e_errno{}; - BOOST_TEST(ss.str().find(std::strerror(ENOENT)) != std::string::npos); + std::string s = ss.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_STD_DIAGNOSTICS + BOOST_TEST(s.find(std::strerror(ENOENT)) != std::string::npos); +#endif #endif int r = leaf::try_handle_all( diff --git a/test/optional_test.cpp b/test/optional_test.cpp index 6661f71a..e83b5d84 100644 --- a/test/optional_test.cpp +++ b/test/optional_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/test/preload_basic_test.cpp b/test/preload_basic_test.cpp index e374083d..7a14006a 100644 --- a/test/preload_basic_test.cpp +++ b/test/preload_basic_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -11,8 +11,12 @@ # include #endif +#if BOOST_LEAF_CFG_STD_STRING +# include +# include +#endif + #include "lightweight_test.hpp" -#include namespace leaf = boost::leaf; @@ -40,9 +44,10 @@ void test( G && g ) { BOOST_TEST_EQ(i42.value, 42); #if BOOST_LEAF_CFG_STD_STRING - std::stringstream ss; ss << di; + std::stringstream ss; + ss << di; std::string s = ss.str(); - std::cout << s; + std::cout << s << std::endl; #if BOOST_LEAF_CFG_DIAGNOSTICS BOOST_TEST(s.find("info<-42>")!=s.npos); #else diff --git a/test/print_test.cpp b/test/print_test.cpp index e9ed0e35..57c1fa33 100644 --- a/test/print_test.cpp +++ b/test/print_test.cpp @@ -1,11 +1,11 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include -#if !BOOST_LEAF_CFG_DIAGNOSTICS +#if !BOOST_LEAF_CFG_DIAGNOSTICS && BOOST_LEAF_CFG_STD_STRING #include @@ -23,8 +23,10 @@ int main() # include #endif -#include "lightweight_test.hpp" #include +#include + +#include "lightweight_test.hpp" namespace leaf = boost::leaf; @@ -67,13 +69,14 @@ struct c4 unprintable value;; }; -template +template bool check( T const & x, char const * sub ) { using namespace leaf::leaf_detail; std::ostringstream s; diagnostic::print(s,x); std::string q = s.str(); + std::cout << "LINE " << Line << ": " << q << std::endl; return q.find(sub)!=q.npos; } @@ -84,42 +87,42 @@ struct my_exception: std::exception int main() { - BOOST_TEST(check(c0{ },"c0")); - BOOST_TEST(check(c1{42},"c1")); + BOOST_TEST(check<__LINE__>(c0{ },"c0")); + BOOST_TEST(check<__LINE__>(c1{42},"c1")); { c1 x; c1 & y = x; - BOOST_TEST(check(x,"c1")); - BOOST_TEST(check(y,"c1")); + BOOST_TEST(check<__LINE__>(x,"c1")); + BOOST_TEST(check<__LINE__>(y,"c1")); } - BOOST_TEST(check(c2{42},"c2")); + BOOST_TEST(check<__LINE__>(c2{42},"c2")); { c2 x = {42}; c2 & y = x; - BOOST_TEST(check(x,"c2")); - BOOST_TEST(check(y,"c2")); + BOOST_TEST(check<__LINE__>(x,"c2")); + BOOST_TEST(check<__LINE__>(y,"c2")); } - BOOST_TEST(check(c3{42},"c3")); - BOOST_TEST(check(c3{42},"42")); + BOOST_TEST(check<__LINE__>(c3{42},"c3")); + BOOST_TEST(check<__LINE__>(c3{42},"42")); { c3 x = {42}; c3 & y = x; - BOOST_TEST(check(x,"c3")); - BOOST_TEST(check(x,"42")); - BOOST_TEST(check(y,"c3")); - BOOST_TEST(check(y,"42")); + BOOST_TEST(check<__LINE__>(x,"c3")); + BOOST_TEST(check<__LINE__>(x,"42")); + BOOST_TEST(check<__LINE__>(y,"c3")); + BOOST_TEST(check<__LINE__>(y,"42")); } - BOOST_TEST(check(c4(),"c4")); - BOOST_TEST(check(c4(),"{Non-Printable}")); + BOOST_TEST(check<__LINE__>(c4(),"c4")); + BOOST_TEST(check<__LINE__>(c4(),"{not printable}")); { c4 x; c4 & y = x; - BOOST_TEST(check(x,"c4")); - BOOST_TEST(check(x,"{Non-Printable}")); - BOOST_TEST(check(y,"c4")); - BOOST_TEST(check(y,"{Non-Printable}")); + BOOST_TEST(check<__LINE__>(x,"c4")); + BOOST_TEST(check<__LINE__>(x,"{not printable}")); + BOOST_TEST(check<__LINE__>(y,"c4")); + BOOST_TEST(check<__LINE__>(y,"{not printable}")); } - BOOST_TEST(check(my_exception{}, "std::exception::what(): my_exception_what")); + BOOST_TEST(check<__LINE__>(my_exception{}, "std::exception::what(): my_exception_what")); return boost::report_errors(); } diff --git a/test/result_print_test.cpp b/test/result_print_test.cpp new file mode 100644 index 00000000..8bc28e11 --- /dev/null +++ b/test/result_print_test.cpp @@ -0,0 +1,117 @@ +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifdef BOOST_LEAF_TEST_SINGLE_HEADER +# include "leaf.hpp" +#else +# include +# include +# include +#endif + +#if BOOST_LEAF_CFG_STD_STRING +# include +# include +#endif + +#include "lightweight_test.hpp" + +namespace leaf = boost::leaf; + +struct non_printable_value +{ +}; + +struct e_err +{ + template + friend std::ostream & operator<<( std::basic_ostream & os, e_err const & ) + { + return os << "e_err"; + } +}; + +int main() +{ + { + leaf::result r = 42; + BOOST_TEST(r); +#if BOOST_LEAF_CFG_STD_STRING + std::stringstream ss; + ss << r; + std::string s = ss.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_EQ(s, "42"); +#endif +#endif + } + + { + leaf::result r; + BOOST_TEST(r); +#if BOOST_LEAF_CFG_STD_STRING + std::stringstream ss; + ss << r; + std::string s = ss.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_EQ(s, "{not printable}"); +#endif +#endif + } + + { + leaf::result r; + BOOST_TEST(r); +#if BOOST_LEAF_CFG_STD_STRING + std::stringstream ss; + ss << r; + std::string s = ss.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_EQ(s, "No error"); +#endif +#endif + } + + { + leaf::result r = leaf::new_error(e_err{ }); + BOOST_TEST(!r); +#if BOOST_LEAF_CFG_STD_STRING + std::stringstream ss; + ss << r; + std::string s = ss.str(); + std::cout << s << std::endl; + leaf::error_id err = r.error(); +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_EQ(s, "Error ID " + std::to_string(err.value())); +#endif +#endif + } + +#if BOOST_LEAF_CFG_CAPTURE + { + using context_type = leaf::leaf_detail::polymorphic_context_impl>; + { + leaf::result r = leaf::capture( std::make_shared(), []{ return leaf::result( leaf::new_error( e_err { } ) ); } ); +#if BOOST_LEAF_CFG_STD_STRING + std::stringstream ss; + ss << r; + std::string s = ss.str(); + std::cout << s << std::endl; + leaf::error_id err = r.error(); + BOOST_TEST_NE(s.find("Error ID " + std::to_string(err.value())), s.npos); +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_NE(s.find("captured error objects"), s.npos); + BOOST_TEST_NE(s.find("e_err"), s.npos); +#endif +#endif + } + } +#endif + + return boost::report_errors(); +} diff --git a/test/visibility_test.cpp b/test/visibility_test.cpp index d3d58fe9..c02756cb 100644 --- a/test/visibility_test.cpp +++ b/test/visibility_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -11,8 +11,13 @@ #endif #include "visibility_test_lib.hpp" + +#if BOOST_LEAF_CFG_STD_STRING +# include +# include +#endif + #include "lightweight_test.hpp" -#include namespace leaf = boost::leaf; @@ -36,14 +41,22 @@ int main() { #if BOOST_LEAF_CFG_STD_STRING std::stringstream ss; ss << info; - BOOST_TEST_NE(ss.str().find("1 attempt to communicate an unexpected error object"), std::string::npos); + std::string s = ss.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_NE(s.find("1 attempt to communicate an unexpected error object"), std::string::npos); +#endif #endif } if( BOOST_LEAF_CFG_DIAGNOSTICS ) { #if BOOST_LEAF_CFG_STD_STRING std::stringstream ss; ss << vinfo; - BOOST_TEST_NE(ss.str().find("Test my_info<3>::value = 3"), std::string::npos); + std::string s = ss.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_NE(s.find("Test my_info<3>::value = 3"), std::string::npos); +#endif #endif } return 1; @@ -71,14 +84,22 @@ int main() { #if BOOST_LEAF_CFG_STD_STRING std::stringstream ss; ss << info; - BOOST_TEST_NE(ss.str().find("1 attempt to communicate an unexpected error object"), std::string::npos); + std::string s = ss.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_NE(s.find("1 attempt to communicate an unexpected error object"), std::string::npos); +#endif #endif } if( BOOST_LEAF_CFG_DIAGNOSTICS ) { #if BOOST_LEAF_CFG_STD_STRING std::stringstream ss; ss << vinfo; - BOOST_TEST_NE(ss.str().find("Test my_info<3>::value = 3"), std::string::npos); + std::string s = ss.str(); + std::cout << s << std::endl; +#if BOOST_LEAF_CFG_DIAGNOSTICS + BOOST_TEST_NE(s.find("Test my_info<3>::value = 3"), std::string::npos); +#endif #endif } return 1; diff --git a/test/visibility_test_lib.hpp b/test/visibility_test_lib.hpp index bd924c3f..cc7d6fc6 100644 --- a/test/visibility_test_lib.hpp +++ b/test/visibility_test_lib.hpp @@ -1,7 +1,7 @@ #ifndef VISIBILITY_TEST_LIB_HPP_INCLUDED #define VISIBILITY_TEST_LIB_HPP_INCLUDED -// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc. +// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -15,7 +15,7 @@ struct BOOST_SYMBOL_VISIBLE my_info int value; template - friend std::basic_ostream & operator<<( std::basic_ostream & os, my_info const & x ) + friend std::ostream & operator<<( std::basic_ostream & os, my_info const & x ) { return os << "Test my_info<" << Tag << ">::value = " << x.value; } From a84943f0308083ac0d938079ea32603b433a74f6 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Fri, 15 Sep 2023 13:58:40 -0700 Subject: [PATCH 027/103] Removing references to deleted doc png files --- doc/Jamfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Jamfile b/doc/Jamfile index 84edc47c..1443ba55 100644 --- a/doc/Jamfile +++ b/doc/Jamfile @@ -9,7 +9,7 @@ project doc/leaf ; import asciidoctor ; html index.html : leaf.adoc : stylesheet=zajo-dark.css linkcss ; -install html_ : index.html LEAF-1.png LEAF-2.png skin.png zajo-dark.css zajo-light.css rouge-github.css : html ; +install html_ : index.html skin.png zajo-dark.css zajo-light.css rouge-github.css : html ; pdf leaf.pdf : leaf.adoc : book pdf-themesdir=. pdf-theme=leaf ; install pdf_ : leaf.pdf : html ; From 863bfdd3691b2f2213fd45ed6c6699da87b1fe36 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sat, 16 Sep 2023 12:13:58 -0700 Subject: [PATCH 028/103] Disabled GCC 4.9 in Drone unit tests --- .drone.jsonnet | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.drone.jsonnet b/.drone.jsonnet index e84bfab0..867f472d 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -96,14 +96,6 @@ local windows_pipeline(name, image, environment, arch = "amd64") = }; [ - linux_pipeline( - "Linux 14.04 GCC 4.9", - "cppalliance/droneubuntu1404:1", - { TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '11' }, - "g++-4.9", - [ "ppa:ubuntu-toolchain-r/test" ], - ), - linux_pipeline( "Linux 16.04 GCC 5*", "cppalliance/droneubuntu1604:1", From 49a1fb31f6b5ae8b4f1df57eed86033b6cac7bc5 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Fri, 22 Sep 2023 09:54:47 -0700 Subject: [PATCH 029/103] Issue 60 --- include/boost/leaf/result.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/leaf/result.hpp b/include/boost/leaf/result.hpp index 958ab1a1..7236ff38 100644 --- a/include/boost/leaf/result.hpp +++ b/include/boost/leaf/result.hpp @@ -165,7 +165,7 @@ namespace leaf_detail //////////////////////////////////////// template -class result +class BOOST_LEAF_NODISCARD result { template friend class result; @@ -608,7 +608,7 @@ namespace leaf_detail } template <> -class result: +class BOOST_LEAF_NODISCARD result: result { using result_discriminant = leaf_detail::result_discriminant; From 51f6f6597aa2561da20a9e4d5c989cb6905f0322 Mon Sep 17 00:00:00 2001 From: godmaycrying <601216481@qq.com> Date: Fri, 27 Oct 2023 15:25:06 +0800 Subject: [PATCH 030/103] Visual studio 2015 build error fixing --- include/boost/leaf/error.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index 34fed80b..9c644239 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -698,6 +698,17 @@ class BOOST_LEAF_SYMBOL_VISIBLE error_id return *this; } + template + BOOST_LEAF_CONSTEXPR error_id load(Item && item) const noexcept + { + if (int err_id = value()) + { + int const unused[] = { 42, leaf_detail::load_item::load_(err_id, std::forward(item)) }; + (void)unused; + } + return *this; + } + template BOOST_LEAF_CONSTEXPR error_id load( Item && ... item ) const noexcept { From 5b5673c27372b4f527b2df26b5e49e5e7141c2bc Mon Sep 17 00:00:00 2001 From: godmaycrying Date: Sat, 28 Oct 2023 10:44:38 +0800 Subject: [PATCH 031/103] Update error.hpp --- include/boost/leaf/error.hpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index 9c644239..4e409d70 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -698,16 +698,16 @@ class BOOST_LEAF_SYMBOL_VISIBLE error_id return *this; } - template - BOOST_LEAF_CONSTEXPR error_id load(Item && item) const noexcept - { - if (int err_id = value()) - { - int const unused[] = { 42, leaf_detail::load_item::load_(err_id, std::forward(item)) }; - (void)unused; - } - return *this; - } + template + BOOST_LEAF_CONSTEXPR error_id load(Item && item) const noexcept + { + if (int err_id = value()) + { + int const unused[] = { 42, leaf_detail::load_item::load_(err_id, std::forward(item)) }; + (void)unused; + } + return *this; + } template BOOST_LEAF_CONSTEXPR error_id load( Item && ... item ) const noexcept From c353af70da237af56182377988bab8ddb91cd927 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sat, 28 Oct 2023 16:33:24 -0700 Subject: [PATCH 032/103] GHA compat --- .github/workflows/ci.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1aedba33..6a607e2c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -119,17 +119,20 @@ jobs: - toolset: clang compiler: clang++-13 cxxstd: "11,14,17,20,2b" - os: ubuntu-22.04 + container: ubuntu:22.04 + os: ubuntu-latest install: clang-13 - toolset: clang compiler: clang++-14 cxxstd: "11,14,17,20,2b" - os: ubuntu-22.04 + container: ubuntu:22.04 + os: ubuntu-latest install: clang-14 - toolset: clang compiler: clang++-15 cxxstd: "11,14,17,20,2b" - os: ubuntu-22.04 + container: ubuntu:22.04 + os: ubuntu-latest install: clang-15 - toolset: clang compiler: clang++-16 From 867e2c94d936c1af04880c7fc4e14736e9babdc4 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sat, 28 Oct 2023 16:36:16 -0700 Subject: [PATCH 033/103] removed redundant logic in error_id::value() --- include/boost/leaf/error.hpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index 4e409d70..40a15f2e 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -722,13 +722,8 @@ class BOOST_LEAF_SYMBOL_VISIBLE error_id BOOST_LEAF_CONSTEXPR int value() const noexcept { - if( int v = value_ ) - { - BOOST_LEAF_ASSERT((v&3)==1); - return (v&~3)|1; - } - else - return 0; + BOOST_LEAF_ASSERT(value_==0 || ((value_&3)==1)); + return value_; } BOOST_LEAF_CONSTEXPR explicit operator bool() const noexcept From c4977866bc400971b7fa6f0ec08a29e1b4e80fda Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sun, 5 Nov 2023 13:53:17 -0800 Subject: [PATCH 034/103] Public result::value_type --- include/boost/leaf/result.hpp | 32 +++++++++++++++++--------------- test/result_state_test.cpp | 6 ++++++ 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/include/boost/leaf/result.hpp b/include/boost/leaf/result.hpp index 7236ff38..7737f600 100644 --- a/include/boost/leaf/result.hpp +++ b/include/boost/leaf/result.hpp @@ -75,19 +75,19 @@ namespace leaf_detail struct stored { using type = T; - using value_type = T; - using value_type_const = T const; + using value_no_ref = T; + using value_no_ref_const = T const; using value_cref = T const &; using value_ref = T &; using value_rv_cref = T const &&; using value_rv_ref = T &&; - static value_type_const * cptr( type const & v ) noexcept + static value_no_ref_const * cptr( type const & v ) noexcept { return &v; } - static value_type * ptr( type & v ) noexcept + static value_no_ref * ptr( type & v ) noexcept { return &v; } @@ -97,19 +97,19 @@ namespace leaf_detail struct stored { using type = std::reference_wrapper; - using value_type_const = T; - using value_type = T; + using value_no_ref = T; + using value_no_ref_const = T; using value_ref = T &; using value_cref = T &; using value_rv_ref = T &; using value_rv_cref = T &; - static value_type_const * cptr( type const & v ) noexcept + static value_no_ref_const * cptr( type const & v ) noexcept { return &v.get(); } - static value_type * ptr( type const & v ) noexcept + static value_no_ref * ptr( type const & v ) noexcept { return &v.get(); } @@ -226,8 +226,8 @@ class BOOST_LEAF_NODISCARD result }; using stored_type = typename leaf_detail::stored::type; - using value_type = typename leaf_detail::stored::value_type; - using value_type_const = typename leaf_detail::stored::value_type_const; + using value_no_ref = typename leaf_detail::stored::value_no_ref; + using value_no_ref_const = typename leaf_detail::stored::value_no_ref_const; using value_ref = typename leaf_detail::stored::value_ref; using value_cref = typename leaf_detail::stored::value_cref; using value_rv_ref = typename leaf_detail::stored::value_rv_ref; @@ -330,6 +330,8 @@ class BOOST_LEAF_NODISCARD result public: + using value_type = T; + result( result && x ) noexcept: what_(move_from(std::move(x))) { @@ -347,13 +349,13 @@ class BOOST_LEAF_NODISCARD result { } - result( value_type && v ) noexcept: - stored_(std::forward(v)), + result( value_no_ref && v ) noexcept: + stored_(std::forward(v)), what_(result_discriminant::kind_val{}) { } - result( value_type const & v ): + result( value_no_ref const & v ): stored_(v), what_(result_discriminant::kind_val{}) { @@ -501,12 +503,12 @@ class BOOST_LEAF_NODISCARD result #endif - value_type_const * operator->() const noexcept + value_no_ref_const * operator->() const noexcept { return has_value() ? leaf_detail::stored::cptr(stored_) : nullptr; } - value_type * operator->() noexcept + value_no_ref * operator->() noexcept { return has_value() ? leaf_detail::stored::ptr(stored_) : nullptr; } diff --git a/test/result_state_test.cpp b/test/result_state_test.cpp index 8588afbc..fde52c3e 100644 --- a/test/result_state_test.cpp +++ b/test/result_state_test.cpp @@ -15,6 +15,12 @@ namespace leaf = boost::leaf; +static_assert(std::is_same::value_type>::value, "Bad value_type"); +static_assert(std::is_same::value_type>::value, "Bad value_type"); +static_assert(std::is_same::value_type>::value, "Bad value_type"); +static_assert(std::is_same::value_type>::value, "Bad value_type"); +static_assert(std::is_same::value_type>::value, "Bad value_type"); + struct val { static int id_count; From 30a6e2a0a56d5cf53a6d114d53888e9163a0a9e8 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sun, 5 Nov 2023 16:28:42 -0800 Subject: [PATCH 035/103] Documentation update for result::value_type --- doc/leaf.adoc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/doc/leaf.adoc b/doc/leaf.adoc index f18c7b4c..90b397d4 100644 --- a/doc/leaf.adoc +++ b/doc/leaf.adoc @@ -2422,6 +2422,8 @@ namespace boost { namespace leaf { { public: + using value_type = T; + result() noexcept; result( T && v ) noexcept; result( T const & v ); @@ -2474,6 +2476,8 @@ namespace boost { namespace leaf { { public: + using value_type = void; + result() noexcept; result( error_id err ) noexcept; @@ -4408,6 +4412,8 @@ namespace boost { namespace leaf { { public: + using value_type = T; + result() noexcept; result( T && v ) noexcept; result( T const & v ); @@ -4457,6 +4463,8 @@ namespace boost { namespace leaf { { public: + using value_type = void; + result() noexcept; result( error_id err ) noexcept; @@ -4735,6 +4743,15 @@ namespace boost { namespace leaf { } } ---- +''' + +[[result::value_type]] +==== `value_type` + +A member type of `result`, defined as a synonim for `T`. + +''' + [[result::bad_result]] Effects: :: If `*this` is in <>, returns a reference to the stored value, otherwise throws `bad_result`. From 971ecacf0fb753bf51f892589249df315b7522c6 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sun, 24 Dec 2023 18:52:14 -0800 Subject: [PATCH 036/103] dynamic_capture -> result, a new way to hold and transport errors across threads. Legacy capture functionality removed. --- doc/leaf.adoc | 1154 +++++++---------- ...n_exception.cpp => dynamic_capture_eh.cpp} | 48 +- ..._result.cpp => dynamic_capture_result.cpp} | 46 +- .../print_file/print_file_outcome_result.cpp | 16 +- example/readme.md | 4 +- include/boost/leaf/capture.hpp | 239 ---- include/boost/leaf/config.hpp | 26 +- include/boost/leaf/config/tls_array.hpp | 14 +- include/boost/leaf/config/tls_freertos.hpp | 5 + include/boost/leaf/context.hpp | 124 +- include/boost/leaf/detail/all.hpp | 2 - include/boost/leaf/detail/capture_list.hpp | 129 ++ include/boost/leaf/detail/demangle.hpp | 6 +- include/boost/leaf/detail/optional.hpp | 10 +- include/boost/leaf/error.hpp | 621 +++++---- include/boost/leaf/exception.hpp | 2 +- include/boost/leaf/handle_errors.hpp | 410 +++--- include/boost/leaf/on_error.hpp | 2 +- include/boost/leaf/result.hpp | 263 ++-- meson.build | 10 +- test/Jamfile.v2 | 17 +- test/_compile-fail-BOOST_LEAF_ASSIGN.cpp | 9 - test/_compile-fail-BOOST_LEAF_AUTO.cpp | 9 - test/capture_exception_async_test.cpp | 65 +- test/capture_exception_result_async_test.cpp | 67 +- test/capture_exception_result_unload_test.cpp | 213 +++ test/capture_exception_state_test.cpp | 82 +- test/capture_exception_unload_test.cpp | 167 ++- test/capture_result_async_test.cpp | 56 +- test/capture_result_state_test.cpp | 47 +- test/capture_result_unload_test.cpp | 44 +- test/context_activator_test.cpp | 2 +- test/context_deduction_test.cpp | 9 +- test/defer_basic_test.cpp | 9 +- test/diagnostic_info_test1.cpp | 177 ++- test/diagnostic_info_test2.cpp | 16 +- test/diagnostic_info_test3.cpp | 10 +- test/diagnostic_info_test4.cpp | 12 +- test/diagnostic_info_test5.cpp | 38 +- test/dynamic_capture_print_test.cpp | 69 + test/dynamic_capture_test.cpp | 338 +++++ test/e_LastError_test.cpp | 2 +- test/e_errno_test.cpp | 2 +- test/error_code_test.cpp | 20 +- test/github_issue53x_test.cpp | 1 + test/handle_all_other_result_test.cpp | 2 +- test/handle_some_other_result_test.cpp | 2 +- test/handle_some_test.cpp | 238 +++- test/multiple_errors_test.cpp | 25 + test/optional_test.cpp | 8 +- test/preload_basic_test.cpp | 16 - test/print_test.cpp | 2 +- test/result_print_test.cpp | 63 +- test/result_ref_test.cpp | 1 - test/result_state_test.cpp | 206 ++- test/tls_array_alloc_test1.cpp | 16 +- test/tls_array_alloc_test2.cpp | 16 +- test/tls_array_alloc_test3.cpp | 16 +- test/to_variant_test.cpp | 4 +- test/try_catch_system_error_test.cpp | 1 + test/try_catch_test.cpp | 1 + test/visibility_test.cpp | 40 +- 62 files changed, 2898 insertions(+), 2371 deletions(-) rename example/{capture_in_exception.cpp => dynamic_capture_eh.cpp} (61%) rename example/{capture_in_result.cpp => dynamic_capture_result.cpp} (67%) delete mode 100644 include/boost/leaf/capture.hpp create mode 100644 include/boost/leaf/detail/capture_list.hpp create mode 100644 test/capture_exception_result_unload_test.cpp create mode 100644 test/dynamic_capture_print_test.cpp create mode 100644 test/dynamic_capture_test.cpp diff --git a/doc/leaf.adoc b/doc/leaf.adoc index 90b397d4..a5371210 100644 --- a/doc/leaf.adoc +++ b/doc/leaf.adoc @@ -75,9 +75,9 @@ What is a failure? It is simply the inability of a function to return a valid re A typical design is to return a variant type, e.g. `result`. Internally, such variant types must store a discriminant (in this case a boolean) to indicate whether the object holds a `T` or an `E`. -The design of LEAF is informed by the observation that the immediate caller must have access to the discriminant in order to determine the availability of a valid `T`, but otherwise it rarely needs to access the `E`. The error object is only needed once an error handling scope is reached. +The design of LEAF is informed by the observation that the immediate caller must have access to the discriminant in order to determine the availability of a valid `T`, but otherwise it is rare that it needs to access any error objects. They are only needed once an error handling scope is reached. -Therefore what would have been a `result` becomes `result`, which stores the discriminant and (optionally) a `T`, while the `E` is communicated directly to the error handling scope where it is needed. +Therefore what would have been a `result` becomes `result`, which stores the discriminant and (optionally) a `T`, while error objects are delivered directly to the error handling scope where it is needed. The benefit of this decomposition is that `result` becomes extremely lightweight, as it is not coupled with error types; further, error objects are communicated in constant time (independent of the call stack depth). Even very large objects are handled efficiently without dynamic memory allocation. @@ -209,11 +209,11 @@ leaf::result r = leaf::try_handle_some( [.text-right] <> | <> | <> -The first lambda passed to `try_handle_some` is executed first; it attempts to produce a `result`, but it may fail. +First, `try_handle_some` executes the first function passed to it; it attempts to produce a `result`, but it may fail. -The second lambda is an error handler: it will be called iff the first lambda fails and an error object of type `err1` was communicated to LEAF. That object is stored on the stack, local to the `try_handle_some` function (LEAF knows to allocate this storage because we gave it an error handler that takes an `err1`). Error handlers passed to `leaf::try_handle_some` can return a valid `leaf::result` but are allowed to fail. +The second lambda is an error handler: it will be called iff the first lambda fails, producing an error object of type `err1`. That object is stored on the stack, local to the `try_handle_some` function (LEAF knows to allocate this storage because we gave it an error handler that takes an `err1`). Error handlers passed to `leaf::try_handle_some` can return a valid `leaf::result` but are allowed to fail. -It is possible for an error handler to specify that it can only deal with some values of a given error type: +It is possible for an error handler to declare that it can only handle some specific values of a given error type: [source,c++] ---- @@ -246,9 +246,9 @@ LEAF considers the provided error handlers in order, and calls the first one for * Otherwise the second error handler will be called iff an error object of type `err1` is available, regardless of its value. -* Otherwise `leaf::try_handle_some` fails. +* Otherwise `leaf::try_handle_some` is unable to handle the error. -It is possible for an error handler to conditionally leave the current failure unhandled: +It is possible for an error handler to conditionally leave the failure unhandled: [source,c++] ---- @@ -390,7 +390,7 @@ leaf::result r = leaf::try_handle_some( []( io_error ec, e_file_name fn ) -> leaf::result { - // Handle I/O errors when a file name is available. + // Handle I/O errors when a file name is also available. }, []( io_error ec ) -> leaf::result @@ -422,7 +422,7 @@ leaf::result r = leaf::try_handle_some( []( io_error ec, e_file_name const * fn ) -> leaf::result { if( fn ) - .... // Handle I/O errors when a file name is available. + .... // Handle I/O errors when a file name is also available. else .... // Handle I/O errors when no file name is available. } ); @@ -469,7 +469,7 @@ leaf::result process_file( FILE * f ) [.text-right] <> | <> -Because `process_file` does not handle errors, it remains neutral to failures, except to attach the `current_line` if something goes wrong. The object returned by `on_error` holds a copy of the `current_line` wrapped in `struct e_line`. If `parse_line` succeeds, the `e_line` object is simply discarded; if it fails, the `e_line` object will be automatically "attached" to the failure. +Because `process_file` does not handle errors, it remains neutral to failures, except to attach the `current_line` if something goes wrong. The object returned by `on_error` holds a copy of `current_line` wrapped in `struct e_line`. If `parse_line` succeeds, the `e_line` object is simply discarded; if it fails, the `e_line` object will be automatically "attached" to the failure. Such failures can then be handled like so: @@ -646,7 +646,7 @@ If instead we want to use the legacy convention of throwing different types to i leaf::throw_exception(std::runtime_error("Error!"), err1::e1, err2::e2); ---- -In this case the returned object will be of type that derives from `std::runtime_error`, rather than from `std::exception`. +In this case the thrown exception object will be of type that derives from `std::runtime_error`, rather than from `std::exception`. Finally, `leaf::on_error` "just works" as well. Here is our `process_file` function rewritten to work with exceptions, rather than return a `leaf::result` (see <>): @@ -701,7 +701,7 @@ leaf::result f() [.text-right] <> | <> -Later we simply call `leaf::try_handle_some` passing an error handler for each type: +Later we simply call `leaf::try_handle_some`, passing an error handler for each type: [source,c++] ---- @@ -756,7 +756,7 @@ lib2::result bar(); int g( int a, int b ); -lib3::result f() +lib3::result f() // Note: return type is not leaf::result { auto a = foo(); if( !a ) @@ -806,7 +806,7 @@ Ideally, when an error is detected, a program using LEAF would always call <>. [[tutorial-loading]] === Loading of Error Objects -To load an error object is to move it into an active <> object, usually contained within a <>, a <> or a <> scope in the calling thread, where it becomes uniquely associated with a specific <> -- or discarded if storage is not available. +Recall that error objects communicated to LEAF are stored on the stack, local to the `try_handle_same`, `try_handle_all` or `try_catch` function used to handle errors. To _load_ an error object means to move it into such storage, if available. Various LEAF functions take a list of error objects to load. As an example, if a function `copy_file` that takes the name of the input file and the name of the output file as its arguments detects a failure, it could communicate an error code `ec`, plus the two relevant file names using <>: @@ -864,7 +864,7 @@ Besides error objects, `load` can take function arguments: * If we pass a function that takes no arguments, it is invoked, and the returned error object is loaded. + -Consider that if we pass to `load` an error object that is not needed by any error handler, it will be discarded. If the object is expensive to compute, it would be better if the computation can be skipped as well. Passing a function with no arguments to `load` is an excellent way to achieve this behavior: +Consider that if we pass to `load` an error object that is not used by an error handler, it will be discarded. If the object is expensive to compute, it would be better if the computation is only performed in case of an error. Passing a function with no arguments to `load` is an excellent way to achieve this behavior: + [source,c++] ---- @@ -893,7 +893,7 @@ leaf::result operation( char const * file_name ) noexcept <> | <> + <1> Success! Use `r.value()`. -<2> `try_something` has failed; `compute_info` will only be called if an error handler exists which takes a `info` argument. +<2> `try_something` has failed; `compute_info` will only be called if an error handler exists in the call stack which takes a `info` argument. + * If we pass a function that takes a single argument of type `E &`, LEAF calls the function with the object of type `E` currently loaded in an active `context`, associated with the error. If no such object is available, a new one is default-initialized and then passed to the function. + @@ -960,8 +960,8 @@ leaf::result parse_file( char const * file_name ) noexcept [.text-right] <> | <> | <> -<1> `parse_info` parses `f`, communicating errors using `leaf::result`. -<2> Using `on_error` ensures that the file name is included with any error reported out of `parse_file`. When the `load` object expires, if an error is being reported, the passed `e_file_name` value will be automatically associated with it. +<1> `parse_info` communicates errors using `leaf::result`. +<2> `on_error` ensures that the file name is included with any error reported out of `parse_file`. When the `load` object expires, if an error is being reported, the passed `e_file_name` value will be automatically associated with it. TIP: `on_error` -- like `new_error` -- can be passed any number of arguments. @@ -977,7 +977,7 @@ For example, if we want to use `on_error` to capture `errno`, we can't just pass ---- void read_file(FILE * f) { - auto load = leaf::on_error([]{ return e_errno{errno}; }); + auto load = leaf::on_error([]{ return leaf::e_errno{errno}; }); .... size_t nr1=fread(buf1,1,count1,f); @@ -997,7 +997,7 @@ void read_file(FILE * f) { Above, if an exception is thrown, LEAF will invoke the function passed to `on_error` and associate the returned `e_errno` object with the exception. -Finally, if `on_error` is passed a function that takes a single error object by mutable reference, the behavior is similar to how such functions are used by `load`; see <>. +Finally, if `on_error` is passed a function that takes a single error object by mutable reference, the behavior is similar to how such functions are handled by `load`; see <>. ''' @@ -1026,31 +1026,27 @@ return leaf::try_handle_some( [] { - return f(); // returns leaf::result + return f(); // Returns leaf::result }, - []( my_error e ) - { <1> + []( my_error e ) // handle my_error objects + { switch(e) { case my_error::e1: - ....; <2> + ....; // Handle e1 error values break; case my_error::e2: case my_error::e3: - ....; <3> + ....; // Handle e2 and e3 error values break; default: - ....; <4> + ....; // Handle bad my_error values break; } ); ---- -<1> This handler will be selected if we've got a `my_error` object. -<2> Handle `e1` errors. -<3> Handle `e2` and `e3` errors. -<4> Handle bad `my_error` values. -If `my_error` object is available, LEAF will call our error handler. If not, the failure will be forwarded to our caller. +If a `my_error` object is available, LEAF will call our error handler. If not, the failure will be forwarded to the caller. This can be rewritten using the <> predicate to organize the different cases in different error handlers. The following is equivalent: @@ -1064,25 +1060,22 @@ return leaf::try_handle_some( }, []( leaf::match m ) - { <1> + { assert(m.matched == my_error::e1); ....; }, []( leaf::match m ) - { <2> + { assert(m.matched == my_error::e2 || m.matched == my_error::e3); ....; }, []( my_error e ) - { <3> + { ....; } ); ---- -<1> We've got a `my_error` object that compares equal to `e1`. -<2> We`ve got a `my_error` object that compares equal to either `e2` or `e3`. -<3> Handle bad `my_error` values. The first argument to the `match` template generally specifies the type `E` of the error object `e` that must be available for the error handler to be considered at all. Typically, the rest of the arguments are values. The error handler is dropped if `e` does not compare equal to any of them. @@ -1095,7 +1088,7 @@ In particular, `match` works great with `std::error_code`. The following handler } ---- -This, however, requires {CPP}17 or newer, because it is impossible to infer the type of the error enum (in this case, `std::errc`) from the specified type `std::error_code`, and {CPP}11 does not allow `auto` template arguments. LEAF provides the following workaround, compatible with {CPP}11: +This, however, requires {CPP}17 or newer. LEAF provides the following workaround, compatible with {CPP}11: [source,c++] ---- @@ -1104,7 +1097,7 @@ This, however, requires {CPP}17 or newer, because it is impossible to infer the } ---- -In addition, it is possible to select a handler based on `std::error_category`. The following handler will match any `std::error_code` of the `std::generic_category` (requires {CPP}17 or newer): +It is also possible to select a handler based on `std::error_category`. The following handler will match any `std::error_code` of the `std::generic_category` (requires {CPP}17 or newer): [source,c++] ---- @@ -1123,7 +1116,7 @@ The following predicates are available: * `<>`: Similar to `match`, but checks whether the caught `std::exception` object can be `dynamic_cast` to any of the `Ex` types. * <> is a special predicate that takes any other predicate `Pred` and requires that an error object of type `E` is available and that `Pred` evaluates to `false`. For example, `if_not>` requires that an object `e` of type `E` is available, and that it does not compare equal to any of the specified `V...`. -Finally, the predicate system is easily extensible, see <>. +The predicate system is easily extensible, see <>. NOTE: See also <>. @@ -1162,7 +1155,7 @@ leaf::try_handle_all( [.text-right] <> | <> -Looks pretty simple, but what if we need to attempt a different set of operations yet use the same handlers? We could repeat the same thing with a different function passed as `TryBlock` for `try_handle_all`: +If we need to attempt a different set of operations yet use the same handlers, we could repeat the same thing with a different function passed as the `TryBlock` for `try_handle_all`: [source,c++] ---- @@ -1189,7 +1182,7 @@ leaf::try_handle_all( }); ---- -That works, but it may be better to bind the error handlers in a `std::tuple`: +That works, but it is also possible to bind the error handlers in a `std::tuple`: [source,c++] ---- @@ -1245,14 +1238,14 @@ Error handling functions accept a `std::tuple` of error handlers in place of any ''' [[tutorial-async]] -=== Transporting Error Objects Between Threads +=== Transporting Errors Between Threads -Like exceptions, error objects are local to a thread. When using concurrency, sometimes we need to collect error objects in one thread, then use them to handle the error in another thread. +Like exceptions, LEAF error objects are local to a thread. When using concurrency, sometimes we need to collect error objects in one thread, then use them to handle errors in another thread. -LEAF offers two interfaces for this purpose, one using `result`, and another using exception handling. +LEAF supports this functionality with or without exception handling. In both cases error objects are captured and transported in a `leaf::<>` object. [[tutorial-async_result]] -==== Using `result` +==== Transporting Errors Between Threads Without Exception Handling Let's assume we have a `task` that we want to launch asynchronously, which produces a `task_result` but could also fail: @@ -1261,37 +1254,7 @@ Let's assume we have a `task` that we want to launch asynchronously, which produ leaf::result task(); ---- -Because the task will run asynchronously, in case of a failure we need it to capture the relevant error objects but not handle errors. To this end, in the main thread we bind our error handlers in a `std::tuple`, which we will later use to handle errors from each completed asynchronous task (see <>): - -[source,c++] ----- -auto error_handlers = std::make_tuple( - - [](E1 e1, E2 e2) - { - //Deal with E1, E2 - .... - return { }; - }, - - [](E3 e3) - { - //Deal with E3 - .... - return { }; - } ); ----- - -Why did we start with this step? Because we need to create a <> object to collect the error objects we need. We could just instantiate the `context` template with `E1`, `E2` and `E3`, but that would be prone to errors, since it could get out of sync with the handlers we use. Thankfully LEAF can deduce the types we need automatically, we just need to show it our `error_handlers`: - -[source,c++] ----- -std::shared_ptr ctx = leaf::make_shared_context(error_handlers); ----- - -The `polymorphic_context` type is an abstract base class that has the same members as any instance of the `context` class template, allowing us to erase its exact type. In this case what we're holding in `ctx` is a `context`, where `E1`, `E2` and `E3` were deduced automatically from the `error_handlers` tuple we passed to `make_shared_context`. - -We're now ready to launch our asynchronous task: +Because the task will run asynchronously, in case of a failure we need to capture any produced error objects but not handle errors. We do this by invoking `try_handle_some`, passing an error handler that takes an argument of type <>: [source,c++] ---- @@ -1301,16 +1264,23 @@ std::future> launch_task() noexcept std::launch::async, [&] { - std::shared_ptr ctx = leaf::make_shared_context(error_handlers); - return leaf::capture(ctx, &task); + return leaf::try_handle_some( + [&]() -> leaf::result + { + return task(); + }, + []( leaf::dynamic_capture const & cap ) -> leaf::result + { + return cap; + }); } ); } ---- [.text-right] -<> | <> | <> +<> | <> -That's it! Later when we `get` the `std::future`, we can process the returned `result` in a call to <>, using the `error_handlers` tuple we created earlier: +The `dynamic_capture` object passed to the error handler can hold multiple error objects of different types, at the cost of dynamic memory allocations. Returning it from the error handler converts it to `leaf::result`, which now holds the captured error objects. The `result` object can then be stashed away or moved to another thread, and later passed to an error-handling function to unload its content and handle errors: [source,c++] ---- @@ -1326,30 +1296,6 @@ return leaf::try_handle_some( return { } }, - error_handlers ); ----- - -[.text-right] -<> | <> | <> - -NOTE: Follow this link to see a complete example program: https://github.com/boostorg/leaf/blob/master/example/capture_in_result.cpp?ts=4[capture_in_result.cpp]. - -[[tutorial-async_eh]] -==== Using Exception Handling - -Let's assume we have an asynchronous `task` which produces a `task_result` but could also throw: - -[source,c++] ----- -task_result task(); ----- - -Just like we saw in <>, first we will bind our error handlers in a `std::tuple`: - -[source,c++] ----- -auto handle_errors = std::make_tuple( - [](E1 e1, E2 e2) { //Deal with E1, E2 @@ -1365,7 +1311,22 @@ auto handle_errors = std::make_tuple( } ); ---- -Launching the task looks the same as before, except that we don't use `result`: +[.text-right] +<> | <> | <> + +NOTE: Follow this link to see a complete example program: https://github.com/boostorg/leaf/blob/master/example/dynamic_capture_result.cpp?ts=4[dynamic_capture_result.cpp]. + +[[tutorial-async_eh]] +==== Transporting Errors Between Threads With Exception Handling + +Let's assume we have an asynchronous `task` which produces a `task_result` but could also throw: + +[source,c++] +---- +task_result task(); +---- + +We use `try_catch` together with `dynamic_capture` to capture all error objects and the `std::current_exception()` in a `result`: [source,c++] ---- @@ -1375,37 +1336,55 @@ std::future launch_task() std::launch::async, [&] { - std::shared_ptr ctx = leaf::make_shared_context(&handle_error); - return leaf::capture(ctx, &task); + return leaf::try_catch( + [&]() -> leaf::result + { + return task(); + }, + []( leaf::dynamic_capture const & cap ) -> leaf::result + { + return cap; + }); } ); } ---- [.text-right] -<> | <> +<> -That's it! Later when we `get` the `std::future`, we can process the returned `task_result` in a call to <>, using the `error_handlers` we saved earlier, as if it was generated locally: +To handle errors after waiting on the future, we use `try_catch` as usual: [source,c++] ---- -//std::future fut; +//std::future> fut; fut.wait(); return leaf::try_catch( [&] { - task_result r = fut.get(); // Throws on error + leaf::result r = fut.get(); + task_result v = r.value(); // throws on error //Success! }, - error_handlers ); + [](E1 e1, E2 e2) + { + //Deal with E1, E2 + .... + }, + + [](E3 e3) + { + //Deal with E3 + .... + } ); ---- [.text-right] -<> +<> | <> -NOTE: Follow this link to see a complete example program: https://github.com/boostorg/leaf/blob/master/example/capture_in_exception.cpp?ts=4[capture_in_exception.cpp]. +NOTE: Follow this link to see a complete example program: https://github.com/boostorg/leaf/blob/master/example/dynamic_capture_eh.cpp?ts=4[dynamic_capture_eh.cpp]. ''' @@ -1444,7 +1423,7 @@ It will get called if the value of the `error_code` enum communicated with the f But what if later we add support for detecting and reporting a new type of input error, e.g. `permissions_error`? It is easy to add that to our `error_code` enum; but now our input error handler won't recognize this new input error -- and we have a bug. -If we can use exceptions, the situation is better because exception types can be organized in a hierarchy in order to classify failures: +Using exceptions is an improvement because exception types can be organized in a hierarchy in order to classify failures: [source,c++] ---- @@ -1667,7 +1646,7 @@ NOTE: The complete program illustrating this technique is available https://gith [[tutorial-on_error_in_c_callbacks]] === Using `error_monitor` to Report Arbitrary Errors from C-callbacks -Communicating information pertaining to a failure detected in a C callback is tricky, because C callbacks are limited to a specific static signature, which may not use {CPP} types. +Communicating information pertaining to a failure detected in a C callback is tricky, because C callbacks are limited to a specific function signature, which may not use {CPP} types. LEAF makes this easy. As an example, we'll write a program that uses Lua and reports a failure from a {CPP} function registered as a C callback, called from a Lua program. The failure will be propagated from {CPP}, through the Lua interpreter (written in C), back to the {CPP} function which called it. @@ -1858,7 +1837,7 @@ leaf::try_handle_all( ---- <1> We handle all failures that occur in this try block. <2> One or more error handlers that should handle all possible failures. -<3> The "catch all" error handler is required by `try_handle_all`. It will be called if LEAF is unable to use another error handler. +<3> This "catch all" error handler is required by `try_handle_all`. It will be called if LEAF is unable to use another error handler. The `verbose_diagnostic_info` output for the snippet above tells us that we got an `error_code` with value `1` (`write_error`), and an object of type `e_file_name` with `"file.txt"` stored in its `.value`: @@ -2276,7 +2255,8 @@ namespace boost { namespace leaf { template error_id load( Item && ... item ) const noexcept; - friend std::ostream & operator<<( std::ostream & os, error_id x ); + template + friend std::ostream & operator<<( std::basic_ostream &, error_id ); }; bool is_error_id( std::error_code const & ec ) noexcept; @@ -2288,29 +2268,6 @@ namespace boost { namespace leaf { ////////////////////////////////////////// - class polymorphic_context - { - protected: - - polymorphic_context() noexcept = default; - ~polymorphic_context() noexcept = default; - - public: - - virtual void activate() noexcept = 0; - virtual void deactivate() noexcept = 0; - virtual bool is_active() const noexcept = 0; - - virtual void propagate( error_id ) noexcept = 0; - - virtual void print( std::ostream & ) const = 0; - - template - friend std::ostream & operator<<( std::basic_ostream & os, polymorphic_context const & ctx ); - }; - - ////////////////////////////////////////// - template class context_activator { @@ -2359,7 +2316,7 @@ namespace boost { namespace leaf { ---- [.text-right] -Reference: <> | <> | <> | <> | <> | <> | <> | <> | <> | <> | <> | <> +Reference: <> | <> | <> | <> | <> | <> | <> | <> | <> | <> | <> ==== [[common.hpp]] @@ -2383,7 +2340,9 @@ namespace boost { namespace leaf { { int value; explicit e_errno(int value=errno); - friend std::ostream & operator<<(std::ostream &, e_errno const &); + + template + friend std::ostream & operator<<( std::basic_ostream &, e_errno const &); }; namespace windows @@ -2396,7 +2355,9 @@ namespace boost { namespace leaf { #if BOOST_LEAF_CFG_WIN32 e_LastError(); - friend std::ostream & operator<<(std::ostream &, e_LastError const &); + + template + friend std::ostream & operator<<( std::basic_ostream &, e_LastError const &); #endif }; } @@ -2431,9 +2392,6 @@ namespace boost { namespace leaf { template result( U && u, <> ); - result( error_id err ) noexcept; - result( std::shared_ptr && ctx ) noexcept; - template result( Enum e, typename std::enable_if::value, Enum>::type * = 0 ) noexcept; @@ -2466,9 +2424,11 @@ namespace boost { namespace leaf { template error_id load( Item && ... item ) noexcept; + + void unload(); template - friend std::ostream & operator<<( std::basic_ostream & os, result const & r ); + friend std::ostream & operator<<( std::basic_ostream &, result const & ); }; template <> @@ -2481,7 +2441,6 @@ namespace boost { namespace leaf { result() noexcept; result( error_id err ) noexcept; - result( std::shared_ptr && ctx ) noexcept; template result( Enum e, typename std::enable_if::value, Enum>::type * = 0 ) noexcept; @@ -2506,9 +2465,11 @@ namespace boost { namespace leaf { template error_id load( Item && ... item ) noexcept; + + void unload(); template - friend std::ostream & operator<<( std::basic_ostream & os, result const & r ); + friend std::ostream & operator<<( std::basic_ostream &, result const &); }; struct bad_result: std::exception { }; @@ -2594,25 +2555,6 @@ Reference: <> | <> <2> Only enabled if !std::is_base_of::value. ==== -==== `capture.hpp` - -==== -[source,c++] -.#include ----- -namespace boost { namespace leaf { - - template - decltype(std::declval()(std::forward(std::declval())...)) - capture(std::shared_ptr && ctx, F && f, A... a); - -} } ----- - -[.text-right] -Reference: <> | <> -==== - ''' [[tutorial-handling]] @@ -2644,12 +2586,12 @@ namespace boost { namespace leaf { void deactivate() noexcept; bool is_active() const noexcept; - void propagate( error_id ) noexcept; + void unload( error_id ) noexcept; void print( std::ostream & os ) const; template - friend std::ostream & operator<<( std::basic_ostream & os, context const & ctx ); + friend std::ostream & operator<<( std::basic_ostream &, context const & ); template R handle_error( R &, H && ... ) const; @@ -2666,17 +2608,11 @@ namespace boost { namespace leaf { template BOOST_LEAF_CONSTEXPR context_type_from_handlers make_context( H && ... ) noexcept; - template - context_ptr make_shared_context() noexcept; - - template - context_ptr make_shared_context( H && ... ) noexcept; - } } ---- [.text-right] -Reference: <> | <> | <> | <> +Reference: <> | <> | <> ==== [[handle_errors.hpp]] @@ -2702,6 +2638,22 @@ namespace boost { namespace leaf { ////////////////////////////////////////// +#if BOOST_LEAF_CFG_CAPTURE + class dynamic_capture + { + //No public constructors + + bool empty() const noexcept; + int size() const noexcept; + + template + operator result() const noexcept; + + template + friend std::ostream & operator<<( std::basic_ostream &, dynamic_capture const & ); + }; +#endif + class error_info { //No public constructors @@ -2713,28 +2665,31 @@ namespace boost { namespace leaf { bool exception_caught() const noexcept; std::exception const * exception() const noexcept; - friend std::ostream & operator<<( std::ostream & os, error_info const & x ); + template + friend std::ostream & operator<<( std::basic_ostream &, error_info const & ); }; class diagnostic_info: public error_info { //No public constructors - friend std::ostream & operator<<( std::ostream & os, diagnostic_info const & x ); + template + friend std::ostream & operator<<( std::basic_ostream &, diagnostic_info const & ); }; class verbose_diagnostic_info: public error_info { //No public constructors - friend std::ostream & operator<<( std::ostream & os, diagnostic_info const & x ); + template + friend std::ostream & operator<<( std::basic_ostream &, diagnostic_info const & ); }; } } ---- [.text-right] -Reference: <> | <> | <> | <> | <> | <> +Reference: <> | <> | <> | <> | <> | <> | <> ==== [[handle_errors.hpp]] @@ -2905,46 +2860,6 @@ leaf::context ctx; ''' -[[capture]] -=== `capture` - -.#include -[source,c++] ----- -namespace boost { namespace leaf { - - template - decltype(std::declval()(std::forward(std::declval())...)) - capture(std::shared_ptr && ctx, F && f, A... a); - -} } ----- - -[.text-right] -<> - -This function can be used to capture error objects stored in a <> in one thread and transport them to a different thread for handling, either in a `<>` object or in an exception. - -Returns: :: The same type returned by `F`. - -Effects: :: Uses an internal <> to <> `*ctx`, then invokes `std::forward(f)(std::forward(a)...)`. Then: -+ --- -* If the returned value `r` is not a `result` type (see <>), it is forwarded to the caller. -* Otherwise: -** If `!r`, the return value of `capture` is initialized with `ctx`; -+ -NOTE: An object of type `leaf::<>` can be initialized with a `std::shared_ptr`. -+ -** otherwise, it is initialized with `r`. --- -+ -In case `f` throws, `capture` catches the exception in a `std::exception_ptr`, and throws a different exception of unspecified type that transports both the `std::exception_ptr` as well as `ctx`. This exception type is recognized by <>, which automatically unpacks the original exception and propagates the contents of `*ctx` (presumably, in a different thread). - -TIP: See also <> from the Tutorial. - -''' - [[context_type_from_handlers]] === `context_type_from_handlers` @@ -3121,36 +3036,6 @@ auto ctx = leaf::make_context( <1> ''' -[[make_shared_context]] -=== `make_shared_context` - -.#include -[source,c++] ----- -namespace boost { namespace leaf { - - template - context_ptr make_shared_context() noexcept - { - return std::make_shared>>(); - } - - template - context_ptr make_shared_context( H && ... ) noexcept - { - return std::make_shared>>(); - } - -} } ----- - -[.text-right] -<> - -TIP: See also <> from the tutorial. - -''' - [[new_error]] === `new_error` @@ -3427,6 +3312,7 @@ Requires: :: ** must return a type that can be used to initialize an object of the type `R`; in case R is a `result` (that is, in case of success it does not communicate a value), handlers that return `void` are permitted. If such a handler is selected, the `try_handle_some` return value is initialized by `{}`; ** may take any error objects, by value, by (`const`) reference, or as pointer (to `const`); ** may take arguments, by value, of any predicate type: <>, <>, <>, <>, <>, or of any user-defined predicate type `Pred` for which `<>::value` is `true`; +** may take a <> argument by `const &`; ** may take an <> argument by `const &`; ** may take a <> argument by `const &`; ** may take a <> argument by `const &`. @@ -3520,6 +3406,31 @@ try_handle_some( + NOTE: See also: <>. + +* If `a~i~` is of type `dynamic_capture const &`, `try_handle_some` is always able to produce it. It captures error objects which would otherwise have been discarded. ++ +.Example: +[source,c++] +---- +.... +try_handle_some( + + [] + { + return f(); // returns leaf::result + }, + + [](leaf::dynamic_capture const & cap) -> leaf::result <1> + { + return cap; <2> + } ); +---- ++ +<1> This handler matches any error. +<2> In this typical use, the contents of `cap` are captured in the returned `leaf::result`. ++ +[.text-right] +<> | <> ++ * If `a~i~` is of type `error_info const &`, `try_handle_some` is always able to produce it. + .Example: @@ -3633,7 +3544,7 @@ namespace boost { namespace leaf { void deactivate() noexcept; bool is_active() const noexcept; - void propagate( error_id ) noexcept; + void unload( error_id ) noexcept; void print( std::ostream & os ) const; @@ -3648,7 +3559,7 @@ namespace boost { namespace leaf { } } ---- [.text-right] -<> | <> | <> | <> | <> | <> | <> | <> +<> | <> | <> | <> | <> | <> | <> | <> The `context` class template provides storage for each of the specified `E...` types. Typically, `context` objects are not used directly; they're created internally when the <>, <> or <> functions are invoked, instantiated with types that are automatically deduced from the types of the arguments of the passed handlers. @@ -3658,7 +3569,7 @@ Even in that case it is recommended that users do not instantiate the `context` To be able to load up error objects in a `context` object, it must be activated. Activating a `context` object `ctx` binds it to the calling thread, setting thread-local pointers of the stored `E...` types to point to the corresponding storage within `ctx`. It is possible, even likely, to have more than one active `context` in any given thread. In this case, activation/deactivation must happen in a LIFO manner. For this reason, it is best to use a <>, which relies on RAII to activate and deactivate a `context`. -When a `context` is deactivated, it detaches from the calling thread, restoring the thread-local pointers to their pre-`activate` values. Typically, at this point the stored error objects, if any, are either discarded (by default) or moved to corresponding storage in other `context` objects active in the calling thread (if available), by calling <>. +When a `context` is deactivated, it detaches from the calling thread, restoring the thread-local pointers to their pre-`activate` values. Typically, at this point the stored error objects, if any, are either discarded (by default) or moved to corresponding storage in other `context` objects active in the calling thread (if available), by calling <>. While error handling typically uses <>, <> or <>, it is also possible to handle errors by calling the member function <>. It takes an <>, and attempts to select an error handler based on the error objects stored in `*this`, associated with the passed `error_id`. @@ -3796,7 +3707,7 @@ namespace boost { namespace leaf { void context::print( std::ostream & os ) const; template - friend std::ostream & context::operator<<( std::basic_ostream & os, context const & ctx ) + friend std::ostream & context::operator<<( std::basic_ostream &, context const & ) { ctx.print(os); return os; @@ -3809,8 +3720,8 @@ Effects: :: Prints all error objects currently stored in `*this`, together with ''' -[[context::propagate]] -==== `propagate` +[[context::unload]] +==== `unload` .#include [source,c++] @@ -3818,7 +3729,7 @@ Effects: :: Prints all error objects currently stored in `*this`, together with namespace boost { namespace leaf { template - void context::propagate( error_id id ) noexcept; + void context::unload( error_id id ) noexcept; } } ---- @@ -3880,7 +3791,8 @@ namespace boost { namespace leaf { { //Constructors unspecified - friend std::ostream & operator<<( std::ostream & os, diagnostic_info const & x ); + template + friend std::ostream & operator<<( std::basic_ostream &, diagnostic_info const & ); }; } } @@ -3902,68 +3814,200 @@ The behavior of `diagnostic_info` (and <>) is affected ''' -[[error_id]] -=== `error_id` +[[dynamic_capture]] +=== `dynamic_capture` -.#include +.#include [source,c++] ---- +#if BOOST_LEAF_CFG_CAPTURE + namespace boost { namespace leaf { - class error_id + class dynamic_capture { - public: - - error_id() noexcept; - - template - result( Enum e, typename std::enable_if::value, Enum>::type * = 0 ) noexcept; + //Constructors unspecified - error_id( std::error_code const & ec ) noexcept; + public: - int value() const noexcept; - explicit operator bool() const noexcept; + bool empty() const noexcept; + + int size() const noexcept; - std::error_code to_error_code() const noexcept; + template + operator result() const noexcept; - friend bool operator==( error_id a, error_id b ) noexcept; - friend bool operator!=( error_id a, error_id b ) noexcept; - friend bool operator<( error_id a, error_id b ) noexcept; + template + friend std::ostream & operator<<( std::basic_ostream &, dynamic_capture const & ); + }; - template - error_id load( Item && ... item ) const noexcept; +} } - friend std::ostream & operator<<( std::ostream & os, error_id x ); - }; +#endif +---- - bool is_error_id( std::error_code const & ec ) noexcept; +By default, error objects reported via LEAF which are not taken as arguments by any active handler are discarted. If an active handler exists which takes an argument of type `dynamic_capture const &`, that object collects the error objects that would otherwise have been discarded, storing them on the heap. - template - error_id new_error( E && ... e ) noexcept; +The message printed by `operator<<` includes diagnostic information about the captured error objects, except if `BOOST_LEAF_CFG_DIAGNOSTICS=0` is defined, in which case it does not. - error_id current_error() noexcept; +When an object of type `dynamic_capture const &` is returned from a handler that produces a `leaf::<>`, its contents are captured (together with the `std::current_exception`) by the returned `result` object, which can later be used with <> to handle the captured error objects. See <>. -} } ----- +Under `BOOST_LEAF_CFG_CAPTURE=0`, `dynamic_capture` is unavailable. -[.text-right] -<> | <> | <> | <> | <> | <> | <> | <> | <> +[WARNING] +-- +A `dynamic_capture` does not capture all error objects, only the ones that would have been discarded if not for the presence of a `dynamic_capture` handler. In the example below, the returned `result` will capture the error object of type `E2` but not `e1`: +``` +auto r = try_handle_some( + []() -> leaf::result + { + return leaf::new_error(E1{}, E2{}); + }, + []( E1 e1, leaf::dynamic_capture const & cap ) -> leaf::result + { + return cap; + }); +``` +Perhaps more surprising, this is true for the next example as well: +``` +auto r = try_handle_some( + []() -> leaf::result + { + return try_handle_some( + []() -> leaf::result + { + return leaf::new_error(E1{}, E2{}); + }, + []( leaf::dynamic_capture const & cap ) -> leaf::result + { + return cap; + }); + }, + []( E1 e1 ) + { + }); +``` +-- -Values of type `error_id` identify a specific occurrence of a failure across the entire program. They can be copied, moved, assigned to, and compared to other `error_id` objects. They're as efficient as an `int`. +See also: :: <>. ''' -[[error_id::error_id]] -==== Constructors +[[dynamic_capture::empty]] +==== `empty` -.#include +.#include [source,c++] ---- namespace boost { namespace leaf { - error_id::error_id() noexcept = default; + bool dynamic_capture::empty() const noexcept; - template +} } +---- + +Returns: :: `true` if the `dynamic_capture` objects is empty, `false` otherwise. + +''' + +[[dynamic_capture::size]] +==== `size` + +.#include +[source,c++] +---- +namespace boost { namespace leaf { + + int dynamic_capture::size() const noexcept; + +} } +---- + +Returns: :: The number of error objects captured by `*this`. + +''' + +[[dynamic_capture::operator_result]] +==== `operator result` + +.#include +[source,c++] +---- +namespace boost { namespace leaf { + + template + operator result() const noexcept; + +} } +---- + +Effects: :: Implicit conversion to `leaf::<>`. The contents of `*this`, together with the `std::current_exception()` (if available) are moved and stored in the returned `result` object, which can be stashed away to be used at a later time with <> / <> / <> to handle the captured errors. + +''' + +[[error_id]] +=== `error_id` + +.#include +[source,c++] +---- +namespace boost { namespace leaf { + + class error_id + { + public: + + error_id() noexcept; + + template + result( Enum e, typename std::enable_if::value, Enum>::type * = 0 ) noexcept; + + error_id( std::error_code const & ec ) noexcept; + + int value() const noexcept; + explicit operator bool() const noexcept; + + std::error_code to_error_code() const noexcept; + + friend bool operator==( error_id a, error_id b ) noexcept; + friend bool operator!=( error_id a, error_id b ) noexcept; + friend bool operator<( error_id a, error_id b ) noexcept; + + template + error_id load( Item && ... item ) const noexcept; + + template + friend std::ostream & operator<<( std::basic_ostream &, error_id ); + }; + + bool is_error_id( std::error_code const & ec ) noexcept; + + template + error_id new_error( E && ... e ) noexcept; + + error_id current_error() noexcept; + +} } +---- + +[.text-right] +<> | <> | <> | <> | <> | <> | <> | <> | <> + +Values of type `error_id` identify a specific occurrence of a failure across the entire program. They can be copied, moved, assigned to, and compared to other `error_id` objects. They're as efficient as an `int`. + +''' + +[[error_id::error_id]] +==== Constructors + +.#include +[source,c++] +---- +namespace boost { namespace leaf { + + error_id::error_id() noexcept = default; + + template error_id::error_id( Enum e, typename std::enable_if::value, Enum>::type * = 0 ) noexcept; error_id::error_id( std::error_code const & ec ) noexcept; @@ -4220,7 +4264,9 @@ namespace boost { namespace leaf { { int value; explicit e_errno(int value=errno); - friend std::ostream & operator<<( std::ostream & os, e_errno const & err ); + + template + friend std::ostream & operator<<( std::basic_ostream &, e_errno const & ); }; } } @@ -4267,7 +4313,9 @@ namespace boost { namespace leaf { #if BOOST_LEAF_CFG_WIN32 e_LastError(); - friend std::ostream & operator<<(std::ostream &, e_LastError const &); + + template + friend std::ostream & operator<<( std::basic_ostream &, e_LastError const & ); #endif }; } @@ -4293,7 +4341,8 @@ namespace boost { namespace leaf { int line; char const * function; - friend std::ostream & operator<<( std::ostream & os, e_source_location const & x ); + template + friend std::ostream & operator<<( std::basic_ostream &, e_source_location const & ); }; } } @@ -4339,7 +4388,8 @@ namespace boost { namespace leaf { bool exception_caught() const noexcept; std::exception const * exception() const noexcept; - friend std::ostream & operator<<( std::ostream & os, error_info const & x ); + template + friend std::ostream & operator<<( std::basic_ostream &, error_info const & ); }; } } @@ -4359,46 +4409,6 @@ The `operator<<` overload prints diagnostic information about each error object ''' -[[polymorphic_context]] -=== `polymorphic_context` - -.#include -[source,c++] ----- -namespace boost { namespace leaf { - - class polymorphic_context - { - protected: - - polymorphic_context() noexcept; - ~polymorphic_context() noexcept; - - public: - - virtual void activate() noexcept = 0; - virtual void deactivate() noexcept = 0; - virtual bool is_active() const noexcept = 0; - - virtual void propagate( error_id ) noexcept = 0; - - virtual void print( std::ostream & ) const = 0; - - template - friend std::ostream & operator<<( std::basic_ostream & os, polymorphic_context const & ctx ) - { - ctx.print(os); - return os; - } - }; - -} } ----- - -The `polymorphic_context` class is an abstract base type which can be used to erase the type of the exact instantiation of the <> class template used. See <>. - -''' - [[result]] === `result` @@ -4422,7 +4432,6 @@ namespace boost { namespace leaf { result( U &&, <> ); result( error_id err ) noexcept; - result( std::shared_ptr && ctx ) noexcept; template result( Enum e, typename std::enable_if::value, Enum>::type * = 0 ) noexcept; @@ -4468,7 +4477,6 @@ namespace boost { namespace leaf { result() noexcept; result( error_id err ) noexcept; - result( std::shared_ptr && ctx ) noexcept; template result( Enum e, typename std::enable_if::value, Enum>::type * = 0 ) noexcept; @@ -4509,9 +4517,9 @@ The `result` type can be returned by functions which produce a value of type Requires: :: `T` must be movable, and its move constructor may not throw. Invariant: :: A `result` object is in one of three states: -* Value state, in which case it contains an object of type `T`, and <>/<>/<> can be used to access the contained value. +* Value state, in which case it contains an object of type `T`, and <> / <> / <> can be used to access the contained value. * Error state, in which case it contains an error ID, and calling <> throws `leaf::bad_result`. -* Error capture state, which is the same as the Error state, but in addition to the error ID, it holds a `std::shared_ptr<<>>`. +* Dynamic capture state, which is the same as the Error state, but in addition to the error ID, it holds a list of dynamically captured error objects; see <>. `result` objects are nothrow-moveable but are not copyable. @@ -4548,9 +4556,6 @@ namespace boost { namespace leaf { template result::result( std::error_code const & ec ) noexcept; - template - result::result( std::shared_ptr && ctx ) noexcept; - template result::result( result && ) noexcept; @@ -4579,7 +4584,7 @@ CAUTION: Initializing a `result` with a default-initialized `error_id` object + ** a `std::error_code` object. ** an object of type `Enum` for which `std::is_error_code_enum::value` is `true`. -* To get a `result` in <>, initialize it with a `std::shared_ptr<<>>` (which can be obtained by calling e.g. <>). +* To get a `result` in <>, write an error handler that takes a <> object and returns a `result` object, and return the capture object from the error handler. -- + When a `result` object is initialized with a `std::error_code` object, it is used to initialize an `error_id` object, then the behavior is the same as if initialized with `error_id`. @@ -4743,6 +4748,14 @@ namespace boost { namespace leaf { } } ---- +Effects: + +* If `*this` is in <>, returns a reference to the stored value. +* If `*this` is in <>, the captured error objects are unloaded, and: +** If `*this` contains a captured exception object `ex`, the behavior is equivalent to `<>(ex)`. +** Otherwise, the behavior is equivalent to `<>(bad_result{})`. +* If `*this` is in any other state, the behavior is equivalent to `<>(bad_result{})`. + ''' [[result::value_type]] @@ -4813,7 +4826,8 @@ namespace boost { namespace leaf { { //Constructors unspecified - friend std::ostream & operator<<( std::ostream & os, verbose_diagnostic_info const & x ); + template + friend std::ostream & operator<<( std::basic_ostream &, verbose_diagnostic_info const & ); }; } } @@ -5385,7 +5399,7 @@ The error handling functionality provided by <> and <` type R, you must specialize the `is_result_type` template so that `is_result_type::value` evaluates to `true`. -Naturally, the provided `leaf::<>` class template satisfies these requirements. In addition, it allows error objects to be transported across thread boundaries, using a `std::shared_ptr<<>>`. +Naturally, the provided `leaf::<>` class template satisfies these requirements. In addition, it allows error objects to be transported across thread boundaries, using a <>. [[macros]] == Reference: Macros @@ -5552,10 +5566,129 @@ Effects: :: `BOOST_LEAF_THROW_EXCEPTION(e...)` is equivalent to `leaf::<>(e...)`, except the current source location is automatically passed, in a `<>` object (in addition to all `e...` objects). -[[rationale]] -== Design +[[configuration]] +== Configuration + +The following configuration macros are recognized: + +* `BOOST_LEAF_CFG_DIAGNOSTICS`: Defining this macro as `0` stubs out both <> and <> (if the macro is left undefined, LEAF defines it as `1`). + +* `BOOST_LEAF_CFG_STD_SYSTEM_ERROR`: Defining this macro as `0` disables the `std::error_code` / `std::error_condition` integration. In this case LEAF does not `#include `, which may be too heavy for embedded platforms (if the macro is left undefined, LEAF defines it as `1`). + +* `BOOST_LEAF_CFG_STD_STRING`: Defining this macro as `0` disables all use of `std::string` (this requires `BOOST_LEAF_CFG_DIAGNOSTICS=0` as well). In this case LEAF does not `#include ` which may be too heavy for embedded platforms (if the macro is left undefined, LEAF defines it as `1`). + +* `BOOST_LEAF_CFG_CAPTURE`: Defining this macro as `0` disables the <> functionality, which (only if used) allocates memory dynamically (if the macro is left undefined, LEAF defines it as `1`). + +* `BOOST_LEAF_CFG_GNUC_STMTEXPR`: This macro controls whether or not <> is defined in terms of a https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html[GNU C statement expression], which enables its use to check for errors similarly to how the questionmark operator works in some languages (see <>). By default the macro is defined as `1` under `pass:[__GNUC__]`, otherwise as `0`. + +* `BOOST_LEAF_CFG_WIN32`: Defining this macro as 1 enables the default constructor in <>, and the automatic conversion to string (via `FormatMessageA`) when <> is printed. If the macro is left undefined, LEAF defines it as `0` (even on windows, since including `windows.h` is generally not desirable). Note that the `e_LastError` type itself is available on all platforms, there is no need for conditional compilation in error handlers that use it. + +* `BOOST_LEAF_NO_EXCEPTIONS`: Disables all exception handling support. If left undefined, LEAF defines it automatically based on the compiler configuration (e.g. `-fno-exceptions`). + +* `BOOST_LEAF_NO_THREADS`: Disables all thread safety in LEAF. + +[[configuring_tls_access]] +=== Configuring TLS Access + +LEAF requires support for thread-local `void` pointers. By default, this is implemented by means of the {CPP}11 `thread_local` keyword, but in order to support <>, it is possible to configure LEAF to use an array of thread local pointers instead, by defining `BOOST_LEAF_USE_TLS_ARRAY`. In this case, the user is required to define the following two functions to implement the required TLS access: + +[source,c++] +---- +namespace boost { namespace leaf { + +namespace tls +{ + void * read_void_ptr( int tls_index ) noexcept; + void write_void_ptr( int tls_index, void * p ) noexcept; +} + +} } +---- + +TIP: For efficiency, `read_void_ptr` and `write_void_ptr` should be defined `inline`. + +Under `BOOST_LEAF_USE_TLS_ARRAY` the following additional configuration macros are recognized: + +* `BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX` specifies the start TLS array index available to LEAF (if the macro is left undefined, LEAF defines it as `0`). + +* `BOOST_LEAF_CFG_TLS_ARRAY_SIZE` may be defined to specify the size of the TLS array. In this case TLS indices are validated via `BOOST_LEAF_ASSERT` before being passed to `read_void_ptr` / `write_void_ptr`. + +* `BOOST_LEAF_CFG_TLS_INDEX_TYPE` may be defined to specify the integral type used to store assigned TLS indices (if the macro is left undefined, LEAF defines it as `unsigned char`). + +TIP: Reporting error objects of types that are not used by the program to handle failures does not consume TLS pointers. The minimum size of the TLS pointer array required by LEAF is the total number of different types used as arguments to error handlers (in the entire program), plus one. + +WARNING: Beware of `read_void_ptr`/`write_void_ptr` accessing thread local pointers beyond the static boundaries of the thread local pointer array; this will likely result in undefined behavior. + +[[embedded_platforms]] +=== Embedded Platforms + +Defining `BOOST_LEAF_EMBEDDED` is equivalent to the following: + +[source,c++] +---- +#ifndef BOOST_LEAF_CFG_DIAGNOSTICS +# define BOOST_LEAF_CFG_DIAGNOSTICS 0 +#endif + +#ifndef BOOST_LEAF_CFG_STD_SYSTEM_ERROR +# define BOOST_LEAF_CFG_STD_SYSTEM_ERROR 0 +#endif + +#ifndef BOOST_LEAF_CFG_STD_STRING +# define BOOST_LEAF_CFG_STD_STRING 0 +#endif + +#ifndef BOOST_LEAF_CFG_CAPTURE +# define BOOST_LEAF_CFG_CAPTURE 0 +#endif +---- + +LEAF supports FreeRTOS out of the box, please define `BOOST_LEAF_TLS_FREERTOS` (in which case LEAF automatically defines `BOOST_LEAF_EMBEDDED`, if it is not defined already). + +For other embedded platforms, please define `BOOST_LEAF_USE_TLS_ARRAY`, see <>. + +If your program does not use concurrency at all, simply define `BOOST_LEAF_NO_THREADS`, which requires no TLS support at all (but is NOT thread-safe). + +[[portability]] +== Portability + +The source code is compatible with {CPP}11 or newer. + +LEAF uses thread-local storage (only for pointers). By default, this is implemented via the {CPP}11 `thread_local` storage class specifier, but the library is easily configurable to use any platform-specific TLS API instead (it ships with built-in support for FreeRTOS). See <>. + +== Running the Unit Tests + +The unit tests can be run with https://mesonbuild.com[Meson Build] or with Boost Build. To run the unit tests: + +=== Meson Build + +Clone LEAF into any local directory and execute: + +[source,sh] +---- +cd leaf +meson bld/debug +cd bld/debug +meson test +---- + +See `meson_options.txt` found in the root directory for available build options. + +=== Boost Build + +Assuming the current working directory is `/libs/leaf`: + +[source,sh] +---- +../../b2 test +---- + +== Benchmark + +https://github.com/boostorg/leaf/blob/master/benchmark/benchmark.md[This benchmark] compares the performance of LEAF, Boost Outcome and `tl::expected`. -=== Rationale +[[rationale]] +== Design Rationale Definition: :: Objects that carry information about error conditions are called error objects. For example, objects of type `std::error_code` are error objects. @@ -5699,185 +5832,21 @@ return leaf::try_handle_some( [.text-right] <> | <> | <> | <> | <> -NOTE: Please post questions and feedback on the Boost Developers Mailing List. - -''' - -[[exception_specifications]] -=== Critique 1: Error Types Do Not Participate in Function Signatures - -A knee-jerk critique of the LEAF design is that it does not statically enforce that each possible error condition is recognized and handled by the program. One idea I've heard from multiple sources is to add `E...` parameter pack to `result`, essentially turning it into `expected`, so we could write something along these lines: - -[source,c++] ----- -expected f() noexcept; <1> - -expected g() noexcept <2> -{ - if( expected r = f() ) - { - return r; //Success, return the T - } - else - { - return r.handle_error( [] ( .... ) <3> - { - .... - } ); - } -} ----- -<1> `f` may only return error objects of type `E1`, `E2`, `E3`. -<2> `g` narrows that to only `E1` and `E3`. -<3> Because `g` may only return error objects of type `E1` and `E3`, it uses `handle_error` to deal with `E2`. In case `r` contains `E1` or `E3`, `handle_error` simply returns `r`, narrowing the error type parameter pack from `E1, E2, E3` down to `E1, E3`. If `r` contains an `E2`, `handle_error` calls the supplied lambda, which is required to return one of `E1`, `E3` (or a valid `T`). - -The motivation here is to help avoid bugs in functions that handle errors that pop out of `g`: as long as the programmer deals with `E1` and `E3`, he can rest assured that no error is left unhandled. - -Congratulations, we've just discovered exception specifications. The difference is that exception specifications, before being removed from {CPP}, were enforced dynamically, while this idea is equivalent to statically-enforced exception specifications, like they are in Java. - -Why not use the equivalent of exception specifications, even if they are enforced statically? - -"The short answer is that nobody knows how to fix exception specifications in any language, because the dynamic enforcement {CPP} chose has only different (not greater or fewer) problems than the static enforcement Java chose. ... When you go down the Java path, people love exception specifications until they find themselves all too often encouraged, or even forced, to add `throws Exception`, which immediately renders the exception specification entirely meaningless. (Example: Imagine writing a Java generic that manipulates an arbitrary type `T`).footnote:[https://herbsutter.com/2007/01/24/questions-about-exception-specifications/]" --- Herb Sutter - -Consider again the example above: assuming we don't want important error-related information to be lost, values of type `E1` and/or `E3` must be able to encode any `E2` value dynamically. But like Sutter points out, in generic contexts we don't know what errors may result in calling a user-supplied function. The only way around that is to specify a single type (e.g. `std::error_code`) that can communicate any and all errors, which ultimately defeats the idea of using static type checking to enforce correct error handling. - -That said, in every program there are certain _error handling_ functions (e.g. `main`) which are required to handle any error, and it is highly desirable to be able to enforce this requirement at compile-time. In LEAF, the `try_handle_all` function implements this idea: if the user fails to supply at least one handler that will match any error, the result is a compile error. This guarantees that the scope invoking `try_handle_all` is prepared to recover from any failure. - -''' - -[[translation]] -=== Critique 2: LEAF Does Not Facilitate Mapping Between Different Error Types - -Most {CPP} programs use multiple C and {CPP} libraries, and each library may provide its own system of error codes. But because it is difficult to define static interfaces that can communicate arbitrary error code types, a popular idea is to map each library-specific error code to a common program-wide enum. - -For example, if we have -- - -[source,c++,options="nowrap"] ----- -namespace lib_a -{ - enum error - { - ok, - ec1, - ec2, - .... - }; -} ----- - -[source,c++,options="nowrap"] ----- -namespace lib_b -{ - enum error - { - ok, - ec1, - ec2, - .... - }; -} ----- - --- we could define: - -[source,c++] ----- -namespace program -{ - enum error - { - ok, - lib_a_ec1, - lib_a_ec2, - .... - lib_b_ec1, - lib_b_ec2, - .... - }; -} ----- - -An error handling library could provide conversion API that uses the {CPP} static type system to automate the mapping between the different error enums. For example, it may define a class template `result` with value-or-error variant semantics, so that: - -* `lib_a` errors are transported in `result`, -* `lib_b` errors are transported in `result`, -* then both are automatically mapped to `result` once control reaches the appropriate scope. - -There are several problems with this idea: - -* It is prone to errors, both during the initial implementation as well as under maintenance. - -* It does not compose well. For example, if both of `lib_a` and `lib_b` use `lib_c`, errors that originate in `lib_c` would be obfuscated by the different APIs exposed by each of `lib_a` and `lib_b`. - -* It presumes that all errors in the program can be specified by exactly one error code, which is false. +== Limitations -To elaborate on the last point, consider a program that attempts to read a configuration file from three different locations: in case all of the attempts fail, it should communicate each of the failures. In theory `result` handles this case well: +When using dynamic linking, it is required that error types are declared with `default` visibility, e.g.: [source,c++] ---- -struct attempted_location -{ - std::string path; - error ec; -}; - -struct config_error +struct __attribute__ ((visibility ("default"))) my_error_info { - attempted_location current_dir, user_dir, app_dir; + int value; }; - -result read_config(); ----- - -This looks nice, until we realize what the `config_error` type means for the automatic mapping API we wanted to define: an `enum` can not represent a `struct`. It is a fact that we can not assume that all error conditions can be fully specified by an `enum`; an error handling library must be able to transport arbitrary static types efficiently. - -[[errors_are_not_implementation_details]] -=== Critique 3: LEAF Does Not Treat Low Level Error Types as Implementation Details - -This critique is a combination of <> and <>, but it deserves special attention. Let's consider this example using LEAF: - -[source,c++] ----- -leaf::result read_line( reader & r ); - -leaf::result parse_line( std::string const & line ); - -leaf::result read_and_parse_line( reader & r ) -{ - BOOST_LEAF_AUTO(line, read_line(r)); <1> - BOOST_LEAF_AUTO(parsed, parse_line(line)); <2> - return parsed; -} ---- -[.text-right] -<> | <> - -<1> Read a line, forward errors to the caller. -<2> Parse the line, forward errors to the caller. - -The objection is that LEAF will forward verbatim the errors that are detected in `read_line` or `parse_line` to the caller of `read_and_parse_line`. The premise of this objection is that such low-level errors are implementation details and should be treated as such. Under this premise, `read_and_parse_line` should act as a translator of sorts, in both directions: - -* When called, it should translate its own arguments to call `read_line` and `parse_line`; -* If an error is detected, it should translate the errors from the error types returned by `read_line` and `parse_line` to a higher-level type. - -The motivation is to isolate the caller of `read_and_parse_line` from its implementation details `read_line` and `parse_line`. - -There are two possible ways to implement this translation: -*1)* `read_and_parse_line` understands the semantics of *all possible failures* that may be reported by both `read_line` and `parse_line`, implementing a non-trivial mapping which both _erases_ information that is considered not relevant to its caller, as well as encodes _different_ semantics in the error it reports. In this case `read_and_parse_line` assumes full responsibility for describing precisely what went wrong, using its own type specifically designed for the job. - -*2)* `read_and_parse_line` returns an error object that essentially indicates which of the two inner functions failed, and also transports the original error object without understanding its semantics and without any loss of information, wrapping it in a new error type. - -The problem with *1)* is that typically the caller of `read_and_parse_line` is not going to handle the error, but it does need to forward it to its caller. In our attempt to protect the *one* error handling function from "implementation details", we've coupled the interface of *all* intermediate error neutral functions with the static types of errors they do not understand and do not handle. - -Consider the case where `read_line` communicates `errno` in its errors. What is `read_and_parse_line` supposed to do with e.g. `EACCESS`? Turn it into `READ_AND_PARSE_LINE_EACCESS`? To what end, other than to obfuscate the original (already complex and platform-specific) semantics of `errno`? - -And what if the call to `read` is polymorphic, which is also typical? What if it involves a user-supplied function object? What kinds of errors does it return and why should `read_and_parse_line` care? +This works as expected except on Windows, where thread-local storage is not shared between the individual binary modules. For this reason, to transport error objects across DLL boundaries, it is required that they're captured in a <>, just like when <>. -Therefore, we're left with *2)*. There's almost nothing wrong with this option, since it passes any and all error-related information from lower level functions without any loss. However, using a wrapper type to grant (presumably dynamic) access to any lower-level error type it may be transporting is cumbersome and (like Niall Douglas <>) in general probably requires dynamic allocations. It is better to use independent error types that communicate the additional information not available in the original error object, while error handlers rely on LEAF to provide efficient access to any and all low-level error types, as needed. +TIP: When using dynamic linking, it is always best to define module interfaces in terms of C (and implement them in {CPP} if appropriate). == Alternatives to LEAF @@ -6103,143 +6072,6 @@ Further, consider that Outcome aims to hopefully become _the_ one error handling In contrast, the design of LEAF acknowledges that {CPP} programmers don't even agree on what a string is. If your project uses 10 different libraries, this probably means 15 different ways to report errors, sometimes across uncooperative interfaces (e.g. C APIs). LEAF helps you get the job done. -== Benchmark - -https://github.com/boostorg/leaf/blob/master/benchmark/benchmark.md[This benchmark] compares the performance of LEAF, Boost Outcome and `tl::expected`. - -== Running the Unit Tests - -The unit tests can be run with https://mesonbuild.com[Meson Build] or with Boost Build. To run the unit tests: - -=== Meson Build - -Clone LEAF into any local directory and execute: - -[source,sh] ----- -cd leaf -meson bld/debug -cd bld/debug -meson test ----- - -See `meson_options.txt` found in the root directory for available build options. - -=== Boost Build - -Assuming the current working directory is `/libs/leaf`: - -[source,sh] ----- -../../b2 test ----- - -[[configuration]] -== Configuration - -The following configuration macros are recognized: - -* `BOOST_LEAF_CFG_DIAGNOSTICS`: Defining this macro as `0` stubs out both <> and <> (if the macro is left undefined, LEAF defines it as `1`). - -* `BOOST_LEAF_CFG_STD_SYSTEM_ERROR`: Defining this macro as `0` disables the `std::error_code` / `std::error_condition` integration. In this case LEAF does not `#include `, which may be too heavy for embedded platforms (if the macro is left undefined, LEAF defines it as `1`). - -* `BOOST_LEAF_CFG_STD_STRING`: Defining this macro as `0` disables all use of `std::string` (this requires `BOOST_LEAF_CFG_DIAGNOSTICS=0` as well). In this case LEAF does not `#include ` which may be too heavy for embedded platforms (if the macro is left undefined, LEAF defines it as `1`). - -* `BOOST_LEAF_CFG_CAPTURE`: Defining this macro as `0` disables the ability of `leaf::result` to transport errors between threads. In this case LEAF does not `#include `, which may be too heavy for embedded platforms (if the macro is left undefined, LEAF defines it as `1`). - -* `BOOST_LEAF_CFG_GNUC_STMTEXPR`: This macro controls whether or not <> is defined in terms of a https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html[GNU C statement expression], which enables its use to check for errors similarly to how the questionmark operator works in some languages (see <>). By default the macro is defined as `1` under `pass:[__GNUC__]`, otherwise as `0`. - -* `BOOST_LEAF_CFG_WIN32`: Defining this macro as 1 enables the default constructor in <>, and the automatic conversion to string (via `FormatMessageA`) when <> is printed. If the macro is left undefined, LEAF defines it as `0` (even on windows, since including `windows.h` is generally not desirable). Note that the `e_LastError` type itself is available on all platforms, there is no need for conditional compilation in error handlers that use it. - -* `BOOST_LEAF_NO_EXCEPTIONS`: Disables all exception handling support. If left undefined, LEAF defines it automatically based on the compiler configuration (e.g. `-fno-exceptions`). - -* `BOOST_LEAF_NO_THREADS`: Disables all thread safety in LEAF. - -[[configuring_tls_access]] -=== Configuring TLS Access - -LEAF requires support for thread-local `void` pointers. By default, this is implemented by means of the {CPP}11 `thread_local` keyword, but in order to support <>, it is possible to configure LEAF to use an array of thread local pointers instead, by defining `BOOST_LEAF_USE_TLS_ARRAY`. In this case, the user is required to define the following two functions to implement the required TLS access: - -[source,c++] ----- -namespace boost { namespace leaf { - -namespace tls -{ - void * read_void_ptr( int tls_index ) noexcept; - void write_void_ptr( int tls_index, void * p ) noexcept; -} - -} } ----- - -TIP: For efficiency, `read_void_ptr` and `write_void_ptr` should be defined `inline`. - -Under `BOOST_LEAF_USE_TLS_ARRAY` the following additional configuration macros are recognized: - -* `BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX` specifies the start TLS array index available to LEAF (if the macro is left undefined, LEAF defines it as `0`). - -* `BOOST_LEAF_CFG_TLS_ARRAY_SIZE` may be defined to specify the size of the TLS array. In this case TLS indices are validated via `BOOST_LEAF_ASSERT` before being passed to `read_void_ptr` / `write_void_ptr`. - -* `BOOST_LEAF_CFG_TLS_INDEX_TYPE` may be defined to specify the integral type used to store assigned TLS indices (if the macro is left undefined, LEAF defines it as `unsigned char`). - -TIP: Reporting error objects of types that are not used by the program to handle failures does not consume TLS pointers. The minimum size of the TLS pointer array required by LEAF is the total number of different types used as arguments to error handlers (in the entire program), plus one. - -WARNING: Beware of `read_void_ptr`/`write_void_ptr` accessing thread local pointers beyond the static boundaries of the thread local pointer array; this will likely result in undefined behavior. - -[[embedded_platforms]] -=== Embedded Platforms - -Defining `BOOST_LEAF_EMBEDDED` is equivalent to the following: - -[source,c++] ----- -#ifndef BOOST_LEAF_CFG_DIAGNOSTICS -# define BOOST_LEAF_CFG_DIAGNOSTICS 0 -#endif - -#ifndef BOOST_LEAF_CFG_STD_SYSTEM_ERROR -# define BOOST_LEAF_CFG_STD_SYSTEM_ERROR 0 -#endif - -#ifndef BOOST_LEAF_CFG_STD_STRING -# define BOOST_LEAF_CFG_STD_STRING 0 -#endif - -#ifndef BOOST_LEAF_CFG_CAPTURE -# define BOOST_LEAF_CFG_CAPTURE 0 -#endif ----- - -LEAF supports FreeRTOS out of the box, please define `BOOST_LEAF_TLS_FREERTOS` (in which case LEAF automatically defines `BOOST_LEAF_EMBEDDED`, if it is not defined already). - -For other embedded platforms, please define `BOOST_LEAF_USE_TLS_ARRAY`, see <>. - -If your program does not use concurrency at all, simply define `BOOST_LEAF_NO_THREADS`, which requires no TLS support at all (but is NOT thread-safe). - -[[portability]] -== Portability - -The source code is compatible with {CPP}11 or newer. - -LEAF uses thread-local storage (only for pointers). By default, this is implemented via the {CPP}11 `thread_local` storage class specifier, but the library is easily configurable to use any platform-specific TLS API instead (it ships with built-in support for FreeRTOS). See <>. - -== Limitations - -When using dynamic linking, it is required that error types are declared with `default` visibility, e.g.: - -[source,c++] ----- -struct __attribute__ ((visibility ("default"))) my_error_info -{ - int value; -}; ----- - -This works as expected except on Windows, where thread-local storage is not shared between the individual binary modules. For this reason, to transport error objects across DLL boundaries, it is required that they're captured in a <>, just like when <>. - -TIP: When using dynamic linking, it is always best to define module interfaces in terms of C (and implement them in {CPP} if appropriate). - == Acknowledgements Special thanks to Peter Dimov and Sorin Fetche. diff --git a/example/capture_in_exception.cpp b/example/dynamic_capture_eh.cpp similarity index 61% rename from example/capture_in_exception.cpp rename to example/dynamic_capture_eh.cpp index a73d30d9..7b34a833 100644 --- a/example/capture_in_exception.cpp +++ b/example/dynamic_capture_eh.cpp @@ -44,30 +44,12 @@ int main() { int const task_count = 42; - // The error_handlers are used in this thread (see leaf::try_catch below). - // The arguments passed to individual lambdas are transported from the - // worker thread to the main thread automatically. - auto error_handlers = std::make_tuple( - []( e_failure_info1 const & v1, e_failure_info2 const & v2, e_thread_id const & tid ) - { - std::cerr << "Error in thread " << tid.value << "! failure_info1: " << v1.value << ", failure_info2: " << v2.value << std::endl; - }, - []( leaf::diagnostic_info const & unmatched ) - { - std::cerr << - "Unknown failure detected" << std::endl << - "Cryptic diagnostic information follows" << std::endl << - unmatched; - } ); - // Container to collect the generated std::future objects. - std::vector> fut; + std::vector>> fut; // Launch the tasks, but rather than launching the task function directly, - // we launch a wrapper function which calls leaf::capture, passing a context - // object that will hold the error objects reported from the task in case it - // throws. The error types the context is able to hold statically are - // automatically deduced from the type of the error_handlers tuple. + // we use leaf::try_catch in compbination with leaf::dynamic_capture: + // in case of a failure, the returned leaf::result<> will capture all error objects. std::generate_n( std::back_inserter(fut), task_count, [&] { @@ -75,7 +57,15 @@ int main() std::launch::async, [&] { - return leaf::capture(leaf::make_shared_context(error_handlers), &task); + return leaf::try_catch( + [&]() -> leaf::result + { + return task(); + }, + []( leaf::dynamic_capture const & cap ) -> leaf::result + { + return cap; + } ); } ); } ); @@ -87,12 +77,22 @@ int main() leaf::try_catch( [&] { - task_result r = f.get(); + task_result r = f.get().value(); // Success! Use r to access task_result. std::cout << "Success!" << std::endl; (void) r; // Presumably we'll somehow use the task_result. }, - error_handlers ); + []( e_failure_info1 const & v1, e_failure_info2 const & v2, e_thread_id const & tid ) + { + std::cerr << "Error in thread " << tid.value << "! failure_info1: " << v1.value << ", failure_info2: " << v2.value << std::endl; + }, + []( leaf::diagnostic_info const & unmatched ) + { + std::cerr << + "Unknown failure detected" << std::endl << + "Cryptic diagnostic information follows" << std::endl << + unmatched; + } ); } } diff --git a/example/capture_in_result.cpp b/example/dynamic_capture_result.cpp similarity index 67% rename from example/capture_in_result.cpp rename to example/dynamic_capture_result.cpp index c8c9ad7f..bf3374cb 100644 --- a/example/capture_in_result.cpp +++ b/example/dynamic_capture_result.cpp @@ -44,30 +44,12 @@ int main() { int const task_count = 42; - // The error_handlers are used in this thread (see leaf::try_handle_all - // below). The arguments passed to individual lambdas are transported from - // the worker thread to the main thread automatically. - auto error_handlers = std::make_tuple( - []( e_failure_info1 const & v1, e_failure_info2 const & v2, e_thread_id const & tid ) - { - std::cerr << "Error in thread " << tid.value << "! failure_info1: " << v1.value << ", failure_info2: " << v2.value << std::endl; - }, - []( leaf::diagnostic_info const & unmatched ) - { - std::cerr << - "Unknown failure detected" << std::endl << - "Cryptic diagnostic information follows" << std::endl << - unmatched; - } ); - // Container to collect the generated std::future objects. std::vector>> fut; // Launch the tasks, but rather than launching the task function directly, - // we launch a wrapper function which calls leaf::capture, passing a context - // object that will hold the error objects reported from the task in case of - // an error. The error types the context is able to hold statically are - // automatically deduced from the type of the error_handlers tuple. + // we use leaf::try_handle_some in compbination with leaf::dynamic_capture: + // in case of a failure, the returned leaf::result<> will capture all error objects. std::generate_n( std::back_inserter(fut), task_count, [&] { @@ -75,7 +57,15 @@ int main() std::launch::async, [&] { - return leaf::capture(leaf::make_shared_context(error_handlers), &task); + return leaf::try_handle_some( + [&]() -> leaf::result + { + return task(); + }, + []( leaf::dynamic_capture const & cap ) -> leaf::result + { + return cap; + } ); } ); } ); @@ -87,14 +77,24 @@ int main() leaf::try_handle_all( [&]() -> leaf::result { - BOOST_LEAF_AUTO(r,f.get()); + BOOST_LEAF_AUTO(r, f.get()); // Success! Use r to access task_result. std::cout << "Success!" << std::endl; (void) r; // Presumably we'll somehow use the task_result. return { }; }, - error_handlers ); + []( e_failure_info1 const & v1, e_failure_info2 const & v2, e_thread_id const & tid ) + { + std::cerr << "Error in thread " << tid.value << "! failure_info1: " << v1.value << ", failure_info2: " << v2.value << std::endl; + }, + []( leaf::diagnostic_info const & unmatched ) + { + std::cerr << + "Unknown failure detected" << std::endl << + "Cryptic diagnostic information follows" << std::endl << + unmatched; + } ); } } diff --git a/example/print_file/print_file_outcome_result.cpp b/example/print_file/print_file_outcome_result.cpp index 5c642699..bd152c47 100644 --- a/example/print_file/print_file_outcome_result.cpp +++ b/example/print_file/print_file_outcome_result.cpp @@ -79,7 +79,7 @@ int main( int argc, char const * argv[] ) std::cout << buffer; std::cout.flush(); if( std::cout.fail() ) - return leaf::new_error(output_error, leaf::e_errno{errno}).to_error_code(); + return leaf::new_error(output_error, leaf::e_errno{errno}); return 0; }, @@ -164,7 +164,7 @@ result parse_command_line( int argc, char const * argv[] ) if( argc==2 ) return argv[1]; else - return leaf::new_error(bad_command_line).to_error_code(); + return leaf::new_error(bad_command_line); } @@ -174,7 +174,7 @@ result> file_open( char const * file_name ) if( FILE * f = fopen(file_name, "rb") ) return std::shared_ptr(f, &fclose); else - return leaf::new_error(open_error, leaf::e_errno{errno}).to_error_code(); + return leaf::new_error(open_error, leaf::e_errno{errno}); } @@ -184,14 +184,14 @@ result file_size( FILE & f ) auto load = leaf::on_error([] { return leaf::e_errno{errno}; }); if( fseek(&f, 0, SEEK_END) ) - return leaf::new_error(size_error).to_error_code(); + return leaf::new_error(size_error); long s = ftell(&f); if( s==-1L ) - return leaf::new_error(size_error).to_error_code(); + return leaf::new_error(size_error); if( fseek(&f,0,SEEK_SET) ) - return leaf::new_error(size_error).to_error_code(); + return leaf::new_error(size_error); return std::size_t(s); } @@ -203,10 +203,10 @@ result file_read( FILE & f, void * buf, std::size_t size ) std::size_t n = fread(buf, 1, size, &f); if( ferror(&f) ) - return leaf::new_error(read_error, leaf::e_errno{errno}).to_error_code(); + return leaf::new_error(read_error, leaf::e_errno{errno}); if( n!=size ) - return leaf::new_error(eof_error).to_error_code(); + return leaf::new_error(eof_error); return outcome::success(); } diff --git a/example/readme.md b/example/readme.md index 3e98584a..323d9e4b 100644 --- a/example/readme.md +++ b/example/readme.md @@ -2,8 +2,8 @@ * [print_file](./print_file): The complete example from the [Five Minute Introduction](https://boostorg.github.io/leaf/#introduction). This directory contains several versions of the same program, each using a different error handling style. -* [capture_in_result.cpp](https://github.com/boostorg/leaf/blob/master/example/capture_in_result.cpp?ts=4): Shows how to transport error objects between threads in a `leaf::result` object. -* [capture_in_exception.cpp](https://github.com/boostorg/leaf/blob/master/example/capture_in_exception.cpp?ts=4): Shows how to transport error objects between threads in an exception object. +* [dynamic_capture_result.cpp](https://github.com/boostorg/leaf/blob/master/example/dynamic_capture_result.cpp?ts=4): Shows how to transport error objects between threads in a `leaf::result` object without using exception handling. +* [dynamic_capture_eh.cpp](https://github.com/boostorg/leaf/blob/master/example/dynamic_capture_eh.cpp?ts=4): Shows how to transport error objects between threads in an a `leaf::result` object using exception handling. * [lua_callback_result.cpp](https://github.com/boostorg/leaf/blob/master/example/lua_callback_result.cpp?ts=4): Transporting arbitrary error objects through an uncooperative C API. * [lua_callback_eh.cpp](https://github.com/boostorg/leaf/blob/master/example/lua_callback_eh.cpp?ts=4): Transporting arbitrary error objects through an uncooperative exception-safe API. * [exception_to_result.cpp](https://github.com/boostorg/leaf/blob/master/example/exception_to_result.cpp?ts=4): Demonstrates how to transport exceptions through a `noexcept` layer in the program. diff --git a/include/boost/leaf/capture.hpp b/include/boost/leaf/capture.hpp deleted file mode 100644 index 9235a824..00000000 --- a/include/boost/leaf/capture.hpp +++ /dev/null @@ -1,239 +0,0 @@ -#ifndef BOOST_LEAF_CAPTURE_HPP_INCLUDED -#define BOOST_LEAF_CAPTURE_HPP_INCLUDED - -// Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc. - -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include - -#if BOOST_LEAF_CFG_CAPTURE - -namespace boost { namespace leaf { - -namespace leaf_detail -{ - template ::value> - struct is_result_tag; - - template - struct is_result_tag - { - }; - - template - struct is_result_tag - { - }; -} - -#ifdef BOOST_LEAF_NO_EXCEPTIONS - -namespace leaf_detail -{ - template - inline - decltype(std::declval()(std::forward(std::declval())...)) - capture_impl(is_result_tag, ContextPtr && ctx, F && f, A... a) noexcept - { - auto active_context = activate_context(*ctx); - return std::forward(f)(std::forward(a)...); - } - - template - inline - decltype(std::declval()(std::forward(std::declval())...)) - capture_impl(is_result_tag, ContextPtr && ctx, F && f, A... a) noexcept - { - auto active_context = activate_context(*ctx); - if( auto r = std::forward(f)(std::forward(a)...) ) - return r; - else - { - ctx->captured_id_ = r.error(); - return std::forward(ctx); - } - } - - template - inline - decltype(std::declval().get()) - future_get_impl(is_result_tag, Future & fut) noexcept - { - return fut.get(); - } - - template - inline - decltype(std::declval().get()) - future_get_impl(is_result_tag, Future & fut) noexcept - { - if( auto r = fut.get() ) - return r; - else - return error_id(r.error()); // unloads - } -} - -#else - -namespace leaf_detail -{ - class capturing_exception: - public std::exception - { - std::exception_ptr ex_; - context_ptr ctx_; - - public: - - template - capturing_exception(std::exception_ptr && ex, ContextPtr && ctx) noexcept: - ex_(std::move(ex)), - ctx_(std::forward(ctx)) - { - BOOST_LEAF_ASSERT(ex_); - BOOST_LEAF_ASSERT(ctx_); - BOOST_LEAF_ASSERT(ctx_->captured_id_); - } - - [[noreturn]] void unload_and_rethrow_original_exception() const - { - BOOST_LEAF_ASSERT(ctx_->captured_id_); - tls::write_uint(unsigned(ctx_->captured_id_.value())); - ctx_->propagate(ctx_->captured_id_); - std::rethrow_exception(ex_); - } - }; - - template - inline - decltype(std::declval()(std::forward(std::declval())...)) - capture_impl(is_result_tag, ContextPtr && ctx, F && f, A... a) - { - auto active_context = activate_context(*ctx); - error_monitor cur_err; - try - { - return std::forward(f)(std::forward(a)...); - } - catch( capturing_exception const & ) - { - throw; - } - catch( exception_base const & e ) - { - ctx->captured_id_ = e.get_error_id(); - leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::forward(ctx)) ); - } - catch(...) - { - ctx->captured_id_ = cur_err.assigned_error_id(); - leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::forward(ctx)) ); - } - } - - template - inline - decltype(std::declval()(std::forward(std::declval())...)) - capture_impl(is_result_tag, ContextPtr && ctx, F && f, A... a) - { - auto active_context = activate_context(*ctx); - error_monitor cur_err; - try - { - if( auto && r = std::forward(f)(std::forward(a)...) ) - return std::move(r); - else - { - ctx->captured_id_ = r.error(); - return std::forward(ctx); - } - } - catch( capturing_exception const & ) - { - throw; - } - catch( exception_base const & e ) - { - ctx->captured_id_ = e.get_error_id(); - leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::forward(ctx)) ); - } - catch(...) - { - ctx->captured_id_ = cur_err.assigned_error_id(); - leaf_detail::throw_exception_impl( capturing_exception(std::current_exception(), std::forward(ctx)) ); - } - } - - template - inline - decltype(std::declval().get()) - future_get_impl(is_result_tag, Future & fut ) - { - try - { - return fut.get(); - } - catch( capturing_exception const & cap ) - { - cap.unload_and_rethrow_original_exception(); - } - } - - template - inline - decltype(std::declval().get()) - future_get_impl(is_result_tag, Future & fut ) - { - try - { - if( auto r = fut.get() ) - return r; - else - return error_id(r.error()); // unloads - } - catch( capturing_exception const & cap ) - { - cap.unload_and_rethrow_original_exception(); - } - } -} - -#endif - -template -inline -decltype(std::declval()(std::forward(std::declval())...)) -capture(context_ptr const & ctx, F && f, A... a) -{ - using namespace leaf_detail; - return capture_impl(is_result_tag()(std::forward(std::declval())...))>(), ctx, std::forward(f), std::forward(a)...); -} - -template -inline -decltype(std::declval()(std::forward(std::declval())...)) -capture(context_ptr && ctx, F && f, A... a) -{ - using namespace leaf_detail; - return capture_impl(is_result_tag()(std::forward(std::declval())...))>(), std::move(ctx), std::forward(f), std::forward(a)...); -} - -template -inline -decltype(std::declval().get()) -future_get( Future & fut ) -{ - using namespace leaf_detail; - return future_get_impl(is_result_tag().get())>(), fut); -} - -} } - -#endif - -#endif diff --git a/include/boost/leaf/config.hpp b/include/boost/leaf/config.hpp index bf3118f7..8b712512 100644 --- a/include/boost/leaf/config.hpp +++ b/include/boost/leaf/config.hpp @@ -102,10 +102,6 @@ # error BOOST_LEAF_CFG_CAPTURE must be 0 or 1. #endif -#if BOOST_LEAF_CFG_DIAGNOSTICS && !BOOST_LEAF_CFG_STD_STRING -# error BOOST_LEAF_CFG_DIAGNOSTICS requires the use of std::string -#endif - #if BOOST_LEAF_CFG_WIN32!=0 && BOOST_LEAF_CFG_WIN32!=1 # error BOOST_LEAF_CFG_WIN32 must be 0 or 1. #endif @@ -114,8 +110,12 @@ # error BOOST_LEAF_CFG_GNUC_STMTEXPR must be 0 or 1. #endif +#if BOOST_LEAF_CFG_DIAGNOSTICS && !BOOST_LEAF_CFG_STD_STRING +# error BOOST_LEAF_CFG_DIAGNOSTICS requires BOOST_LEAF_CFG_STD_STRING, which has been disabled. +#endif + #if BOOST_LEAF_CFG_STD_SYSTEM_ERROR && !BOOST_LEAF_CFG_STD_STRING -# error BOOST_LEAF_CFG_STD_SYSTEM_ERROR != 0 requires BOOST_LEAF_CFG_STD_STRING != 0 +# error BOOST_LEAF_CFG_STD_SYSTEM_ERROR requires BOOST_LEAF_CFG_STD_STRING, which has been disabled. #endif //////////////////////////////////////// @@ -209,12 +209,18 @@ //////////////////////////////////////// -#ifndef BOOST_LEAF_NODISCARD -# if __cplusplus >= 201703L -# define BOOST_LEAF_NODISCARD [[nodiscard]] -# else -# define BOOST_LEAF_NODISCARD +#if defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130) +# if __has_attribute(nodiscard) +# define BOOST_LEAF_ATTRIBUTE_NODISCARD [[nodiscard]] # endif +#elif defined(__has_cpp_attribute) + //clang-6 accepts [[nodiscard]] with -std=c++14, but warns about it -pedantic +# if __has_cpp_attribute(nodiscard) && !(defined(__clang__) && (__cplusplus < 201703L)) && !(defined(__GNUC__) && (__cplusplus < 201100)) +# define BOOST_LEAF_ATTRIBUTE_NODISCARD [[nodiscard]] +# endif +#endif +#ifndef BOOST_LEAF_ATTRIBUTE_NODISCARD +# define BOOST_LEAF_ATTRIBUTE_NODISCARD #endif //////////////////////////////////////// diff --git a/include/boost/leaf/config/tls_array.hpp b/include/boost/leaf/config/tls_array.hpp index a78addc8..01e2afc1 100644 --- a/include/boost/leaf/config/tls_array.hpp +++ b/include/boost/leaf/config/tls_array.hpp @@ -65,15 +65,21 @@ namespace tls { static int c_; - public: - - static BOOST_LEAF_CFG_TLS_INDEX_TYPE next() + static BOOST_LEAF_CFG_TLS_INDEX_TYPE next_() noexcept { int idx = ++c_; BOOST_LEAF_ASSERT(idx > (BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX)); BOOST_LEAF_ASSERT(idx < (BOOST_LEAF_CFG_TLS_ARRAY_SIZE)); return idx; } + + public: + + template + static BOOST_LEAF_CFG_TLS_INDEX_TYPE next() noexcept + { + return next_(); // Set breakpoint here to monitor TLS index allocation for T. + } }; template @@ -95,7 +101,7 @@ namespace tls BOOST_LEAF_CFG_TLS_INDEX_TYPE tls_index::idx = BOOST_LEAF_CFG_TLS_ARRAY_START_INDEX; template - BOOST_LEAF_CFG_TLS_INDEX_TYPE const alloc_tls_index::idx = tls_index::idx = index_counter<>::next(); + BOOST_LEAF_CFG_TLS_INDEX_TYPE const alloc_tls_index::idx = tls_index::idx = index_counter<>::next(); //////////////////////////////////////// diff --git a/include/boost/leaf/config/tls_freertos.hpp b/include/boost/leaf/config/tls_freertos.hpp index 182bd1ad..0d440ffc 100644 --- a/include/boost/leaf/config/tls_freertos.hpp +++ b/include/boost/leaf/config/tls_freertos.hpp @@ -7,6 +7,11 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// LEAF requires thread local storage support for pointers and for uin32_t values. + +// This header implements "thread local" storage via FreeTOS functions +// pvTaskGetThreadLocalStoragePointer / pvTaskSetThreadLocalStoragePointer + #include #ifndef BOOST_LEAF_USE_TLS_ARRAY diff --git a/include/boost/leaf/context.hpp b/include/boost/leaf/context.hpp index 57238f55..49040dd1 100644 --- a/include/boost/leaf/context.hpp +++ b/include/boost/leaf/context.hpp @@ -18,6 +18,7 @@ namespace boost { namespace leaf { class error_info; class diagnostic_info; class verbose_diagnostic_info; +class dynamic_capture; template struct is_predicate: std::false_type @@ -59,6 +60,7 @@ namespace leaf_detail static_assert(!std::is_same::value, "Handlers must take leaf::error_info arguments by const &"); static_assert(!std::is_same::value, "Handlers must take leaf::diagnostic_info arguments by const &"); static_assert(!std::is_same::value, "Handlers must take leaf::verbose_diagnostic_info arguments by const &"); + static_assert(!std::is_same::value, "Handlers must take leaf::dynamic_capture arguments by const &"); }; template @@ -125,16 +127,6 @@ namespace leaf_detail } }; - template <> - struct handler_argument_traits: handler_argument_always_available - { - template - BOOST_LEAF_CONSTEXPR static error_info const & get( Tup const &, error_info const & ei ) noexcept - { - return ei; - } - }; - template struct handler_argument_traits_require_by_value { @@ -163,30 +155,21 @@ namespace leaf_detail tuple_for_each::deactivate(tup); } - BOOST_LEAF_CONSTEXPR static void propagate( Tuple & tup, int err_id ) noexcept - { - static_assert(!std::is_same(tup))>::type>::value, "Bug in LEAF: context type deduction"); - auto & sl = std::get(tup); - sl.propagate(err_id); - tuple_for_each::propagate(tup, err_id); - } - - BOOST_LEAF_CONSTEXPR static void propagate_captured( Tuple & tup, int err_id ) noexcept + BOOST_LEAF_CONSTEXPR static void unload( Tuple & tup, int err_id ) noexcept { static_assert(!std::is_same(tup))>::type>::value, "Bug in LEAF: context type deduction"); BOOST_LEAF_ASSERT(err_id != 0); auto & sl = std::get(tup); - if( sl.has_value(err_id) ) - (void) load_slot(err_id, std::move(sl).value(err_id)); - tuple_for_each::propagate_captured(tup, err_id); + sl.unload(err_id); + tuple_for_each::unload(tup, err_id); } template - static void print( std::basic_ostream & os, void const * tup, int key_to_print ) + static void print( std::basic_ostream & os, void const * tup, int err_id_to_print ) { BOOST_LEAF_ASSERT(tup != nullptr); - tuple_for_each::print(os, tup, key_to_print); - std::get(*static_cast(tup)).print(os, key_to_print); + tuple_for_each::print(os, tup, err_id_to_print); + std::get(*static_cast(tup)).print(os, err_id_to_print); } }; @@ -195,8 +178,7 @@ namespace leaf_detail { BOOST_LEAF_CONSTEXPR static void activate( Tuple & ) noexcept { } BOOST_LEAF_CONSTEXPR static void deactivate( Tuple & ) noexcept { } - BOOST_LEAF_CONSTEXPR static void propagate( Tuple &, int ) noexcept { } - BOOST_LEAF_CONSTEXPR static void propagate_captured( Tuple &, int ) noexcept { } + BOOST_LEAF_CONSTEXPR static void unload( Tuple &, int ) noexcept { } template BOOST_LEAF_CONSTEXPR static void print( std::basic_ostream &, void const *, int ) { } }; @@ -204,37 +186,6 @@ namespace leaf_detail //////////////////////////////////////////// -#if BOOST_LEAF_CFG_DIAGNOSTICS - -namespace leaf_detail -{ - template struct requires_unexpected { constexpr static bool value = false; }; - template struct requires_unexpected { constexpr static bool value = requires_unexpected::value; }; - template struct requires_unexpected { constexpr static bool value = requires_unexpected::value; }; - template struct requires_unexpected { constexpr static bool value = requires_unexpected::value; }; - template <> struct requires_unexpected { constexpr static bool value = true; }; - template <> struct requires_unexpected { constexpr static bool value = true; }; - - template - struct unexpected_requested; - - template