blob: 252dae0e677fa32d89c6539ce4b8c4dbe4a328b1 [file] [log] [blame]
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source of the Rust file `/root/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-syntax-0.7.2/src/hir/mod.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>mod.rs - source</title><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceSerif4-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../FiraSans-Regular.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../FiraSans-Medium.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceCodePro-Regular.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceSerif4-Bold.ttf.woff2"><link rel="preload" as="font" type="font/woff2" crossorigin href="../../../SourceCodePro-Semibold.ttf.woff2"><link rel="stylesheet" href="../../../normalize.css"><link rel="stylesheet" href="../../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" href="../../../ayu.css" disabled><link rel="stylesheet" href="../../../dark.css" disabled><link rel="stylesheet" href="../../../light.css" id="themeStyle"><script id="default-settings" ></script><script src="../../../storage.js"></script><script defer src="../../../source-script.js"></script><script defer src="../../../source-files.js"></script><script defer src="../../../main.js"></script><noscript><link rel="stylesheet" href="../../../noscript.css"></noscript><link rel="alternate icon" type="image/png" href="../../../favicon-16x16.png"><link rel="alternate icon" type="image/png" href="../../../favicon-32x32.png"><link rel="icon" type="image/svg+xml" href="../../../favicon.svg"></head><body class="rustdoc source"><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><a class="sidebar-logo" href="../../../regex_syntax/index.html"><div class="logo-container"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></div></a></nav><main><div class="width-limiter"><nav class="sub"><a class="sub-logo-container" href="../../../regex_syntax/index.html"><img class="rust-logo" src="../../../rust-logo.svg" alt="logo"></a><form class="search-form"><div class="search-container"><span></span><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press ‘S’ to search, ‘?’ for more options…" type="search"><div id="help-button" title="help" tabindex="-1"><a href="../../../help.html">?</a></div><div id="settings-menu" tabindex="-1"><a href="../../../settings.html" title="settings"><img width="22" height="22" alt="Change settings" src="../../../wheel.svg"></a></div></div></form></nav><section id="main-content" class="content"><div class="example-wrap"><pre class="src-line-numbers"><span id="1">1</span>
<span id="2">2</span>
<span id="3">3</span>
<span id="4">4</span>
<span id="5">5</span>
<span id="6">6</span>
<span id="7">7</span>
<span id="8">8</span>
<span id="9">9</span>
<span id="10">10</span>
<span id="11">11</span>
<span id="12">12</span>
<span id="13">13</span>
<span id="14">14</span>
<span id="15">15</span>
<span id="16">16</span>
<span id="17">17</span>
<span id="18">18</span>
<span id="19">19</span>
<span id="20">20</span>
<span id="21">21</span>
<span id="22">22</span>
<span id="23">23</span>
<span id="24">24</span>
<span id="25">25</span>
<span id="26">26</span>
<span id="27">27</span>
<span id="28">28</span>
<span id="29">29</span>
<span id="30">30</span>
<span id="31">31</span>
<span id="32">32</span>
<span id="33">33</span>
<span id="34">34</span>
<span id="35">35</span>
<span id="36">36</span>
<span id="37">37</span>
<span id="38">38</span>
<span id="39">39</span>
<span id="40">40</span>
<span id="41">41</span>
<span id="42">42</span>
<span id="43">43</span>
<span id="44">44</span>
<span id="45">45</span>
<span id="46">46</span>
<span id="47">47</span>
<span id="48">48</span>
<span id="49">49</span>
<span id="50">50</span>
<span id="51">51</span>
<span id="52">52</span>
<span id="53">53</span>
<span id="54">54</span>
<span id="55">55</span>
<span id="56">56</span>
<span id="57">57</span>
<span id="58">58</span>
<span id="59">59</span>
<span id="60">60</span>
<span id="61">61</span>
<span id="62">62</span>
<span id="63">63</span>
<span id="64">64</span>
<span id="65">65</span>
<span id="66">66</span>
<span id="67">67</span>
<span id="68">68</span>
<span id="69">69</span>
<span id="70">70</span>
<span id="71">71</span>
<span id="72">72</span>
<span id="73">73</span>
<span id="74">74</span>
<span id="75">75</span>
<span id="76">76</span>
<span id="77">77</span>
<span id="78">78</span>
<span id="79">79</span>
<span id="80">80</span>
<span id="81">81</span>
<span id="82">82</span>
<span id="83">83</span>
<span id="84">84</span>
<span id="85">85</span>
<span id="86">86</span>
<span id="87">87</span>
<span id="88">88</span>
<span id="89">89</span>
<span id="90">90</span>
<span id="91">91</span>
<span id="92">92</span>
<span id="93">93</span>
<span id="94">94</span>
<span id="95">95</span>
<span id="96">96</span>
<span id="97">97</span>
<span id="98">98</span>
<span id="99">99</span>
<span id="100">100</span>
<span id="101">101</span>
<span id="102">102</span>
<span id="103">103</span>
<span id="104">104</span>
<span id="105">105</span>
<span id="106">106</span>
<span id="107">107</span>
<span id="108">108</span>
<span id="109">109</span>
<span id="110">110</span>
<span id="111">111</span>
<span id="112">112</span>
<span id="113">113</span>
<span id="114">114</span>
<span id="115">115</span>
<span id="116">116</span>
<span id="117">117</span>
<span id="118">118</span>
<span id="119">119</span>
<span id="120">120</span>
<span id="121">121</span>
<span id="122">122</span>
<span id="123">123</span>
<span id="124">124</span>
<span id="125">125</span>
<span id="126">126</span>
<span id="127">127</span>
<span id="128">128</span>
<span id="129">129</span>
<span id="130">130</span>
<span id="131">131</span>
<span id="132">132</span>
<span id="133">133</span>
<span id="134">134</span>
<span id="135">135</span>
<span id="136">136</span>
<span id="137">137</span>
<span id="138">138</span>
<span id="139">139</span>
<span id="140">140</span>
<span id="141">141</span>
<span id="142">142</span>
<span id="143">143</span>
<span id="144">144</span>
<span id="145">145</span>
<span id="146">146</span>
<span id="147">147</span>
<span id="148">148</span>
<span id="149">149</span>
<span id="150">150</span>
<span id="151">151</span>
<span id="152">152</span>
<span id="153">153</span>
<span id="154">154</span>
<span id="155">155</span>
<span id="156">156</span>
<span id="157">157</span>
<span id="158">158</span>
<span id="159">159</span>
<span id="160">160</span>
<span id="161">161</span>
<span id="162">162</span>
<span id="163">163</span>
<span id="164">164</span>
<span id="165">165</span>
<span id="166">166</span>
<span id="167">167</span>
<span id="168">168</span>
<span id="169">169</span>
<span id="170">170</span>
<span id="171">171</span>
<span id="172">172</span>
<span id="173">173</span>
<span id="174">174</span>
<span id="175">175</span>
<span id="176">176</span>
<span id="177">177</span>
<span id="178">178</span>
<span id="179">179</span>
<span id="180">180</span>
<span id="181">181</span>
<span id="182">182</span>
<span id="183">183</span>
<span id="184">184</span>
<span id="185">185</span>
<span id="186">186</span>
<span id="187">187</span>
<span id="188">188</span>
<span id="189">189</span>
<span id="190">190</span>
<span id="191">191</span>
<span id="192">192</span>
<span id="193">193</span>
<span id="194">194</span>
<span id="195">195</span>
<span id="196">196</span>
<span id="197">197</span>
<span id="198">198</span>
<span id="199">199</span>
<span id="200">200</span>
<span id="201">201</span>
<span id="202">202</span>
<span id="203">203</span>
<span id="204">204</span>
<span id="205">205</span>
<span id="206">206</span>
<span id="207">207</span>
<span id="208">208</span>
<span id="209">209</span>
<span id="210">210</span>
<span id="211">211</span>
<span id="212">212</span>
<span id="213">213</span>
<span id="214">214</span>
<span id="215">215</span>
<span id="216">216</span>
<span id="217">217</span>
<span id="218">218</span>
<span id="219">219</span>
<span id="220">220</span>
<span id="221">221</span>
<span id="222">222</span>
<span id="223">223</span>
<span id="224">224</span>
<span id="225">225</span>
<span id="226">226</span>
<span id="227">227</span>
<span id="228">228</span>
<span id="229">229</span>
<span id="230">230</span>
<span id="231">231</span>
<span id="232">232</span>
<span id="233">233</span>
<span id="234">234</span>
<span id="235">235</span>
<span id="236">236</span>
<span id="237">237</span>
<span id="238">238</span>
<span id="239">239</span>
<span id="240">240</span>
<span id="241">241</span>
<span id="242">242</span>
<span id="243">243</span>
<span id="244">244</span>
<span id="245">245</span>
<span id="246">246</span>
<span id="247">247</span>
<span id="248">248</span>
<span id="249">249</span>
<span id="250">250</span>
<span id="251">251</span>
<span id="252">252</span>
<span id="253">253</span>
<span id="254">254</span>
<span id="255">255</span>
<span id="256">256</span>
<span id="257">257</span>
<span id="258">258</span>
<span id="259">259</span>
<span id="260">260</span>
<span id="261">261</span>
<span id="262">262</span>
<span id="263">263</span>
<span id="264">264</span>
<span id="265">265</span>
<span id="266">266</span>
<span id="267">267</span>
<span id="268">268</span>
<span id="269">269</span>
<span id="270">270</span>
<span id="271">271</span>
<span id="272">272</span>
<span id="273">273</span>
<span id="274">274</span>
<span id="275">275</span>
<span id="276">276</span>
<span id="277">277</span>
<span id="278">278</span>
<span id="279">279</span>
<span id="280">280</span>
<span id="281">281</span>
<span id="282">282</span>
<span id="283">283</span>
<span id="284">284</span>
<span id="285">285</span>
<span id="286">286</span>
<span id="287">287</span>
<span id="288">288</span>
<span id="289">289</span>
<span id="290">290</span>
<span id="291">291</span>
<span id="292">292</span>
<span id="293">293</span>
<span id="294">294</span>
<span id="295">295</span>
<span id="296">296</span>
<span id="297">297</span>
<span id="298">298</span>
<span id="299">299</span>
<span id="300">300</span>
<span id="301">301</span>
<span id="302">302</span>
<span id="303">303</span>
<span id="304">304</span>
<span id="305">305</span>
<span id="306">306</span>
<span id="307">307</span>
<span id="308">308</span>
<span id="309">309</span>
<span id="310">310</span>
<span id="311">311</span>
<span id="312">312</span>
<span id="313">313</span>
<span id="314">314</span>
<span id="315">315</span>
<span id="316">316</span>
<span id="317">317</span>
<span id="318">318</span>
<span id="319">319</span>
<span id="320">320</span>
<span id="321">321</span>
<span id="322">322</span>
<span id="323">323</span>
<span id="324">324</span>
<span id="325">325</span>
<span id="326">326</span>
<span id="327">327</span>
<span id="328">328</span>
<span id="329">329</span>
<span id="330">330</span>
<span id="331">331</span>
<span id="332">332</span>
<span id="333">333</span>
<span id="334">334</span>
<span id="335">335</span>
<span id="336">336</span>
<span id="337">337</span>
<span id="338">338</span>
<span id="339">339</span>
<span id="340">340</span>
<span id="341">341</span>
<span id="342">342</span>
<span id="343">343</span>
<span id="344">344</span>
<span id="345">345</span>
<span id="346">346</span>
<span id="347">347</span>
<span id="348">348</span>
<span id="349">349</span>
<span id="350">350</span>
<span id="351">351</span>
<span id="352">352</span>
<span id="353">353</span>
<span id="354">354</span>
<span id="355">355</span>
<span id="356">356</span>
<span id="357">357</span>
<span id="358">358</span>
<span id="359">359</span>
<span id="360">360</span>
<span id="361">361</span>
<span id="362">362</span>
<span id="363">363</span>
<span id="364">364</span>
<span id="365">365</span>
<span id="366">366</span>
<span id="367">367</span>
<span id="368">368</span>
<span id="369">369</span>
<span id="370">370</span>
<span id="371">371</span>
<span id="372">372</span>
<span id="373">373</span>
<span id="374">374</span>
<span id="375">375</span>
<span id="376">376</span>
<span id="377">377</span>
<span id="378">378</span>
<span id="379">379</span>
<span id="380">380</span>
<span id="381">381</span>
<span id="382">382</span>
<span id="383">383</span>
<span id="384">384</span>
<span id="385">385</span>
<span id="386">386</span>
<span id="387">387</span>
<span id="388">388</span>
<span id="389">389</span>
<span id="390">390</span>
<span id="391">391</span>
<span id="392">392</span>
<span id="393">393</span>
<span id="394">394</span>
<span id="395">395</span>
<span id="396">396</span>
<span id="397">397</span>
<span id="398">398</span>
<span id="399">399</span>
<span id="400">400</span>
<span id="401">401</span>
<span id="402">402</span>
<span id="403">403</span>
<span id="404">404</span>
<span id="405">405</span>
<span id="406">406</span>
<span id="407">407</span>
<span id="408">408</span>
<span id="409">409</span>
<span id="410">410</span>
<span id="411">411</span>
<span id="412">412</span>
<span id="413">413</span>
<span id="414">414</span>
<span id="415">415</span>
<span id="416">416</span>
<span id="417">417</span>
<span id="418">418</span>
<span id="419">419</span>
<span id="420">420</span>
<span id="421">421</span>
<span id="422">422</span>
<span id="423">423</span>
<span id="424">424</span>
<span id="425">425</span>
<span id="426">426</span>
<span id="427">427</span>
<span id="428">428</span>
<span id="429">429</span>
<span id="430">430</span>
<span id="431">431</span>
<span id="432">432</span>
<span id="433">433</span>
<span id="434">434</span>
<span id="435">435</span>
<span id="436">436</span>
<span id="437">437</span>
<span id="438">438</span>
<span id="439">439</span>
<span id="440">440</span>
<span id="441">441</span>
<span id="442">442</span>
<span id="443">443</span>
<span id="444">444</span>
<span id="445">445</span>
<span id="446">446</span>
<span id="447">447</span>
<span id="448">448</span>
<span id="449">449</span>
<span id="450">450</span>
<span id="451">451</span>
<span id="452">452</span>
<span id="453">453</span>
<span id="454">454</span>
<span id="455">455</span>
<span id="456">456</span>
<span id="457">457</span>
<span id="458">458</span>
<span id="459">459</span>
<span id="460">460</span>
<span id="461">461</span>
<span id="462">462</span>
<span id="463">463</span>
<span id="464">464</span>
<span id="465">465</span>
<span id="466">466</span>
<span id="467">467</span>
<span id="468">468</span>
<span id="469">469</span>
<span id="470">470</span>
<span id="471">471</span>
<span id="472">472</span>
<span id="473">473</span>
<span id="474">474</span>
<span id="475">475</span>
<span id="476">476</span>
<span id="477">477</span>
<span id="478">478</span>
<span id="479">479</span>
<span id="480">480</span>
<span id="481">481</span>
<span id="482">482</span>
<span id="483">483</span>
<span id="484">484</span>
<span id="485">485</span>
<span id="486">486</span>
<span id="487">487</span>
<span id="488">488</span>
<span id="489">489</span>
<span id="490">490</span>
<span id="491">491</span>
<span id="492">492</span>
<span id="493">493</span>
<span id="494">494</span>
<span id="495">495</span>
<span id="496">496</span>
<span id="497">497</span>
<span id="498">498</span>
<span id="499">499</span>
<span id="500">500</span>
<span id="501">501</span>
<span id="502">502</span>
<span id="503">503</span>
<span id="504">504</span>
<span id="505">505</span>
<span id="506">506</span>
<span id="507">507</span>
<span id="508">508</span>
<span id="509">509</span>
<span id="510">510</span>
<span id="511">511</span>
<span id="512">512</span>
<span id="513">513</span>
<span id="514">514</span>
<span id="515">515</span>
<span id="516">516</span>
<span id="517">517</span>
<span id="518">518</span>
<span id="519">519</span>
<span id="520">520</span>
<span id="521">521</span>
<span id="522">522</span>
<span id="523">523</span>
<span id="524">524</span>
<span id="525">525</span>
<span id="526">526</span>
<span id="527">527</span>
<span id="528">528</span>
<span id="529">529</span>
<span id="530">530</span>
<span id="531">531</span>
<span id="532">532</span>
<span id="533">533</span>
<span id="534">534</span>
<span id="535">535</span>
<span id="536">536</span>
<span id="537">537</span>
<span id="538">538</span>
<span id="539">539</span>
<span id="540">540</span>
<span id="541">541</span>
<span id="542">542</span>
<span id="543">543</span>
<span id="544">544</span>
<span id="545">545</span>
<span id="546">546</span>
<span id="547">547</span>
<span id="548">548</span>
<span id="549">549</span>
<span id="550">550</span>
<span id="551">551</span>
<span id="552">552</span>
<span id="553">553</span>
<span id="554">554</span>
<span id="555">555</span>
<span id="556">556</span>
<span id="557">557</span>
<span id="558">558</span>
<span id="559">559</span>
<span id="560">560</span>
<span id="561">561</span>
<span id="562">562</span>
<span id="563">563</span>
<span id="564">564</span>
<span id="565">565</span>
<span id="566">566</span>
<span id="567">567</span>
<span id="568">568</span>
<span id="569">569</span>
<span id="570">570</span>
<span id="571">571</span>
<span id="572">572</span>
<span id="573">573</span>
<span id="574">574</span>
<span id="575">575</span>
<span id="576">576</span>
<span id="577">577</span>
<span id="578">578</span>
<span id="579">579</span>
<span id="580">580</span>
<span id="581">581</span>
<span id="582">582</span>
<span id="583">583</span>
<span id="584">584</span>
<span id="585">585</span>
<span id="586">586</span>
<span id="587">587</span>
<span id="588">588</span>
<span id="589">589</span>
<span id="590">590</span>
<span id="591">591</span>
<span id="592">592</span>
<span id="593">593</span>
<span id="594">594</span>
<span id="595">595</span>
<span id="596">596</span>
<span id="597">597</span>
<span id="598">598</span>
<span id="599">599</span>
<span id="600">600</span>
<span id="601">601</span>
<span id="602">602</span>
<span id="603">603</span>
<span id="604">604</span>
<span id="605">605</span>
<span id="606">606</span>
<span id="607">607</span>
<span id="608">608</span>
<span id="609">609</span>
<span id="610">610</span>
<span id="611">611</span>
<span id="612">612</span>
<span id="613">613</span>
<span id="614">614</span>
<span id="615">615</span>
<span id="616">616</span>
<span id="617">617</span>
<span id="618">618</span>
<span id="619">619</span>
<span id="620">620</span>
<span id="621">621</span>
<span id="622">622</span>
<span id="623">623</span>
<span id="624">624</span>
<span id="625">625</span>
<span id="626">626</span>
<span id="627">627</span>
<span id="628">628</span>
<span id="629">629</span>
<span id="630">630</span>
<span id="631">631</span>
<span id="632">632</span>
<span id="633">633</span>
<span id="634">634</span>
<span id="635">635</span>
<span id="636">636</span>
<span id="637">637</span>
<span id="638">638</span>
<span id="639">639</span>
<span id="640">640</span>
<span id="641">641</span>
<span id="642">642</span>
<span id="643">643</span>
<span id="644">644</span>
<span id="645">645</span>
<span id="646">646</span>
<span id="647">647</span>
<span id="648">648</span>
<span id="649">649</span>
<span id="650">650</span>
<span id="651">651</span>
<span id="652">652</span>
<span id="653">653</span>
<span id="654">654</span>
<span id="655">655</span>
<span id="656">656</span>
<span id="657">657</span>
<span id="658">658</span>
<span id="659">659</span>
<span id="660">660</span>
<span id="661">661</span>
<span id="662">662</span>
<span id="663">663</span>
<span id="664">664</span>
<span id="665">665</span>
<span id="666">666</span>
<span id="667">667</span>
<span id="668">668</span>
<span id="669">669</span>
<span id="670">670</span>
<span id="671">671</span>
<span id="672">672</span>
<span id="673">673</span>
<span id="674">674</span>
<span id="675">675</span>
<span id="676">676</span>
<span id="677">677</span>
<span id="678">678</span>
<span id="679">679</span>
<span id="680">680</span>
<span id="681">681</span>
<span id="682">682</span>
<span id="683">683</span>
<span id="684">684</span>
<span id="685">685</span>
<span id="686">686</span>
<span id="687">687</span>
<span id="688">688</span>
<span id="689">689</span>
<span id="690">690</span>
<span id="691">691</span>
<span id="692">692</span>
<span id="693">693</span>
<span id="694">694</span>
<span id="695">695</span>
<span id="696">696</span>
<span id="697">697</span>
<span id="698">698</span>
<span id="699">699</span>
<span id="700">700</span>
<span id="701">701</span>
<span id="702">702</span>
<span id="703">703</span>
<span id="704">704</span>
<span id="705">705</span>
<span id="706">706</span>
<span id="707">707</span>
<span id="708">708</span>
<span id="709">709</span>
<span id="710">710</span>
<span id="711">711</span>
<span id="712">712</span>
<span id="713">713</span>
<span id="714">714</span>
<span id="715">715</span>
<span id="716">716</span>
<span id="717">717</span>
<span id="718">718</span>
<span id="719">719</span>
<span id="720">720</span>
<span id="721">721</span>
<span id="722">722</span>
<span id="723">723</span>
<span id="724">724</span>
<span id="725">725</span>
<span id="726">726</span>
<span id="727">727</span>
<span id="728">728</span>
<span id="729">729</span>
<span id="730">730</span>
<span id="731">731</span>
<span id="732">732</span>
<span id="733">733</span>
<span id="734">734</span>
<span id="735">735</span>
<span id="736">736</span>
<span id="737">737</span>
<span id="738">738</span>
<span id="739">739</span>
<span id="740">740</span>
<span id="741">741</span>
<span id="742">742</span>
<span id="743">743</span>
<span id="744">744</span>
<span id="745">745</span>
<span id="746">746</span>
<span id="747">747</span>
<span id="748">748</span>
<span id="749">749</span>
<span id="750">750</span>
<span id="751">751</span>
<span id="752">752</span>
<span id="753">753</span>
<span id="754">754</span>
<span id="755">755</span>
<span id="756">756</span>
<span id="757">757</span>
<span id="758">758</span>
<span id="759">759</span>
<span id="760">760</span>
<span id="761">761</span>
<span id="762">762</span>
<span id="763">763</span>
<span id="764">764</span>
<span id="765">765</span>
<span id="766">766</span>
<span id="767">767</span>
<span id="768">768</span>
<span id="769">769</span>
<span id="770">770</span>
<span id="771">771</span>
<span id="772">772</span>
<span id="773">773</span>
<span id="774">774</span>
<span id="775">775</span>
<span id="776">776</span>
<span id="777">777</span>
<span id="778">778</span>
<span id="779">779</span>
<span id="780">780</span>
<span id="781">781</span>
<span id="782">782</span>
<span id="783">783</span>
<span id="784">784</span>
<span id="785">785</span>
<span id="786">786</span>
<span id="787">787</span>
<span id="788">788</span>
<span id="789">789</span>
<span id="790">790</span>
<span id="791">791</span>
<span id="792">792</span>
<span id="793">793</span>
<span id="794">794</span>
<span id="795">795</span>
<span id="796">796</span>
<span id="797">797</span>
<span id="798">798</span>
<span id="799">799</span>
<span id="800">800</span>
<span id="801">801</span>
<span id="802">802</span>
<span id="803">803</span>
<span id="804">804</span>
<span id="805">805</span>
<span id="806">806</span>
<span id="807">807</span>
<span id="808">808</span>
<span id="809">809</span>
<span id="810">810</span>
<span id="811">811</span>
<span id="812">812</span>
<span id="813">813</span>
<span id="814">814</span>
<span id="815">815</span>
<span id="816">816</span>
<span id="817">817</span>
<span id="818">818</span>
<span id="819">819</span>
<span id="820">820</span>
<span id="821">821</span>
<span id="822">822</span>
<span id="823">823</span>
<span id="824">824</span>
<span id="825">825</span>
<span id="826">826</span>
<span id="827">827</span>
<span id="828">828</span>
<span id="829">829</span>
<span id="830">830</span>
<span id="831">831</span>
<span id="832">832</span>
<span id="833">833</span>
<span id="834">834</span>
<span id="835">835</span>
<span id="836">836</span>
<span id="837">837</span>
<span id="838">838</span>
<span id="839">839</span>
<span id="840">840</span>
<span id="841">841</span>
<span id="842">842</span>
<span id="843">843</span>
<span id="844">844</span>
<span id="845">845</span>
<span id="846">846</span>
<span id="847">847</span>
<span id="848">848</span>
<span id="849">849</span>
<span id="850">850</span>
<span id="851">851</span>
<span id="852">852</span>
<span id="853">853</span>
<span id="854">854</span>
<span id="855">855</span>
<span id="856">856</span>
<span id="857">857</span>
<span id="858">858</span>
<span id="859">859</span>
<span id="860">860</span>
<span id="861">861</span>
<span id="862">862</span>
<span id="863">863</span>
<span id="864">864</span>
<span id="865">865</span>
<span id="866">866</span>
<span id="867">867</span>
<span id="868">868</span>
<span id="869">869</span>
<span id="870">870</span>
<span id="871">871</span>
<span id="872">872</span>
<span id="873">873</span>
<span id="874">874</span>
<span id="875">875</span>
<span id="876">876</span>
<span id="877">877</span>
<span id="878">878</span>
<span id="879">879</span>
<span id="880">880</span>
<span id="881">881</span>
<span id="882">882</span>
<span id="883">883</span>
<span id="884">884</span>
<span id="885">885</span>
<span id="886">886</span>
<span id="887">887</span>
<span id="888">888</span>
<span id="889">889</span>
<span id="890">890</span>
<span id="891">891</span>
<span id="892">892</span>
<span id="893">893</span>
<span id="894">894</span>
<span id="895">895</span>
<span id="896">896</span>
<span id="897">897</span>
<span id="898">898</span>
<span id="899">899</span>
<span id="900">900</span>
<span id="901">901</span>
<span id="902">902</span>
<span id="903">903</span>
<span id="904">904</span>
<span id="905">905</span>
<span id="906">906</span>
<span id="907">907</span>
<span id="908">908</span>
<span id="909">909</span>
<span id="910">910</span>
<span id="911">911</span>
<span id="912">912</span>
<span id="913">913</span>
<span id="914">914</span>
<span id="915">915</span>
<span id="916">916</span>
<span id="917">917</span>
<span id="918">918</span>
<span id="919">919</span>
<span id="920">920</span>
<span id="921">921</span>
<span id="922">922</span>
<span id="923">923</span>
<span id="924">924</span>
<span id="925">925</span>
<span id="926">926</span>
<span id="927">927</span>
<span id="928">928</span>
<span id="929">929</span>
<span id="930">930</span>
<span id="931">931</span>
<span id="932">932</span>
<span id="933">933</span>
<span id="934">934</span>
<span id="935">935</span>
<span id="936">936</span>
<span id="937">937</span>
<span id="938">938</span>
<span id="939">939</span>
<span id="940">940</span>
<span id="941">941</span>
<span id="942">942</span>
<span id="943">943</span>
<span id="944">944</span>
<span id="945">945</span>
<span id="946">946</span>
<span id="947">947</span>
<span id="948">948</span>
<span id="949">949</span>
<span id="950">950</span>
<span id="951">951</span>
<span id="952">952</span>
<span id="953">953</span>
<span id="954">954</span>
<span id="955">955</span>
<span id="956">956</span>
<span id="957">957</span>
<span id="958">958</span>
<span id="959">959</span>
<span id="960">960</span>
<span id="961">961</span>
<span id="962">962</span>
<span id="963">963</span>
<span id="964">964</span>
<span id="965">965</span>
<span id="966">966</span>
<span id="967">967</span>
<span id="968">968</span>
<span id="969">969</span>
<span id="970">970</span>
<span id="971">971</span>
<span id="972">972</span>
<span id="973">973</span>
<span id="974">974</span>
<span id="975">975</span>
<span id="976">976</span>
<span id="977">977</span>
<span id="978">978</span>
<span id="979">979</span>
<span id="980">980</span>
<span id="981">981</span>
<span id="982">982</span>
<span id="983">983</span>
<span id="984">984</span>
<span id="985">985</span>
<span id="986">986</span>
<span id="987">987</span>
<span id="988">988</span>
<span id="989">989</span>
<span id="990">990</span>
<span id="991">991</span>
<span id="992">992</span>
<span id="993">993</span>
<span id="994">994</span>
<span id="995">995</span>
<span id="996">996</span>
<span id="997">997</span>
<span id="998">998</span>
<span id="999">999</span>
<span id="1000">1000</span>
<span id="1001">1001</span>
<span id="1002">1002</span>
<span id="1003">1003</span>
<span id="1004">1004</span>
<span id="1005">1005</span>
<span id="1006">1006</span>
<span id="1007">1007</span>
<span id="1008">1008</span>
<span id="1009">1009</span>
<span id="1010">1010</span>
<span id="1011">1011</span>
<span id="1012">1012</span>
<span id="1013">1013</span>
<span id="1014">1014</span>
<span id="1015">1015</span>
<span id="1016">1016</span>
<span id="1017">1017</span>
<span id="1018">1018</span>
<span id="1019">1019</span>
<span id="1020">1020</span>
<span id="1021">1021</span>
<span id="1022">1022</span>
<span id="1023">1023</span>
<span id="1024">1024</span>
<span id="1025">1025</span>
<span id="1026">1026</span>
<span id="1027">1027</span>
<span id="1028">1028</span>
<span id="1029">1029</span>
<span id="1030">1030</span>
<span id="1031">1031</span>
<span id="1032">1032</span>
<span id="1033">1033</span>
<span id="1034">1034</span>
<span id="1035">1035</span>
<span id="1036">1036</span>
<span id="1037">1037</span>
<span id="1038">1038</span>
<span id="1039">1039</span>
<span id="1040">1040</span>
<span id="1041">1041</span>
<span id="1042">1042</span>
<span id="1043">1043</span>
<span id="1044">1044</span>
<span id="1045">1045</span>
<span id="1046">1046</span>
<span id="1047">1047</span>
<span id="1048">1048</span>
<span id="1049">1049</span>
<span id="1050">1050</span>
<span id="1051">1051</span>
<span id="1052">1052</span>
<span id="1053">1053</span>
<span id="1054">1054</span>
<span id="1055">1055</span>
<span id="1056">1056</span>
<span id="1057">1057</span>
<span id="1058">1058</span>
<span id="1059">1059</span>
<span id="1060">1060</span>
<span id="1061">1061</span>
<span id="1062">1062</span>
<span id="1063">1063</span>
<span id="1064">1064</span>
<span id="1065">1065</span>
<span id="1066">1066</span>
<span id="1067">1067</span>
<span id="1068">1068</span>
<span id="1069">1069</span>
<span id="1070">1070</span>
<span id="1071">1071</span>
<span id="1072">1072</span>
<span id="1073">1073</span>
<span id="1074">1074</span>
<span id="1075">1075</span>
<span id="1076">1076</span>
<span id="1077">1077</span>
<span id="1078">1078</span>
<span id="1079">1079</span>
<span id="1080">1080</span>
<span id="1081">1081</span>
<span id="1082">1082</span>
<span id="1083">1083</span>
<span id="1084">1084</span>
<span id="1085">1085</span>
<span id="1086">1086</span>
<span id="1087">1087</span>
<span id="1088">1088</span>
<span id="1089">1089</span>
<span id="1090">1090</span>
<span id="1091">1091</span>
<span id="1092">1092</span>
<span id="1093">1093</span>
<span id="1094">1094</span>
<span id="1095">1095</span>
<span id="1096">1096</span>
<span id="1097">1097</span>
<span id="1098">1098</span>
<span id="1099">1099</span>
<span id="1100">1100</span>
<span id="1101">1101</span>
<span id="1102">1102</span>
<span id="1103">1103</span>
<span id="1104">1104</span>
<span id="1105">1105</span>
<span id="1106">1106</span>
<span id="1107">1107</span>
<span id="1108">1108</span>
<span id="1109">1109</span>
<span id="1110">1110</span>
<span id="1111">1111</span>
<span id="1112">1112</span>
<span id="1113">1113</span>
<span id="1114">1114</span>
<span id="1115">1115</span>
<span id="1116">1116</span>
<span id="1117">1117</span>
<span id="1118">1118</span>
<span id="1119">1119</span>
<span id="1120">1120</span>
<span id="1121">1121</span>
<span id="1122">1122</span>
<span id="1123">1123</span>
<span id="1124">1124</span>
<span id="1125">1125</span>
<span id="1126">1126</span>
<span id="1127">1127</span>
<span id="1128">1128</span>
<span id="1129">1129</span>
<span id="1130">1130</span>
<span id="1131">1131</span>
<span id="1132">1132</span>
<span id="1133">1133</span>
<span id="1134">1134</span>
<span id="1135">1135</span>
<span id="1136">1136</span>
<span id="1137">1137</span>
<span id="1138">1138</span>
<span id="1139">1139</span>
<span id="1140">1140</span>
<span id="1141">1141</span>
<span id="1142">1142</span>
<span id="1143">1143</span>
<span id="1144">1144</span>
<span id="1145">1145</span>
<span id="1146">1146</span>
<span id="1147">1147</span>
<span id="1148">1148</span>
<span id="1149">1149</span>
<span id="1150">1150</span>
<span id="1151">1151</span>
<span id="1152">1152</span>
<span id="1153">1153</span>
<span id="1154">1154</span>
<span id="1155">1155</span>
<span id="1156">1156</span>
<span id="1157">1157</span>
<span id="1158">1158</span>
<span id="1159">1159</span>
<span id="1160">1160</span>
<span id="1161">1161</span>
<span id="1162">1162</span>
<span id="1163">1163</span>
<span id="1164">1164</span>
<span id="1165">1165</span>
<span id="1166">1166</span>
<span id="1167">1167</span>
<span id="1168">1168</span>
<span id="1169">1169</span>
<span id="1170">1170</span>
<span id="1171">1171</span>
<span id="1172">1172</span>
<span id="1173">1173</span>
<span id="1174">1174</span>
<span id="1175">1175</span>
<span id="1176">1176</span>
<span id="1177">1177</span>
<span id="1178">1178</span>
<span id="1179">1179</span>
<span id="1180">1180</span>
<span id="1181">1181</span>
<span id="1182">1182</span>
<span id="1183">1183</span>
<span id="1184">1184</span>
<span id="1185">1185</span>
<span id="1186">1186</span>
<span id="1187">1187</span>
<span id="1188">1188</span>
<span id="1189">1189</span>
<span id="1190">1190</span>
<span id="1191">1191</span>
<span id="1192">1192</span>
<span id="1193">1193</span>
<span id="1194">1194</span>
<span id="1195">1195</span>
<span id="1196">1196</span>
<span id="1197">1197</span>
<span id="1198">1198</span>
<span id="1199">1199</span>
<span id="1200">1200</span>
<span id="1201">1201</span>
<span id="1202">1202</span>
<span id="1203">1203</span>
<span id="1204">1204</span>
<span id="1205">1205</span>
<span id="1206">1206</span>
<span id="1207">1207</span>
<span id="1208">1208</span>
<span id="1209">1209</span>
<span id="1210">1210</span>
<span id="1211">1211</span>
<span id="1212">1212</span>
<span id="1213">1213</span>
<span id="1214">1214</span>
<span id="1215">1215</span>
<span id="1216">1216</span>
<span id="1217">1217</span>
<span id="1218">1218</span>
<span id="1219">1219</span>
<span id="1220">1220</span>
<span id="1221">1221</span>
<span id="1222">1222</span>
<span id="1223">1223</span>
<span id="1224">1224</span>
<span id="1225">1225</span>
<span id="1226">1226</span>
<span id="1227">1227</span>
<span id="1228">1228</span>
<span id="1229">1229</span>
<span id="1230">1230</span>
<span id="1231">1231</span>
<span id="1232">1232</span>
<span id="1233">1233</span>
<span id="1234">1234</span>
<span id="1235">1235</span>
<span id="1236">1236</span>
<span id="1237">1237</span>
<span id="1238">1238</span>
<span id="1239">1239</span>
<span id="1240">1240</span>
<span id="1241">1241</span>
<span id="1242">1242</span>
<span id="1243">1243</span>
<span id="1244">1244</span>
<span id="1245">1245</span>
<span id="1246">1246</span>
<span id="1247">1247</span>
<span id="1248">1248</span>
<span id="1249">1249</span>
<span id="1250">1250</span>
<span id="1251">1251</span>
<span id="1252">1252</span>
<span id="1253">1253</span>
<span id="1254">1254</span>
<span id="1255">1255</span>
<span id="1256">1256</span>
<span id="1257">1257</span>
<span id="1258">1258</span>
<span id="1259">1259</span>
<span id="1260">1260</span>
<span id="1261">1261</span>
<span id="1262">1262</span>
<span id="1263">1263</span>
<span id="1264">1264</span>
<span id="1265">1265</span>
<span id="1266">1266</span>
<span id="1267">1267</span>
<span id="1268">1268</span>
<span id="1269">1269</span>
<span id="1270">1270</span>
<span id="1271">1271</span>
<span id="1272">1272</span>
<span id="1273">1273</span>
<span id="1274">1274</span>
<span id="1275">1275</span>
<span id="1276">1276</span>
<span id="1277">1277</span>
<span id="1278">1278</span>
<span id="1279">1279</span>
<span id="1280">1280</span>
<span id="1281">1281</span>
<span id="1282">1282</span>
<span id="1283">1283</span>
<span id="1284">1284</span>
<span id="1285">1285</span>
<span id="1286">1286</span>
<span id="1287">1287</span>
<span id="1288">1288</span>
<span id="1289">1289</span>
<span id="1290">1290</span>
<span id="1291">1291</span>
<span id="1292">1292</span>
<span id="1293">1293</span>
<span id="1294">1294</span>
<span id="1295">1295</span>
<span id="1296">1296</span>
<span id="1297">1297</span>
<span id="1298">1298</span>
<span id="1299">1299</span>
<span id="1300">1300</span>
<span id="1301">1301</span>
<span id="1302">1302</span>
<span id="1303">1303</span>
<span id="1304">1304</span>
<span id="1305">1305</span>
<span id="1306">1306</span>
<span id="1307">1307</span>
<span id="1308">1308</span>
<span id="1309">1309</span>
<span id="1310">1310</span>
<span id="1311">1311</span>
<span id="1312">1312</span>
<span id="1313">1313</span>
<span id="1314">1314</span>
<span id="1315">1315</span>
<span id="1316">1316</span>
<span id="1317">1317</span>
<span id="1318">1318</span>
<span id="1319">1319</span>
<span id="1320">1320</span>
<span id="1321">1321</span>
<span id="1322">1322</span>
<span id="1323">1323</span>
<span id="1324">1324</span>
<span id="1325">1325</span>
<span id="1326">1326</span>
<span id="1327">1327</span>
<span id="1328">1328</span>
<span id="1329">1329</span>
<span id="1330">1330</span>
<span id="1331">1331</span>
<span id="1332">1332</span>
<span id="1333">1333</span>
<span id="1334">1334</span>
<span id="1335">1335</span>
<span id="1336">1336</span>
<span id="1337">1337</span>
<span id="1338">1338</span>
<span id="1339">1339</span>
<span id="1340">1340</span>
<span id="1341">1341</span>
<span id="1342">1342</span>
<span id="1343">1343</span>
<span id="1344">1344</span>
<span id="1345">1345</span>
<span id="1346">1346</span>
<span id="1347">1347</span>
<span id="1348">1348</span>
<span id="1349">1349</span>
<span id="1350">1350</span>
<span id="1351">1351</span>
<span id="1352">1352</span>
<span id="1353">1353</span>
<span id="1354">1354</span>
<span id="1355">1355</span>
<span id="1356">1356</span>
<span id="1357">1357</span>
<span id="1358">1358</span>
<span id="1359">1359</span>
<span id="1360">1360</span>
<span id="1361">1361</span>
<span id="1362">1362</span>
<span id="1363">1363</span>
<span id="1364">1364</span>
<span id="1365">1365</span>
<span id="1366">1366</span>
<span id="1367">1367</span>
<span id="1368">1368</span>
<span id="1369">1369</span>
<span id="1370">1370</span>
<span id="1371">1371</span>
<span id="1372">1372</span>
<span id="1373">1373</span>
<span id="1374">1374</span>
<span id="1375">1375</span>
<span id="1376">1376</span>
<span id="1377">1377</span>
<span id="1378">1378</span>
<span id="1379">1379</span>
<span id="1380">1380</span>
<span id="1381">1381</span>
<span id="1382">1382</span>
<span id="1383">1383</span>
<span id="1384">1384</span>
<span id="1385">1385</span>
<span id="1386">1386</span>
<span id="1387">1387</span>
<span id="1388">1388</span>
<span id="1389">1389</span>
<span id="1390">1390</span>
<span id="1391">1391</span>
<span id="1392">1392</span>
<span id="1393">1393</span>
<span id="1394">1394</span>
<span id="1395">1395</span>
<span id="1396">1396</span>
<span id="1397">1397</span>
<span id="1398">1398</span>
<span id="1399">1399</span>
<span id="1400">1400</span>
<span id="1401">1401</span>
<span id="1402">1402</span>
<span id="1403">1403</span>
<span id="1404">1404</span>
<span id="1405">1405</span>
<span id="1406">1406</span>
<span id="1407">1407</span>
<span id="1408">1408</span>
<span id="1409">1409</span>
<span id="1410">1410</span>
<span id="1411">1411</span>
<span id="1412">1412</span>
<span id="1413">1413</span>
<span id="1414">1414</span>
<span id="1415">1415</span>
<span id="1416">1416</span>
<span id="1417">1417</span>
<span id="1418">1418</span>
<span id="1419">1419</span>
<span id="1420">1420</span>
<span id="1421">1421</span>
<span id="1422">1422</span>
<span id="1423">1423</span>
<span id="1424">1424</span>
<span id="1425">1425</span>
<span id="1426">1426</span>
<span id="1427">1427</span>
<span id="1428">1428</span>
<span id="1429">1429</span>
<span id="1430">1430</span>
<span id="1431">1431</span>
<span id="1432">1432</span>
<span id="1433">1433</span>
<span id="1434">1434</span>
<span id="1435">1435</span>
<span id="1436">1436</span>
<span id="1437">1437</span>
<span id="1438">1438</span>
<span id="1439">1439</span>
<span id="1440">1440</span>
<span id="1441">1441</span>
<span id="1442">1442</span>
<span id="1443">1443</span>
<span id="1444">1444</span>
<span id="1445">1445</span>
<span id="1446">1446</span>
<span id="1447">1447</span>
<span id="1448">1448</span>
<span id="1449">1449</span>
<span id="1450">1450</span>
<span id="1451">1451</span>
<span id="1452">1452</span>
<span id="1453">1453</span>
<span id="1454">1454</span>
<span id="1455">1455</span>
<span id="1456">1456</span>
<span id="1457">1457</span>
<span id="1458">1458</span>
<span id="1459">1459</span>
<span id="1460">1460</span>
<span id="1461">1461</span>
<span id="1462">1462</span>
<span id="1463">1463</span>
<span id="1464">1464</span>
<span id="1465">1465</span>
<span id="1466">1466</span>
<span id="1467">1467</span>
<span id="1468">1468</span>
<span id="1469">1469</span>
<span id="1470">1470</span>
<span id="1471">1471</span>
<span id="1472">1472</span>
<span id="1473">1473</span>
<span id="1474">1474</span>
<span id="1475">1475</span>
<span id="1476">1476</span>
<span id="1477">1477</span>
<span id="1478">1478</span>
<span id="1479">1479</span>
<span id="1480">1480</span>
<span id="1481">1481</span>
<span id="1482">1482</span>
<span id="1483">1483</span>
<span id="1484">1484</span>
<span id="1485">1485</span>
<span id="1486">1486</span>
<span id="1487">1487</span>
<span id="1488">1488</span>
<span id="1489">1489</span>
<span id="1490">1490</span>
<span id="1491">1491</span>
<span id="1492">1492</span>
<span id="1493">1493</span>
<span id="1494">1494</span>
<span id="1495">1495</span>
<span id="1496">1496</span>
<span id="1497">1497</span>
<span id="1498">1498</span>
<span id="1499">1499</span>
<span id="1500">1500</span>
<span id="1501">1501</span>
<span id="1502">1502</span>
<span id="1503">1503</span>
<span id="1504">1504</span>
<span id="1505">1505</span>
<span id="1506">1506</span>
<span id="1507">1507</span>
<span id="1508">1508</span>
<span id="1509">1509</span>
<span id="1510">1510</span>
<span id="1511">1511</span>
<span id="1512">1512</span>
<span id="1513">1513</span>
<span id="1514">1514</span>
<span id="1515">1515</span>
<span id="1516">1516</span>
<span id="1517">1517</span>
<span id="1518">1518</span>
<span id="1519">1519</span>
<span id="1520">1520</span>
<span id="1521">1521</span>
<span id="1522">1522</span>
<span id="1523">1523</span>
<span id="1524">1524</span>
<span id="1525">1525</span>
<span id="1526">1526</span>
<span id="1527">1527</span>
<span id="1528">1528</span>
<span id="1529">1529</span>
<span id="1530">1530</span>
<span id="1531">1531</span>
<span id="1532">1532</span>
<span id="1533">1533</span>
<span id="1534">1534</span>
<span id="1535">1535</span>
<span id="1536">1536</span>
<span id="1537">1537</span>
<span id="1538">1538</span>
<span id="1539">1539</span>
<span id="1540">1540</span>
<span id="1541">1541</span>
<span id="1542">1542</span>
<span id="1543">1543</span>
<span id="1544">1544</span>
<span id="1545">1545</span>
<span id="1546">1546</span>
<span id="1547">1547</span>
<span id="1548">1548</span>
<span id="1549">1549</span>
<span id="1550">1550</span>
<span id="1551">1551</span>
<span id="1552">1552</span>
<span id="1553">1553</span>
<span id="1554">1554</span>
<span id="1555">1555</span>
<span id="1556">1556</span>
<span id="1557">1557</span>
<span id="1558">1558</span>
<span id="1559">1559</span>
<span id="1560">1560</span>
<span id="1561">1561</span>
<span id="1562">1562</span>
<span id="1563">1563</span>
<span id="1564">1564</span>
<span id="1565">1565</span>
<span id="1566">1566</span>
<span id="1567">1567</span>
<span id="1568">1568</span>
<span id="1569">1569</span>
<span id="1570">1570</span>
<span id="1571">1571</span>
<span id="1572">1572</span>
<span id="1573">1573</span>
<span id="1574">1574</span>
<span id="1575">1575</span>
<span id="1576">1576</span>
<span id="1577">1577</span>
<span id="1578">1578</span>
<span id="1579">1579</span>
<span id="1580">1580</span>
<span id="1581">1581</span>
<span id="1582">1582</span>
<span id="1583">1583</span>
<span id="1584">1584</span>
<span id="1585">1585</span>
<span id="1586">1586</span>
<span id="1587">1587</span>
<span id="1588">1588</span>
<span id="1589">1589</span>
<span id="1590">1590</span>
<span id="1591">1591</span>
<span id="1592">1592</span>
<span id="1593">1593</span>
<span id="1594">1594</span>
<span id="1595">1595</span>
<span id="1596">1596</span>
<span id="1597">1597</span>
<span id="1598">1598</span>
<span id="1599">1599</span>
<span id="1600">1600</span>
<span id="1601">1601</span>
<span id="1602">1602</span>
<span id="1603">1603</span>
<span id="1604">1604</span>
<span id="1605">1605</span>
<span id="1606">1606</span>
<span id="1607">1607</span>
<span id="1608">1608</span>
<span id="1609">1609</span>
<span id="1610">1610</span>
<span id="1611">1611</span>
<span id="1612">1612</span>
<span id="1613">1613</span>
<span id="1614">1614</span>
<span id="1615">1615</span>
<span id="1616">1616</span>
<span id="1617">1617</span>
<span id="1618">1618</span>
<span id="1619">1619</span>
<span id="1620">1620</span>
<span id="1621">1621</span>
<span id="1622">1622</span>
<span id="1623">1623</span>
<span id="1624">1624</span>
<span id="1625">1625</span>
<span id="1626">1626</span>
<span id="1627">1627</span>
<span id="1628">1628</span>
<span id="1629">1629</span>
<span id="1630">1630</span>
<span id="1631">1631</span>
<span id="1632">1632</span>
<span id="1633">1633</span>
<span id="1634">1634</span>
<span id="1635">1635</span>
<span id="1636">1636</span>
<span id="1637">1637</span>
<span id="1638">1638</span>
<span id="1639">1639</span>
<span id="1640">1640</span>
<span id="1641">1641</span>
<span id="1642">1642</span>
<span id="1643">1643</span>
<span id="1644">1644</span>
<span id="1645">1645</span>
<span id="1646">1646</span>
<span id="1647">1647</span>
<span id="1648">1648</span>
<span id="1649">1649</span>
<span id="1650">1650</span>
<span id="1651">1651</span>
<span id="1652">1652</span>
<span id="1653">1653</span>
<span id="1654">1654</span>
<span id="1655">1655</span>
<span id="1656">1656</span>
<span id="1657">1657</span>
<span id="1658">1658</span>
<span id="1659">1659</span>
<span id="1660">1660</span>
<span id="1661">1661</span>
<span id="1662">1662</span>
<span id="1663">1663</span>
<span id="1664">1664</span>
<span id="1665">1665</span>
<span id="1666">1666</span>
<span id="1667">1667</span>
<span id="1668">1668</span>
<span id="1669">1669</span>
<span id="1670">1670</span>
<span id="1671">1671</span>
<span id="1672">1672</span>
<span id="1673">1673</span>
<span id="1674">1674</span>
<span id="1675">1675</span>
<span id="1676">1676</span>
<span id="1677">1677</span>
<span id="1678">1678</span>
<span id="1679">1679</span>
<span id="1680">1680</span>
<span id="1681">1681</span>
<span id="1682">1682</span>
<span id="1683">1683</span>
<span id="1684">1684</span>
<span id="1685">1685</span>
<span id="1686">1686</span>
<span id="1687">1687</span>
<span id="1688">1688</span>
<span id="1689">1689</span>
<span id="1690">1690</span>
<span id="1691">1691</span>
<span id="1692">1692</span>
<span id="1693">1693</span>
<span id="1694">1694</span>
<span id="1695">1695</span>
<span id="1696">1696</span>
<span id="1697">1697</span>
<span id="1698">1698</span>
<span id="1699">1699</span>
<span id="1700">1700</span>
<span id="1701">1701</span>
<span id="1702">1702</span>
<span id="1703">1703</span>
<span id="1704">1704</span>
<span id="1705">1705</span>
<span id="1706">1706</span>
<span id="1707">1707</span>
<span id="1708">1708</span>
<span id="1709">1709</span>
<span id="1710">1710</span>
<span id="1711">1711</span>
<span id="1712">1712</span>
<span id="1713">1713</span>
<span id="1714">1714</span>
<span id="1715">1715</span>
<span id="1716">1716</span>
<span id="1717">1717</span>
<span id="1718">1718</span>
<span id="1719">1719</span>
<span id="1720">1720</span>
<span id="1721">1721</span>
<span id="1722">1722</span>
<span id="1723">1723</span>
<span id="1724">1724</span>
<span id="1725">1725</span>
<span id="1726">1726</span>
<span id="1727">1727</span>
<span id="1728">1728</span>
<span id="1729">1729</span>
<span id="1730">1730</span>
<span id="1731">1731</span>
<span id="1732">1732</span>
<span id="1733">1733</span>
<span id="1734">1734</span>
<span id="1735">1735</span>
<span id="1736">1736</span>
<span id="1737">1737</span>
<span id="1738">1738</span>
<span id="1739">1739</span>
<span id="1740">1740</span>
<span id="1741">1741</span>
<span id="1742">1742</span>
<span id="1743">1743</span>
<span id="1744">1744</span>
<span id="1745">1745</span>
<span id="1746">1746</span>
<span id="1747">1747</span>
<span id="1748">1748</span>
<span id="1749">1749</span>
<span id="1750">1750</span>
<span id="1751">1751</span>
<span id="1752">1752</span>
<span id="1753">1753</span>
<span id="1754">1754</span>
<span id="1755">1755</span>
<span id="1756">1756</span>
<span id="1757">1757</span>
<span id="1758">1758</span>
<span id="1759">1759</span>
<span id="1760">1760</span>
<span id="1761">1761</span>
<span id="1762">1762</span>
<span id="1763">1763</span>
<span id="1764">1764</span>
<span id="1765">1765</span>
<span id="1766">1766</span>
<span id="1767">1767</span>
<span id="1768">1768</span>
<span id="1769">1769</span>
<span id="1770">1770</span>
<span id="1771">1771</span>
<span id="1772">1772</span>
<span id="1773">1773</span>
<span id="1774">1774</span>
<span id="1775">1775</span>
<span id="1776">1776</span>
<span id="1777">1777</span>
<span id="1778">1778</span>
<span id="1779">1779</span>
<span id="1780">1780</span>
<span id="1781">1781</span>
<span id="1782">1782</span>
<span id="1783">1783</span>
<span id="1784">1784</span>
<span id="1785">1785</span>
<span id="1786">1786</span>
<span id="1787">1787</span>
<span id="1788">1788</span>
<span id="1789">1789</span>
<span id="1790">1790</span>
<span id="1791">1791</span>
<span id="1792">1792</span>
<span id="1793">1793</span>
<span id="1794">1794</span>
<span id="1795">1795</span>
<span id="1796">1796</span>
<span id="1797">1797</span>
<span id="1798">1798</span>
<span id="1799">1799</span>
<span id="1800">1800</span>
<span id="1801">1801</span>
<span id="1802">1802</span>
<span id="1803">1803</span>
<span id="1804">1804</span>
<span id="1805">1805</span>
<span id="1806">1806</span>
<span id="1807">1807</span>
<span id="1808">1808</span>
<span id="1809">1809</span>
<span id="1810">1810</span>
<span id="1811">1811</span>
<span id="1812">1812</span>
<span id="1813">1813</span>
<span id="1814">1814</span>
<span id="1815">1815</span>
<span id="1816">1816</span>
<span id="1817">1817</span>
<span id="1818">1818</span>
<span id="1819">1819</span>
<span id="1820">1820</span>
<span id="1821">1821</span>
<span id="1822">1822</span>
<span id="1823">1823</span>
<span id="1824">1824</span>
<span id="1825">1825</span>
<span id="1826">1826</span>
<span id="1827">1827</span>
<span id="1828">1828</span>
<span id="1829">1829</span>
<span id="1830">1830</span>
<span id="1831">1831</span>
<span id="1832">1832</span>
<span id="1833">1833</span>
<span id="1834">1834</span>
<span id="1835">1835</span>
<span id="1836">1836</span>
<span id="1837">1837</span>
<span id="1838">1838</span>
<span id="1839">1839</span>
<span id="1840">1840</span>
<span id="1841">1841</span>
<span id="1842">1842</span>
<span id="1843">1843</span>
<span id="1844">1844</span>
<span id="1845">1845</span>
<span id="1846">1846</span>
<span id="1847">1847</span>
<span id="1848">1848</span>
<span id="1849">1849</span>
<span id="1850">1850</span>
<span id="1851">1851</span>
<span id="1852">1852</span>
<span id="1853">1853</span>
<span id="1854">1854</span>
<span id="1855">1855</span>
<span id="1856">1856</span>
<span id="1857">1857</span>
<span id="1858">1858</span>
<span id="1859">1859</span>
<span id="1860">1860</span>
<span id="1861">1861</span>
<span id="1862">1862</span>
<span id="1863">1863</span>
<span id="1864">1864</span>
<span id="1865">1865</span>
<span id="1866">1866</span>
<span id="1867">1867</span>
<span id="1868">1868</span>
<span id="1869">1869</span>
<span id="1870">1870</span>
<span id="1871">1871</span>
<span id="1872">1872</span>
<span id="1873">1873</span>
<span id="1874">1874</span>
<span id="1875">1875</span>
<span id="1876">1876</span>
<span id="1877">1877</span>
<span id="1878">1878</span>
<span id="1879">1879</span>
<span id="1880">1880</span>
<span id="1881">1881</span>
<span id="1882">1882</span>
<span id="1883">1883</span>
<span id="1884">1884</span>
<span id="1885">1885</span>
<span id="1886">1886</span>
<span id="1887">1887</span>
<span id="1888">1888</span>
<span id="1889">1889</span>
<span id="1890">1890</span>
<span id="1891">1891</span>
<span id="1892">1892</span>
<span id="1893">1893</span>
<span id="1894">1894</span>
<span id="1895">1895</span>
<span id="1896">1896</span>
<span id="1897">1897</span>
<span id="1898">1898</span>
<span id="1899">1899</span>
<span id="1900">1900</span>
<span id="1901">1901</span>
<span id="1902">1902</span>
<span id="1903">1903</span>
<span id="1904">1904</span>
<span id="1905">1905</span>
<span id="1906">1906</span>
<span id="1907">1907</span>
<span id="1908">1908</span>
<span id="1909">1909</span>
<span id="1910">1910</span>
<span id="1911">1911</span>
<span id="1912">1912</span>
<span id="1913">1913</span>
<span id="1914">1914</span>
<span id="1915">1915</span>
<span id="1916">1916</span>
<span id="1917">1917</span>
<span id="1918">1918</span>
<span id="1919">1919</span>
<span id="1920">1920</span>
<span id="1921">1921</span>
<span id="1922">1922</span>
<span id="1923">1923</span>
<span id="1924">1924</span>
<span id="1925">1925</span>
<span id="1926">1926</span>
<span id="1927">1927</span>
<span id="1928">1928</span>
<span id="1929">1929</span>
<span id="1930">1930</span>
<span id="1931">1931</span>
<span id="1932">1932</span>
<span id="1933">1933</span>
<span id="1934">1934</span>
<span id="1935">1935</span>
<span id="1936">1936</span>
<span id="1937">1937</span>
<span id="1938">1938</span>
<span id="1939">1939</span>
<span id="1940">1940</span>
<span id="1941">1941</span>
<span id="1942">1942</span>
<span id="1943">1943</span>
<span id="1944">1944</span>
<span id="1945">1945</span>
<span id="1946">1946</span>
<span id="1947">1947</span>
<span id="1948">1948</span>
<span id="1949">1949</span>
<span id="1950">1950</span>
<span id="1951">1951</span>
<span id="1952">1952</span>
<span id="1953">1953</span>
<span id="1954">1954</span>
<span id="1955">1955</span>
<span id="1956">1956</span>
<span id="1957">1957</span>
<span id="1958">1958</span>
<span id="1959">1959</span>
<span id="1960">1960</span>
<span id="1961">1961</span>
<span id="1962">1962</span>
<span id="1963">1963</span>
<span id="1964">1964</span>
<span id="1965">1965</span>
<span id="1966">1966</span>
<span id="1967">1967</span>
<span id="1968">1968</span>
<span id="1969">1969</span>
<span id="1970">1970</span>
<span id="1971">1971</span>
<span id="1972">1972</span>
<span id="1973">1973</span>
<span id="1974">1974</span>
<span id="1975">1975</span>
<span id="1976">1976</span>
<span id="1977">1977</span>
<span id="1978">1978</span>
<span id="1979">1979</span>
<span id="1980">1980</span>
<span id="1981">1981</span>
<span id="1982">1982</span>
<span id="1983">1983</span>
<span id="1984">1984</span>
<span id="1985">1985</span>
<span id="1986">1986</span>
<span id="1987">1987</span>
<span id="1988">1988</span>
<span id="1989">1989</span>
<span id="1990">1990</span>
<span id="1991">1991</span>
<span id="1992">1992</span>
<span id="1993">1993</span>
<span id="1994">1994</span>
<span id="1995">1995</span>
<span id="1996">1996</span>
<span id="1997">1997</span>
<span id="1998">1998</span>
<span id="1999">1999</span>
<span id="2000">2000</span>
<span id="2001">2001</span>
<span id="2002">2002</span>
<span id="2003">2003</span>
<span id="2004">2004</span>
<span id="2005">2005</span>
<span id="2006">2006</span>
<span id="2007">2007</span>
<span id="2008">2008</span>
<span id="2009">2009</span>
<span id="2010">2010</span>
<span id="2011">2011</span>
<span id="2012">2012</span>
<span id="2013">2013</span>
<span id="2014">2014</span>
<span id="2015">2015</span>
<span id="2016">2016</span>
<span id="2017">2017</span>
<span id="2018">2018</span>
<span id="2019">2019</span>
<span id="2020">2020</span>
<span id="2021">2021</span>
<span id="2022">2022</span>
<span id="2023">2023</span>
<span id="2024">2024</span>
<span id="2025">2025</span>
<span id="2026">2026</span>
<span id="2027">2027</span>
<span id="2028">2028</span>
<span id="2029">2029</span>
<span id="2030">2030</span>
<span id="2031">2031</span>
<span id="2032">2032</span>
<span id="2033">2033</span>
<span id="2034">2034</span>
<span id="2035">2035</span>
<span id="2036">2036</span>
<span id="2037">2037</span>
<span id="2038">2038</span>
<span id="2039">2039</span>
<span id="2040">2040</span>
<span id="2041">2041</span>
<span id="2042">2042</span>
<span id="2043">2043</span>
<span id="2044">2044</span>
<span id="2045">2045</span>
<span id="2046">2046</span>
<span id="2047">2047</span>
<span id="2048">2048</span>
<span id="2049">2049</span>
<span id="2050">2050</span>
<span id="2051">2051</span>
<span id="2052">2052</span>
<span id="2053">2053</span>
<span id="2054">2054</span>
<span id="2055">2055</span>
<span id="2056">2056</span>
<span id="2057">2057</span>
<span id="2058">2058</span>
<span id="2059">2059</span>
<span id="2060">2060</span>
<span id="2061">2061</span>
<span id="2062">2062</span>
<span id="2063">2063</span>
<span id="2064">2064</span>
<span id="2065">2065</span>
<span id="2066">2066</span>
<span id="2067">2067</span>
<span id="2068">2068</span>
<span id="2069">2069</span>
<span id="2070">2070</span>
<span id="2071">2071</span>
<span id="2072">2072</span>
<span id="2073">2073</span>
<span id="2074">2074</span>
<span id="2075">2075</span>
<span id="2076">2076</span>
<span id="2077">2077</span>
<span id="2078">2078</span>
<span id="2079">2079</span>
<span id="2080">2080</span>
<span id="2081">2081</span>
<span id="2082">2082</span>
<span id="2083">2083</span>
<span id="2084">2084</span>
<span id="2085">2085</span>
<span id="2086">2086</span>
<span id="2087">2087</span>
<span id="2088">2088</span>
<span id="2089">2089</span>
<span id="2090">2090</span>
<span id="2091">2091</span>
<span id="2092">2092</span>
<span id="2093">2093</span>
<span id="2094">2094</span>
<span id="2095">2095</span>
<span id="2096">2096</span>
<span id="2097">2097</span>
<span id="2098">2098</span>
<span id="2099">2099</span>
<span id="2100">2100</span>
<span id="2101">2101</span>
<span id="2102">2102</span>
<span id="2103">2103</span>
<span id="2104">2104</span>
<span id="2105">2105</span>
<span id="2106">2106</span>
<span id="2107">2107</span>
<span id="2108">2108</span>
<span id="2109">2109</span>
<span id="2110">2110</span>
<span id="2111">2111</span>
<span id="2112">2112</span>
<span id="2113">2113</span>
<span id="2114">2114</span>
<span id="2115">2115</span>
<span id="2116">2116</span>
<span id="2117">2117</span>
<span id="2118">2118</span>
<span id="2119">2119</span>
<span id="2120">2120</span>
<span id="2121">2121</span>
<span id="2122">2122</span>
<span id="2123">2123</span>
<span id="2124">2124</span>
<span id="2125">2125</span>
<span id="2126">2126</span>
<span id="2127">2127</span>
<span id="2128">2128</span>
<span id="2129">2129</span>
<span id="2130">2130</span>
<span id="2131">2131</span>
<span id="2132">2132</span>
<span id="2133">2133</span>
<span id="2134">2134</span>
<span id="2135">2135</span>
<span id="2136">2136</span>
<span id="2137">2137</span>
<span id="2138">2138</span>
<span id="2139">2139</span>
<span id="2140">2140</span>
<span id="2141">2141</span>
<span id="2142">2142</span>
<span id="2143">2143</span>
<span id="2144">2144</span>
<span id="2145">2145</span>
<span id="2146">2146</span>
<span id="2147">2147</span>
<span id="2148">2148</span>
<span id="2149">2149</span>
<span id="2150">2150</span>
<span id="2151">2151</span>
<span id="2152">2152</span>
<span id="2153">2153</span>
<span id="2154">2154</span>
<span id="2155">2155</span>
<span id="2156">2156</span>
<span id="2157">2157</span>
<span id="2158">2158</span>
<span id="2159">2159</span>
<span id="2160">2160</span>
<span id="2161">2161</span>
<span id="2162">2162</span>
<span id="2163">2163</span>
<span id="2164">2164</span>
<span id="2165">2165</span>
<span id="2166">2166</span>
<span id="2167">2167</span>
<span id="2168">2168</span>
<span id="2169">2169</span>
<span id="2170">2170</span>
<span id="2171">2171</span>
<span id="2172">2172</span>
<span id="2173">2173</span>
<span id="2174">2174</span>
<span id="2175">2175</span>
<span id="2176">2176</span>
<span id="2177">2177</span>
<span id="2178">2178</span>
<span id="2179">2179</span>
<span id="2180">2180</span>
<span id="2181">2181</span>
<span id="2182">2182</span>
<span id="2183">2183</span>
<span id="2184">2184</span>
<span id="2185">2185</span>
<span id="2186">2186</span>
<span id="2187">2187</span>
<span id="2188">2188</span>
<span id="2189">2189</span>
<span id="2190">2190</span>
<span id="2191">2191</span>
<span id="2192">2192</span>
<span id="2193">2193</span>
<span id="2194">2194</span>
<span id="2195">2195</span>
<span id="2196">2196</span>
<span id="2197">2197</span>
<span id="2198">2198</span>
<span id="2199">2199</span>
<span id="2200">2200</span>
<span id="2201">2201</span>
<span id="2202">2202</span>
<span id="2203">2203</span>
<span id="2204">2204</span>
<span id="2205">2205</span>
<span id="2206">2206</span>
<span id="2207">2207</span>
<span id="2208">2208</span>
<span id="2209">2209</span>
<span id="2210">2210</span>
<span id="2211">2211</span>
<span id="2212">2212</span>
<span id="2213">2213</span>
<span id="2214">2214</span>
<span id="2215">2215</span>
<span id="2216">2216</span>
<span id="2217">2217</span>
<span id="2218">2218</span>
<span id="2219">2219</span>
<span id="2220">2220</span>
<span id="2221">2221</span>
<span id="2222">2222</span>
<span id="2223">2223</span>
<span id="2224">2224</span>
<span id="2225">2225</span>
<span id="2226">2226</span>
<span id="2227">2227</span>
<span id="2228">2228</span>
<span id="2229">2229</span>
<span id="2230">2230</span>
<span id="2231">2231</span>
<span id="2232">2232</span>
<span id="2233">2233</span>
<span id="2234">2234</span>
<span id="2235">2235</span>
<span id="2236">2236</span>
<span id="2237">2237</span>
<span id="2238">2238</span>
<span id="2239">2239</span>
<span id="2240">2240</span>
<span id="2241">2241</span>
<span id="2242">2242</span>
<span id="2243">2243</span>
<span id="2244">2244</span>
<span id="2245">2245</span>
<span id="2246">2246</span>
<span id="2247">2247</span>
<span id="2248">2248</span>
<span id="2249">2249</span>
<span id="2250">2250</span>
<span id="2251">2251</span>
<span id="2252">2252</span>
<span id="2253">2253</span>
<span id="2254">2254</span>
<span id="2255">2255</span>
<span id="2256">2256</span>
<span id="2257">2257</span>
<span id="2258">2258</span>
<span id="2259">2259</span>
<span id="2260">2260</span>
<span id="2261">2261</span>
<span id="2262">2262</span>
<span id="2263">2263</span>
<span id="2264">2264</span>
<span id="2265">2265</span>
<span id="2266">2266</span>
<span id="2267">2267</span>
<span id="2268">2268</span>
<span id="2269">2269</span>
<span id="2270">2270</span>
<span id="2271">2271</span>
<span id="2272">2272</span>
<span id="2273">2273</span>
<span id="2274">2274</span>
<span id="2275">2275</span>
<span id="2276">2276</span>
<span id="2277">2277</span>
<span id="2278">2278</span>
<span id="2279">2279</span>
<span id="2280">2280</span>
<span id="2281">2281</span>
<span id="2282">2282</span>
<span id="2283">2283</span>
<span id="2284">2284</span>
<span id="2285">2285</span>
<span id="2286">2286</span>
<span id="2287">2287</span>
<span id="2288">2288</span>
<span id="2289">2289</span>
<span id="2290">2290</span>
<span id="2291">2291</span>
<span id="2292">2292</span>
<span id="2293">2293</span>
<span id="2294">2294</span>
<span id="2295">2295</span>
<span id="2296">2296</span>
<span id="2297">2297</span>
<span id="2298">2298</span>
<span id="2299">2299</span>
<span id="2300">2300</span>
<span id="2301">2301</span>
<span id="2302">2302</span>
<span id="2303">2303</span>
<span id="2304">2304</span>
<span id="2305">2305</span>
<span id="2306">2306</span>
<span id="2307">2307</span>
<span id="2308">2308</span>
<span id="2309">2309</span>
<span id="2310">2310</span>
<span id="2311">2311</span>
<span id="2312">2312</span>
<span id="2313">2313</span>
<span id="2314">2314</span>
<span id="2315">2315</span>
<span id="2316">2316</span>
<span id="2317">2317</span>
<span id="2318">2318</span>
<span id="2319">2319</span>
<span id="2320">2320</span>
<span id="2321">2321</span>
<span id="2322">2322</span>
<span id="2323">2323</span>
<span id="2324">2324</span>
<span id="2325">2325</span>
<span id="2326">2326</span>
<span id="2327">2327</span>
<span id="2328">2328</span>
<span id="2329">2329</span>
<span id="2330">2330</span>
<span id="2331">2331</span>
<span id="2332">2332</span>
<span id="2333">2333</span>
<span id="2334">2334</span>
<span id="2335">2335</span>
<span id="2336">2336</span>
<span id="2337">2337</span>
<span id="2338">2338</span>
<span id="2339">2339</span>
<span id="2340">2340</span>
<span id="2341">2341</span>
<span id="2342">2342</span>
<span id="2343">2343</span>
<span id="2344">2344</span>
<span id="2345">2345</span>
<span id="2346">2346</span>
<span id="2347">2347</span>
<span id="2348">2348</span>
<span id="2349">2349</span>
<span id="2350">2350</span>
<span id="2351">2351</span>
<span id="2352">2352</span>
<span id="2353">2353</span>
<span id="2354">2354</span>
<span id="2355">2355</span>
<span id="2356">2356</span>
<span id="2357">2357</span>
<span id="2358">2358</span>
<span id="2359">2359</span>
<span id="2360">2360</span>
<span id="2361">2361</span>
<span id="2362">2362</span>
<span id="2363">2363</span>
<span id="2364">2364</span>
<span id="2365">2365</span>
<span id="2366">2366</span>
<span id="2367">2367</span>
<span id="2368">2368</span>
<span id="2369">2369</span>
<span id="2370">2370</span>
<span id="2371">2371</span>
<span id="2372">2372</span>
<span id="2373">2373</span>
<span id="2374">2374</span>
<span id="2375">2375</span>
<span id="2376">2376</span>
<span id="2377">2377</span>
<span id="2378">2378</span>
<span id="2379">2379</span>
<span id="2380">2380</span>
<span id="2381">2381</span>
<span id="2382">2382</span>
<span id="2383">2383</span>
<span id="2384">2384</span>
<span id="2385">2385</span>
<span id="2386">2386</span>
<span id="2387">2387</span>
<span id="2388">2388</span>
<span id="2389">2389</span>
<span id="2390">2390</span>
<span id="2391">2391</span>
<span id="2392">2392</span>
<span id="2393">2393</span>
<span id="2394">2394</span>
<span id="2395">2395</span>
<span id="2396">2396</span>
<span id="2397">2397</span>
<span id="2398">2398</span>
<span id="2399">2399</span>
<span id="2400">2400</span>
<span id="2401">2401</span>
<span id="2402">2402</span>
<span id="2403">2403</span>
<span id="2404">2404</span>
<span id="2405">2405</span>
<span id="2406">2406</span>
<span id="2407">2407</span>
<span id="2408">2408</span>
<span id="2409">2409</span>
<span id="2410">2410</span>
<span id="2411">2411</span>
<span id="2412">2412</span>
<span id="2413">2413</span>
<span id="2414">2414</span>
<span id="2415">2415</span>
<span id="2416">2416</span>
<span id="2417">2417</span>
<span id="2418">2418</span>
<span id="2419">2419</span>
<span id="2420">2420</span>
<span id="2421">2421</span>
<span id="2422">2422</span>
<span id="2423">2423</span>
<span id="2424">2424</span>
<span id="2425">2425</span>
<span id="2426">2426</span>
<span id="2427">2427</span>
<span id="2428">2428</span>
<span id="2429">2429</span>
<span id="2430">2430</span>
<span id="2431">2431</span>
<span id="2432">2432</span>
<span id="2433">2433</span>
<span id="2434">2434</span>
<span id="2435">2435</span>
<span id="2436">2436</span>
<span id="2437">2437</span>
<span id="2438">2438</span>
<span id="2439">2439</span>
<span id="2440">2440</span>
<span id="2441">2441</span>
<span id="2442">2442</span>
<span id="2443">2443</span>
<span id="2444">2444</span>
<span id="2445">2445</span>
<span id="2446">2446</span>
<span id="2447">2447</span>
<span id="2448">2448</span>
<span id="2449">2449</span>
<span id="2450">2450</span>
<span id="2451">2451</span>
<span id="2452">2452</span>
<span id="2453">2453</span>
<span id="2454">2454</span>
<span id="2455">2455</span>
<span id="2456">2456</span>
<span id="2457">2457</span>
<span id="2458">2458</span>
<span id="2459">2459</span>
<span id="2460">2460</span>
<span id="2461">2461</span>
<span id="2462">2462</span>
<span id="2463">2463</span>
<span id="2464">2464</span>
<span id="2465">2465</span>
<span id="2466">2466</span>
<span id="2467">2467</span>
<span id="2468">2468</span>
<span id="2469">2469</span>
<span id="2470">2470</span>
<span id="2471">2471</span>
<span id="2472">2472</span>
<span id="2473">2473</span>
<span id="2474">2474</span>
<span id="2475">2475</span>
<span id="2476">2476</span>
<span id="2477">2477</span>
<span id="2478">2478</span>
<span id="2479">2479</span>
<span id="2480">2480</span>
<span id="2481">2481</span>
<span id="2482">2482</span>
<span id="2483">2483</span>
<span id="2484">2484</span>
<span id="2485">2485</span>
<span id="2486">2486</span>
<span id="2487">2487</span>
<span id="2488">2488</span>
<span id="2489">2489</span>
<span id="2490">2490</span>
<span id="2491">2491</span>
<span id="2492">2492</span>
<span id="2493">2493</span>
<span id="2494">2494</span>
<span id="2495">2495</span>
<span id="2496">2496</span>
<span id="2497">2497</span>
<span id="2498">2498</span>
<span id="2499">2499</span>
<span id="2500">2500</span>
<span id="2501">2501</span>
<span id="2502">2502</span>
<span id="2503">2503</span>
<span id="2504">2504</span>
<span id="2505">2505</span>
<span id="2506">2506</span>
<span id="2507">2507</span>
<span id="2508">2508</span>
<span id="2509">2509</span>
<span id="2510">2510</span>
<span id="2511">2511</span>
<span id="2512">2512</span>
<span id="2513">2513</span>
<span id="2514">2514</span>
<span id="2515">2515</span>
<span id="2516">2516</span>
<span id="2517">2517</span>
<span id="2518">2518</span>
<span id="2519">2519</span>
<span id="2520">2520</span>
<span id="2521">2521</span>
<span id="2522">2522</span>
<span id="2523">2523</span>
<span id="2524">2524</span>
<span id="2525">2525</span>
<span id="2526">2526</span>
<span id="2527">2527</span>
<span id="2528">2528</span>
<span id="2529">2529</span>
<span id="2530">2530</span>
<span id="2531">2531</span>
<span id="2532">2532</span>
<span id="2533">2533</span>
<span id="2534">2534</span>
<span id="2535">2535</span>
<span id="2536">2536</span>
<span id="2537">2537</span>
<span id="2538">2538</span>
<span id="2539">2539</span>
<span id="2540">2540</span>
<span id="2541">2541</span>
<span id="2542">2542</span>
<span id="2543">2543</span>
<span id="2544">2544</span>
<span id="2545">2545</span>
<span id="2546">2546</span>
<span id="2547">2547</span>
<span id="2548">2548</span>
<span id="2549">2549</span>
<span id="2550">2550</span>
<span id="2551">2551</span>
<span id="2552">2552</span>
<span id="2553">2553</span>
<span id="2554">2554</span>
<span id="2555">2555</span>
<span id="2556">2556</span>
<span id="2557">2557</span>
<span id="2558">2558</span>
<span id="2559">2559</span>
<span id="2560">2560</span>
<span id="2561">2561</span>
<span id="2562">2562</span>
<span id="2563">2563</span>
<span id="2564">2564</span>
<span id="2565">2565</span>
<span id="2566">2566</span>
<span id="2567">2567</span>
<span id="2568">2568</span>
<span id="2569">2569</span>
<span id="2570">2570</span>
<span id="2571">2571</span>
<span id="2572">2572</span>
<span id="2573">2573</span>
<span id="2574">2574</span>
<span id="2575">2575</span>
<span id="2576">2576</span>
<span id="2577">2577</span>
<span id="2578">2578</span>
<span id="2579">2579</span>
<span id="2580">2580</span>
<span id="2581">2581</span>
<span id="2582">2582</span>
<span id="2583">2583</span>
<span id="2584">2584</span>
<span id="2585">2585</span>
<span id="2586">2586</span>
<span id="2587">2587</span>
<span id="2588">2588</span>
<span id="2589">2589</span>
<span id="2590">2590</span>
<span id="2591">2591</span>
<span id="2592">2592</span>
<span id="2593">2593</span>
<span id="2594">2594</span>
<span id="2595">2595</span>
<span id="2596">2596</span>
<span id="2597">2597</span>
<span id="2598">2598</span>
<span id="2599">2599</span>
<span id="2600">2600</span>
<span id="2601">2601</span>
<span id="2602">2602</span>
<span id="2603">2603</span>
<span id="2604">2604</span>
<span id="2605">2605</span>
<span id="2606">2606</span>
<span id="2607">2607</span>
<span id="2608">2608</span>
<span id="2609">2609</span>
<span id="2610">2610</span>
<span id="2611">2611</span>
<span id="2612">2612</span>
<span id="2613">2613</span>
<span id="2614">2614</span>
<span id="2615">2615</span>
<span id="2616">2616</span>
<span id="2617">2617</span>
<span id="2618">2618</span>
<span id="2619">2619</span>
<span id="2620">2620</span>
<span id="2621">2621</span>
<span id="2622">2622</span>
<span id="2623">2623</span>
<span id="2624">2624</span>
<span id="2625">2625</span>
<span id="2626">2626</span>
<span id="2627">2627</span>
<span id="2628">2628</span>
<span id="2629">2629</span>
<span id="2630">2630</span>
<span id="2631">2631</span>
<span id="2632">2632</span>
<span id="2633">2633</span>
<span id="2634">2634</span>
<span id="2635">2635</span>
<span id="2636">2636</span>
<span id="2637">2637</span>
<span id="2638">2638</span>
<span id="2639">2639</span>
<span id="2640">2640</span>
<span id="2641">2641</span>
<span id="2642">2642</span>
<span id="2643">2643</span>
<span id="2644">2644</span>
<span id="2645">2645</span>
<span id="2646">2646</span>
<span id="2647">2647</span>
<span id="2648">2648</span>
<span id="2649">2649</span>
<span id="2650">2650</span>
<span id="2651">2651</span>
<span id="2652">2652</span>
<span id="2653">2653</span>
<span id="2654">2654</span>
<span id="2655">2655</span>
<span id="2656">2656</span>
<span id="2657">2657</span>
<span id="2658">2658</span>
<span id="2659">2659</span>
<span id="2660">2660</span>
<span id="2661">2661</span>
<span id="2662">2662</span>
<span id="2663">2663</span>
<span id="2664">2664</span>
<span id="2665">2665</span>
<span id="2666">2666</span>
<span id="2667">2667</span>
<span id="2668">2668</span>
<span id="2669">2669</span>
<span id="2670">2670</span>
<span id="2671">2671</span>
<span id="2672">2672</span>
<span id="2673">2673</span>
<span id="2674">2674</span>
<span id="2675">2675</span>
<span id="2676">2676</span>
<span id="2677">2677</span>
<span id="2678">2678</span>
<span id="2679">2679</span>
<span id="2680">2680</span>
<span id="2681">2681</span>
<span id="2682">2682</span>
<span id="2683">2683</span>
<span id="2684">2684</span>
<span id="2685">2685</span>
<span id="2686">2686</span>
<span id="2687">2687</span>
<span id="2688">2688</span>
<span id="2689">2689</span>
<span id="2690">2690</span>
<span id="2691">2691</span>
<span id="2692">2692</span>
<span id="2693">2693</span>
<span id="2694">2694</span>
<span id="2695">2695</span>
<span id="2696">2696</span>
<span id="2697">2697</span>
<span id="2698">2698</span>
<span id="2699">2699</span>
<span id="2700">2700</span>
<span id="2701">2701</span>
<span id="2702">2702</span>
<span id="2703">2703</span>
<span id="2704">2704</span>
<span id="2705">2705</span>
<span id="2706">2706</span>
<span id="2707">2707</span>
<span id="2708">2708</span>
<span id="2709">2709</span>
<span id="2710">2710</span>
<span id="2711">2711</span>
<span id="2712">2712</span>
<span id="2713">2713</span>
<span id="2714">2714</span>
<span id="2715">2715</span>
<span id="2716">2716</span>
<span id="2717">2717</span>
<span id="2718">2718</span>
<span id="2719">2719</span>
<span id="2720">2720</span>
<span id="2721">2721</span>
<span id="2722">2722</span>
<span id="2723">2723</span>
<span id="2724">2724</span>
<span id="2725">2725</span>
<span id="2726">2726</span>
<span id="2727">2727</span>
<span id="2728">2728</span>
<span id="2729">2729</span>
<span id="2730">2730</span>
<span id="2731">2731</span>
<span id="2732">2732</span>
<span id="2733">2733</span>
<span id="2734">2734</span>
<span id="2735">2735</span>
<span id="2736">2736</span>
<span id="2737">2737</span>
<span id="2738">2738</span>
<span id="2739">2739</span>
<span id="2740">2740</span>
<span id="2741">2741</span>
<span id="2742">2742</span>
<span id="2743">2743</span>
<span id="2744">2744</span>
<span id="2745">2745</span>
<span id="2746">2746</span>
<span id="2747">2747</span>
<span id="2748">2748</span>
<span id="2749">2749</span>
<span id="2750">2750</span>
<span id="2751">2751</span>
<span id="2752">2752</span>
<span id="2753">2753</span>
<span id="2754">2754</span>
<span id="2755">2755</span>
<span id="2756">2756</span>
<span id="2757">2757</span>
<span id="2758">2758</span>
<span id="2759">2759</span>
<span id="2760">2760</span>
<span id="2761">2761</span>
<span id="2762">2762</span>
<span id="2763">2763</span>
<span id="2764">2764</span>
<span id="2765">2765</span>
<span id="2766">2766</span>
<span id="2767">2767</span>
<span id="2768">2768</span>
<span id="2769">2769</span>
<span id="2770">2770</span>
<span id="2771">2771</span>
<span id="2772">2772</span>
<span id="2773">2773</span>
<span id="2774">2774</span>
<span id="2775">2775</span>
<span id="2776">2776</span>
<span id="2777">2777</span>
<span id="2778">2778</span>
<span id="2779">2779</span>
<span id="2780">2780</span>
<span id="2781">2781</span>
<span id="2782">2782</span>
<span id="2783">2783</span>
<span id="2784">2784</span>
<span id="2785">2785</span>
<span id="2786">2786</span>
<span id="2787">2787</span>
<span id="2788">2788</span>
<span id="2789">2789</span>
<span id="2790">2790</span>
<span id="2791">2791</span>
<span id="2792">2792</span>
<span id="2793">2793</span>
<span id="2794">2794</span>
<span id="2795">2795</span>
<span id="2796">2796</span>
<span id="2797">2797</span>
<span id="2798">2798</span>
<span id="2799">2799</span>
<span id="2800">2800</span>
<span id="2801">2801</span>
<span id="2802">2802</span>
<span id="2803">2803</span>
<span id="2804">2804</span>
<span id="2805">2805</span>
<span id="2806">2806</span>
<span id="2807">2807</span>
<span id="2808">2808</span>
<span id="2809">2809</span>
<span id="2810">2810</span>
<span id="2811">2811</span>
<span id="2812">2812</span>
<span id="2813">2813</span>
<span id="2814">2814</span>
<span id="2815">2815</span>
<span id="2816">2816</span>
<span id="2817">2817</span>
<span id="2818">2818</span>
<span id="2819">2819</span>
<span id="2820">2820</span>
<span id="2821">2821</span>
<span id="2822">2822</span>
<span id="2823">2823</span>
<span id="2824">2824</span>
<span id="2825">2825</span>
<span id="2826">2826</span>
<span id="2827">2827</span>
<span id="2828">2828</span>
<span id="2829">2829</span>
<span id="2830">2830</span>
<span id="2831">2831</span>
<span id="2832">2832</span>
<span id="2833">2833</span>
<span id="2834">2834</span>
<span id="2835">2835</span>
<span id="2836">2836</span>
<span id="2837">2837</span>
<span id="2838">2838</span>
<span id="2839">2839</span>
<span id="2840">2840</span>
<span id="2841">2841</span>
<span id="2842">2842</span>
<span id="2843">2843</span>
<span id="2844">2844</span>
<span id="2845">2845</span>
<span id="2846">2846</span>
<span id="2847">2847</span>
<span id="2848">2848</span>
<span id="2849">2849</span>
<span id="2850">2850</span>
<span id="2851">2851</span>
<span id="2852">2852</span>
<span id="2853">2853</span>
<span id="2854">2854</span>
<span id="2855">2855</span>
<span id="2856">2856</span>
<span id="2857">2857</span>
<span id="2858">2858</span>
<span id="2859">2859</span>
<span id="2860">2860</span>
<span id="2861">2861</span>
<span id="2862">2862</span>
<span id="2863">2863</span>
<span id="2864">2864</span>
<span id="2865">2865</span>
<span id="2866">2866</span>
<span id="2867">2867</span>
<span id="2868">2868</span>
<span id="2869">2869</span>
<span id="2870">2870</span>
<span id="2871">2871</span>
<span id="2872">2872</span>
<span id="2873">2873</span>
<span id="2874">2874</span>
<span id="2875">2875</span>
<span id="2876">2876</span>
<span id="2877">2877</span>
<span id="2878">2878</span>
<span id="2879">2879</span>
<span id="2880">2880</span>
<span id="2881">2881</span>
<span id="2882">2882</span>
<span id="2883">2883</span>
<span id="2884">2884</span>
<span id="2885">2885</span>
<span id="2886">2886</span>
<span id="2887">2887</span>
<span id="2888">2888</span>
<span id="2889">2889</span>
<span id="2890">2890</span>
<span id="2891">2891</span>
<span id="2892">2892</span>
<span id="2893">2893</span>
<span id="2894">2894</span>
<span id="2895">2895</span>
<span id="2896">2896</span>
<span id="2897">2897</span>
<span id="2898">2898</span>
<span id="2899">2899</span>
<span id="2900">2900</span>
<span id="2901">2901</span>
<span id="2902">2902</span>
<span id="2903">2903</span>
<span id="2904">2904</span>
<span id="2905">2905</span>
<span id="2906">2906</span>
<span id="2907">2907</span>
<span id="2908">2908</span>
<span id="2909">2909</span>
<span id="2910">2910</span>
<span id="2911">2911</span>
<span id="2912">2912</span>
<span id="2913">2913</span>
<span id="2914">2914</span>
<span id="2915">2915</span>
<span id="2916">2916</span>
<span id="2917">2917</span>
<span id="2918">2918</span>
<span id="2919">2919</span>
<span id="2920">2920</span>
<span id="2921">2921</span>
<span id="2922">2922</span>
<span id="2923">2923</span>
<span id="2924">2924</span>
<span id="2925">2925</span>
<span id="2926">2926</span>
<span id="2927">2927</span>
<span id="2928">2928</span>
<span id="2929">2929</span>
<span id="2930">2930</span>
<span id="2931">2931</span>
<span id="2932">2932</span>
<span id="2933">2933</span>
<span id="2934">2934</span>
<span id="2935">2935</span>
<span id="2936">2936</span>
<span id="2937">2937</span>
<span id="2938">2938</span>
<span id="2939">2939</span>
<span id="2940">2940</span>
<span id="2941">2941</span>
<span id="2942">2942</span>
<span id="2943">2943</span>
<span id="2944">2944</span>
<span id="2945">2945</span>
<span id="2946">2946</span>
<span id="2947">2947</span>
<span id="2948">2948</span>
<span id="2949">2949</span>
<span id="2950">2950</span>
<span id="2951">2951</span>
<span id="2952">2952</span>
<span id="2953">2953</span>
<span id="2954">2954</span>
<span id="2955">2955</span>
<span id="2956">2956</span>
<span id="2957">2957</span>
<span id="2958">2958</span>
<span id="2959">2959</span>
<span id="2960">2960</span>
<span id="2961">2961</span>
<span id="2962">2962</span>
<span id="2963">2963</span>
<span id="2964">2964</span>
<span id="2965">2965</span>
<span id="2966">2966</span>
<span id="2967">2967</span>
<span id="2968">2968</span>
<span id="2969">2969</span>
<span id="2970">2970</span>
<span id="2971">2971</span>
<span id="2972">2972</span>
<span id="2973">2973</span>
<span id="2974">2974</span>
<span id="2975">2975</span>
<span id="2976">2976</span>
<span id="2977">2977</span>
<span id="2978">2978</span>
<span id="2979">2979</span>
<span id="2980">2980</span>
<span id="2981">2981</span>
<span id="2982">2982</span>
<span id="2983">2983</span>
<span id="2984">2984</span>
<span id="2985">2985</span>
<span id="2986">2986</span>
<span id="2987">2987</span>
<span id="2988">2988</span>
<span id="2989">2989</span>
<span id="2990">2990</span>
<span id="2991">2991</span>
<span id="2992">2992</span>
<span id="2993">2993</span>
<span id="2994">2994</span>
<span id="2995">2995</span>
<span id="2996">2996</span>
<span id="2997">2997</span>
<span id="2998">2998</span>
<span id="2999">2999</span>
<span id="3000">3000</span>
<span id="3001">3001</span>
<span id="3002">3002</span>
<span id="3003">3003</span>
<span id="3004">3004</span>
<span id="3005">3005</span>
<span id="3006">3006</span>
<span id="3007">3007</span>
<span id="3008">3008</span>
<span id="3009">3009</span>
<span id="3010">3010</span>
<span id="3011">3011</span>
<span id="3012">3012</span>
<span id="3013">3013</span>
<span id="3014">3014</span>
<span id="3015">3015</span>
<span id="3016">3016</span>
<span id="3017">3017</span>
<span id="3018">3018</span>
<span id="3019">3019</span>
<span id="3020">3020</span>
<span id="3021">3021</span>
<span id="3022">3022</span>
<span id="3023">3023</span>
<span id="3024">3024</span>
<span id="3025">3025</span>
<span id="3026">3026</span>
<span id="3027">3027</span>
<span id="3028">3028</span>
<span id="3029">3029</span>
<span id="3030">3030</span>
<span id="3031">3031</span>
<span id="3032">3032</span>
<span id="3033">3033</span>
<span id="3034">3034</span>
<span id="3035">3035</span>
<span id="3036">3036</span>
<span id="3037">3037</span>
<span id="3038">3038</span>
<span id="3039">3039</span>
<span id="3040">3040</span>
<span id="3041">3041</span>
<span id="3042">3042</span>
<span id="3043">3043</span>
<span id="3044">3044</span>
<span id="3045">3045</span>
<span id="3046">3046</span>
<span id="3047">3047</span>
<span id="3048">3048</span>
<span id="3049">3049</span>
<span id="3050">3050</span>
<span id="3051">3051</span>
<span id="3052">3052</span>
<span id="3053">3053</span>
<span id="3054">3054</span>
<span id="3055">3055</span>
<span id="3056">3056</span>
<span id="3057">3057</span>
<span id="3058">3058</span>
<span id="3059">3059</span>
<span id="3060">3060</span>
<span id="3061">3061</span>
<span id="3062">3062</span>
<span id="3063">3063</span>
<span id="3064">3064</span>
<span id="3065">3065</span>
<span id="3066">3066</span>
<span id="3067">3067</span>
<span id="3068">3068</span>
<span id="3069">3069</span>
<span id="3070">3070</span>
<span id="3071">3071</span>
<span id="3072">3072</span>
<span id="3073">3073</span>
<span id="3074">3074</span>
<span id="3075">3075</span>
<span id="3076">3076</span>
<span id="3077">3077</span>
<span id="3078">3078</span>
<span id="3079">3079</span>
<span id="3080">3080</span>
<span id="3081">3081</span>
<span id="3082">3082</span>
<span id="3083">3083</span>
<span id="3084">3084</span>
<span id="3085">3085</span>
<span id="3086">3086</span>
<span id="3087">3087</span>
<span id="3088">3088</span>
<span id="3089">3089</span>
<span id="3090">3090</span>
<span id="3091">3091</span>
<span id="3092">3092</span>
<span id="3093">3093</span>
<span id="3094">3094</span>
<span id="3095">3095</span>
<span id="3096">3096</span>
<span id="3097">3097</span>
<span id="3098">3098</span>
<span id="3099">3099</span>
<span id="3100">3100</span>
<span id="3101">3101</span>
<span id="3102">3102</span>
<span id="3103">3103</span>
<span id="3104">3104</span>
<span id="3105">3105</span>
<span id="3106">3106</span>
<span id="3107">3107</span>
<span id="3108">3108</span>
<span id="3109">3109</span>
<span id="3110">3110</span>
<span id="3111">3111</span>
<span id="3112">3112</span>
<span id="3113">3113</span>
<span id="3114">3114</span>
<span id="3115">3115</span>
<span id="3116">3116</span>
<span id="3117">3117</span>
<span id="3118">3118</span>
<span id="3119">3119</span>
<span id="3120">3120</span>
<span id="3121">3121</span>
<span id="3122">3122</span>
<span id="3123">3123</span>
<span id="3124">3124</span>
<span id="3125">3125</span>
<span id="3126">3126</span>
<span id="3127">3127</span>
<span id="3128">3128</span>
<span id="3129">3129</span>
<span id="3130">3130</span>
<span id="3131">3131</span>
<span id="3132">3132</span>
<span id="3133">3133</span>
<span id="3134">3134</span>
<span id="3135">3135</span>
<span id="3136">3136</span>
<span id="3137">3137</span>
<span id="3138">3138</span>
<span id="3139">3139</span>
<span id="3140">3140</span>
<span id="3141">3141</span>
<span id="3142">3142</span>
<span id="3143">3143</span>
<span id="3144">3144</span>
<span id="3145">3145</span>
<span id="3146">3146</span>
<span id="3147">3147</span>
<span id="3148">3148</span>
<span id="3149">3149</span>
<span id="3150">3150</span>
<span id="3151">3151</span>
<span id="3152">3152</span>
<span id="3153">3153</span>
<span id="3154">3154</span>
<span id="3155">3155</span>
<span id="3156">3156</span>
<span id="3157">3157</span>
<span id="3158">3158</span>
<span id="3159">3159</span>
<span id="3160">3160</span>
<span id="3161">3161</span>
<span id="3162">3162</span>
<span id="3163">3163</span>
<span id="3164">3164</span>
<span id="3165">3165</span>
<span id="3166">3166</span>
<span id="3167">3167</span>
<span id="3168">3168</span>
<span id="3169">3169</span>
<span id="3170">3170</span>
<span id="3171">3171</span>
<span id="3172">3172</span>
<span id="3173">3173</span>
<span id="3174">3174</span>
<span id="3175">3175</span>
<span id="3176">3176</span>
<span id="3177">3177</span>
<span id="3178">3178</span>
<span id="3179">3179</span>
<span id="3180">3180</span>
<span id="3181">3181</span>
<span id="3182">3182</span>
<span id="3183">3183</span>
<span id="3184">3184</span>
<span id="3185">3185</span>
<span id="3186">3186</span>
<span id="3187">3187</span>
<span id="3188">3188</span>
<span id="3189">3189</span>
<span id="3190">3190</span>
<span id="3191">3191</span>
<span id="3192">3192</span>
<span id="3193">3193</span>
<span id="3194">3194</span>
<span id="3195">3195</span>
<span id="3196">3196</span>
<span id="3197">3197</span>
<span id="3198">3198</span>
<span id="3199">3199</span>
<span id="3200">3200</span>
<span id="3201">3201</span>
<span id="3202">3202</span>
<span id="3203">3203</span>
<span id="3204">3204</span>
<span id="3205">3205</span>
<span id="3206">3206</span>
<span id="3207">3207</span>
<span id="3208">3208</span>
<span id="3209">3209</span>
<span id="3210">3210</span>
<span id="3211">3211</span>
<span id="3212">3212</span>
<span id="3213">3213</span>
<span id="3214">3214</span>
<span id="3215">3215</span>
<span id="3216">3216</span>
<span id="3217">3217</span>
<span id="3218">3218</span>
<span id="3219">3219</span>
<span id="3220">3220</span>
<span id="3221">3221</span>
<span id="3222">3222</span>
<span id="3223">3223</span>
<span id="3224">3224</span>
<span id="3225">3225</span>
<span id="3226">3226</span>
<span id="3227">3227</span>
<span id="3228">3228</span>
<span id="3229">3229</span>
<span id="3230">3230</span>
<span id="3231">3231</span>
<span id="3232">3232</span>
<span id="3233">3233</span>
<span id="3234">3234</span>
<span id="3235">3235</span>
<span id="3236">3236</span>
<span id="3237">3237</span>
<span id="3238">3238</span>
<span id="3239">3239</span>
<span id="3240">3240</span>
<span id="3241">3241</span>
<span id="3242">3242</span>
<span id="3243">3243</span>
<span id="3244">3244</span>
<span id="3245">3245</span>
<span id="3246">3246</span>
<span id="3247">3247</span>
<span id="3248">3248</span>
<span id="3249">3249</span>
<span id="3250">3250</span>
<span id="3251">3251</span>
<span id="3252">3252</span>
<span id="3253">3253</span>
<span id="3254">3254</span>
<span id="3255">3255</span>
<span id="3256">3256</span>
<span id="3257">3257</span>
<span id="3258">3258</span>
<span id="3259">3259</span>
<span id="3260">3260</span>
<span id="3261">3261</span>
<span id="3262">3262</span>
<span id="3263">3263</span>
<span id="3264">3264</span>
<span id="3265">3265</span>
<span id="3266">3266</span>
<span id="3267">3267</span>
<span id="3268">3268</span>
<span id="3269">3269</span>
<span id="3270">3270</span>
<span id="3271">3271</span>
<span id="3272">3272</span>
<span id="3273">3273</span>
<span id="3274">3274</span>
<span id="3275">3275</span>
<span id="3276">3276</span>
<span id="3277">3277</span>
<span id="3278">3278</span>
<span id="3279">3279</span>
<span id="3280">3280</span>
<span id="3281">3281</span>
<span id="3282">3282</span>
<span id="3283">3283</span>
<span id="3284">3284</span>
<span id="3285">3285</span>
<span id="3286">3286</span>
<span id="3287">3287</span>
<span id="3288">3288</span>
<span id="3289">3289</span>
<span id="3290">3290</span>
<span id="3291">3291</span>
<span id="3292">3292</span>
<span id="3293">3293</span>
<span id="3294">3294</span>
<span id="3295">3295</span>
<span id="3296">3296</span>
<span id="3297">3297</span>
<span id="3298">3298</span>
<span id="3299">3299</span>
<span id="3300">3300</span>
<span id="3301">3301</span>
<span id="3302">3302</span>
<span id="3303">3303</span>
<span id="3304">3304</span>
<span id="3305">3305</span>
<span id="3306">3306</span>
<span id="3307">3307</span>
<span id="3308">3308</span>
<span id="3309">3309</span>
<span id="3310">3310</span>
<span id="3311">3311</span>
<span id="3312">3312</span>
<span id="3313">3313</span>
<span id="3314">3314</span>
<span id="3315">3315</span>
<span id="3316">3316</span>
<span id="3317">3317</span>
<span id="3318">3318</span>
<span id="3319">3319</span>
<span id="3320">3320</span>
<span id="3321">3321</span>
<span id="3322">3322</span>
<span id="3323">3323</span>
<span id="3324">3324</span>
<span id="3325">3325</span>
<span id="3326">3326</span>
<span id="3327">3327</span>
<span id="3328">3328</span>
<span id="3329">3329</span>
<span id="3330">3330</span>
<span id="3331">3331</span>
<span id="3332">3332</span>
<span id="3333">3333</span>
<span id="3334">3334</span>
<span id="3335">3335</span>
<span id="3336">3336</span>
<span id="3337">3337</span>
<span id="3338">3338</span>
<span id="3339">3339</span>
<span id="3340">3340</span>
<span id="3341">3341</span>
<span id="3342">3342</span>
<span id="3343">3343</span>
<span id="3344">3344</span>
<span id="3345">3345</span>
<span id="3346">3346</span>
<span id="3347">3347</span>
<span id="3348">3348</span>
<span id="3349">3349</span>
<span id="3350">3350</span>
<span id="3351">3351</span>
<span id="3352">3352</span>
<span id="3353">3353</span>
<span id="3354">3354</span>
<span id="3355">3355</span>
<span id="3356">3356</span>
<span id="3357">3357</span>
<span id="3358">3358</span>
<span id="3359">3359</span>
<span id="3360">3360</span>
<span id="3361">3361</span>
<span id="3362">3362</span>
<span id="3363">3363</span>
<span id="3364">3364</span>
<span id="3365">3365</span>
<span id="3366">3366</span>
<span id="3367">3367</span>
<span id="3368">3368</span>
<span id="3369">3369</span>
<span id="3370">3370</span>
<span id="3371">3371</span>
<span id="3372">3372</span>
<span id="3373">3373</span>
<span id="3374">3374</span>
<span id="3375">3375</span>
<span id="3376">3376</span>
<span id="3377">3377</span>
<span id="3378">3378</span>
<span id="3379">3379</span>
<span id="3380">3380</span>
<span id="3381">3381</span>
<span id="3382">3382</span>
<span id="3383">3383</span>
<span id="3384">3384</span>
<span id="3385">3385</span>
<span id="3386">3386</span>
<span id="3387">3387</span>
<span id="3388">3388</span>
<span id="3389">3389</span>
<span id="3390">3390</span>
<span id="3391">3391</span>
<span id="3392">3392</span>
<span id="3393">3393</span>
<span id="3394">3394</span>
<span id="3395">3395</span>
<span id="3396">3396</span>
<span id="3397">3397</span>
<span id="3398">3398</span>
<span id="3399">3399</span>
<span id="3400">3400</span>
<span id="3401">3401</span>
<span id="3402">3402</span>
<span id="3403">3403</span>
<span id="3404">3404</span>
<span id="3405">3405</span>
<span id="3406">3406</span>
<span id="3407">3407</span>
<span id="3408">3408</span>
<span id="3409">3409</span>
<span id="3410">3410</span>
<span id="3411">3411</span>
<span id="3412">3412</span>
<span id="3413">3413</span>
<span id="3414">3414</span>
<span id="3415">3415</span>
<span id="3416">3416</span>
<span id="3417">3417</span>
<span id="3418">3418</span>
<span id="3419">3419</span>
<span id="3420">3420</span>
<span id="3421">3421</span>
<span id="3422">3422</span>
<span id="3423">3423</span>
<span id="3424">3424</span>
<span id="3425">3425</span>
<span id="3426">3426</span>
<span id="3427">3427</span>
<span id="3428">3428</span>
<span id="3429">3429</span>
<span id="3430">3430</span>
<span id="3431">3431</span>
<span id="3432">3432</span>
<span id="3433">3433</span>
<span id="3434">3434</span>
<span id="3435">3435</span>
<span id="3436">3436</span>
<span id="3437">3437</span>
<span id="3438">3438</span>
<span id="3439">3439</span>
<span id="3440">3440</span>
<span id="3441">3441</span>
<span id="3442">3442</span>
<span id="3443">3443</span>
<span id="3444">3444</span>
<span id="3445">3445</span>
<span id="3446">3446</span>
<span id="3447">3447</span>
<span id="3448">3448</span>
<span id="3449">3449</span>
<span id="3450">3450</span>
<span id="3451">3451</span>
<span id="3452">3452</span>
<span id="3453">3453</span>
<span id="3454">3454</span>
<span id="3455">3455</span>
<span id="3456">3456</span>
<span id="3457">3457</span>
<span id="3458">3458</span>
<span id="3459">3459</span>
<span id="3460">3460</span>
<span id="3461">3461</span>
<span id="3462">3462</span>
<span id="3463">3463</span>
<span id="3464">3464</span>
<span id="3465">3465</span>
<span id="3466">3466</span>
<span id="3467">3467</span>
<span id="3468">3468</span>
<span id="3469">3469</span>
<span id="3470">3470</span>
<span id="3471">3471</span>
<span id="3472">3472</span>
<span id="3473">3473</span>
<span id="3474">3474</span>
<span id="3475">3475</span>
<span id="3476">3476</span>
<span id="3477">3477</span>
<span id="3478">3478</span>
<span id="3479">3479</span>
<span id="3480">3480</span>
<span id="3481">3481</span>
<span id="3482">3482</span>
<span id="3483">3483</span>
<span id="3484">3484</span>
<span id="3485">3485</span>
<span id="3486">3486</span>
<span id="3487">3487</span>
<span id="3488">3488</span>
<span id="3489">3489</span>
<span id="3490">3490</span>
<span id="3491">3491</span>
<span id="3492">3492</span>
<span id="3493">3493</span>
<span id="3494">3494</span>
<span id="3495">3495</span>
<span id="3496">3496</span>
<span id="3497">3497</span>
<span id="3498">3498</span>
<span id="3499">3499</span>
<span id="3500">3500</span>
<span id="3501">3501</span>
<span id="3502">3502</span>
<span id="3503">3503</span>
<span id="3504">3504</span>
<span id="3505">3505</span>
<span id="3506">3506</span>
<span id="3507">3507</span>
<span id="3508">3508</span>
<span id="3509">3509</span>
<span id="3510">3510</span>
<span id="3511">3511</span>
<span id="3512">3512</span>
<span id="3513">3513</span>
<span id="3514">3514</span>
<span id="3515">3515</span>
<span id="3516">3516</span>
<span id="3517">3517</span>
<span id="3518">3518</span>
<span id="3519">3519</span>
<span id="3520">3520</span>
<span id="3521">3521</span>
<span id="3522">3522</span>
<span id="3523">3523</span>
<span id="3524">3524</span>
<span id="3525">3525</span>
<span id="3526">3526</span>
<span id="3527">3527</span>
<span id="3528">3528</span>
<span id="3529">3529</span>
<span id="3530">3530</span>
<span id="3531">3531</span>
<span id="3532">3532</span>
<span id="3533">3533</span>
<span id="3534">3534</span>
<span id="3535">3535</span>
<span id="3536">3536</span>
<span id="3537">3537</span>
<span id="3538">3538</span>
<span id="3539">3539</span>
<span id="3540">3540</span>
<span id="3541">3541</span>
<span id="3542">3542</span>
<span id="3543">3543</span>
<span id="3544">3544</span>
<span id="3545">3545</span>
<span id="3546">3546</span>
<span id="3547">3547</span>
<span id="3548">3548</span>
<span id="3549">3549</span>
<span id="3550">3550</span>
<span id="3551">3551</span>
<span id="3552">3552</span>
<span id="3553">3553</span>
<span id="3554">3554</span>
<span id="3555">3555</span>
<span id="3556">3556</span>
<span id="3557">3557</span>
<span id="3558">3558</span>
<span id="3559">3559</span>
<span id="3560">3560</span>
<span id="3561">3561</span>
<span id="3562">3562</span>
<span id="3563">3563</span>
<span id="3564">3564</span>
<span id="3565">3565</span>
<span id="3566">3566</span>
<span id="3567">3567</span>
<span id="3568">3568</span>
<span id="3569">3569</span>
<span id="3570">3570</span>
<span id="3571">3571</span>
<span id="3572">3572</span>
<span id="3573">3573</span>
<span id="3574">3574</span>
<span id="3575">3575</span>
<span id="3576">3576</span>
<span id="3577">3577</span>
<span id="3578">3578</span>
<span id="3579">3579</span>
<span id="3580">3580</span>
<span id="3581">3581</span>
<span id="3582">3582</span>
<span id="3583">3583</span>
<span id="3584">3584</span>
<span id="3585">3585</span>
<span id="3586">3586</span>
<span id="3587">3587</span>
<span id="3588">3588</span>
<span id="3589">3589</span>
<span id="3590">3590</span>
<span id="3591">3591</span>
<span id="3592">3592</span>
<span id="3593">3593</span>
<span id="3594">3594</span>
<span id="3595">3595</span>
<span id="3596">3596</span>
<span id="3597">3597</span>
<span id="3598">3598</span>
<span id="3599">3599</span>
<span id="3600">3600</span>
<span id="3601">3601</span>
<span id="3602">3602</span>
<span id="3603">3603</span>
<span id="3604">3604</span>
<span id="3605">3605</span>
<span id="3606">3606</span>
<span id="3607">3607</span>
<span id="3608">3608</span>
<span id="3609">3609</span>
<span id="3610">3610</span>
<span id="3611">3611</span>
<span id="3612">3612</span>
<span id="3613">3613</span>
<span id="3614">3614</span>
<span id="3615">3615</span>
<span id="3616">3616</span>
<span id="3617">3617</span>
<span id="3618">3618</span>
<span id="3619">3619</span>
<span id="3620">3620</span>
<span id="3621">3621</span>
<span id="3622">3622</span>
<span id="3623">3623</span>
<span id="3624">3624</span>
<span id="3625">3625</span>
<span id="3626">3626</span>
<span id="3627">3627</span>
<span id="3628">3628</span>
<span id="3629">3629</span>
<span id="3630">3630</span>
<span id="3631">3631</span>
<span id="3632">3632</span>
<span id="3633">3633</span>
<span id="3634">3634</span>
<span id="3635">3635</span>
<span id="3636">3636</span>
<span id="3637">3637</span>
<span id="3638">3638</span>
<span id="3639">3639</span>
<span id="3640">3640</span>
<span id="3641">3641</span>
<span id="3642">3642</span>
<span id="3643">3643</span>
<span id="3644">3644</span>
<span id="3645">3645</span>
<span id="3646">3646</span>
<span id="3647">3647</span>
<span id="3648">3648</span>
<span id="3649">3649</span>
<span id="3650">3650</span>
<span id="3651">3651</span>
<span id="3652">3652</span>
<span id="3653">3653</span>
<span id="3654">3654</span>
<span id="3655">3655</span>
<span id="3656">3656</span>
<span id="3657">3657</span>
<span id="3658">3658</span>
<span id="3659">3659</span>
<span id="3660">3660</span>
<span id="3661">3661</span>
<span id="3662">3662</span>
<span id="3663">3663</span>
<span id="3664">3664</span>
<span id="3665">3665</span>
<span id="3666">3666</span>
<span id="3667">3667</span>
<span id="3668">3668</span>
<span id="3669">3669</span>
<span id="3670">3670</span>
<span id="3671">3671</span>
<span id="3672">3672</span>
<span id="3673">3673</span>
<span id="3674">3674</span>
<span id="3675">3675</span>
<span id="3676">3676</span>
<span id="3677">3677</span>
<span id="3678">3678</span>
<span id="3679">3679</span>
<span id="3680">3680</span>
<span id="3681">3681</span>
<span id="3682">3682</span>
<span id="3683">3683</span>
<span id="3684">3684</span>
<span id="3685">3685</span>
<span id="3686">3686</span>
<span id="3687">3687</span>
<span id="3688">3688</span>
<span id="3689">3689</span>
<span id="3690">3690</span>
<span id="3691">3691</span>
<span id="3692">3692</span>
<span id="3693">3693</span>
<span id="3694">3694</span>
<span id="3695">3695</span>
<span id="3696">3696</span>
<span id="3697">3697</span>
<span id="3698">3698</span>
<span id="3699">3699</span>
<span id="3700">3700</span>
<span id="3701">3701</span>
<span id="3702">3702</span>
<span id="3703">3703</span>
<span id="3704">3704</span>
<span id="3705">3705</span>
<span id="3706">3706</span>
<span id="3707">3707</span>
<span id="3708">3708</span>
<span id="3709">3709</span>
<span id="3710">3710</span>
<span id="3711">3711</span>
<span id="3712">3712</span>
<span id="3713">3713</span>
<span id="3714">3714</span>
<span id="3715">3715</span>
<span id="3716">3716</span>
<span id="3717">3717</span>
<span id="3718">3718</span>
<span id="3719">3719</span>
<span id="3720">3720</span>
<span id="3721">3721</span>
<span id="3722">3722</span>
<span id="3723">3723</span>
<span id="3724">3724</span>
<span id="3725">3725</span>
<span id="3726">3726</span>
<span id="3727">3727</span>
<span id="3728">3728</span>
<span id="3729">3729</span>
<span id="3730">3730</span>
<span id="3731">3731</span>
<span id="3732">3732</span>
<span id="3733">3733</span>
<span id="3734">3734</span>
<span id="3735">3735</span>
<span id="3736">3736</span>
<span id="3737">3737</span>
<span id="3738">3738</span>
<span id="3739">3739</span>
</pre><pre class="rust"><code><span class="doccomment">/*!
Defines a high-level intermediate (HIR) representation for regular expressions.
The HIR is represented by the [`Hir`] type, and it principally constructed via
[translation](translate) from an [`Ast`](crate::ast::Ast). Alternatively, users
may use the smart constructors defined on `Hir` to build their own by hand. The
smart constructors simultaneously simplify and &quot;optimize&quot; the HIR, and are also
the same routines used by translation.
Most regex engines only have an HIR like this, and usually construct it
directly from the concrete syntax. This crate however first parses the
concrete syntax into an `Ast`, and only then creates the HIR from the `Ast`,
as mentioned above. It&#39;s done this way to facilitate better error reporting,
and to have a structured representation of a regex that faithfully represents
its concrete syntax. Namely, while an `Hir` value can be converted back to an
equivalent regex pattern string, it is unlikely to look like the original due
to its simplified structure.
*/
</span><span class="kw">use </span>core::{char, cmp};
<span class="kw">use </span>alloc::{
boxed::Box,
format,
string::{String, ToString},
vec,
vec::Vec,
};
<span class="kw">use crate</span>::{
ast::Span,
hir::interval::{Interval, IntervalSet, IntervalSetIter},
unicode,
};
<span class="kw">pub use crate</span>::{
hir::visitor::{visit, Visitor},
unicode::CaseFoldError,
};
<span class="kw">mod </span>interval;
<span class="kw">pub mod </span>literal;
<span class="kw">pub mod </span>print;
<span class="kw">pub mod </span>translate;
<span class="kw">mod </span>visitor;
<span class="doccomment">/// An error that can occur while translating an `Ast` to a `Hir`.
</span><span class="attribute">#[derive(Clone, Debug, Eq, PartialEq)]
</span><span class="kw">pub struct </span>Error {
<span class="doccomment">/// The kind of error.
</span>kind: ErrorKind,
<span class="doccomment">/// The original pattern that the translator&#39;s Ast was parsed from. Every
/// span in an error is a valid range into this string.
</span>pattern: String,
<span class="doccomment">/// The span of this error, derived from the Ast given to the translator.
</span>span: Span,
}
<span class="kw">impl </span>Error {
<span class="doccomment">/// Return the type of this error.
</span><span class="kw">pub fn </span>kind(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>ErrorKind {
<span class="kw-2">&amp;</span><span class="self">self</span>.kind
}
<span class="doccomment">/// The original pattern string in which this error occurred.
///
/// Every span reported by this error is reported in terms of this string.
</span><span class="kw">pub fn </span>pattern(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>str {
<span class="kw-2">&amp;</span><span class="self">self</span>.pattern
}
<span class="doccomment">/// Return the span at which this error occurred.
</span><span class="kw">pub fn </span>span(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>Span {
<span class="kw-2">&amp;</span><span class="self">self</span>.span
}
}
<span class="doccomment">/// The type of an error that occurred while building an `Hir`.
///
/// This error type is marked as `non_exhaustive`. This means that adding a
/// new variant is not considered a breaking change.
</span><span class="attribute">#[non_exhaustive]
#[derive(Clone, Debug, Eq, PartialEq)]
</span><span class="kw">pub enum </span>ErrorKind {
<span class="doccomment">/// This error occurs when a Unicode feature is used when Unicode
/// support is disabled. For example `(?-u:\pL)` would trigger this error.
</span>UnicodeNotAllowed,
<span class="doccomment">/// This error occurs when translating a pattern that could match a byte
/// sequence that isn&#39;t UTF-8 and `utf8` was enabled.
</span>InvalidUtf8,
<span class="doccomment">/// This occurs when an unrecognized Unicode property name could not
/// be found.
</span>UnicodePropertyNotFound,
<span class="doccomment">/// This occurs when an unrecognized Unicode property value could not
/// be found.
</span>UnicodePropertyValueNotFound,
<span class="doccomment">/// This occurs when a Unicode-aware Perl character class (`\w`, `\s` or
/// `\d`) could not be found. This can occur when the `unicode-perl`
/// crate feature is not enabled.
</span>UnicodePerlClassNotFound,
<span class="doccomment">/// This occurs when the Unicode simple case mapping tables are not
/// available, and the regular expression required Unicode aware case
/// insensitivity.
</span>UnicodeCaseUnavailable,
}
<span class="attribute">#[cfg(feature = <span class="string">&quot;std&quot;</span>)]
</span><span class="kw">impl </span>std::error::Error <span class="kw">for </span>Error {}
<span class="kw">impl </span>core::fmt::Display <span class="kw">for </span>Error {
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>core::fmt::Formatter&lt;<span class="lifetime">&#39;_</span>&gt;) -&gt; core::fmt::Result {
<span class="kw">crate</span>::error::Formatter::from(<span class="self">self</span>).fmt(f)
}
}
<span class="kw">impl </span>core::fmt::Display <span class="kw">for </span>ErrorKind {
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>core::fmt::Formatter&lt;<span class="lifetime">&#39;_</span>&gt;) -&gt; core::fmt::Result {
<span class="kw">use </span><span class="self">self</span>::ErrorKind::<span class="kw-2">*</span>;
<span class="kw">let </span>msg = <span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
UnicodeNotAllowed =&gt; <span class="string">&quot;Unicode not allowed here&quot;</span>,
InvalidUtf8 =&gt; <span class="string">&quot;pattern can match invalid UTF-8&quot;</span>,
UnicodePropertyNotFound =&gt; <span class="string">&quot;Unicode property not found&quot;</span>,
UnicodePropertyValueNotFound =&gt; <span class="string">&quot;Unicode property value not found&quot;</span>,
UnicodePerlClassNotFound =&gt; {
<span class="string">&quot;Unicode-aware Perl class not found \
(make sure the unicode-perl feature is enabled)&quot;
</span>}
UnicodeCaseUnavailable =&gt; {
<span class="string">&quot;Unicode-aware case insensitivity matching is not available \
(make sure the unicode-case feature is enabled)&quot;
</span>}
};
f.write_str(msg)
}
}
<span class="doccomment">/// A high-level intermediate representation (HIR) for a regular expression.
///
/// An HIR value is a combination of a [`HirKind`] and a set of [`Properties`].
/// An `HirKind` indicates what kind of regular expression it is (a literal,
/// a repetition, a look-around assertion, etc.), where as a `Properties`
/// describes various facts about the regular expression. For example, whether
/// it matches UTF-8 or if it matches the empty string.
///
/// The HIR of a regular expression represents an intermediate step between
/// its abstract syntax (a structured description of the concrete syntax) and
/// an actual regex matcher. The purpose of HIR is to make regular expressions
/// easier to analyze. In particular, the AST is much more complex than the
/// HIR. For example, while an AST supports arbitrarily nested character
/// classes, the HIR will flatten all nested classes into a single set. The HIR
/// will also &quot;compile away&quot; every flag present in the concrete syntax. For
/// example, users of HIR expressions never need to worry about case folding;
/// it is handled automatically by the translator (e.g., by translating
/// `(?i:A)` to `[aA]`).
///
/// The specific type of an HIR expression can be accessed via its `kind`
/// or `into_kind` methods. This extra level of indirection exists for two
/// reasons:
///
/// 1. Construction of an HIR expression *must* use the constructor methods on
/// this `Hir` type instead of building the `HirKind` values directly. This
/// permits construction to enforce invariants like &quot;concatenations always
/// consist of two or more sub-expressions.&quot;
/// 2. Every HIR expression contains attributes that are defined inductively,
/// and can be computed cheaply during the construction process. For example,
/// one such attribute is whether the expression must match at the beginning of
/// the haystack.
///
/// In particular, if you have an `HirKind` value, then there is intentionally
/// no way to build an `Hir` value from it. You instead need to do case
/// analysis on the `HirKind` value and build the `Hir` value using its smart
/// constructors.
///
/// # UTF-8
///
/// If the HIR was produced by a translator with
/// [`TranslatorBuilder::utf8`](translate::TranslatorBuilder::utf8) enabled,
/// then the HIR is guaranteed to match UTF-8 exclusively for all non-empty
/// matches.
///
/// For empty matches, those can occur at any position. It is the
/// repsonsibility of the regex engine to determine whether empty matches are
/// permitted between the code units of a single codepoint.
///
/// # Stack space
///
/// This type defines its own destructor that uses constant stack space and
/// heap space proportional to the size of the HIR.
///
/// Also, an `Hir`&#39;s `fmt::Display` implementation prints an HIR as a regular
/// expression pattern string, and uses constant stack space and heap space
/// proportional to the size of the `Hir`. The regex it prints is guaranteed to
/// be _semantically_ equivalent to the original concrete syntax, but it may
/// look very different. (And potentially not practically readable by a human.)
///
/// An `Hir`&#39;s `fmt::Debug` implementation currently does not use constant
/// stack space. The implementation will also suppress some details (such as
/// the `Properties` inlined into every `Hir` value to make it less noisy).
</span><span class="attribute">#[derive(Clone, Eq, PartialEq)]
</span><span class="kw">pub struct </span>Hir {
<span class="doccomment">/// The underlying HIR kind.
</span>kind: HirKind,
<span class="doccomment">/// Analysis info about this HIR, computed during construction.
</span>props: Properties,
}
<span class="doccomment">/// Methods for accessing the underlying `HirKind` and `Properties`.
</span><span class="kw">impl </span>Hir {
<span class="doccomment">/// Returns a reference to the underlying HIR kind.
</span><span class="kw">pub fn </span>kind(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>HirKind {
<span class="kw-2">&amp;</span><span class="self">self</span>.kind
}
<span class="doccomment">/// Consumes ownership of this HIR expression and returns its underlying
/// `HirKind`.
</span><span class="kw">pub fn </span>into_kind(<span class="kw-2">mut </span><span class="self">self</span>) -&gt; HirKind {
core::mem::replace(<span class="kw-2">&amp;mut </span><span class="self">self</span>.kind, HirKind::Empty)
}
<span class="doccomment">/// Returns the properties computed for this `Hir`.
</span><span class="kw">pub fn </span>properties(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>Properties {
<span class="kw-2">&amp;</span><span class="self">self</span>.props
}
<span class="doccomment">/// Splits this HIR into its constituent parts.
///
/// This is useful because `let Hir { kind, props } = hir;` does not work
/// because of `Hir`&#39;s custom `Drop` implementation.
</span><span class="kw">fn </span>into_parts(<span class="kw-2">mut </span><span class="self">self</span>) -&gt; (HirKind, Properties) {
(
core::mem::replace(<span class="kw-2">&amp;mut </span><span class="self">self</span>.kind, HirKind::Empty),
core::mem::replace(<span class="kw-2">&amp;mut </span><span class="self">self</span>.props, Properties::empty()),
)
}
}
<span class="doccomment">/// Smart constructors for HIR values.
///
/// These constructors are called &quot;smart&quot; because they do inductive work or
/// simplifications. For example, calling `Hir::repetition` with a repetition
/// like `a{0}` will actually return a `Hir` with a `HirKind::Empty` kind
/// since it is equivalent to an empty regex. Another example is calling
/// `Hir::concat(vec![expr])`. Instead of getting a `HirKind::Concat`, you&#39;ll
/// just get back the original `expr` since it&#39;s precisely equivalent.
///
/// Smart constructors enable maintaining invariants about the HIR data type
/// while also simulanteously keeping the representation as simple as possible.
</span><span class="kw">impl </span>Hir {
<span class="doccomment">/// Returns an empty HIR expression.
///
/// An empty HIR expression always matches, including the empty string.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>empty() -&gt; Hir {
<span class="kw">let </span>props = Properties::empty();
Hir { kind: HirKind::Empty, props }
}
<span class="doccomment">/// Returns an HIR expression that can never match anything. That is,
/// the size of the set of strings in the language described by the HIR
/// returned is `0`.
///
/// This is distinct from [`Hir::empty`] in that the empty string matches
/// the HIR returned by `Hir::empty`. That is, the set of strings in the
/// language describe described by `Hir::empty` is non-empty.
///
/// Note that currently, the HIR returned uses an empty character class to
/// indicate that nothing can match. An equivalent expression that cannot
/// match is an empty alternation, but all such &quot;fail&quot; expressions are
/// normalized (via smart constructors) to empty character classes. This is
/// because empty character classes can be spelled in the concrete syntax
/// of a regex (e.g., `\P{any}` or `(?-u:[^\x00-\xFF])` or `[a&amp;&amp;b]`), but
/// empty alternations cannot.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>fail() -&gt; Hir {
<span class="kw">let </span>class = Class::Bytes(ClassBytes::empty());
<span class="kw">let </span>props = Properties::class(<span class="kw-2">&amp;</span>class);
<span class="comment">// We can&#39;t just call Hir::class here because it defers to Hir::fail
// in order to canonicalize the Hir value used to represent &quot;cannot
// match.&quot;
</span>Hir { kind: HirKind::Class(class), props }
}
<span class="doccomment">/// Creates a literal HIR expression.
///
/// This accepts anything that can be converted into a `Box&lt;[u8]&gt;`.
///
/// Note that there is no mechanism for storing a `char` or a `Box&lt;str&gt;`
/// in an HIR. Everything is &quot;just bytes.&quot; Whether a `Literal` (or
/// any HIR node) matches valid UTF-8 exclusively can be queried via
/// [`Properties::is_utf8`].
///
/// # Example
///
/// This example shows that concatenations of `Literal` HIR values will
/// automatically get flattened and combined together. So for example, even
/// if you concat multiple `Literal` values that are themselves not valid
/// UTF-8, they might add up to valid UTF-8. This also demonstrates just
/// how &quot;smart&quot; Hir&#39;s smart constructors are.
///
/// ```
/// use regex_syntax::hir::{Hir, HirKind, Literal};
///
/// let literals = vec![
/// Hir::literal([0xE2]),
/// Hir::literal([0x98]),
/// Hir::literal([0x83]),
/// ];
/// // Each literal, on its own, is invalid UTF-8.
/// assert!(literals.iter().all(|hir| !hir.properties().is_utf8()));
///
/// let concat = Hir::concat(literals);
/// // But the concatenation is valid UTF-8!
/// assert!(concat.properties().is_utf8());
///
/// // And also notice that the literals have been concatenated into a
/// // single `Literal`, to the point where there is no explicit `Concat`!
/// let expected = HirKind::Literal(Literal(Box::from(&quot;☃&quot;.as_bytes())));
/// assert_eq!(&amp;expected, concat.kind());
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>literal&lt;B: Into&lt;Box&lt;[u8]&gt;&gt;&gt;(lit: B) -&gt; Hir {
<span class="kw">let </span>bytes = lit.into();
<span class="kw">if </span>bytes.is_empty() {
<span class="kw">return </span>Hir::empty();
}
<span class="kw">let </span>lit = Literal(bytes);
<span class="kw">let </span>props = Properties::literal(<span class="kw-2">&amp;</span>lit);
Hir { kind: HirKind::Literal(lit), props }
}
<span class="doccomment">/// Creates a class HIR expression. The class may either be defined over
/// ranges of Unicode codepoints or ranges of raw byte values.
///
/// Note that an empty class is permitted. An empty class is equivalent to
/// `Hir::fail()`.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>class(class: Class) -&gt; Hir {
<span class="kw">if </span>class.is_empty() {
<span class="kw">return </span>Hir::fail();
} <span class="kw">else if let </span><span class="prelude-val">Some</span>(bytes) = class.literal() {
<span class="kw">return </span>Hir::literal(bytes);
}
<span class="kw">let </span>props = Properties::class(<span class="kw-2">&amp;</span>class);
Hir { kind: HirKind::Class(class), props }
}
<span class="doccomment">/// Creates a look-around assertion HIR expression.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>look(look: Look) -&gt; Hir {
<span class="kw">let </span>props = Properties::look(look);
Hir { kind: HirKind::Look(look), props }
}
<span class="doccomment">/// Creates a repetition HIR expression.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>repetition(rep: Repetition) -&gt; Hir {
<span class="comment">// The regex &#39;a{0}&#39; is always equivalent to the empty regex. This is
// true even when &#39;a&#39; is an expression that never matches anything
// (like &#39;\P{any}&#39;).
//
// Additionally, the regex &#39;a{1}&#39; is always equivalent to &#39;a&#39;.
</span><span class="kw">if </span>rep.min == <span class="number">0 </span>&amp;&amp; rep.max == <span class="prelude-val">Some</span>(<span class="number">0</span>) {
<span class="kw">return </span>Hir::empty();
} <span class="kw">else if </span>rep.min == <span class="number">1 </span>&amp;&amp; rep.max == <span class="prelude-val">Some</span>(<span class="number">1</span>) {
<span class="kw">return </span><span class="kw-2">*</span>rep.sub;
}
<span class="kw">let </span>props = Properties::repetition(<span class="kw-2">&amp;</span>rep);
Hir { kind: HirKind::Repetition(rep), props }
}
<span class="doccomment">/// Creates a capture HIR expression.
///
/// Note that there is no explicit HIR value for a non-capturing group.
/// Since a non-capturing group only exists to override precedence in the
/// concrete syntax and since an HIR already does its own grouping based on
/// what is parsed, there is no need to explicitly represent non-capturing
/// groups in the HIR.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>capture(capture: Capture) -&gt; Hir {
<span class="kw">let </span>props = Properties::capture(<span class="kw-2">&amp;</span>capture);
Hir { kind: HirKind::Capture(capture), props }
}
<span class="doccomment">/// Returns the concatenation of the given expressions.
///
/// This attempts to flatten and simplify the concatenation as appropriate.
///
/// # Example
///
/// This shows a simple example of basic flattening of both concatenations
/// and literals.
///
/// ```
/// use regex_syntax::hir::Hir;
///
/// let hir = Hir::concat(vec![
/// Hir::concat(vec![
/// Hir::literal([b&#39;a&#39;]),
/// Hir::literal([b&#39;b&#39;]),
/// Hir::literal([b&#39;c&#39;]),
/// ]),
/// Hir::concat(vec![
/// Hir::literal([b&#39;x&#39;]),
/// Hir::literal([b&#39;y&#39;]),
/// Hir::literal([b&#39;z&#39;]),
/// ]),
/// ]);
/// let expected = Hir::literal(&quot;abcxyz&quot;.as_bytes());
/// assert_eq!(expected, hir);
/// ```
</span><span class="kw">pub fn </span>concat(subs: Vec&lt;Hir&gt;) -&gt; Hir {
<span class="comment">// We rebuild the concatenation by simplifying it. Would be nice to do
// it in place, but that seems a little tricky?
</span><span class="kw">let </span><span class="kw-2">mut </span>new = <span class="macro">vec!</span>[];
<span class="comment">// This gobbles up any adjacent literals in a concatenation and smushes
// them together. Basically, when we see a literal, we add its bytes
// to &#39;prior_lit&#39;, and whenever we see anything else, we first take
// any bytes in &#39;prior_lit&#39; and add it to the &#39;new&#39; concatenation.
</span><span class="kw">let </span><span class="kw-2">mut </span>prior_lit: <span class="prelude-ty">Option</span>&lt;Vec&lt;u8&gt;&gt; = <span class="prelude-val">None</span>;
<span class="kw">for </span>sub <span class="kw">in </span>subs {
<span class="kw">let </span>(kind, props) = sub.into_parts();
<span class="kw">match </span>kind {
HirKind::Literal(Literal(bytes)) =&gt; {
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>prior_bytes) = prior_lit {
prior_bytes.extend_from_slice(<span class="kw-2">&amp;</span>bytes);
} <span class="kw">else </span>{
prior_lit = <span class="prelude-val">Some</span>(bytes.to_vec());
}
}
<span class="comment">// We also flatten concats that are direct children of another
// concat. We only need to do this one level deep since
// Hir::concat is the only way to build concatenations, and so
// flattening happens inductively.
</span>HirKind::Concat(subs2) =&gt; {
<span class="kw">for </span>sub2 <span class="kw">in </span>subs2 {
<span class="kw">let </span>(kind2, props2) = sub2.into_parts();
<span class="kw">match </span>kind2 {
HirKind::Literal(Literal(bytes)) =&gt; {
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>prior_bytes) = prior_lit {
prior_bytes.extend_from_slice(<span class="kw-2">&amp;</span>bytes);
} <span class="kw">else </span>{
prior_lit = <span class="prelude-val">Some</span>(bytes.to_vec());
}
}
kind2 =&gt; {
<span class="kw">if let </span><span class="prelude-val">Some</span>(prior_bytes) = prior_lit.take() {
new.push(Hir::literal(prior_bytes));
}
new.push(Hir { kind: kind2, props: props2 });
}
}
}
}
<span class="comment">// We can just skip empty HIRs.
</span>HirKind::Empty =&gt; {}
kind =&gt; {
<span class="kw">if let </span><span class="prelude-val">Some</span>(prior_bytes) = prior_lit.take() {
new.push(Hir::literal(prior_bytes));
}
new.push(Hir { kind, props });
}
}
}
<span class="kw">if let </span><span class="prelude-val">Some</span>(prior_bytes) = prior_lit.take() {
new.push(Hir::literal(prior_bytes));
}
<span class="kw">if </span>new.is_empty() {
<span class="kw">return </span>Hir::empty();
} <span class="kw">else if </span>new.len() == <span class="number">1 </span>{
<span class="kw">return </span>new.pop().unwrap();
}
<span class="kw">let </span>props = Properties::concat(<span class="kw-2">&amp;</span>new);
Hir { kind: HirKind::Concat(new), props }
}
<span class="doccomment">/// Returns the alternation of the given expressions.
///
/// This flattens and simplifies the alternation as appropriate. This may
/// include factoring out common prefixes or even rewriting the alternation
/// as a character class.
///
/// Note that an empty alternation is equivalent to `Hir::fail()`. (It
/// is not possible for one to write an empty alternation, or even an
/// alternation with a single sub-expression, in the concrete syntax of a
/// regex.)
///
/// # Example
///
/// This is a simple example showing how an alternation might get
/// simplified.
///
/// ```
/// use regex_syntax::hir::{Hir, Class, ClassUnicode, ClassUnicodeRange};
///
/// let hir = Hir::alternation(vec![
/// Hir::literal([b&#39;a&#39;]),
/// Hir::literal([b&#39;b&#39;]),
/// Hir::literal([b&#39;c&#39;]),
/// Hir::literal([b&#39;d&#39;]),
/// Hir::literal([b&#39;e&#39;]),
/// Hir::literal([b&#39;f&#39;]),
/// ]);
/// let expected = Hir::class(Class::Unicode(ClassUnicode::new([
/// ClassUnicodeRange::new(&#39;a&#39;, &#39;f&#39;),
/// ])));
/// assert_eq!(expected, hir);
/// ```
///
/// And another example showing how common prefixes might get factored
/// out.
///
/// ```
/// use regex_syntax::hir::{Hir, Class, ClassUnicode, ClassUnicodeRange};
///
/// let hir = Hir::alternation(vec![
/// Hir::concat(vec![
/// Hir::literal(&quot;abc&quot;.as_bytes()),
/// Hir::class(Class::Unicode(ClassUnicode::new([
/// ClassUnicodeRange::new(&#39;A&#39;, &#39;Z&#39;),
/// ]))),
/// ]),
/// Hir::concat(vec![
/// Hir::literal(&quot;abc&quot;.as_bytes()),
/// Hir::class(Class::Unicode(ClassUnicode::new([
/// ClassUnicodeRange::new(&#39;a&#39;, &#39;z&#39;),
/// ]))),
/// ]),
/// ]);
/// let expected = Hir::concat(vec![
/// Hir::literal(&quot;abc&quot;.as_bytes()),
/// Hir::alternation(vec![
/// Hir::class(Class::Unicode(ClassUnicode::new([
/// ClassUnicodeRange::new(&#39;A&#39;, &#39;Z&#39;),
/// ]))),
/// Hir::class(Class::Unicode(ClassUnicode::new([
/// ClassUnicodeRange::new(&#39;a&#39;, &#39;z&#39;),
/// ]))),
/// ]),
/// ]);
/// assert_eq!(expected, hir);
/// ```
///
/// Note that these sorts of simplifications are not guaranteed.
</span><span class="kw">pub fn </span>alternation(subs: Vec&lt;Hir&gt;) -&gt; Hir {
<span class="comment">// We rebuild the alternation by simplifying it. We proceed similarly
// as the concatenation case. But in this case, there&#39;s no literal
// simplification happening. We&#39;re just flattening alternations.
</span><span class="kw">let </span><span class="kw-2">mut </span>new = <span class="macro">vec!</span>[];
<span class="kw">for </span>sub <span class="kw">in </span>subs {
<span class="kw">let </span>(kind, props) = sub.into_parts();
<span class="kw">match </span>kind {
HirKind::Alternation(subs2) =&gt; {
new.extend(subs2);
}
kind =&gt; {
new.push(Hir { kind, props });
}
}
}
<span class="kw">if </span>new.is_empty() {
<span class="kw">return </span>Hir::fail();
} <span class="kw">else if </span>new.len() == <span class="number">1 </span>{
<span class="kw">return </span>new.pop().unwrap();
}
<span class="comment">// Now that it&#39;s completely flattened, look for the special case of
// &#39;char1|char2|...|charN&#39; and collapse that into a class. Note that
// we look for &#39;char&#39; first and then bytes. The issue here is that if
// we find both non-ASCII codepoints and non-ASCII singleton bytes,
// then it isn&#39;t actually possible to smush them into a single class.
// (Because classes are either &quot;all codepoints&quot; or &quot;all bytes.&quot; You
// can have a class that both matches non-ASCII but valid UTF-8 and
// invalid UTF-8.) So we look for all chars and then all bytes, and
// don&#39;t handle anything else.
</span><span class="kw">if let </span><span class="prelude-val">Some</span>(singletons) = singleton_chars(<span class="kw-2">&amp;</span>new) {
<span class="kw">let </span>it = singletons
.into_iter()
.map(|ch| ClassUnicodeRange { start: ch, end: ch });
<span class="kw">return </span>Hir::class(Class::Unicode(ClassUnicode::new(it)));
}
<span class="kw">if let </span><span class="prelude-val">Some</span>(singletons) = singleton_bytes(<span class="kw-2">&amp;</span>new) {
<span class="kw">let </span>it = singletons
.into_iter()
.map(|b| ClassBytesRange { start: b, end: b });
<span class="kw">return </span>Hir::class(Class::Bytes(ClassBytes::new(it)));
}
<span class="comment">// Similar to singleton chars, we can also look for alternations of
// classes. Those can be smushed into a single class.
</span><span class="kw">if let </span><span class="prelude-val">Some</span>(cls) = class_chars(<span class="kw-2">&amp;</span>new) {
<span class="kw">return </span>Hir::class(cls);
}
<span class="kw">if let </span><span class="prelude-val">Some</span>(cls) = class_bytes(<span class="kw-2">&amp;</span>new) {
<span class="kw">return </span>Hir::class(cls);
}
<span class="comment">// Factor out a common prefix if we can, which might potentially
// simplify the expression and unlock other optimizations downstream.
// It also might generally make NFA matching and DFA construction
// faster by reducing the scope of branching in the regex.
</span>new = <span class="kw">match </span>lift_common_prefix(new) {
<span class="prelude-val">Ok</span>(hir) =&gt; <span class="kw">return </span>hir,
<span class="prelude-val">Err</span>(unchanged) =&gt; unchanged,
};
<span class="kw">let </span>props = Properties::alternation(<span class="kw-2">&amp;</span>new);
Hir { kind: HirKind::Alternation(new), props }
}
<span class="doccomment">/// Returns an HIR expression for `.`.
///
/// * [`Dot::AnyChar`] maps to `(?su-R:.)`.
/// * [`Dot::AnyByte`] maps to `(?s-Ru:.)`.
/// * [`Dot::AnyCharExceptLF`] maps to `(?u-Rs:.)`.
/// * [`Dot::AnyCharExceptCRLF`] maps to `(?Ru-s:.)`.
/// * [`Dot::AnyByteExceptLF`] maps to `(?-Rsu:.)`.
/// * [`Dot::AnyByteExceptCRLF`] maps to `(?R-su:.)`.
///
/// # Example
///
/// Note that this is a convenience routine for constructing the correct
/// character class based on the value of `Dot`. There is no explicit &quot;dot&quot;
/// HIR value. It is just an abbreviation for a common character class.
///
/// ```
/// use regex_syntax::hir::{Hir, Dot, Class, ClassBytes, ClassBytesRange};
///
/// let hir = Hir::dot(Dot::AnyByte);
/// let expected = Hir::class(Class::Bytes(ClassBytes::new([
/// ClassBytesRange::new(0x00, 0xFF),
/// ])));
/// assert_eq!(expected, hir);
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>dot(dot: Dot) -&gt; Hir {
<span class="kw">match </span>dot {
Dot::AnyChar =&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>cls = ClassUnicode::empty();
cls.push(ClassUnicodeRange::new(<span class="string">&#39;\0&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>));
Hir::class(Class::Unicode(cls))
}
Dot::AnyByte =&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>cls = ClassBytes::empty();
cls.push(ClassBytesRange::new(<span class="string">b&#39;\0&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>));
Hir::class(Class::Bytes(cls))
}
Dot::AnyCharExceptLF =&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>cls = ClassUnicode::empty();
cls.push(ClassUnicodeRange::new(<span class="string">&#39;\0&#39;</span>, <span class="string">&#39;\x09&#39;</span>));
cls.push(ClassUnicodeRange::new(<span class="string">&#39;\x0B&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>));
Hir::class(Class::Unicode(cls))
}
Dot::AnyCharExceptCRLF =&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>cls = ClassUnicode::empty();
cls.push(ClassUnicodeRange::new(<span class="string">&#39;\0&#39;</span>, <span class="string">&#39;\x09&#39;</span>));
cls.push(ClassUnicodeRange::new(<span class="string">&#39;\x0B&#39;</span>, <span class="string">&#39;\x0C&#39;</span>));
cls.push(ClassUnicodeRange::new(<span class="string">&#39;\x0E&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>));
Hir::class(Class::Unicode(cls))
}
Dot::AnyByteExceptLF =&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>cls = ClassBytes::empty();
cls.push(ClassBytesRange::new(<span class="string">b&#39;\0&#39;</span>, <span class="string">b&#39;\x09&#39;</span>));
cls.push(ClassBytesRange::new(<span class="string">b&#39;\x0B&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>));
Hir::class(Class::Bytes(cls))
}
Dot::AnyByteExceptCRLF =&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>cls = ClassBytes::empty();
cls.push(ClassBytesRange::new(<span class="string">b&#39;\0&#39;</span>, <span class="string">b&#39;\x09&#39;</span>));
cls.push(ClassBytesRange::new(<span class="string">b&#39;\x0B&#39;</span>, <span class="string">b&#39;\x0C&#39;</span>));
cls.push(ClassBytesRange::new(<span class="string">b&#39;\x0E&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>));
Hir::class(Class::Bytes(cls))
}
}
}
}
<span class="doccomment">/// The underlying kind of an arbitrary [`Hir`] expression.
///
/// An `HirKind` is principally useful for doing case analysis on the type
/// of a regular expression. If you&#39;re looking to build new `Hir` values,
/// then you _must_ use the smart constructors defined on `Hir`, like
/// [`Hir::repetition`], to build new `Hir` values. The API intentionally does
/// not expose any way of building an `Hir` directly from an `HirKind`.
</span><span class="attribute">#[derive(Clone, Debug, Eq, PartialEq)]
</span><span class="kw">pub enum </span>HirKind {
<span class="doccomment">/// The empty regular expression, which matches everything, including the
/// empty string.
</span>Empty,
<span class="doccomment">/// A literalstring that matches exactly these bytes.
</span>Literal(Literal),
<span class="doccomment">/// A single character class that matches any of the characters in the
/// class. A class can either consist of Unicode scalar values as
/// characters, or it can use bytes.
///
/// A class may be empty. In which case, it matches nothing.
</span>Class(Class),
<span class="doccomment">/// A look-around assertion. A look-around match always has zero length.
</span>Look(Look),
<span class="doccomment">/// A repetition operation applied to a sub-expression.
</span>Repetition(Repetition),
<span class="doccomment">/// A capturing group, which contains a sub-expression.
</span>Capture(Capture),
<span class="doccomment">/// A concatenation of expressions.
///
/// A concatenation matches only if each of its sub-expressions match one
/// after the other.
///
/// Concatenations are guaranteed by `Hir`&#39;s smart constructors to always
/// have at least two sub-expressions.
</span>Concat(Vec&lt;Hir&gt;),
<span class="doccomment">/// An alternation of expressions.
///
/// An alternation matches only if at least one of its sub-expressions
/// match. If multiple sub-expressions match, then the leftmost is
/// preferred.
///
/// Alternations are guaranteed by `Hir`&#39;s smart constructors to always
/// have at least two sub-expressions.
</span>Alternation(Vec&lt;Hir&gt;),
}
<span class="kw">impl </span>HirKind {
<span class="doccomment">/// Returns a slice of this kind&#39;s sub-expressions, if any.
</span><span class="kw">pub fn </span>subs(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>[Hir] {
<span class="kw">use </span>core::slice::from_ref;
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
HirKind::Empty
| HirKind::Literal(<span class="kw">_</span>)
| HirKind::Class(<span class="kw">_</span>)
| HirKind::Look(<span class="kw">_</span>) =&gt; <span class="kw-2">&amp;</span>[],
HirKind::Repetition(Repetition { <span class="kw-2">ref </span>sub, .. }) =&gt; from_ref(sub),
HirKind::Capture(Capture { <span class="kw-2">ref </span>sub, .. }) =&gt; from_ref(sub),
HirKind::Concat(<span class="kw-2">ref </span>subs) =&gt; subs,
HirKind::Alternation(<span class="kw-2">ref </span>subs) =&gt; subs,
}
}
}
<span class="kw">impl </span>core::fmt::Debug <span class="kw">for </span>Hir {
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>core::fmt::Formatter&lt;<span class="lifetime">&#39;_</span>&gt;) -&gt; core::fmt::Result {
<span class="self">self</span>.kind.fmt(f)
}
}
<span class="doccomment">/// Print a display representation of this Hir.
///
/// The result of this is a valid regular expression pattern string.
///
/// This implementation uses constant stack space and heap space proportional
/// to the size of the `Hir`.
</span><span class="kw">impl </span>core::fmt::Display <span class="kw">for </span>Hir {
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>core::fmt::Formatter&lt;<span class="lifetime">&#39;_</span>&gt;) -&gt; core::fmt::Result {
<span class="kw">crate</span>::hir::print::Printer::new().print(<span class="self">self</span>, f)
}
}
<span class="doccomment">/// The high-level intermediate representation of a literal.
///
/// A literal corresponds to `0` or more bytes that should be matched
/// literally. The smart constructors defined on `Hir` will automatically
/// concatenate adjacent literals into one literal, and will even automatically
/// replace empty literals with `Hir::empty()`.
///
/// Note that despite a literal being represented by a sequence of bytes, its
/// `Debug` implementation will attempt to print it as a normal string. (That
/// is, not a sequence of decimal numbers.)
</span><span class="attribute">#[derive(Clone, Eq, PartialEq)]
</span><span class="kw">pub struct </span>Literal(<span class="kw">pub </span>Box&lt;[u8]&gt;);
<span class="kw">impl </span>core::fmt::Debug <span class="kw">for </span>Literal {
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>core::fmt::Formatter) -&gt; core::fmt::Result {
<span class="kw">crate</span>::debug::Bytes(<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span>).fmt(f)
}
}
<span class="doccomment">/// The high-level intermediate representation of a character class.
///
/// A character class corresponds to a set of characters. A character is either
/// defined by a Unicode scalar value or a byte. Unicode characters are used
/// by default, while bytes are used when Unicode mode (via the `u` flag) is
/// disabled.
///
/// A character class, regardless of its character type, is represented by a
/// sequence of non-overlapping non-adjacent ranges of characters.
///
/// Note that `Bytes` variant may be produced even when it exclusively matches
/// valid UTF-8. This is because a `Bytes` variant represents an intention by
/// the author of the regular expression to disable Unicode mode, which in turn
/// impacts the semantics of case insensitive matching. For example, `(?i)k`
/// and `(?i-u)k` will not match the same set of strings.
</span><span class="attribute">#[derive(Clone, Eq, PartialEq)]
</span><span class="kw">pub enum </span>Class {
<span class="doccomment">/// A set of characters represented by Unicode scalar values.
</span>Unicode(ClassUnicode),
<span class="doccomment">/// A set of characters represented by arbitrary bytes (one byte per
/// character).
</span>Bytes(ClassBytes),
}
<span class="kw">impl </span>Class {
<span class="doccomment">/// Apply Unicode simple case folding to this character class, in place.
/// The character class will be expanded to include all simple case folded
/// character variants.
///
/// If this is a byte oriented character class, then this will be limited
/// to the ASCII ranges `A-Z` and `a-z`.
///
/// # Panics
///
/// This routine panics when the case mapping data necessary for this
/// routine to complete is unavailable. This occurs when the `unicode-case`
/// feature is not enabled and the underlying class is Unicode oriented.
///
/// Callers should prefer using `try_case_fold_simple` instead, which will
/// return an error instead of panicking.
</span><span class="kw">pub fn </span>case_fold_simple(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
Class::Unicode(<span class="kw-2">ref mut </span>x) =&gt; x.case_fold_simple(),
Class::Bytes(<span class="kw-2">ref mut </span>x) =&gt; x.case_fold_simple(),
}
}
<span class="doccomment">/// Apply Unicode simple case folding to this character class, in place.
/// The character class will be expanded to include all simple case folded
/// character variants.
///
/// If this is a byte oriented character class, then this will be limited
/// to the ASCII ranges `A-Z` and `a-z`.
///
/// # Error
///
/// This routine returns an error when the case mapping data necessary
/// for this routine to complete is unavailable. This occurs when the
/// `unicode-case` feature is not enabled and the underlying class is
/// Unicode oriented.
</span><span class="kw">pub fn </span>try_case_fold_simple(
<span class="kw-2">&amp;mut </span><span class="self">self</span>,
) -&gt; core::result::Result&lt;(), CaseFoldError&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
Class::Unicode(<span class="kw-2">ref mut </span>x) =&gt; x.try_case_fold_simple()<span class="question-mark">?</span>,
Class::Bytes(<span class="kw-2">ref mut </span>x) =&gt; x.case_fold_simple(),
}
<span class="prelude-val">Ok</span>(())
}
<span class="doccomment">/// Negate this character class in place.
///
/// After completion, this character class will contain precisely the
/// characters that weren&#39;t previously in the class.
</span><span class="kw">pub fn </span>negate(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
Class::Unicode(<span class="kw-2">ref mut </span>x) =&gt; x.negate(),
Class::Bytes(<span class="kw-2">ref mut </span>x) =&gt; x.negate(),
}
}
<span class="doccomment">/// Returns true if and only if this character class will only ever match
/// valid UTF-8.
///
/// A character class can match invalid UTF-8 only when the following
/// conditions are met:
///
/// 1. The translator was configured to permit generating an expression
/// that can match invalid UTF-8. (By default, this is disabled.)
/// 2. Unicode mode (via the `u` flag) was disabled either in the concrete
/// syntax or in the parser builder. By default, Unicode mode is
/// enabled.
</span><span class="kw">pub fn </span>is_utf8(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
Class::Unicode(<span class="kw">_</span>) =&gt; <span class="bool-val">true</span>,
Class::Bytes(<span class="kw-2">ref </span>x) =&gt; x.is_ascii(),
}
}
<span class="doccomment">/// Returns the length, in bytes, of the smallest string matched by this
/// character class.
///
/// For non-empty byte oriented classes, this always returns `1`. For
/// non-empty Unicode oriented classes, this can return `1`, `2`, `3` or
/// `4`. For empty classes, `None` is returned. It is impossible for `0` to
/// be returned.
///
/// # Example
///
/// This example shows some examples of regexes and their corresponding
/// minimum length, if any.
///
/// ```
/// use regex_syntax::{hir::Properties, parse};
///
/// // The empty string has a min length of 0.
/// let hir = parse(r&quot;&quot;)?;
/// assert_eq!(Some(0), hir.properties().minimum_len());
/// // As do other types of regexes that only match the empty string.
/// let hir = parse(r&quot;^$\b\B&quot;)?;
/// assert_eq!(Some(0), hir.properties().minimum_len());
/// // A regex that can match the empty string but match more is still 0.
/// let hir = parse(r&quot;a*&quot;)?;
/// assert_eq!(Some(0), hir.properties().minimum_len());
/// // A regex that matches nothing has no minimum defined.
/// let hir = parse(r&quot;[a&amp;&amp;b]&quot;)?;
/// assert_eq!(None, hir.properties().minimum_len());
/// // Character classes usually have a minimum length of 1.
/// let hir = parse(r&quot;\w&quot;)?;
/// assert_eq!(Some(1), hir.properties().minimum_len());
/// // But sometimes Unicode classes might be bigger!
/// let hir = parse(r&quot;\p{Cyrillic}&quot;)?;
/// assert_eq!(Some(2), hir.properties().minimum_len());
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
</span><span class="kw">pub fn </span>minimum_len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
Class::Unicode(<span class="kw-2">ref </span>x) =&gt; x.minimum_len(),
Class::Bytes(<span class="kw-2">ref </span>x) =&gt; x.minimum_len(),
}
}
<span class="doccomment">/// Returns the length, in bytes, of the longest string matched by this
/// character class.
///
/// For non-empty byte oriented classes, this always returns `1`. For
/// non-empty Unicode oriented classes, this can return `1`, `2`, `3` or
/// `4`. For empty classes, `None` is returned. It is impossible for `0` to
/// be returned.
///
/// # Example
///
/// This example shows some examples of regexes and their corresponding
/// maximum length, if any.
///
/// ```
/// use regex_syntax::{hir::Properties, parse};
///
/// // The empty string has a max length of 0.
/// let hir = parse(r&quot;&quot;)?;
/// assert_eq!(Some(0), hir.properties().maximum_len());
/// // As do other types of regexes that only match the empty string.
/// let hir = parse(r&quot;^$\b\B&quot;)?;
/// assert_eq!(Some(0), hir.properties().maximum_len());
/// // A regex that matches nothing has no maximum defined.
/// let hir = parse(r&quot;[a&amp;&amp;b]&quot;)?;
/// assert_eq!(None, hir.properties().maximum_len());
/// // Bounded repeats work as you expect.
/// let hir = parse(r&quot;x{2,10}&quot;)?;
/// assert_eq!(Some(10), hir.properties().maximum_len());
/// // An unbounded repeat means there is no maximum.
/// let hir = parse(r&quot;x{2,}&quot;)?;
/// assert_eq!(None, hir.properties().maximum_len());
/// // With Unicode enabled, \w can match up to 4 bytes!
/// let hir = parse(r&quot;\w&quot;)?;
/// assert_eq!(Some(4), hir.properties().maximum_len());
/// // Without Unicode enabled, \w matches at most 1 byte.
/// let hir = parse(r&quot;(?-u)\w&quot;)?;
/// assert_eq!(Some(1), hir.properties().maximum_len());
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
</span><span class="kw">pub fn </span>maximum_len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
Class::Unicode(<span class="kw-2">ref </span>x) =&gt; x.maximum_len(),
Class::Bytes(<span class="kw-2">ref </span>x) =&gt; x.maximum_len(),
}
}
<span class="doccomment">/// Returns true if and only if this character class is empty. That is,
/// it has no elements.
///
/// An empty character can never match anything, including an empty string.
</span><span class="kw">pub fn </span>is_empty(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
Class::Unicode(<span class="kw-2">ref </span>x) =&gt; x.ranges().is_empty(),
Class::Bytes(<span class="kw-2">ref </span>x) =&gt; x.ranges().is_empty(),
}
}
<span class="doccomment">/// If this class consists of exactly one element (whether a codepoint or a
/// byte), then return it as a literal byte string.
///
/// If this class is empty or contains more than one element, then `None`
/// is returned.
</span><span class="kw">pub fn </span>literal(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;Vec&lt;u8&gt;&gt; {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
Class::Unicode(<span class="kw-2">ref </span>x) =&gt; x.literal(),
Class::Bytes(<span class="kw-2">ref </span>x) =&gt; x.literal(),
}
}
}
<span class="kw">impl </span>core::fmt::Debug <span class="kw">for </span>Class {
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>core::fmt::Formatter) -&gt; core::fmt::Result {
<span class="kw">use </span><span class="kw">crate</span>::debug::Byte;
<span class="kw">let </span><span class="kw-2">mut </span>fmter = f.debug_set();
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
Class::Unicode(<span class="kw-2">ref </span>cls) =&gt; {
<span class="kw">for </span>r <span class="kw">in </span>cls.ranges().iter() {
fmter.entry(<span class="kw-2">&amp;</span>(r.start..=r.end));
}
}
Class::Bytes(<span class="kw-2">ref </span>cls) =&gt; {
<span class="kw">for </span>r <span class="kw">in </span>cls.ranges().iter() {
fmter.entry(<span class="kw-2">&amp;</span>(Byte(r.start)..=Byte(r.end)));
}
}
}
fmter.finish()
}
}
<span class="doccomment">/// A set of characters represented by Unicode scalar values.
</span><span class="attribute">#[derive(Clone, Debug, Eq, PartialEq)]
</span><span class="kw">pub struct </span>ClassUnicode {
set: IntervalSet&lt;ClassUnicodeRange&gt;,
}
<span class="kw">impl </span>ClassUnicode {
<span class="doccomment">/// Create a new class from a sequence of ranges.
///
/// The given ranges do not need to be in any specific order, and ranges
/// may overlap. Ranges will automatically be sorted into a canonical
/// non-overlapping order.
</span><span class="kw">pub fn </span>new&lt;I&gt;(ranges: I) -&gt; ClassUnicode
<span class="kw">where
</span>I: IntoIterator&lt;Item = ClassUnicodeRange&gt;,
{
ClassUnicode { set: IntervalSet::new(ranges) }
}
<span class="doccomment">/// Create a new class with no ranges.
///
/// An empty class matches nothing. That is, it is equivalent to
/// [`Hir::fail`].
</span><span class="kw">pub fn </span>empty() -&gt; ClassUnicode {
ClassUnicode::new(<span class="macro">vec!</span>[])
}
<span class="doccomment">/// Add a new range to this set.
</span><span class="kw">pub fn </span>push(<span class="kw-2">&amp;mut </span><span class="self">self</span>, range: ClassUnicodeRange) {
<span class="self">self</span>.set.push(range);
}
<span class="doccomment">/// Return an iterator over all ranges in this class.
///
/// The iterator yields ranges in ascending order.
</span><span class="kw">pub fn </span>iter(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; ClassUnicodeIter&lt;<span class="lifetime">&#39;_</span>&gt; {
ClassUnicodeIter(<span class="self">self</span>.set.iter())
}
<span class="doccomment">/// Return the underlying ranges as a slice.
</span><span class="kw">pub fn </span>ranges(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>[ClassUnicodeRange] {
<span class="self">self</span>.set.intervals()
}
<span class="doccomment">/// Expand this character class such that it contains all case folded
/// characters, according to Unicode&#39;s &quot;simple&quot; mapping. For example, if
/// this class consists of the range `a-z`, then applying case folding will
/// result in the class containing both the ranges `a-z` and `A-Z`.
///
/// # Panics
///
/// This routine panics when the case mapping data necessary for this
/// routine to complete is unavailable. This occurs when the `unicode-case`
/// feature is not enabled.
///
/// Callers should prefer using `try_case_fold_simple` instead, which will
/// return an error instead of panicking.
</span><span class="kw">pub fn </span>case_fold_simple(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="self">self</span>.set
.case_fold_simple()
.expect(<span class="string">&quot;unicode-case feature must be enabled&quot;</span>);
}
<span class="doccomment">/// Expand this character class such that it contains all case folded
/// characters, according to Unicode&#39;s &quot;simple&quot; mapping. For example, if
/// this class consists of the range `a-z`, then applying case folding will
/// result in the class containing both the ranges `a-z` and `A-Z`.
///
/// # Error
///
/// This routine returns an error when the case mapping data necessary
/// for this routine to complete is unavailable. This occurs when the
/// `unicode-case` feature is not enabled.
</span><span class="kw">pub fn </span>try_case_fold_simple(
<span class="kw-2">&amp;mut </span><span class="self">self</span>,
) -&gt; core::result::Result&lt;(), CaseFoldError&gt; {
<span class="self">self</span>.set.case_fold_simple()
}
<span class="doccomment">/// Negate this character class.
///
/// For all `c` where `c` is a Unicode scalar value, if `c` was in this
/// set, then it will not be in this set after negation.
</span><span class="kw">pub fn </span>negate(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="self">self</span>.set.negate();
}
<span class="doccomment">/// Union this character class with the given character class, in place.
</span><span class="kw">pub fn </span>union(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: <span class="kw-2">&amp;</span>ClassUnicode) {
<span class="self">self</span>.set.union(<span class="kw-2">&amp;</span>other.set);
}
<span class="doccomment">/// Intersect this character class with the given character class, in
/// place.
</span><span class="kw">pub fn </span>intersect(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: <span class="kw-2">&amp;</span>ClassUnicode) {
<span class="self">self</span>.set.intersect(<span class="kw-2">&amp;</span>other.set);
}
<span class="doccomment">/// Subtract the given character class from this character class, in place.
</span><span class="kw">pub fn </span>difference(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: <span class="kw-2">&amp;</span>ClassUnicode) {
<span class="self">self</span>.set.difference(<span class="kw-2">&amp;</span>other.set);
}
<span class="doccomment">/// Compute the symmetric difference of the given character classes, in
/// place.
///
/// This computes the symmetric difference of two character classes. This
/// removes all elements in this class that are also in the given class,
/// but all adds all elements from the given class that aren&#39;t in this
/// class. That is, the class will contain all elements in either class,
/// but will not contain any elements that are in both classes.
</span><span class="kw">pub fn </span>symmetric_difference(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: <span class="kw-2">&amp;</span>ClassUnicode) {
<span class="self">self</span>.set.symmetric_difference(<span class="kw-2">&amp;</span>other.set);
}
<span class="doccomment">/// Returns true if and only if this character class will either match
/// nothing or only ASCII bytes. Stated differently, this returns false
/// if and only if this class contains a non-ASCII codepoint.
</span><span class="kw">pub fn </span>is_ascii(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.set.intervals().last().map_or(<span class="bool-val">true</span>, |r| r.end &lt;= <span class="string">&#39;\x7F&#39;</span>)
}
<span class="doccomment">/// Returns the length, in bytes, of the smallest string matched by this
/// character class.
///
/// Returns `None` when the class is empty.
</span><span class="kw">pub fn </span>minimum_len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="kw">let </span>first = <span class="self">self</span>.ranges().get(<span class="number">0</span>)<span class="question-mark">?</span>;
<span class="comment">// Correct because c1 &lt; c2 implies c1.len_utf8() &lt; c2.len_utf8().
</span><span class="prelude-val">Some</span>(first.start.len_utf8())
}
<span class="doccomment">/// Returns the length, in bytes, of the longest string matched by this
/// character class.
///
/// Returns `None` when the class is empty.
</span><span class="kw">pub fn </span>maximum_len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="kw">let </span>last = <span class="self">self</span>.ranges().last()<span class="question-mark">?</span>;
<span class="comment">// Correct because c1 &lt; c2 implies c1.len_utf8() &lt; c2.len_utf8().
</span><span class="prelude-val">Some</span>(last.end.len_utf8())
}
<span class="doccomment">/// If this class consists of exactly one codepoint, then return it as
/// a literal byte string.
///
/// If this class is empty or contains more than one codepoint, then `None`
/// is returned.
</span><span class="kw">pub fn </span>literal(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;Vec&lt;u8&gt;&gt; {
<span class="kw">let </span>rs = <span class="self">self</span>.ranges();
<span class="kw">if </span>rs.len() == <span class="number">1 </span>&amp;&amp; rs[<span class="number">0</span>].start == rs[<span class="number">0</span>].end {
<span class="prelude-val">Some</span>(rs[<span class="number">0</span>].start.encode_utf8(<span class="kw-2">&amp;mut </span>[<span class="number">0</span>; <span class="number">4</span>]).to_string().into_bytes())
} <span class="kw">else </span>{
<span class="prelude-val">None
</span>}
}
<span class="doccomment">/// If this class consists of only ASCII ranges, then return its
/// corresponding and equivalent byte class.
</span><span class="kw">pub fn </span>to_byte_class(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;ClassBytes&gt; {
<span class="kw">if </span>!<span class="self">self</span>.is_ascii() {
<span class="kw">return </span><span class="prelude-val">None</span>;
}
<span class="prelude-val">Some</span>(ClassBytes::new(<span class="self">self</span>.ranges().iter().map(|r| {
<span class="comment">// Since we are guaranteed that our codepoint range is ASCII, the
// &#39;u8::try_from&#39; calls below are guaranteed to be correct.
</span>ClassBytesRange {
start: u8::try_from(r.start).unwrap(),
end: u8::try_from(r.end).unwrap(),
}
})))
}
}
<span class="doccomment">/// An iterator over all ranges in a Unicode character class.
///
/// The lifetime `&#39;a` refers to the lifetime of the underlying class.
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">pub struct </span>ClassUnicodeIter&lt;<span class="lifetime">&#39;a</span>&gt;(IntervalSetIter&lt;<span class="lifetime">&#39;a</span>, ClassUnicodeRange&gt;);
<span class="kw">impl</span>&lt;<span class="lifetime">&#39;a</span>&gt; Iterator <span class="kw">for </span>ClassUnicodeIter&lt;<span class="lifetime">&#39;a</span>&gt; {
<span class="kw">type </span>Item = <span class="kw-2">&amp;</span><span class="lifetime">&#39;a </span>ClassUnicodeRange;
<span class="kw">fn </span>next(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span><span class="lifetime">&#39;a </span>ClassUnicodeRange&gt; {
<span class="self">self</span>.<span class="number">0</span>.next()
}
}
<span class="doccomment">/// A single range of characters represented by Unicode scalar values.
///
/// The range is closed. That is, the start and end of the range are included
/// in the range.
</span><span class="attribute">#[derive(Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord)]
</span><span class="kw">pub struct </span>ClassUnicodeRange {
start: char,
end: char,
}
<span class="kw">impl </span>core::fmt::Debug <span class="kw">for </span>ClassUnicodeRange {
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>core::fmt::Formatter&lt;<span class="lifetime">&#39;_</span>&gt;) -&gt; core::fmt::Result {
<span class="kw">let </span>start = <span class="kw">if </span>!<span class="self">self</span>.start.is_whitespace() &amp;&amp; !<span class="self">self</span>.start.is_control()
{
<span class="self">self</span>.start.to_string()
} <span class="kw">else </span>{
<span class="macro">format!</span>(<span class="string">&quot;0x{:X}&quot;</span>, u32::from(<span class="self">self</span>.start))
};
<span class="kw">let </span>end = <span class="kw">if </span>!<span class="self">self</span>.end.is_whitespace() &amp;&amp; !<span class="self">self</span>.end.is_control() {
<span class="self">self</span>.end.to_string()
} <span class="kw">else </span>{
<span class="macro">format!</span>(<span class="string">&quot;0x{:X}&quot;</span>, u32::from(<span class="self">self</span>.end))
};
f.debug_struct(<span class="string">&quot;ClassUnicodeRange&quot;</span>)
.field(<span class="string">&quot;start&quot;</span>, <span class="kw-2">&amp;</span>start)
.field(<span class="string">&quot;end&quot;</span>, <span class="kw-2">&amp;</span>end)
.finish()
}
}
<span class="kw">impl </span>Interval <span class="kw">for </span>ClassUnicodeRange {
<span class="kw">type </span>Bound = char;
<span class="attribute">#[inline]
</span><span class="kw">fn </span>lower(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; char {
<span class="self">self</span>.start
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>upper(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; char {
<span class="self">self</span>.end
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>set_lower(<span class="kw-2">&amp;mut </span><span class="self">self</span>, bound: char) {
<span class="self">self</span>.start = bound;
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>set_upper(<span class="kw-2">&amp;mut </span><span class="self">self</span>, bound: char) {
<span class="self">self</span>.end = bound;
}
<span class="doccomment">/// Apply simple case folding to this Unicode scalar value range.
///
/// Additional ranges are appended to the given vector. Canonical ordering
/// is *not* maintained in the given vector.
</span><span class="kw">fn </span>case_fold_simple(
<span class="kw-2">&amp;</span><span class="self">self</span>,
ranges: <span class="kw-2">&amp;mut </span>Vec&lt;ClassUnicodeRange&gt;,
) -&gt; <span class="prelude-ty">Result</span>&lt;(), unicode::CaseFoldError&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>folder = unicode::SimpleCaseFolder::new()<span class="question-mark">?</span>;
<span class="kw">if </span>!folder.overlaps(<span class="self">self</span>.start, <span class="self">self</span>.end) {
<span class="kw">return </span><span class="prelude-val">Ok</span>(());
}
<span class="kw">let </span>(start, end) = (u32::from(<span class="self">self</span>.start), u32::from(<span class="self">self</span>.end));
<span class="kw">for </span>cp <span class="kw">in </span>(start..=end).filter_map(char::from_u32) {
<span class="kw">for </span><span class="kw-2">&amp;</span>cp_folded <span class="kw">in </span>folder.mapping(cp) {
ranges.push(ClassUnicodeRange::new(cp_folded, cp_folded));
}
}
<span class="prelude-val">Ok</span>(())
}
}
<span class="kw">impl </span>ClassUnicodeRange {
<span class="doccomment">/// Create a new Unicode scalar value range for a character class.
///
/// The returned range is always in a canonical form. That is, the range
/// returned always satisfies the invariant that `start &lt;= end`.
</span><span class="kw">pub fn </span>new(start: char, end: char) -&gt; ClassUnicodeRange {
ClassUnicodeRange::create(start, end)
}
<span class="doccomment">/// Return the start of this range.
///
/// The start of a range is always less than or equal to the end of the
/// range.
</span><span class="kw">pub fn </span>start(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; char {
<span class="self">self</span>.start
}
<span class="doccomment">/// Return the end of this range.
///
/// The end of a range is always greater than or equal to the start of the
/// range.
</span><span class="kw">pub fn </span>end(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; char {
<span class="self">self</span>.end
}
<span class="doccomment">/// Returns the number of codepoints in this range.
</span><span class="kw">pub fn </span>len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; usize {
<span class="kw">let </span>diff = <span class="number">1 </span>+ u32::from(<span class="self">self</span>.end) - u32::from(<span class="self">self</span>.start);
<span class="comment">// This is likely to panic in 16-bit targets since a usize can only fit
// 2^16. It&#39;s not clear what to do here, other than to return an error
// when building a Unicode class that contains a range whose length
// overflows usize. (Which, to be honest, is probably quite common on
// 16-bit targets. For example, this would imply that &#39;.&#39; and &#39;\p{any}&#39;
// would be impossible to build.)
</span>usize::try_from(diff).expect(<span class="string">&quot;char class len fits in usize&quot;</span>)
}
}
<span class="doccomment">/// A set of characters represented by arbitrary bytes (where one byte
/// corresponds to one character).
</span><span class="attribute">#[derive(Clone, Debug, Eq, PartialEq)]
</span><span class="kw">pub struct </span>ClassBytes {
set: IntervalSet&lt;ClassBytesRange&gt;,
}
<span class="kw">impl </span>ClassBytes {
<span class="doccomment">/// Create a new class from a sequence of ranges.
///
/// The given ranges do not need to be in any specific order, and ranges
/// may overlap. Ranges will automatically be sorted into a canonical
/// non-overlapping order.
</span><span class="kw">pub fn </span>new&lt;I&gt;(ranges: I) -&gt; ClassBytes
<span class="kw">where
</span>I: IntoIterator&lt;Item = ClassBytesRange&gt;,
{
ClassBytes { set: IntervalSet::new(ranges) }
}
<span class="doccomment">/// Create a new class with no ranges.
///
/// An empty class matches nothing. That is, it is equivalent to
/// [`Hir::fail`].
</span><span class="kw">pub fn </span>empty() -&gt; ClassBytes {
ClassBytes::new(<span class="macro">vec!</span>[])
}
<span class="doccomment">/// Add a new range to this set.
</span><span class="kw">pub fn </span>push(<span class="kw-2">&amp;mut </span><span class="self">self</span>, range: ClassBytesRange) {
<span class="self">self</span>.set.push(range);
}
<span class="doccomment">/// Return an iterator over all ranges in this class.
///
/// The iterator yields ranges in ascending order.
</span><span class="kw">pub fn </span>iter(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; ClassBytesIter&lt;<span class="lifetime">&#39;_</span>&gt; {
ClassBytesIter(<span class="self">self</span>.set.iter())
}
<span class="doccomment">/// Return the underlying ranges as a slice.
</span><span class="kw">pub fn </span>ranges(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>[ClassBytesRange] {
<span class="self">self</span>.set.intervals()
}
<span class="doccomment">/// Expand this character class such that it contains all case folded
/// characters. For example, if this class consists of the range `a-z`,
/// then applying case folding will result in the class containing both the
/// ranges `a-z` and `A-Z`.
///
/// Note that this only applies ASCII case folding, which is limited to the
/// characters `a-z` and `A-Z`.
</span><span class="kw">pub fn </span>case_fold_simple(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="self">self</span>.set.case_fold_simple().expect(<span class="string">&quot;ASCII case folding never fails&quot;</span>);
}
<span class="doccomment">/// Negate this byte class.
///
/// For all `b` where `b` is a any byte, if `b` was in this set, then it
/// will not be in this set after negation.
</span><span class="kw">pub fn </span>negate(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="self">self</span>.set.negate();
}
<span class="doccomment">/// Union this byte class with the given byte class, in place.
</span><span class="kw">pub fn </span>union(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: <span class="kw-2">&amp;</span>ClassBytes) {
<span class="self">self</span>.set.union(<span class="kw-2">&amp;</span>other.set);
}
<span class="doccomment">/// Intersect this byte class with the given byte class, in place.
</span><span class="kw">pub fn </span>intersect(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: <span class="kw-2">&amp;</span>ClassBytes) {
<span class="self">self</span>.set.intersect(<span class="kw-2">&amp;</span>other.set);
}
<span class="doccomment">/// Subtract the given byte class from this byte class, in place.
</span><span class="kw">pub fn </span>difference(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: <span class="kw-2">&amp;</span>ClassBytes) {
<span class="self">self</span>.set.difference(<span class="kw-2">&amp;</span>other.set);
}
<span class="doccomment">/// Compute the symmetric difference of the given byte classes, in place.
///
/// This computes the symmetric difference of two byte classes. This
/// removes all elements in this class that are also in the given class,
/// but all adds all elements from the given class that aren&#39;t in this
/// class. That is, the class will contain all elements in either class,
/// but will not contain any elements that are in both classes.
</span><span class="kw">pub fn </span>symmetric_difference(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: <span class="kw-2">&amp;</span>ClassBytes) {
<span class="self">self</span>.set.symmetric_difference(<span class="kw-2">&amp;</span>other.set);
}
<span class="doccomment">/// Returns true if and only if this character class will either match
/// nothing or only ASCII bytes. Stated differently, this returns false
/// if and only if this class contains a non-ASCII byte.
</span><span class="kw">pub fn </span>is_ascii(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.set.intervals().last().map_or(<span class="bool-val">true</span>, |r| r.end &lt;= <span class="number">0x7F</span>)
}
<span class="doccomment">/// Returns the length, in bytes, of the smallest string matched by this
/// character class.
///
/// Returns `None` when the class is empty.
</span><span class="kw">pub fn </span>minimum_len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="kw">if </span><span class="self">self</span>.ranges().is_empty() {
<span class="prelude-val">None
</span>} <span class="kw">else </span>{
<span class="prelude-val">Some</span>(<span class="number">1</span>)
}
}
<span class="doccomment">/// Returns the length, in bytes, of the longest string matched by this
/// character class.
///
/// Returns `None` when the class is empty.
</span><span class="kw">pub fn </span>maximum_len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="kw">if </span><span class="self">self</span>.ranges().is_empty() {
<span class="prelude-val">None
</span>} <span class="kw">else </span>{
<span class="prelude-val">Some</span>(<span class="number">1</span>)
}
}
<span class="doccomment">/// If this class consists of exactly one byte, then return it as
/// a literal byte string.
///
/// If this class is empty or contains more than one byte, then `None`
/// is returned.
</span><span class="kw">pub fn </span>literal(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;Vec&lt;u8&gt;&gt; {
<span class="kw">let </span>rs = <span class="self">self</span>.ranges();
<span class="kw">if </span>rs.len() == <span class="number">1 </span>&amp;&amp; rs[<span class="number">0</span>].start == rs[<span class="number">0</span>].end {
<span class="prelude-val">Some</span>(<span class="macro">vec!</span>[rs[<span class="number">0</span>].start])
} <span class="kw">else </span>{
<span class="prelude-val">None
</span>}
}
<span class="doccomment">/// If this class consists of only ASCII ranges, then return its
/// corresponding and equivalent Unicode class.
</span><span class="kw">pub fn </span>to_unicode_class(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;ClassUnicode&gt; {
<span class="kw">if </span>!<span class="self">self</span>.is_ascii() {
<span class="kw">return </span><span class="prelude-val">None</span>;
}
<span class="prelude-val">Some</span>(ClassUnicode::new(<span class="self">self</span>.ranges().iter().map(|r| {
<span class="comment">// Since we are guaranteed that our byte range is ASCII, the
// &#39;char::from&#39; calls below are correct and will not erroneously
// convert a raw byte value into its corresponding codepoint.
</span>ClassUnicodeRange {
start: char::from(r.start),
end: char::from(r.end),
}
})))
}
}
<span class="doccomment">/// An iterator over all ranges in a byte character class.
///
/// The lifetime `&#39;a` refers to the lifetime of the underlying class.
</span><span class="attribute">#[derive(Debug)]
</span><span class="kw">pub struct </span>ClassBytesIter&lt;<span class="lifetime">&#39;a</span>&gt;(IntervalSetIter&lt;<span class="lifetime">&#39;a</span>, ClassBytesRange&gt;);
<span class="kw">impl</span>&lt;<span class="lifetime">&#39;a</span>&gt; Iterator <span class="kw">for </span>ClassBytesIter&lt;<span class="lifetime">&#39;a</span>&gt; {
<span class="kw">type </span>Item = <span class="kw-2">&amp;</span><span class="lifetime">&#39;a </span>ClassBytesRange;
<span class="kw">fn </span>next(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;<span class="kw-2">&amp;</span><span class="lifetime">&#39;a </span>ClassBytesRange&gt; {
<span class="self">self</span>.<span class="number">0</span>.next()
}
}
<span class="doccomment">/// A single range of characters represented by arbitrary bytes.
///
/// The range is closed. That is, the start and end of the range are included
/// in the range.
</span><span class="attribute">#[derive(Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord)]
</span><span class="kw">pub struct </span>ClassBytesRange {
start: u8,
end: u8,
}
<span class="kw">impl </span>Interval <span class="kw">for </span>ClassBytesRange {
<span class="kw">type </span>Bound = u8;
<span class="attribute">#[inline]
</span><span class="kw">fn </span>lower(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; u8 {
<span class="self">self</span>.start
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>upper(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; u8 {
<span class="self">self</span>.end
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>set_lower(<span class="kw-2">&amp;mut </span><span class="self">self</span>, bound: u8) {
<span class="self">self</span>.start = bound;
}
<span class="attribute">#[inline]
</span><span class="kw">fn </span>set_upper(<span class="kw-2">&amp;mut </span><span class="self">self</span>, bound: u8) {
<span class="self">self</span>.end = bound;
}
<span class="doccomment">/// Apply simple case folding to this byte range. Only ASCII case mappings
/// (for a-z) are applied.
///
/// Additional ranges are appended to the given vector. Canonical ordering
/// is *not* maintained in the given vector.
</span><span class="kw">fn </span>case_fold_simple(
<span class="kw-2">&amp;</span><span class="self">self</span>,
ranges: <span class="kw-2">&amp;mut </span>Vec&lt;ClassBytesRange&gt;,
) -&gt; <span class="prelude-ty">Result</span>&lt;(), unicode::CaseFoldError&gt; {
<span class="kw">if </span>!ClassBytesRange::new(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;z&#39;</span>).is_intersection_empty(<span class="self">self</span>) {
<span class="kw">let </span>lower = cmp::max(<span class="self">self</span>.start, <span class="string">b&#39;a&#39;</span>);
<span class="kw">let </span>upper = cmp::min(<span class="self">self</span>.end, <span class="string">b&#39;z&#39;</span>);
ranges.push(ClassBytesRange::new(lower - <span class="number">32</span>, upper - <span class="number">32</span>));
}
<span class="kw">if </span>!ClassBytesRange::new(<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;Z&#39;</span>).is_intersection_empty(<span class="self">self</span>) {
<span class="kw">let </span>lower = cmp::max(<span class="self">self</span>.start, <span class="string">b&#39;A&#39;</span>);
<span class="kw">let </span>upper = cmp::min(<span class="self">self</span>.end, <span class="string">b&#39;Z&#39;</span>);
ranges.push(ClassBytesRange::new(lower + <span class="number">32</span>, upper + <span class="number">32</span>));
}
<span class="prelude-val">Ok</span>(())
}
}
<span class="kw">impl </span>ClassBytesRange {
<span class="doccomment">/// Create a new byte range for a character class.
///
/// The returned range is always in a canonical form. That is, the range
/// returned always satisfies the invariant that `start &lt;= end`.
</span><span class="kw">pub fn </span>new(start: u8, end: u8) -&gt; ClassBytesRange {
ClassBytesRange::create(start, end)
}
<span class="doccomment">/// Return the start of this range.
///
/// The start of a range is always less than or equal to the end of the
/// range.
</span><span class="kw">pub fn </span>start(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; u8 {
<span class="self">self</span>.start
}
<span class="doccomment">/// Return the end of this range.
///
/// The end of a range is always greater than or equal to the start of the
/// range.
</span><span class="kw">pub fn </span>end(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; u8 {
<span class="self">self</span>.end
}
<span class="doccomment">/// Returns the number of bytes in this range.
</span><span class="kw">pub fn </span>len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; usize {
usize::from(<span class="self">self</span>.end.checked_sub(<span class="self">self</span>.start).unwrap())
.checked_add(<span class="number">1</span>)
.unwrap()
}
}
<span class="kw">impl </span>core::fmt::Debug <span class="kw">for </span>ClassBytesRange {
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>core::fmt::Formatter&lt;<span class="lifetime">&#39;_</span>&gt;) -&gt; core::fmt::Result {
f.debug_struct(<span class="string">&quot;ClassBytesRange&quot;</span>)
.field(<span class="string">&quot;start&quot;</span>, <span class="kw-2">&amp;</span><span class="kw">crate</span>::debug::Byte(<span class="self">self</span>.start))
.field(<span class="string">&quot;end&quot;</span>, <span class="kw-2">&amp;</span><span class="kw">crate</span>::debug::Byte(<span class="self">self</span>.end))
.finish()
}
}
<span class="doccomment">/// The high-level intermediate representation for a look-around assertion.
///
/// An assertion match is always zero-length. Also called an &quot;empty match.&quot;
</span><span class="attribute">#[derive(Clone, Copy, Debug, Eq, PartialEq)]
</span><span class="kw">pub enum </span>Look {
<span class="doccomment">/// Match the beginning of text. Specifically, this matches at the starting
/// position of the input.
</span>Start = <span class="number">1 </span>&lt;&lt; <span class="number">0</span>,
<span class="doccomment">/// Match the end of text. Specifically, this matches at the ending
/// position of the input.
</span>End = <span class="number">1 </span>&lt;&lt; <span class="number">1</span>,
<span class="doccomment">/// Match the beginning of a line or the beginning of text. Specifically,
/// this matches at the starting position of the input, or at the position
/// immediately following a `\n` character.
</span>StartLF = <span class="number">1 </span>&lt;&lt; <span class="number">2</span>,
<span class="doccomment">/// Match the end of a line or the end of text. Specifically, this matches
/// at the end position of the input, or at the position immediately
/// preceding a `\n` character.
</span>EndLF = <span class="number">1 </span>&lt;&lt; <span class="number">3</span>,
<span class="doccomment">/// Match the beginning of a line or the beginning of text. Specifically,
/// this matches at the starting position of the input, or at the position
/// immediately following either a `\r` or `\n` character, but never after
/// a `\r` when a `\n` follows.
</span>StartCRLF = <span class="number">1 </span>&lt;&lt; <span class="number">4</span>,
<span class="doccomment">/// Match the end of a line or the end of text. Specifically, this matches
/// at the end position of the input, or at the position immediately
/// preceding a `\r` or `\n` character, but never before a `\n` when a `\r`
/// precedes it.
</span>EndCRLF = <span class="number">1 </span>&lt;&lt; <span class="number">5</span>,
<span class="doccomment">/// Match an ASCII-only word boundary. That is, this matches a position
/// where the left adjacent character and right adjacent character
/// correspond to a word and non-word or a non-word and word character.
</span>WordAscii = <span class="number">1 </span>&lt;&lt; <span class="number">6</span>,
<span class="doccomment">/// Match an ASCII-only negation of a word boundary.
</span>WordAsciiNegate = <span class="number">1 </span>&lt;&lt; <span class="number">7</span>,
<span class="doccomment">/// Match a Unicode-aware word boundary. That is, this matches a position
/// where the left adjacent character and right adjacent character
/// correspond to a word and non-word or a non-word and word character.
</span>WordUnicode = <span class="number">1 </span>&lt;&lt; <span class="number">8</span>,
<span class="doccomment">/// Match a Unicode-aware negation of a word boundary.
</span>WordUnicodeNegate = <span class="number">1 </span>&lt;&lt; <span class="number">9</span>,
}
<span class="kw">impl </span>Look {
<span class="doccomment">/// Flip the look-around assertion to its equivalent for reverse searches.
/// For example, `StartLF` gets translated to `EndLF`.
///
/// Some assertions, such as `WordUnicode`, remain the same since they
/// match the same positions regardless of the direction of the search.
</span><span class="attribute">#[inline]
</span><span class="kw">pub const fn </span>reversed(<span class="self">self</span>) -&gt; Look {
<span class="kw">match </span><span class="self">self </span>{
Look::Start =&gt; Look::End,
Look::End =&gt; Look::Start,
Look::StartLF =&gt; Look::EndLF,
Look::EndLF =&gt; Look::StartLF,
Look::StartCRLF =&gt; Look::EndCRLF,
Look::EndCRLF =&gt; Look::StartCRLF,
Look::WordAscii =&gt; Look::WordAscii,
Look::WordAsciiNegate =&gt; Look::WordAsciiNegate,
Look::WordUnicode =&gt; Look::WordUnicode,
Look::WordUnicodeNegate =&gt; Look::WordUnicodeNegate,
}
}
<span class="doccomment">/// Return the underlying representation of this look-around enumeration
/// as an integer. Giving the return value to the [`Look::from_repr`]
/// constructor is guaranteed to return the same look-around variant that
/// one started with within a semver compatible release of this crate.
</span><span class="attribute">#[inline]
</span><span class="kw">pub const fn </span>as_repr(<span class="self">self</span>) -&gt; u16 {
<span class="comment">// AFAIK, &#39;as&#39; is the only way to zero-cost convert an int enum to an
// actual int.
</span><span class="self">self </span><span class="kw">as </span>u16
}
<span class="doccomment">/// Given the underlying representation of a `Look` value, return the
/// corresponding `Look` value if the representation is valid. Otherwise
/// `None` is returned.
</span><span class="attribute">#[inline]
</span><span class="kw">pub const fn </span>from_repr(repr: u16) -&gt; <span class="prelude-ty">Option</span>&lt;Look&gt; {
<span class="kw">match </span>repr {
<span class="number">0b00_0000_0001 </span>=&gt; <span class="prelude-val">Some</span>(Look::Start),
<span class="number">0b00_0000_0010 </span>=&gt; <span class="prelude-val">Some</span>(Look::End),
<span class="number">0b00_0000_0100 </span>=&gt; <span class="prelude-val">Some</span>(Look::StartLF),
<span class="number">0b00_0000_1000 </span>=&gt; <span class="prelude-val">Some</span>(Look::EndLF),
<span class="number">0b00_0001_0000 </span>=&gt; <span class="prelude-val">Some</span>(Look::StartCRLF),
<span class="number">0b00_0010_0000 </span>=&gt; <span class="prelude-val">Some</span>(Look::EndCRLF),
<span class="number">0b00_0100_0000 </span>=&gt; <span class="prelude-val">Some</span>(Look::WordAscii),
<span class="number">0b00_1000_0000 </span>=&gt; <span class="prelude-val">Some</span>(Look::WordAsciiNegate),
<span class="number">0b01_0000_0000 </span>=&gt; <span class="prelude-val">Some</span>(Look::WordUnicode),
<span class="number">0b10_0000_0000 </span>=&gt; <span class="prelude-val">Some</span>(Look::WordUnicodeNegate),
<span class="kw">_ </span>=&gt; <span class="prelude-val">None</span>,
}
}
<span class="doccomment">/// Returns a convenient single codepoint representation of this
/// look-around assertion. Each assertion is guaranteed to be represented
/// by a distinct character.
///
/// This is useful for succinctly representing a look-around assertion in
/// human friendly but succinct output intended for a programmer working on
/// regex internals.
</span><span class="attribute">#[inline]
</span><span class="kw">pub const fn </span>as_char(<span class="self">self</span>) -&gt; char {
<span class="kw">match </span><span class="self">self </span>{
Look::Start =&gt; <span class="string">&#39;A&#39;</span>,
Look::End =&gt; <span class="string">&#39;z&#39;</span>,
Look::StartLF =&gt; <span class="string">&#39;^&#39;</span>,
Look::EndLF =&gt; <span class="string">&#39;$&#39;</span>,
Look::StartCRLF =&gt; <span class="string">&#39;r&#39;</span>,
Look::EndCRLF =&gt; <span class="string">&#39;R&#39;</span>,
Look::WordAscii =&gt; <span class="string">&#39;b&#39;</span>,
Look::WordAsciiNegate =&gt; <span class="string">&#39;B&#39;</span>,
Look::WordUnicode =&gt; <span class="string">&#39;𝛃&#39;</span>,
Look::WordUnicodeNegate =&gt; <span class="string">&#39;𝚩&#39;</span>,
}
}
}
<span class="doccomment">/// The high-level intermediate representation for a capturing group.
///
/// A capturing group always has an index and a child expression. It may
/// also have a name associated with it (e.g., `(?P&lt;foo&gt;\w)`), but it&#39;s not
/// necessary.
///
/// Note that there is no explicit representation of a non-capturing group
/// in a `Hir`. Instead, non-capturing grouping is handled automatically by
/// the recursive structure of the `Hir` itself.
</span><span class="attribute">#[derive(Clone, Debug, Eq, PartialEq)]
</span><span class="kw">pub struct </span>Capture {
<span class="doccomment">/// The capture index of the capture.
</span><span class="kw">pub </span>index: u32,
<span class="doccomment">/// The name of the capture, if it exists.
</span><span class="kw">pub </span>name: <span class="prelude-ty">Option</span>&lt;Box&lt;str&gt;&gt;,
<span class="doccomment">/// The expression inside the capturing group, which may be empty.
</span><span class="kw">pub </span>sub: Box&lt;Hir&gt;,
}
<span class="doccomment">/// The high-level intermediate representation of a repetition operator.
///
/// A repetition operator permits the repetition of an arbitrary
/// sub-expression.
</span><span class="attribute">#[derive(Clone, Debug, Eq, PartialEq)]
</span><span class="kw">pub struct </span>Repetition {
<span class="doccomment">/// The minimum range of the repetition.
///
/// Note that special cases like `?`, `+` and `*` all get translated into
/// the ranges `{0,1}`, `{1,}` and `{0,}`, respectively.
///
/// When `min` is zero, this expression can match the empty string
/// regardless of what its sub-expression is.
</span><span class="kw">pub </span>min: u32,
<span class="doccomment">/// The maximum range of the repetition.
///
/// Note that when `max` is `None`, `min` acts as a lower bound but where
/// there is no upper bound. For something like `x{5}` where the min and
/// max are equivalent, `min` will be set to `5` and `max` will be set to
/// `Some(5)`.
</span><span class="kw">pub </span>max: <span class="prelude-ty">Option</span>&lt;u32&gt;,
<span class="doccomment">/// Whether this repetition operator is greedy or not. A greedy operator
/// will match as much as it can. A non-greedy operator will match as
/// little as it can.
///
/// Typically, operators are greedy by default and are only non-greedy when
/// a `?` suffix is used, e.g., `(expr)*` is greedy while `(expr)*?` is
/// not. However, this can be inverted via the `U` &quot;ungreedy&quot; flag.
</span><span class="kw">pub </span>greedy: bool,
<span class="doccomment">/// The expression being repeated.
</span><span class="kw">pub </span>sub: Box&lt;Hir&gt;,
}
<span class="kw">impl </span>Repetition {
<span class="doccomment">/// Returns a new repetition with the same `min`, `max` and `greedy`
/// values, but with its sub-expression replaced with the one given.
</span><span class="kw">pub fn </span>with(<span class="kw-2">&amp;</span><span class="self">self</span>, sub: Hir) -&gt; Repetition {
Repetition {
min: <span class="self">self</span>.min,
max: <span class="self">self</span>.max,
greedy: <span class="self">self</span>.greedy,
sub: Box::new(sub),
}
}
}
<span class="doccomment">/// A type describing the different flavors of `.`.
///
/// This type is meant to be used with [`Hir::dot`], which is a convenience
/// routine for building HIR values derived from the `.` regex.
</span><span class="attribute">#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
</span><span class="kw">pub enum </span>Dot {
<span class="doccomment">/// Matches the UTF-8 encoding of any Unicode scalar value.
///
/// This is equivalent to `(?su:.)` and also `\p{any}`.
</span>AnyChar,
<span class="doccomment">/// Matches any byte value.
///
/// This is equivalent to `(?s-u:.)` and also `(?-u:[\x00-\xFF])`.
</span>AnyByte,
<span class="doccomment">/// Matches the UTF-8 encoding of any Unicode scalar value except for `\n`.
///
/// This is equivalent to `(?u-s:.)` and also `[\p{any}--\n]`.
</span>AnyCharExceptLF,
<span class="doccomment">/// Matches the UTF-8 encoding of any Unicode scalar value except for `\r`
/// and `\n`.
///
/// This is equivalent to `(?uR-s:.)` and also `[\p{any}--\r\n]`.
</span>AnyCharExceptCRLF,
<span class="doccomment">/// Matches any byte value except for `\n`.
///
/// This is equivalent to `(?-su:.)` and also `(?-u:[[\x00-\xFF]--\n])`.
</span>AnyByteExceptLF,
<span class="doccomment">/// Matches any byte value except for `\r` and `\n`.
///
/// This is equivalent to `(?R-su:.)` and also `(?-u:[[\x00-\xFF]--\r\n])`.
</span>AnyByteExceptCRLF,
}
<span class="doccomment">/// A custom `Drop` impl is used for `HirKind` such that it uses constant stack
/// space but heap space proportional to the depth of the total `Hir`.
</span><span class="kw">impl </span>Drop <span class="kw">for </span>Hir {
<span class="kw">fn </span>drop(<span class="kw-2">&amp;mut </span><span class="self">self</span>) {
<span class="kw">use </span>core::mem;
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self</span>.kind() {
HirKind::Empty
| HirKind::Literal(<span class="kw">_</span>)
| HirKind::Class(<span class="kw">_</span>)
| HirKind::Look(<span class="kw">_</span>) =&gt; <span class="kw">return</span>,
HirKind::Capture(<span class="kw-2">ref </span>x) <span class="kw">if </span>x.sub.kind.subs().is_empty() =&gt; <span class="kw">return</span>,
HirKind::Repetition(<span class="kw-2">ref </span>x) <span class="kw">if </span>x.sub.kind.subs().is_empty() =&gt; {
<span class="kw">return
</span>}
HirKind::Concat(<span class="kw-2">ref </span>x) <span class="kw">if </span>x.is_empty() =&gt; <span class="kw">return</span>,
HirKind::Alternation(<span class="kw-2">ref </span>x) <span class="kw">if </span>x.is_empty() =&gt; <span class="kw">return</span>,
<span class="kw">_ </span>=&gt; {}
}
<span class="kw">let </span><span class="kw-2">mut </span>stack = <span class="macro">vec!</span>[mem::replace(<span class="self">self</span>, Hir::empty())];
<span class="kw">while let </span><span class="prelude-val">Some</span>(<span class="kw-2">mut </span>expr) = stack.pop() {
<span class="kw">match </span>expr.kind {
HirKind::Empty
| HirKind::Literal(<span class="kw">_</span>)
| HirKind::Class(<span class="kw">_</span>)
| HirKind::Look(<span class="kw">_</span>) =&gt; {}
HirKind::Capture(<span class="kw-2">ref mut </span>x) =&gt; {
stack.push(mem::replace(<span class="kw-2">&amp;mut </span>x.sub, Hir::empty()));
}
HirKind::Repetition(<span class="kw-2">ref mut </span>x) =&gt; {
stack.push(mem::replace(<span class="kw-2">&amp;mut </span>x.sub, Hir::empty()));
}
HirKind::Concat(<span class="kw-2">ref mut </span>x) =&gt; {
stack.extend(x.drain(..));
}
HirKind::Alternation(<span class="kw-2">ref mut </span>x) =&gt; {
stack.extend(x.drain(..));
}
}
}
}
}
<span class="doccomment">/// A type that collects various properties of an HIR value.
///
/// Properties are always scalar values and represent meta data that is
/// computed inductively on an HIR value. Properties are defined for all
/// HIR values.
///
/// All methods on a `Properties` value take constant time and are meant to
/// be cheap to call.
</span><span class="attribute">#[derive(Clone, Debug, Eq, PartialEq)]
</span><span class="kw">pub struct </span>Properties(Box&lt;PropertiesI&gt;);
<span class="doccomment">/// The property definition. It is split out so that we can box it, and
/// there by make `Properties` use less stack size. This is kind-of important
/// because every HIR value has a `Properties` attached to it.
///
/// This does have the unfortunate consequence that creating any HIR value
/// always leads to at least one alloc for properties, but this is generally
/// true anyway (for pretty much all HirKinds except for look-arounds).
</span><span class="attribute">#[derive(Clone, Debug, Eq, PartialEq)]
</span><span class="kw">struct </span>PropertiesI {
minimum_len: <span class="prelude-ty">Option</span>&lt;usize&gt;,
maximum_len: <span class="prelude-ty">Option</span>&lt;usize&gt;,
look_set: LookSet,
look_set_prefix: LookSet,
look_set_suffix: LookSet,
look_set_prefix_any: LookSet,
look_set_suffix_any: LookSet,
utf8: bool,
explicit_captures_len: usize,
static_explicit_captures_len: <span class="prelude-ty">Option</span>&lt;usize&gt;,
literal: bool,
alternation_literal: bool,
}
<span class="kw">impl </span>Properties {
<span class="doccomment">/// Returns the length (in bytes) of the smallest string matched by this
/// HIR.
///
/// A return value of `0` is possible and occurs when the HIR can match an
/// empty string.
///
/// `None` is returned when there is no minimum length. This occurs in
/// precisely the cases where the HIR matches nothing. i.e., The language
/// the regex matches is empty. An example of such a regex is `\P{any}`.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>minimum_len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="self">self</span>.<span class="number">0</span>.minimum_len
}
<span class="doccomment">/// Returns the length (in bytes) of the longest string matched by this
/// HIR.
///
/// A return value of `0` is possible and occurs when nothing longer than
/// the empty string is in the language described by this HIR.
///
/// `None` is returned when there is no longest matching string. This
/// occurs when the HIR matches nothing or when there is no upper bound on
/// the length of matching strings. Example of such regexes are `\P{any}`
/// (matches nothing) and `a+` (has no upper bound).
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>maximum_len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="self">self</span>.<span class="number">0</span>.maximum_len
}
<span class="doccomment">/// Returns a set of all look-around assertions that appear at least once
/// in this HIR value.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>look_set(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; LookSet {
<span class="self">self</span>.<span class="number">0</span>.look_set
}
<span class="doccomment">/// Returns a set of all look-around assertions that appear as a prefix for
/// this HIR value. That is, the set returned corresponds to the set of
/// assertions that must be passed before matching any bytes in a haystack.
///
/// For example, `hir.look_set_prefix().contains(Look::Start)` returns true
/// if and only if the HIR is fully anchored at the start.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>look_set_prefix(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; LookSet {
<span class="self">self</span>.<span class="number">0</span>.look_set_prefix
}
<span class="doccomment">/// Returns a set of all look-around assertions that appear as a _possible_
/// prefix for this HIR value. That is, the set returned corresponds to the
/// set of assertions that _may_ be passed before matching any bytes in a
/// haystack.
///
/// For example, `hir.look_set_prefix_any().contains(Look::Start)` returns
/// true if and only if it&#39;s possible for the regex to match through a
/// anchored assertion before consuming any input.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>look_set_prefix_any(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; LookSet {
<span class="self">self</span>.<span class="number">0</span>.look_set_prefix_any
}
<span class="doccomment">/// Returns a set of all look-around assertions that appear as a suffix for
/// this HIR value. That is, the set returned corresponds to the set of
/// assertions that must be passed in order to be considered a match after
/// all other consuming HIR expressions.
///
/// For example, `hir.look_set_suffix().contains(Look::End)` returns true
/// if and only if the HIR is fully anchored at the end.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>look_set_suffix(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; LookSet {
<span class="self">self</span>.<span class="number">0</span>.look_set_suffix
}
<span class="doccomment">/// Returns a set of all look-around assertions that appear as a _possible_
/// suffix for this HIR value. That is, the set returned corresponds to the
/// set of assertions that _may_ be passed before matching any bytes in a
/// haystack.
///
/// For example, `hir.look_set_suffix_any().contains(Look::End)` returns
/// true if and only if it&#39;s possible for the regex to match through a
/// anchored assertion at the end of a match without consuming any input.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>look_set_suffix_any(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; LookSet {
<span class="self">self</span>.<span class="number">0</span>.look_set_suffix_any
}
<span class="doccomment">/// Return true if and only if the corresponding HIR will always match
/// valid UTF-8.
///
/// When this returns false, then it is possible for this HIR expression to
/// match invalid UTF-8, including by matching between the code units of
/// a single UTF-8 encoded codepoint.
///
/// Note that this returns true even when the corresponding HIR can match
/// the empty string. Since an empty string can technically appear between
/// UTF-8 code units, it is possible for a match to be reported that splits
/// a codepoint which could in turn be considered matching invalid UTF-8.
/// However, it is generally assumed that such empty matches are handled
/// specially by the search routine if it is absolutely required that
/// matches not split a codepoint.
///
/// # Example
///
/// This code example shows the UTF-8 property of a variety of patterns.
///
/// ```
/// use regex_syntax::{ParserBuilder, parse};
///
/// // Examples of &#39;is_utf8() == true&#39;.
/// assert!(parse(r&quot;a&quot;)?.properties().is_utf8());
/// assert!(parse(r&quot;[^a]&quot;)?.properties().is_utf8());
/// assert!(parse(r&quot;.&quot;)?.properties().is_utf8());
/// assert!(parse(r&quot;\W&quot;)?.properties().is_utf8());
/// assert!(parse(r&quot;\b&quot;)?.properties().is_utf8());
/// assert!(parse(r&quot;\B&quot;)?.properties().is_utf8());
/// assert!(parse(r&quot;(?-u)\b&quot;)?.properties().is_utf8());
/// assert!(parse(r&quot;(?-u)\B&quot;)?.properties().is_utf8());
/// // Unicode mode is enabled by default, and in
/// // that mode, all \x hex escapes are treated as
/// // codepoints. So this actually matches the UTF-8
/// // encoding of U+00FF.
/// assert!(parse(r&quot;\xFF&quot;)?.properties().is_utf8());
///
/// // Now we show examples of &#39;is_utf8() == false&#39;.
/// // The only way to do this is to force the parser
/// // to permit invalid UTF-8, otherwise all of these
/// // would fail to parse!
/// let parse = |pattern| {
/// ParserBuilder::new().utf8(false).build().parse(pattern)
/// };
/// assert!(!parse(r&quot;(?-u)[^a]&quot;)?.properties().is_utf8());
/// assert!(!parse(r&quot;(?-u).&quot;)?.properties().is_utf8());
/// assert!(!parse(r&quot;(?-u)\W&quot;)?.properties().is_utf8());
/// // Conversely to the equivalent example above,
/// // when Unicode mode is disabled, \x hex escapes
/// // are treated as their raw byte values.
/// assert!(!parse(r&quot;(?-u)\xFF&quot;)?.properties().is_utf8());
/// // Note that just because we disabled UTF-8 in the
/// // parser doesn&#39;t mean we still can&#39;t use Unicode.
/// // It is enabled by default, so \xFF is still
/// // equivalent to matching the UTF-8 encoding of
/// // U+00FF by default.
/// assert!(parse(r&quot;\xFF&quot;)?.properties().is_utf8());
/// // Even though we use raw bytes that individually
/// // are not valid UTF-8, when combined together, the
/// // overall expression *does* match valid UTF-8!
/// assert!(parse(r&quot;(?-u)\xE2\x98\x83&quot;)?.properties().is_utf8());
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>is_utf8(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.<span class="number">0</span>.utf8
}
<span class="doccomment">/// Returns the total number of explicit capturing groups in the
/// corresponding HIR.
///
/// Note that this does not include the implicit capturing group
/// corresponding to the entire match that is typically included by regex
/// engines.
///
/// # Example
///
/// This method will return `0` for `a` and `1` for `(a)`:
///
/// ```
/// use regex_syntax::parse;
///
/// assert_eq!(0, parse(&quot;a&quot;)?.properties().explicit_captures_len());
/// assert_eq!(1, parse(&quot;(a)&quot;)?.properties().explicit_captures_len());
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>explicit_captures_len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; usize {
<span class="self">self</span>.<span class="number">0</span>.explicit_captures_len
}
<span class="doccomment">/// Returns the total number of explicit capturing groups that appear in
/// every possible match.
///
/// If the number of capture groups can vary depending on the match, then
/// this returns `None`. That is, a value is only returned when the number
/// of matching groups is invariant or &quot;static.&quot;
///
/// Note that this does not include the implicit capturing group
/// corresponding to the entire match.
///
/// # Example
///
/// This shows a few cases where a static number of capture groups is
/// available and a few cases where it is not.
///
/// ```
/// use regex_syntax::parse;
///
/// let len = |pattern| {
/// parse(pattern).map(|h| {
/// h.properties().static_explicit_captures_len()
/// })
/// };
///
/// assert_eq!(Some(0), len(&quot;a&quot;)?);
/// assert_eq!(Some(1), len(&quot;(a)&quot;)?);
/// assert_eq!(Some(1), len(&quot;(a)|(b)&quot;)?);
/// assert_eq!(Some(2), len(&quot;(a)(b)|(c)(d)&quot;)?);
/// assert_eq!(None, len(&quot;(a)|b&quot;)?);
/// assert_eq!(None, len(&quot;a|(b)&quot;)?);
/// assert_eq!(None, len(&quot;(b)*&quot;)?);
/// assert_eq!(Some(1), len(&quot;(b)+&quot;)?);
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>static_explicit_captures_len(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;usize&gt; {
<span class="self">self</span>.<span class="number">0</span>.static_explicit_captures_len
}
<span class="doccomment">/// Return true if and only if this HIR is a simple literal. This is
/// only true when this HIR expression is either itself a `Literal` or a
/// concatenation of only `Literal`s.
///
/// For example, `f` and `foo` are literals, but `f+`, `(foo)`, `foo()` and
/// the empty string are not (even though they contain sub-expressions that
/// are literals).
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>is_literal(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.<span class="number">0</span>.literal
}
<span class="doccomment">/// Return true if and only if this HIR is either a simple literal or an
/// alternation of simple literals. This is only
/// true when this HIR expression is either itself a `Literal` or a
/// concatenation of only `Literal`s or an alternation of only `Literal`s.
///
/// For example, `f`, `foo`, `a|b|c`, and `foo|bar|baz` are alternation
/// literals, but `f+`, `(foo)`, `foo()`, and the empty pattern are not
/// (even though that contain sub-expressions that are literals).
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>is_alternation_literal(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.<span class="number">0</span>.alternation_literal
}
<span class="doccomment">/// Returns the total amount of heap memory usage, in bytes, used by this
/// `Properties` value.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>memory_usage(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; usize {
core::mem::size_of::&lt;PropertiesI&gt;()
}
<span class="doccomment">/// Returns a new set of properties that corresponds to the union of the
/// iterator of properties given.
///
/// This is useful when one has multiple `Hir` expressions and wants
/// to combine them into a single alternation without constructing the
/// corresponding `Hir`. This routine provides a way of combining the
/// properties of each `Hir` expression into one set of properties
/// representing the union of those expressions.
///
/// # Example: union with HIRs that never match
///
/// This example shows that unioning properties together with one that
/// represents a regex that never matches will &quot;poison&quot; certain attributes,
/// like the minimum and maximum lengths.
///
/// ```
/// use regex_syntax::{hir::Properties, parse};
///
/// let hir1 = parse(&quot;ab?c?&quot;)?;
/// assert_eq!(Some(1), hir1.properties().minimum_len());
/// assert_eq!(Some(3), hir1.properties().maximum_len());
///
/// let hir2 = parse(r&quot;[a&amp;&amp;b]&quot;)?;
/// assert_eq!(None, hir2.properties().minimum_len());
/// assert_eq!(None, hir2.properties().maximum_len());
///
/// let hir3 = parse(r&quot;wxy?z?&quot;)?;
/// assert_eq!(Some(2), hir3.properties().minimum_len());
/// assert_eq!(Some(4), hir3.properties().maximum_len());
///
/// let unioned = Properties::union([
/// hir1.properties(),
/// hir2.properties(),
/// hir3.properties(),
/// ]);
/// assert_eq!(None, unioned.minimum_len());
/// assert_eq!(None, unioned.maximum_len());
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
///
/// The maximum length can also be &quot;poisoned&quot; by a pattern that has no
/// upper bound on the length of a match. The minimum length remains
/// unaffected:
///
/// ```
/// use regex_syntax::{hir::Properties, parse};
///
/// let hir1 = parse(&quot;ab?c?&quot;)?;
/// assert_eq!(Some(1), hir1.properties().minimum_len());
/// assert_eq!(Some(3), hir1.properties().maximum_len());
///
/// let hir2 = parse(r&quot;a+&quot;)?;
/// assert_eq!(Some(1), hir2.properties().minimum_len());
/// assert_eq!(None, hir2.properties().maximum_len());
///
/// let hir3 = parse(r&quot;wxy?z?&quot;)?;
/// assert_eq!(Some(2), hir3.properties().minimum_len());
/// assert_eq!(Some(4), hir3.properties().maximum_len());
///
/// let unioned = Properties::union([
/// hir1.properties(),
/// hir2.properties(),
/// hir3.properties(),
/// ]);
/// assert_eq!(Some(1), unioned.minimum_len());
/// assert_eq!(None, unioned.maximum_len());
///
/// # Ok::&lt;(), Box&lt;dyn std::error::Error&gt;&gt;(())
/// ```
</span><span class="kw">pub fn </span>union&lt;I, P&gt;(props: I) -&gt; Properties
<span class="kw">where
</span>I: IntoIterator&lt;Item = P&gt;,
P: core::borrow::Borrow&lt;Properties&gt;,
{
<span class="kw">let </span><span class="kw-2">mut </span>it = props.into_iter().peekable();
<span class="comment">// While empty alternations aren&#39;t possible, we still behave as if they
// are. When we have an empty alternate, then clearly the look-around
// prefix and suffix is empty. Otherwise, it is the intersection of all
// prefixes and suffixes (respectively) of the branches.
</span><span class="kw">let </span>fix = <span class="kw">if </span>it.peek().is_none() {
LookSet::empty()
} <span class="kw">else </span>{
LookSet::full()
};
<span class="comment">// And also, an empty alternate means we have 0 static capture groups,
// but we otherwise start with the number corresponding to the first
// alternate. If any subsequent alternate has a different number of
// static capture groups, then we overall have a variation and not a
// static number of groups.
</span><span class="kw">let </span>static_explicit_captures_len =
it.peek().and_then(|p| p.borrow().static_explicit_captures_len());
<span class="comment">// The base case is an empty alternation, which matches nothing.
// Note though that empty alternations aren&#39;t possible, because the
// Hir::alternation smart constructor rewrites those as empty character
// classes.
</span><span class="kw">let </span><span class="kw-2">mut </span>props = PropertiesI {
minimum_len: <span class="prelude-val">None</span>,
maximum_len: <span class="prelude-val">None</span>,
look_set: LookSet::empty(),
look_set_prefix: fix,
look_set_suffix: fix,
look_set_prefix_any: LookSet::empty(),
look_set_suffix_any: LookSet::empty(),
utf8: <span class="bool-val">true</span>,
explicit_captures_len: <span class="number">0</span>,
static_explicit_captures_len,
literal: <span class="bool-val">false</span>,
alternation_literal: <span class="bool-val">true</span>,
};
<span class="kw">let </span>(<span class="kw-2">mut </span>min_poisoned, <span class="kw-2">mut </span>max_poisoned) = (<span class="bool-val">false</span>, <span class="bool-val">false</span>);
<span class="comment">// Handle properties that need to visit every child hir.
</span><span class="kw">for </span>prop <span class="kw">in </span>it {
<span class="kw">let </span>p = prop.borrow();
props.look_set.set_union(p.look_set());
props.look_set_prefix.set_intersect(p.look_set_prefix());
props.look_set_suffix.set_intersect(p.look_set_suffix());
props.look_set_prefix_any.set_union(p.look_set_prefix_any());
props.look_set_suffix_any.set_union(p.look_set_suffix_any());
props.utf8 = props.utf8 &amp;&amp; p.is_utf8();
props.explicit_captures_len = props
.explicit_captures_len
.saturating_add(p.explicit_captures_len());
<span class="kw">if </span>props.static_explicit_captures_len
!= p.static_explicit_captures_len()
{
props.static_explicit_captures_len = <span class="prelude-val">None</span>;
}
props.alternation_literal =
props.alternation_literal &amp;&amp; p.is_literal();
<span class="kw">if </span>!min_poisoned {
<span class="kw">if let </span><span class="prelude-val">Some</span>(xmin) = p.minimum_len() {
<span class="kw">if </span>props.minimum_len.map_or(<span class="bool-val">true</span>, |pmin| xmin &lt; pmin) {
props.minimum_len = <span class="prelude-val">Some</span>(xmin);
}
} <span class="kw">else </span>{
props.minimum_len = <span class="prelude-val">None</span>;
min_poisoned = <span class="bool-val">true</span>;
}
}
<span class="kw">if </span>!max_poisoned {
<span class="kw">if let </span><span class="prelude-val">Some</span>(xmax) = p.maximum_len() {
<span class="kw">if </span>props.maximum_len.map_or(<span class="bool-val">true</span>, |pmax| xmax &gt; pmax) {
props.maximum_len = <span class="prelude-val">Some</span>(xmax);
}
} <span class="kw">else </span>{
props.maximum_len = <span class="prelude-val">None</span>;
max_poisoned = <span class="bool-val">true</span>;
}
}
}
Properties(Box::new(props))
}
}
<span class="kw">impl </span>Properties {
<span class="doccomment">/// Create a new set of HIR properties for an empty regex.
</span><span class="kw">fn </span>empty() -&gt; Properties {
<span class="kw">let </span>inner = PropertiesI {
minimum_len: <span class="prelude-val">Some</span>(<span class="number">0</span>),
maximum_len: <span class="prelude-val">Some</span>(<span class="number">0</span>),
look_set: LookSet::empty(),
look_set_prefix: LookSet::empty(),
look_set_suffix: LookSet::empty(),
look_set_prefix_any: LookSet::empty(),
look_set_suffix_any: LookSet::empty(),
<span class="comment">// It is debatable whether an empty regex always matches at valid
// UTF-8 boundaries. Strictly speaking, at a byte oriented view,
// it is clearly false. There are, for example, many empty strings
// between the bytes encoding a &#39;☃&#39;.
//
// However, when Unicode mode is enabled, the fundamental atom
// of matching is really a codepoint. And in that scenario, an
// empty regex is defined to only match at valid UTF-8 boundaries
// and to never split a codepoint. It just so happens that this
// enforcement is somewhat tricky to do for regexes that match
// the empty string inside regex engines themselves. It usually
// requires some layer above the regex engine to filter out such
// matches.
//
// In any case, &#39;true&#39; is really the only coherent option. If it
// were false, for example, then &#39;a*&#39; would also need to be false
// since it too can match the empty string.
</span>utf8: <span class="bool-val">true</span>,
explicit_captures_len: <span class="number">0</span>,
static_explicit_captures_len: <span class="prelude-val">Some</span>(<span class="number">0</span>),
literal: <span class="bool-val">false</span>,
alternation_literal: <span class="bool-val">false</span>,
};
Properties(Box::new(inner))
}
<span class="doccomment">/// Create a new set of HIR properties for a literal regex.
</span><span class="kw">fn </span>literal(lit: <span class="kw-2">&amp;</span>Literal) -&gt; Properties {
<span class="kw">let </span>inner = PropertiesI {
minimum_len: <span class="prelude-val">Some</span>(lit.<span class="number">0</span>.len()),
maximum_len: <span class="prelude-val">Some</span>(lit.<span class="number">0</span>.len()),
look_set: LookSet::empty(),
look_set_prefix: LookSet::empty(),
look_set_suffix: LookSet::empty(),
look_set_prefix_any: LookSet::empty(),
look_set_suffix_any: LookSet::empty(),
utf8: core::str::from_utf8(<span class="kw-2">&amp;</span>lit.<span class="number">0</span>).is_ok(),
explicit_captures_len: <span class="number">0</span>,
static_explicit_captures_len: <span class="prelude-val">Some</span>(<span class="number">0</span>),
literal: <span class="bool-val">true</span>,
alternation_literal: <span class="bool-val">true</span>,
};
Properties(Box::new(inner))
}
<span class="doccomment">/// Create a new set of HIR properties for a character class.
</span><span class="kw">fn </span>class(class: <span class="kw-2">&amp;</span>Class) -&gt; Properties {
<span class="kw">let </span>inner = PropertiesI {
minimum_len: class.minimum_len(),
maximum_len: class.maximum_len(),
look_set: LookSet::empty(),
look_set_prefix: LookSet::empty(),
look_set_suffix: LookSet::empty(),
look_set_prefix_any: LookSet::empty(),
look_set_suffix_any: LookSet::empty(),
utf8: class.is_utf8(),
explicit_captures_len: <span class="number">0</span>,
static_explicit_captures_len: <span class="prelude-val">Some</span>(<span class="number">0</span>),
literal: <span class="bool-val">false</span>,
alternation_literal: <span class="bool-val">false</span>,
};
Properties(Box::new(inner))
}
<span class="doccomment">/// Create a new set of HIR properties for a look-around assertion.
</span><span class="kw">fn </span>look(look: Look) -&gt; Properties {
<span class="kw">let </span>inner = PropertiesI {
minimum_len: <span class="prelude-val">Some</span>(<span class="number">0</span>),
maximum_len: <span class="prelude-val">Some</span>(<span class="number">0</span>),
look_set: LookSet::singleton(look),
look_set_prefix: LookSet::singleton(look),
look_set_suffix: LookSet::singleton(look),
look_set_prefix_any: LookSet::singleton(look),
look_set_suffix_any: LookSet::singleton(look),
<span class="comment">// This requires a little explanation. Basically, we don&#39;t consider
// matching an empty string to be equivalent to matching invalid
// UTF-8, even though technically matching every empty string will
// split the UTF-8 encoding of a single codepoint when treating a
// UTF-8 encoded string as a sequence of bytes. Our defense here is
// that in such a case, a codepoint should logically be treated as
// the fundamental atom for matching, and thus the only valid match
// points are between codepoints and not bytes.
//
// More practically, this is true here because it&#39;s also true
// for &#39;Hir::empty()&#39;, otherwise something like &#39;a*&#39; would be
// considered to match invalid UTF-8. That in turn makes this
// property borderline useless.
</span>utf8: <span class="bool-val">true</span>,
explicit_captures_len: <span class="number">0</span>,
static_explicit_captures_len: <span class="prelude-val">Some</span>(<span class="number">0</span>),
literal: <span class="bool-val">false</span>,
alternation_literal: <span class="bool-val">false</span>,
};
Properties(Box::new(inner))
}
<span class="doccomment">/// Create a new set of HIR properties for a repetition.
</span><span class="kw">fn </span>repetition(rep: <span class="kw-2">&amp;</span>Repetition) -&gt; Properties {
<span class="kw">let </span>p = rep.sub.properties();
<span class="kw">let </span>minimum_len = p.minimum_len().map(|child_min| {
<span class="kw">let </span>rep_min = usize::try_from(rep.min).unwrap_or(usize::MAX);
child_min.saturating_mul(rep_min)
});
<span class="kw">let </span>maximum_len = rep.max.and_then(|rep_max| {
<span class="kw">let </span>rep_max = usize::try_from(rep_max).ok()<span class="question-mark">?</span>;
<span class="kw">let </span>child_max = p.maximum_len()<span class="question-mark">?</span>;
child_max.checked_mul(rep_max)
});
<span class="kw">let </span><span class="kw-2">mut </span>inner = PropertiesI {
minimum_len,
maximum_len,
look_set: p.look_set(),
look_set_prefix: LookSet::empty(),
look_set_suffix: LookSet::empty(),
look_set_prefix_any: p.look_set_prefix_any(),
look_set_suffix_any: p.look_set_suffix_any(),
utf8: p.is_utf8(),
explicit_captures_len: p.explicit_captures_len(),
static_explicit_captures_len: p.static_explicit_captures_len(),
literal: <span class="bool-val">false</span>,
alternation_literal: <span class="bool-val">false</span>,
};
<span class="comment">// If the repetition operator can match the empty string, then its
// lookset prefix and suffixes themselves remain empty since they are
// no longer required to match.
</span><span class="kw">if </span>rep.min &gt; <span class="number">0 </span>{
inner.look_set_prefix = p.look_set_prefix();
inner.look_set_suffix = p.look_set_suffix();
}
<span class="comment">// If the static captures len of the sub-expression is not known or is
// zero, then it automatically propagates to the repetition, regardless
// of the repetition. Otherwise, it might change, but only when the
// repetition can match 0 times.
</span><span class="kw">if </span>rep.min == <span class="number">0
</span>&amp;&amp; inner.static_explicit_captures_len.map_or(<span class="bool-val">false</span>, |len| len &gt; <span class="number">0</span>)
{
<span class="comment">// If we require a match 0 times, then our captures len is
// guaranteed to be zero. Otherwise, if we *can* match the empty
// string, then it&#39;s impossible to know how many captures will be
// in the resulting match.
</span><span class="kw">if </span>rep.max == <span class="prelude-val">Some</span>(<span class="number">0</span>) {
inner.static_explicit_captures_len = <span class="prelude-val">Some</span>(<span class="number">0</span>);
} <span class="kw">else </span>{
inner.static_explicit_captures_len = <span class="prelude-val">None</span>;
}
}
Properties(Box::new(inner))
}
<span class="doccomment">/// Create a new set of HIR properties for a capture.
</span><span class="kw">fn </span>capture(capture: <span class="kw-2">&amp;</span>Capture) -&gt; Properties {
<span class="kw">let </span>p = capture.sub.properties();
Properties(Box::new(PropertiesI {
explicit_captures_len: p.explicit_captures_len().saturating_add(<span class="number">1</span>),
static_explicit_captures_len: p
.static_explicit_captures_len()
.map(|len| len.saturating_add(<span class="number">1</span>)),
literal: <span class="bool-val">false</span>,
alternation_literal: <span class="bool-val">false</span>,
..<span class="kw-2">*</span>p.<span class="number">0</span>.clone()
}))
}
<span class="doccomment">/// Create a new set of HIR properties for a concatenation.
</span><span class="kw">fn </span>concat(concat: <span class="kw-2">&amp;</span>[Hir]) -&gt; Properties {
<span class="comment">// The base case is an empty concatenation, which matches the empty
// string. Note though that empty concatenations aren&#39;t possible,
// because the Hir::concat smart constructor rewrites those as
// Hir::empty.
</span><span class="kw">let </span><span class="kw-2">mut </span>props = PropertiesI {
minimum_len: <span class="prelude-val">Some</span>(<span class="number">0</span>),
maximum_len: <span class="prelude-val">Some</span>(<span class="number">0</span>),
look_set: LookSet::empty(),
look_set_prefix: LookSet::empty(),
look_set_suffix: LookSet::empty(),
look_set_prefix_any: LookSet::empty(),
look_set_suffix_any: LookSet::empty(),
utf8: <span class="bool-val">true</span>,
explicit_captures_len: <span class="number">0</span>,
static_explicit_captures_len: <span class="prelude-val">Some</span>(<span class="number">0</span>),
literal: <span class="bool-val">true</span>,
alternation_literal: <span class="bool-val">true</span>,
};
<span class="comment">// Handle properties that need to visit every child hir.
</span><span class="kw">for </span>x <span class="kw">in </span>concat.iter() {
<span class="kw">let </span>p = x.properties();
props.look_set.set_union(p.look_set());
props.utf8 = props.utf8 &amp;&amp; p.is_utf8();
props.explicit_captures_len = props
.explicit_captures_len
.saturating_add(p.explicit_captures_len());
props.static_explicit_captures_len = p
.static_explicit_captures_len()
.and_then(|len1| {
<span class="prelude-val">Some</span>((len1, props.static_explicit_captures_len<span class="question-mark">?</span>))
})
.and_then(|(len1, len2)| <span class="prelude-val">Some</span>(len1.saturating_add(len2)));
props.literal = props.literal &amp;&amp; p.is_literal();
props.alternation_literal =
props.alternation_literal &amp;&amp; p.is_alternation_literal();
<span class="kw">if let </span><span class="prelude-val">Some</span>(minimum_len) = props.minimum_len {
<span class="kw">match </span>p.minimum_len() {
<span class="prelude-val">None </span>=&gt; props.minimum_len = <span class="prelude-val">None</span>,
<span class="prelude-val">Some</span>(len) =&gt; {
<span class="comment">// We use saturating arithmetic here because the
// minimum is just a lower bound. We can&#39;t go any
// higher than what our number types permit.
</span>props.minimum_len =
<span class="prelude-val">Some</span>(minimum_len.saturating_add(len));
}
}
}
<span class="kw">if let </span><span class="prelude-val">Some</span>(maximum_len) = props.maximum_len {
<span class="kw">match </span>p.maximum_len() {
<span class="prelude-val">None </span>=&gt; props.maximum_len = <span class="prelude-val">None</span>,
<span class="prelude-val">Some</span>(len) =&gt; {
props.maximum_len = maximum_len.checked_add(len)
}
}
}
}
<span class="comment">// Handle the prefix properties, which only requires visiting
// child exprs until one matches more than the empty string.
</span><span class="kw">let </span><span class="kw-2">mut </span>it = concat.iter();
<span class="kw">while let </span><span class="prelude-val">Some</span>(x) = it.next() {
props.look_set_prefix.set_union(x.properties().look_set_prefix());
props
.look_set_prefix_any
.set_union(x.properties().look_set_prefix_any());
<span class="kw">if </span>x.properties().maximum_len().map_or(<span class="bool-val">true</span>, |x| x &gt; <span class="number">0</span>) {
<span class="kw">break</span>;
}
}
<span class="comment">// Same thing for the suffix properties, but in reverse.
</span><span class="kw">let </span><span class="kw-2">mut </span>it = concat.iter().rev();
<span class="kw">while let </span><span class="prelude-val">Some</span>(x) = it.next() {
props.look_set_suffix.set_union(x.properties().look_set_suffix());
props
.look_set_suffix_any
.set_union(x.properties().look_set_suffix_any());
<span class="kw">if </span>x.properties().maximum_len().map_or(<span class="bool-val">true</span>, |x| x &gt; <span class="number">0</span>) {
<span class="kw">break</span>;
}
}
Properties(Box::new(props))
}
<span class="doccomment">/// Create a new set of HIR properties for a concatenation.
</span><span class="kw">fn </span>alternation(alts: <span class="kw-2">&amp;</span>[Hir]) -&gt; Properties {
Properties::union(alts.iter().map(|hir| hir.properties()))
}
}
<span class="doccomment">/// A set of look-around assertions.
///
/// This is useful for efficiently tracking look-around assertions. For
/// example, an [`Hir`] provides properties that return `LookSet`s.
</span><span class="attribute">#[derive(Clone, Copy, Default, Eq, PartialEq)]
</span><span class="kw">pub struct </span>LookSet {
<span class="doccomment">/// The underlying representation this set is exposed to make it possible
/// to store it somewhere efficiently. The representation is that
/// of a bitset, where each assertion occupies bit `i` where `i =
/// Look::as_repr()`.
///
/// Note that users of this internal representation must permit the full
/// range of `u16` values to be represented. For example, even if the
/// current implementation only makes use of the 10 least significant bits,
/// it may use more bits in a future semver compatible release.
</span><span class="kw">pub </span>bits: u16,
}
<span class="kw">impl </span>LookSet {
<span class="doccomment">/// Create an empty set of look-around assertions.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>empty() -&gt; LookSet {
LookSet { bits: <span class="number">0 </span>}
}
<span class="doccomment">/// Create a full set of look-around assertions.
///
/// This set contains all possible look-around assertions.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>full() -&gt; LookSet {
LookSet { bits: !<span class="number">0 </span>}
}
<span class="doccomment">/// Create a look-around set containing the look-around assertion given.
///
/// This is a convenience routine for creating an empty set and inserting
/// one look-around assertions.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>singleton(look: Look) -&gt; LookSet {
LookSet::empty().insert(look)
}
<span class="doccomment">/// Returns the total number of look-around assertions in this set.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>len(<span class="self">self</span>) -&gt; usize {
<span class="comment">// OK because max value always fits in a u8, which in turn always
// fits in a usize, regardless of target.
</span>usize::try_from(<span class="self">self</span>.bits.count_ones()).unwrap()
}
<span class="doccomment">/// Returns true if and only if this set is empty.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>is_empty(<span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.len() == <span class="number">0
</span>}
<span class="doccomment">/// Returns true if and only if the given look-around assertion is in this
/// set.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>contains(<span class="self">self</span>, look: Look) -&gt; bool {
<span class="self">self</span>.bits &amp; look.as_repr() != <span class="number">0
</span>}
<span class="doccomment">/// Returns true if and only if this set contains any anchor assertions.
/// This includes both &quot;start/end of haystack&quot; and &quot;start/end of line.&quot;
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>contains_anchor(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.contains_anchor_haystack() || <span class="self">self</span>.contains_anchor_line()
}
<span class="doccomment">/// Returns true if and only if this set contains any &quot;start/end of
/// haystack&quot; anchors. This doesn&#39;t include &quot;start/end of line&quot; anchors.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>contains_anchor_haystack(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.contains(Look::Start) || <span class="self">self</span>.contains(Look::End)
}
<span class="doccomment">/// Returns true if and only if this set contains any &quot;start/end of line&quot;
/// anchors. This doesn&#39;t include &quot;start/end of haystack&quot; anchors. This
/// includes both `\n` line anchors and CRLF (`\r\n`) aware line anchors.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>contains_anchor_line(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.contains(Look::StartLF)
|| <span class="self">self</span>.contains(Look::EndLF)
|| <span class="self">self</span>.contains(Look::StartCRLF)
|| <span class="self">self</span>.contains(Look::EndCRLF)
}
<span class="doccomment">/// Returns true if and only if this set contains any &quot;start/end of line&quot;
/// anchors that only treat `\n` as line terminators. This does not include
/// haystack anchors or CRLF aware line anchors.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>contains_anchor_lf(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.contains(Look::StartLF) || <span class="self">self</span>.contains(Look::EndLF)
}
<span class="doccomment">/// Returns true if and only if this set contains any &quot;start/end of line&quot;
/// anchors that are CRLF-aware. This doesn&#39;t include &quot;start/end of
/// haystack&quot; or &quot;start/end of line-feed&quot; anchors.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>contains_anchor_crlf(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.contains(Look::StartCRLF) || <span class="self">self</span>.contains(Look::EndCRLF)
}
<span class="doccomment">/// Returns true if and only if this set contains any word boundary or
/// negated word boundary assertions. This include both Unicode and ASCII
/// word boundaries.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>contains_word(<span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.contains_word_unicode() || <span class="self">self</span>.contains_word_ascii()
}
<span class="doccomment">/// Returns true if and only if this set contains any Unicode word boundary
/// or negated Unicode word boundary assertions.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>contains_word_unicode(<span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.contains(Look::WordUnicode)
|| <span class="self">self</span>.contains(Look::WordUnicodeNegate)
}
<span class="doccomment">/// Returns true if and only if this set contains any ASCII word boundary
/// or negated ASCII word boundary assertions.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>contains_word_ascii(<span class="self">self</span>) -&gt; bool {
<span class="self">self</span>.contains(Look::WordAscii) || <span class="self">self</span>.contains(Look::WordAsciiNegate)
}
<span class="doccomment">/// Returns an iterator over all of the look-around assertions in this set.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>iter(<span class="self">self</span>) -&gt; LookSetIter {
LookSetIter { set: <span class="self">self </span>}
}
<span class="doccomment">/// Return a new set that is equivalent to the original, but with the given
/// assertion added to it. If the assertion is already in the set, then the
/// returned set is equivalent to the original.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>insert(<span class="self">self</span>, look: Look) -&gt; LookSet {
LookSet { bits: <span class="self">self</span>.bits | look.as_repr() }
}
<span class="doccomment">/// Updates this set in place with the result of inserting the given
/// assertion into this set.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>set_insert(<span class="kw-2">&amp;mut </span><span class="self">self</span>, look: Look) {
<span class="kw-2">*</span><span class="self">self </span>= <span class="self">self</span>.insert(look);
}
<span class="doccomment">/// Return a new set that is equivalent to the original, but with the given
/// assertion removed from it. If the assertion is not in the set, then the
/// returned set is equivalent to the original.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>remove(<span class="self">self</span>, look: Look) -&gt; LookSet {
LookSet { bits: <span class="self">self</span>.bits &amp; !look.as_repr() }
}
<span class="doccomment">/// Updates this set in place with the result of removing the given
/// assertion from this set.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>set_remove(<span class="kw-2">&amp;mut </span><span class="self">self</span>, look: Look) {
<span class="kw-2">*</span><span class="self">self </span>= <span class="self">self</span>.remove(look);
}
<span class="doccomment">/// Returns a new set that is the result of subtracting the given set from
/// this set.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>subtract(<span class="self">self</span>, other: LookSet) -&gt; LookSet {
LookSet { bits: <span class="self">self</span>.bits &amp; !other.bits }
}
<span class="doccomment">/// Updates this set in place with the result of subtracting the given set
/// from this set.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>set_subtract(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: LookSet) {
<span class="kw-2">*</span><span class="self">self </span>= <span class="self">self</span>.subtract(other);
}
<span class="doccomment">/// Returns a new set that is the union of this and the one given.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>union(<span class="self">self</span>, other: LookSet) -&gt; LookSet {
LookSet { bits: <span class="self">self</span>.bits | other.bits }
}
<span class="doccomment">/// Updates this set in place with the result of unioning it with the one
/// given.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>set_union(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: LookSet) {
<span class="kw-2">*</span><span class="self">self </span>= <span class="self">self</span>.union(other);
}
<span class="doccomment">/// Returns a new set that is the intersection of this and the one given.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>intersect(<span class="self">self</span>, other: LookSet) -&gt; LookSet {
LookSet { bits: <span class="self">self</span>.bits &amp; other.bits }
}
<span class="doccomment">/// Updates this set in place with the result of intersecting it with the
/// one given.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>set_intersect(<span class="kw-2">&amp;mut </span><span class="self">self</span>, other: LookSet) {
<span class="kw-2">*</span><span class="self">self </span>= <span class="self">self</span>.intersect(other);
}
<span class="doccomment">/// Return a `LookSet` from the slice given as a native endian 16-bit
/// integer.
///
/// # Panics
///
/// This panics if `slice.len() &lt; 2`.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>read_repr(slice: <span class="kw-2">&amp;</span>[u8]) -&gt; LookSet {
<span class="kw">let </span>bits = u16::from_ne_bytes(slice[..<span class="number">2</span>].try_into().unwrap());
LookSet { bits }
}
<span class="doccomment">/// Write a `LookSet` as a native endian 16-bit integer to the beginning
/// of the slice given.
///
/// # Panics
///
/// This panics if `slice.len() &lt; 2`.
</span><span class="attribute">#[inline]
</span><span class="kw">pub fn </span>write_repr(<span class="self">self</span>, slice: <span class="kw-2">&amp;mut </span>[u8]) {
<span class="kw">let </span>raw = <span class="self">self</span>.bits.to_ne_bytes();
slice[<span class="number">0</span>] = raw[<span class="number">0</span>];
slice[<span class="number">1</span>] = raw[<span class="number">1</span>];
}
}
<span class="kw">impl </span>core::fmt::Debug <span class="kw">for </span>LookSet {
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>core::fmt::Formatter) -&gt; core::fmt::Result {
<span class="kw">if </span><span class="self">self</span>.is_empty() {
<span class="kw">return </span><span class="macro">write!</span>(f, <span class="string">&quot;∅&quot;</span>);
}
<span class="kw">for </span>look <span class="kw">in </span><span class="self">self</span>.iter() {
<span class="macro">write!</span>(f, <span class="string">&quot;{}&quot;</span>, look.as_char())<span class="question-mark">?</span>;
}
<span class="prelude-val">Ok</span>(())
}
}
<span class="doccomment">/// An iterator over all look-around assertions in a [`LookSet`].
///
/// This iterator is created by [`LookSet::iter`].
</span><span class="attribute">#[derive(Clone, Debug)]
</span><span class="kw">pub struct </span>LookSetIter {
set: LookSet,
}
<span class="kw">impl </span>Iterator <span class="kw">for </span>LookSetIter {
<span class="kw">type </span>Item = Look;
<span class="attribute">#[inline]
</span><span class="kw">fn </span>next(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="prelude-ty">Option</span>&lt;Look&gt; {
<span class="kw">if </span><span class="self">self</span>.set.is_empty() {
<span class="kw">return </span><span class="prelude-val">None</span>;
}
<span class="comment">// We&#39;ll never have more than u8::MAX distinct look-around assertions,
// so &#39;repr&#39; will always fit into a u16.
</span><span class="kw">let </span>repr = u16::try_from(<span class="self">self</span>.set.bits.trailing_zeros()).unwrap();
<span class="kw">let </span>look = Look::from_repr(<span class="number">1 </span>&lt;&lt; repr)<span class="question-mark">?</span>;
<span class="self">self</span>.set = <span class="self">self</span>.set.remove(look);
<span class="prelude-val">Some</span>(look)
}
}
<span class="doccomment">/// Given a sequence of HIR values where each value corresponds to a Unicode
/// class (or an all-ASCII byte class), return a single Unicode class
/// corresponding to the union of the classes found.
</span><span class="kw">fn </span>class_chars(hirs: <span class="kw-2">&amp;</span>[Hir]) -&gt; <span class="prelude-ty">Option</span>&lt;Class&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>cls = ClassUnicode::new(<span class="macro">vec!</span>[]);
<span class="kw">for </span>hir <span class="kw">in </span>hirs.iter() {
<span class="kw">match </span><span class="kw-2">*</span>hir.kind() {
HirKind::Class(Class::Unicode(<span class="kw-2">ref </span>cls2)) =&gt; {
cls.union(cls2);
}
HirKind::Class(Class::Bytes(<span class="kw-2">ref </span>cls2)) =&gt; {
cls.union(<span class="kw-2">&amp;</span>cls2.to_unicode_class()<span class="question-mark">?</span>);
}
<span class="kw">_ </span>=&gt; <span class="kw">return </span><span class="prelude-val">None</span>,
};
}
<span class="prelude-val">Some</span>(Class::Unicode(cls))
}
<span class="doccomment">/// Given a sequence of HIR values where each value corresponds to a byte class
/// (or an all-ASCII Unicode class), return a single byte class corresponding
/// to the union of the classes found.
</span><span class="kw">fn </span>class_bytes(hirs: <span class="kw-2">&amp;</span>[Hir]) -&gt; <span class="prelude-ty">Option</span>&lt;Class&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>cls = ClassBytes::new(<span class="macro">vec!</span>[]);
<span class="kw">for </span>hir <span class="kw">in </span>hirs.iter() {
<span class="kw">match </span><span class="kw-2">*</span>hir.kind() {
HirKind::Class(Class::Unicode(<span class="kw-2">ref </span>cls2)) =&gt; {
cls.union(<span class="kw-2">&amp;</span>cls2.to_byte_class()<span class="question-mark">?</span>);
}
HirKind::Class(Class::Bytes(<span class="kw-2">ref </span>cls2)) =&gt; {
cls.union(cls2);
}
<span class="kw">_ </span>=&gt; <span class="kw">return </span><span class="prelude-val">None</span>,
};
}
<span class="prelude-val">Some</span>(Class::Bytes(cls))
}
<span class="doccomment">/// Given a sequence of HIR values where each value corresponds to a literal
/// that is a single `char`, return that sequence of `char`s. Otherwise return
/// None. No deduplication is done.
</span><span class="kw">fn </span>singleton_chars(hirs: <span class="kw-2">&amp;</span>[Hir]) -&gt; <span class="prelude-ty">Option</span>&lt;Vec&lt;char&gt;&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>singletons = <span class="macro">vec!</span>[];
<span class="kw">for </span>hir <span class="kw">in </span>hirs.iter() {
<span class="kw">let </span>literal = <span class="kw">match </span><span class="kw-2">*</span>hir.kind() {
HirKind::Literal(Literal(<span class="kw-2">ref </span>bytes)) =&gt; bytes,
<span class="kw">_ </span>=&gt; <span class="kw">return </span><span class="prelude-val">None</span>,
};
<span class="kw">let </span>ch = <span class="kw">match </span><span class="kw">crate</span>::debug::utf8_decode(literal) {
<span class="prelude-val">None </span>=&gt; <span class="kw">return </span><span class="prelude-val">None</span>,
<span class="prelude-val">Some</span>(<span class="prelude-val">Err</span>(<span class="kw">_</span>)) =&gt; <span class="kw">return </span><span class="prelude-val">None</span>,
<span class="prelude-val">Some</span>(<span class="prelude-val">Ok</span>(ch)) =&gt; ch,
};
<span class="kw">if </span>literal.len() != ch.len_utf8() {
<span class="kw">return </span><span class="prelude-val">None</span>;
}
singletons.push(ch);
}
<span class="prelude-val">Some</span>(singletons)
}
<span class="doccomment">/// Given a sequence of HIR values where each value corresponds to a literal
/// that is a single byte, return that sequence of bytes. Otherwise return
/// None. No deduplication is done.
</span><span class="kw">fn </span>singleton_bytes(hirs: <span class="kw-2">&amp;</span>[Hir]) -&gt; <span class="prelude-ty">Option</span>&lt;Vec&lt;u8&gt;&gt; {
<span class="kw">let </span><span class="kw-2">mut </span>singletons = <span class="macro">vec!</span>[];
<span class="kw">for </span>hir <span class="kw">in </span>hirs.iter() {
<span class="kw">let </span>literal = <span class="kw">match </span><span class="kw-2">*</span>hir.kind() {
HirKind::Literal(Literal(<span class="kw-2">ref </span>bytes)) =&gt; bytes,
<span class="kw">_ </span>=&gt; <span class="kw">return </span><span class="prelude-val">None</span>,
};
<span class="kw">if </span>literal.len() != <span class="number">1 </span>{
<span class="kw">return </span><span class="prelude-val">None</span>;
}
singletons.push(literal[<span class="number">0</span>]);
}
<span class="prelude-val">Some</span>(singletons)
}
<span class="doccomment">/// Looks for a common prefix in the list of alternation branches given. If one
/// is found, then an equivalent but (hopefully) simplified Hir is returned.
/// Otherwise, the original given list of branches is returned unmodified.
///
/// This is not quite as good as it could be. Right now, it requires that
/// all branches are &#39;Concat&#39; expressions. It also doesn&#39;t do well with
/// literals. For example, given &#39;foofoo|foobar&#39;, it will not refactor it to
/// &#39;foo(?:foo|bar)&#39; because literals are flattened into their own special
/// concatenation. (One wonders if perhaps &#39;Literal&#39; should be a single atom
/// instead of a string of bytes because of this. Otherwise, handling the
/// current representation in this routine will be pretty gnarly. Sigh.)
</span><span class="kw">fn </span>lift_common_prefix(hirs: Vec&lt;Hir&gt;) -&gt; <span class="prelude-ty">Result</span>&lt;Hir, Vec&lt;Hir&gt;&gt; {
<span class="kw">if </span>hirs.len() &lt;= <span class="number">1 </span>{
<span class="kw">return </span><span class="prelude-val">Err</span>(hirs);
}
<span class="kw">let </span><span class="kw-2">mut </span>prefix = <span class="kw">match </span>hirs[<span class="number">0</span>].kind() {
HirKind::Concat(<span class="kw-2">ref </span>xs) =&gt; <span class="kw-2">&amp;**</span>xs,
<span class="kw">_ </span>=&gt; <span class="kw">return </span><span class="prelude-val">Err</span>(hirs),
};
<span class="kw">if </span>prefix.is_empty() {
<span class="kw">return </span><span class="prelude-val">Err</span>(hirs);
}
<span class="kw">for </span>h <span class="kw">in </span>hirs.iter().skip(<span class="number">1</span>) {
<span class="kw">let </span>concat = <span class="kw">match </span>h.kind() {
HirKind::Concat(<span class="kw-2">ref </span>xs) =&gt; xs,
<span class="kw">_ </span>=&gt; <span class="kw">return </span><span class="prelude-val">Err</span>(hirs),
};
<span class="kw">let </span>common_len = prefix
.iter()
.zip(concat.iter())
.take_while(|(x, y)| x == y)
.count();
prefix = <span class="kw-2">&amp;</span>prefix[..common_len];
<span class="kw">if </span>prefix.is_empty() {
<span class="kw">return </span><span class="prelude-val">Err</span>(hirs);
}
}
<span class="kw">let </span>len = prefix.len();
<span class="macro">assert_ne!</span>(<span class="number">0</span>, len);
<span class="kw">let </span><span class="kw-2">mut </span>prefix_concat = <span class="macro">vec!</span>[];
<span class="kw">let </span><span class="kw-2">mut </span>suffix_alts = <span class="macro">vec!</span>[];
<span class="kw">for </span>h <span class="kw">in </span>hirs {
<span class="kw">let </span><span class="kw-2">mut </span>concat = <span class="kw">match </span>h.into_kind() {
HirKind::Concat(xs) =&gt; xs,
<span class="comment">// We required all sub-expressions to be
// concats above, so we&#39;re only here if we
// have a concat.
</span><span class="kw">_ </span>=&gt; <span class="macro">unreachable!</span>(),
};
suffix_alts.push(Hir::concat(concat.split_off(len)));
<span class="kw">if </span>prefix_concat.is_empty() {
prefix_concat = concat;
}
}
<span class="kw">let </span><span class="kw-2">mut </span>concat = prefix_concat;
concat.push(Hir::alternation(suffix_alts));
<span class="prelude-val">Ok</span>(Hir::concat(concat))
}
<span class="attribute">#[cfg(test)]
</span><span class="kw">mod </span>tests {
<span class="kw">use super</span>::<span class="kw-2">*</span>;
<span class="kw">fn </span>uclass(ranges: <span class="kw-2">&amp;</span>[(char, char)]) -&gt; ClassUnicode {
<span class="kw">let </span>ranges: Vec&lt;ClassUnicodeRange&gt; = ranges
.iter()
.map(|<span class="kw-2">&amp;</span>(s, e)| ClassUnicodeRange::new(s, e))
.collect();
ClassUnicode::new(ranges)
}
<span class="kw">fn </span>bclass(ranges: <span class="kw-2">&amp;</span>[(u8, u8)]) -&gt; ClassBytes {
<span class="kw">let </span>ranges: Vec&lt;ClassBytesRange&gt; =
ranges.iter().map(|<span class="kw-2">&amp;</span>(s, e)| ClassBytesRange::new(s, e)).collect();
ClassBytes::new(ranges)
}
<span class="kw">fn </span>uranges(cls: <span class="kw-2">&amp;</span>ClassUnicode) -&gt; Vec&lt;(char, char)&gt; {
cls.iter().map(|x| (x.start(), x.end())).collect()
}
<span class="attribute">#[cfg(feature = <span class="string">&quot;unicode-case&quot;</span>)]
</span><span class="kw">fn </span>ucasefold(cls: <span class="kw-2">&amp;</span>ClassUnicode) -&gt; ClassUnicode {
<span class="kw">let </span><span class="kw-2">mut </span>cls_ = cls.clone();
cls_.case_fold_simple();
cls_
}
<span class="kw">fn </span>uunion(cls1: <span class="kw-2">&amp;</span>ClassUnicode, cls2: <span class="kw-2">&amp;</span>ClassUnicode) -&gt; ClassUnicode {
<span class="kw">let </span><span class="kw-2">mut </span>cls_ = cls1.clone();
cls_.union(cls2);
cls_
}
<span class="kw">fn </span>uintersect(cls1: <span class="kw-2">&amp;</span>ClassUnicode, cls2: <span class="kw-2">&amp;</span>ClassUnicode) -&gt; ClassUnicode {
<span class="kw">let </span><span class="kw-2">mut </span>cls_ = cls1.clone();
cls_.intersect(cls2);
cls_
}
<span class="kw">fn </span>udifference(cls1: <span class="kw-2">&amp;</span>ClassUnicode, cls2: <span class="kw-2">&amp;</span>ClassUnicode) -&gt; ClassUnicode {
<span class="kw">let </span><span class="kw-2">mut </span>cls_ = cls1.clone();
cls_.difference(cls2);
cls_
}
<span class="kw">fn </span>usymdifference(
cls1: <span class="kw-2">&amp;</span>ClassUnicode,
cls2: <span class="kw-2">&amp;</span>ClassUnicode,
) -&gt; ClassUnicode {
<span class="kw">let </span><span class="kw-2">mut </span>cls_ = cls1.clone();
cls_.symmetric_difference(cls2);
cls_
}
<span class="kw">fn </span>unegate(cls: <span class="kw-2">&amp;</span>ClassUnicode) -&gt; ClassUnicode {
<span class="kw">let </span><span class="kw-2">mut </span>cls_ = cls.clone();
cls_.negate();
cls_
}
<span class="kw">fn </span>branges(cls: <span class="kw-2">&amp;</span>ClassBytes) -&gt; Vec&lt;(u8, u8)&gt; {
cls.iter().map(|x| (x.start(), x.end())).collect()
}
<span class="kw">fn </span>bcasefold(cls: <span class="kw-2">&amp;</span>ClassBytes) -&gt; ClassBytes {
<span class="kw">let </span><span class="kw-2">mut </span>cls_ = cls.clone();
cls_.case_fold_simple();
cls_
}
<span class="kw">fn </span>bunion(cls1: <span class="kw-2">&amp;</span>ClassBytes, cls2: <span class="kw-2">&amp;</span>ClassBytes) -&gt; ClassBytes {
<span class="kw">let </span><span class="kw-2">mut </span>cls_ = cls1.clone();
cls_.union(cls2);
cls_
}
<span class="kw">fn </span>bintersect(cls1: <span class="kw-2">&amp;</span>ClassBytes, cls2: <span class="kw-2">&amp;</span>ClassBytes) -&gt; ClassBytes {
<span class="kw">let </span><span class="kw-2">mut </span>cls_ = cls1.clone();
cls_.intersect(cls2);
cls_
}
<span class="kw">fn </span>bdifference(cls1: <span class="kw-2">&amp;</span>ClassBytes, cls2: <span class="kw-2">&amp;</span>ClassBytes) -&gt; ClassBytes {
<span class="kw">let </span><span class="kw-2">mut </span>cls_ = cls1.clone();
cls_.difference(cls2);
cls_
}
<span class="kw">fn </span>bsymdifference(cls1: <span class="kw-2">&amp;</span>ClassBytes, cls2: <span class="kw-2">&amp;</span>ClassBytes) -&gt; ClassBytes {
<span class="kw">let </span><span class="kw-2">mut </span>cls_ = cls1.clone();
cls_.symmetric_difference(cls2);
cls_
}
<span class="kw">fn </span>bnegate(cls: <span class="kw-2">&amp;</span>ClassBytes) -&gt; ClassBytes {
<span class="kw">let </span><span class="kw-2">mut </span>cls_ = cls.clone();
cls_.negate();
cls_
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_range_canonical_unicode() {
<span class="kw">let </span>range = ClassUnicodeRange::new(<span class="string">&#39;\u{00FF}&#39;</span>, <span class="string">&#39;\0&#39;</span>);
<span class="macro">assert_eq!</span>(<span class="string">&#39;\0&#39;</span>, range.start());
<span class="macro">assert_eq!</span>(<span class="string">&#39;\u{00FF}&#39;</span>, range.end());
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_range_canonical_bytes() {
<span class="kw">let </span>range = ClassBytesRange::new(<span class="string">b&#39;\xFF&#39;</span>, <span class="string">b&#39;\0&#39;</span>);
<span class="macro">assert_eq!</span>(<span class="string">b&#39;\0&#39;</span>, range.start());
<span class="macro">assert_eq!</span>(<span class="string">b&#39;\xFF&#39;</span>, range.end());
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_canonicalize_unicode() {
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>), (<span class="string">&#39;x&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>), (<span class="string">&#39;x&#39;</span>, <span class="string">&#39;z&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, uranges(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;x&#39;</span>, <span class="string">&#39;z&#39;</span>), (<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>)]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>), (<span class="string">&#39;x&#39;</span>, <span class="string">&#39;z&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, uranges(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;x&#39;</span>, <span class="string">&#39;z&#39;</span>), (<span class="string">&#39;w&#39;</span>, <span class="string">&#39;y&#39;</span>)]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">&#39;w&#39;</span>, <span class="string">&#39;z&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, uranges(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[
(<span class="string">&#39;c&#39;</span>, <span class="string">&#39;f&#39;</span>),
(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;g&#39;</span>),
(<span class="string">&#39;d&#39;</span>, <span class="string">&#39;j&#39;</span>),
(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>),
(<span class="string">&#39;m&#39;</span>, <span class="string">&#39;p&#39;</span>),
(<span class="string">&#39;l&#39;</span>, <span class="string">&#39;s&#39;</span>),
]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;j&#39;</span>), (<span class="string">&#39;l&#39;</span>, <span class="string">&#39;s&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, uranges(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;x&#39;</span>, <span class="string">&#39;z&#39;</span>), (<span class="string">&#39;u&#39;</span>, <span class="string">&#39;w&#39;</span>)]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">&#39;u&#39;</span>, <span class="string">&#39;z&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, uranges(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>), (<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, uranges(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>), (<span class="string">&#39;b&#39;</span>, <span class="string">&#39;b&#39;</span>)]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, uranges(<span class="kw-2">&amp;</span>cls));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_canonicalize_bytes() {
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>), (<span class="string">b&#39;x&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>), (<span class="string">b&#39;x&#39;</span>, <span class="string">b&#39;z&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, branges(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;x&#39;</span>, <span class="string">b&#39;z&#39;</span>), (<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>)]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>), (<span class="string">b&#39;x&#39;</span>, <span class="string">b&#39;z&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, branges(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;x&#39;</span>, <span class="string">b&#39;z&#39;</span>), (<span class="string">b&#39;w&#39;</span>, <span class="string">b&#39;y&#39;</span>)]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">b&#39;w&#39;</span>, <span class="string">b&#39;z&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, branges(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[
(<span class="string">b&#39;c&#39;</span>, <span class="string">b&#39;f&#39;</span>),
(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;g&#39;</span>),
(<span class="string">b&#39;d&#39;</span>, <span class="string">b&#39;j&#39;</span>),
(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>),
(<span class="string">b&#39;m&#39;</span>, <span class="string">b&#39;p&#39;</span>),
(<span class="string">b&#39;l&#39;</span>, <span class="string">b&#39;s&#39;</span>),
]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;j&#39;</span>), (<span class="string">b&#39;l&#39;</span>, <span class="string">b&#39;s&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, branges(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;x&#39;</span>, <span class="string">b&#39;z&#39;</span>), (<span class="string">b&#39;u&#39;</span>, <span class="string">b&#39;w&#39;</span>)]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">b&#39;u&#39;</span>, <span class="string">b&#39;z&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, branges(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;\x00&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>), (<span class="string">b&#39;\x00&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>)]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">b&#39;\x00&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, branges(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>), (<span class="string">b&#39;b&#39;</span>, <span class="string">b&#39;b&#39;</span>)]);
<span class="kw">let </span>expected = <span class="macro">vec!</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>)];
<span class="macro">assert_eq!</span>(expected, branges(<span class="kw-2">&amp;</span>cls));
}
<span class="attribute">#[test]
#[cfg(feature = <span class="string">&quot;unicode-case&quot;</span>)]
</span><span class="kw">fn </span>class_case_fold_unicode() {
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[
(<span class="string">&#39;C&#39;</span>, <span class="string">&#39;F&#39;</span>),
(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;G&#39;</span>),
(<span class="string">&#39;D&#39;</span>, <span class="string">&#39;J&#39;</span>),
(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;C&#39;</span>),
(<span class="string">&#39;M&#39;</span>, <span class="string">&#39;P&#39;</span>),
(<span class="string">&#39;L&#39;</span>, <span class="string">&#39;S&#39;</span>),
(<span class="string">&#39;c&#39;</span>, <span class="string">&#39;f&#39;</span>),
]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[
(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;J&#39;</span>),
(<span class="string">&#39;L&#39;</span>, <span class="string">&#39;S&#39;</span>),
(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;j&#39;</span>),
(<span class="string">&#39;l&#39;</span>, <span class="string">&#39;s&#39;</span>),
(<span class="string">&#39;\u{17F}&#39;</span>, <span class="string">&#39;\u{17F}&#39;</span>),
]);
<span class="macro">assert_eq!</span>(expected, ucasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;Z&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[
(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;Z&#39;</span>),
(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;z&#39;</span>),
(<span class="string">&#39;\u{17F}&#39;</span>, <span class="string">&#39;\u{17F}&#39;</span>),
(<span class="string">&#39;\u{212A}&#39;</span>, <span class="string">&#39;\u{212A}&#39;</span>),
]);
<span class="macro">assert_eq!</span>(expected, ucasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[
(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;Z&#39;</span>),
(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;z&#39;</span>),
(<span class="string">&#39;\u{17F}&#39;</span>, <span class="string">&#39;\u{17F}&#39;</span>),
(<span class="string">&#39;\u{212A}&#39;</span>, <span class="string">&#39;\u{212A}&#39;</span>),
]);
<span class="macro">assert_eq!</span>(expected, ucasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;A&#39;</span>), (<span class="string">&#39;_&#39;</span>, <span class="string">&#39;_&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;A&#39;</span>), (<span class="string">&#39;_&#39;</span>, <span class="string">&#39;_&#39;</span>), (<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, ucasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;A&#39;</span>), (<span class="string">&#39;=&#39;</span>, <span class="string">&#39;=&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;=&#39;</span>, <span class="string">&#39;=&#39;</span>), (<span class="string">&#39;A&#39;</span>, <span class="string">&#39;A&#39;</span>), (<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, ucasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\x10&#39;</span>)]);
<span class="macro">assert_eq!</span>(cls, ucasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;k&#39;</span>, <span class="string">&#39;k&#39;</span>)]);
<span class="kw">let </span>expected =
uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;K&#39;</span>, <span class="string">&#39;K&#39;</span>), (<span class="string">&#39;k&#39;</span>, <span class="string">&#39;k&#39;</span>), (<span class="string">&#39;\u{212A}&#39;</span>, <span class="string">&#39;\u{212A}&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, ucasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;@&#39;</span>, <span class="string">&#39;@&#39;</span>)]);
<span class="macro">assert_eq!</span>(cls, ucasefold(<span class="kw-2">&amp;</span>cls));
}
<span class="attribute">#[test]
#[cfg(not(feature = <span class="string">&quot;unicode-case&quot;</span>))]
</span><span class="kw">fn </span>class_case_fold_unicode_disabled() {
<span class="kw">let </span><span class="kw-2">mut </span>cls = uclass(<span class="kw-2">&amp;</span>[
(<span class="string">&#39;C&#39;</span>, <span class="string">&#39;F&#39;</span>),
(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;G&#39;</span>),
(<span class="string">&#39;D&#39;</span>, <span class="string">&#39;J&#39;</span>),
(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;C&#39;</span>),
(<span class="string">&#39;M&#39;</span>, <span class="string">&#39;P&#39;</span>),
(<span class="string">&#39;L&#39;</span>, <span class="string">&#39;S&#39;</span>),
(<span class="string">&#39;c&#39;</span>, <span class="string">&#39;f&#39;</span>),
]);
<span class="macro">assert!</span>(cls.try_case_fold_simple().is_err());
}
<span class="attribute">#[test]
#[should_panic]
#[cfg(not(feature = <span class="string">&quot;unicode-case&quot;</span>))]
</span><span class="kw">fn </span>class_case_fold_unicode_disabled_panics() {
<span class="kw">let </span><span class="kw-2">mut </span>cls = uclass(<span class="kw-2">&amp;</span>[
(<span class="string">&#39;C&#39;</span>, <span class="string">&#39;F&#39;</span>),
(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;G&#39;</span>),
(<span class="string">&#39;D&#39;</span>, <span class="string">&#39;J&#39;</span>),
(<span class="string">&#39;A&#39;</span>, <span class="string">&#39;C&#39;</span>),
(<span class="string">&#39;M&#39;</span>, <span class="string">&#39;P&#39;</span>),
(<span class="string">&#39;L&#39;</span>, <span class="string">&#39;S&#39;</span>),
(<span class="string">&#39;c&#39;</span>, <span class="string">&#39;f&#39;</span>),
]);
cls.case_fold_simple();
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_case_fold_bytes() {
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[
(<span class="string">b&#39;C&#39;</span>, <span class="string">b&#39;F&#39;</span>),
(<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;G&#39;</span>),
(<span class="string">b&#39;D&#39;</span>, <span class="string">b&#39;J&#39;</span>),
(<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;C&#39;</span>),
(<span class="string">b&#39;M&#39;</span>, <span class="string">b&#39;P&#39;</span>),
(<span class="string">b&#39;L&#39;</span>, <span class="string">b&#39;S&#39;</span>),
(<span class="string">b&#39;c&#39;</span>, <span class="string">b&#39;f&#39;</span>),
]);
<span class="kw">let </span>expected =
bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;J&#39;</span>), (<span class="string">b&#39;L&#39;</span>, <span class="string">b&#39;S&#39;</span>), (<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;j&#39;</span>), (<span class="string">b&#39;l&#39;</span>, <span class="string">b&#39;s&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bcasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;Z&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;Z&#39;</span>), (<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bcasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;Z&#39;</span>), (<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bcasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;A&#39;</span>), (<span class="string">b&#39;_&#39;</span>, <span class="string">b&#39;_&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;A&#39;</span>), (<span class="string">b&#39;_&#39;</span>, <span class="string">b&#39;_&#39;</span>), (<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bcasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;A&#39;</span>), (<span class="string">b&#39;=&#39;</span>, <span class="string">b&#39;=&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;=&#39;</span>, <span class="string">b&#39;=&#39;</span>), (<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;A&#39;</span>), (<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bcasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;\x00&#39;</span>, <span class="string">b&#39;\x10&#39;</span>)]);
<span class="macro">assert_eq!</span>(cls, bcasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;k&#39;</span>, <span class="string">b&#39;k&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;K&#39;</span>, <span class="string">b&#39;K&#39;</span>), (<span class="string">b&#39;k&#39;</span>, <span class="string">b&#39;k&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bcasefold(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;@&#39;</span>, <span class="string">b&#39;@&#39;</span>)]);
<span class="macro">assert_eq!</span>(cls, bcasefold(<span class="kw-2">&amp;</span>cls));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_negate_unicode() {
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\x60&#39;</span>), (<span class="string">&#39;\x62&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, unegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>), (<span class="string">&#39;b&#39;</span>, <span class="string">&#39;b&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\x60&#39;</span>), (<span class="string">&#39;\x63&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, unegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>), (<span class="string">&#39;x&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[
(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\x60&#39;</span>),
(<span class="string">&#39;\x64&#39;</span>, <span class="string">&#39;\x77&#39;</span>),
(<span class="string">&#39;\x7B&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>),
]);
<span class="macro">assert_eq!</span>(expected, unegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x62&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, unegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\x60&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, unegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, unegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, unegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls =
uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\u{10FFFD}&#39;</span>), (<span class="string">&#39;\u{10FFFF}&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\u{10FFFE}&#39;</span>, <span class="string">&#39;\u{10FFFE}&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, unegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\u{D7FF}&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\u{E000}&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, unegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\u{D7FE}&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\u{D7FF}&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, unegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\u{E000}&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\u{D7FF}&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, unegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\u{E001}&#39;</span>, <span class="string">&#39;\u{10FFFF}&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;\x00&#39;</span>, <span class="string">&#39;\u{E000}&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, unegate(<span class="kw-2">&amp;</span>cls));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_negate_bytes() {
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;\x00&#39;</span>, <span class="string">b&#39;\x60&#39;</span>), (<span class="string">b&#39;\x62&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bnegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>), (<span class="string">b&#39;b&#39;</span>, <span class="string">b&#39;b&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;\x00&#39;</span>, <span class="string">b&#39;\x60&#39;</span>), (<span class="string">b&#39;\x63&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bnegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>), (<span class="string">b&#39;x&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[
(<span class="string">b&#39;\x00&#39;</span>, <span class="string">b&#39;\x60&#39;</span>),
(<span class="string">b&#39;\x64&#39;</span>, <span class="string">b&#39;\x77&#39;</span>),
(<span class="string">b&#39;\x7B&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>),
]);
<span class="macro">assert_eq!</span>(expected, bnegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;\x00&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;\x62&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bnegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;\x00&#39;</span>, <span class="string">b&#39;\x60&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bnegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;\x00&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, bnegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;\x00&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bnegate(<span class="kw-2">&amp;</span>cls));
<span class="kw">let </span>cls = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;\x00&#39;</span>, <span class="string">b&#39;\xFD&#39;</span>), (<span class="string">b&#39;\xFF&#39;</span>, <span class="string">b&#39;\xFF&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;\xFE&#39;</span>, <span class="string">b&#39;\xFE&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bnegate(<span class="kw-2">&amp;</span>cls));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_union_unicode() {
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;g&#39;</span>), (<span class="string">&#39;m&#39;</span>, <span class="string">&#39;t&#39;</span>), (<span class="string">&#39;A&#39;</span>, <span class="string">&#39;C&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;z&#39;</span>), (<span class="string">&#39;A&#39;</span>, <span class="string">&#39;C&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, uunion(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_union_bytes() {
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;g&#39;</span>), (<span class="string">b&#39;m&#39;</span>, <span class="string">b&#39;t&#39;</span>), (<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;C&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;z&#39;</span>), (<span class="string">b&#39;A&#39;</span>, <span class="string">b&#39;C&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bunion(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_intersect_unicode() {
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;b&#39;</span>, <span class="string">&#39;b&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;b&#39;</span>, <span class="string">&#39;c&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;b&#39;</span>, <span class="string">&#39;b&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;c&#39;</span>, <span class="string">&#39;d&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;b&#39;</span>, <span class="string">&#39;c&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;d&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;b&#39;</span>, <span class="string">&#39;c&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>), (<span class="string">&#39;d&#39;</span>, <span class="string">&#39;e&#39;</span>), (<span class="string">&#39;g&#39;</span>, <span class="string">&#39;h&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;h&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>), (<span class="string">&#39;d&#39;</span>, <span class="string">&#39;e&#39;</span>), (<span class="string">&#39;g&#39;</span>, <span class="string">&#39;h&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>), (<span class="string">&#39;d&#39;</span>, <span class="string">&#39;e&#39;</span>), (<span class="string">&#39;g&#39;</span>, <span class="string">&#39;h&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>), (<span class="string">&#39;d&#39;</span>, <span class="string">&#39;e&#39;</span>), (<span class="string">&#39;g&#39;</span>, <span class="string">&#39;h&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>), (<span class="string">&#39;d&#39;</span>, <span class="string">&#39;e&#39;</span>), (<span class="string">&#39;g&#39;</span>, <span class="string">&#39;h&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>), (<span class="string">&#39;g&#39;</span>, <span class="string">&#39;h&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;d&#39;</span>, <span class="string">&#39;e&#39;</span>), (<span class="string">&#39;k&#39;</span>, <span class="string">&#39;l&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>), (<span class="string">&#39;d&#39;</span>, <span class="string">&#39;e&#39;</span>), (<span class="string">&#39;g&#39;</span>, <span class="string">&#39;h&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;h&#39;</span>, <span class="string">&#39;h&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;h&#39;</span>, <span class="string">&#39;h&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>), (<span class="string">&#39;e&#39;</span>, <span class="string">&#39;f&#39;</span>), (<span class="string">&#39;i&#39;</span>, <span class="string">&#39;j&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;c&#39;</span>, <span class="string">&#39;d&#39;</span>), (<span class="string">&#39;g&#39;</span>, <span class="string">&#39;h&#39;</span>), (<span class="string">&#39;k&#39;</span>, <span class="string">&#39;l&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;b&#39;</span>), (<span class="string">&#39;c&#39;</span>, <span class="string">&#39;d&#39;</span>), (<span class="string">&#39;e&#39;</span>, <span class="string">&#39;f&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;b&#39;</span>, <span class="string">&#39;c&#39;</span>), (<span class="string">&#39;d&#39;</span>, <span class="string">&#39;e&#39;</span>), (<span class="string">&#39;f&#39;</span>, <span class="string">&#39;g&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;b&#39;</span>, <span class="string">&#39;f&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, uintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_intersect_bytes() {
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;b&#39;</span>, <span class="string">b&#39;b&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;b&#39;</span>, <span class="string">b&#39;c&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;b&#39;</span>, <span class="string">b&#39;b&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;c&#39;</span>, <span class="string">b&#39;d&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;b&#39;</span>, <span class="string">b&#39;c&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;d&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;b&#39;</span>, <span class="string">b&#39;c&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>), (<span class="string">b&#39;d&#39;</span>, <span class="string">b&#39;e&#39;</span>), (<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;h&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;h&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>), (<span class="string">b&#39;d&#39;</span>, <span class="string">b&#39;e&#39;</span>), (<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;h&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>), (<span class="string">b&#39;d&#39;</span>, <span class="string">b&#39;e&#39;</span>), (<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;h&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>), (<span class="string">b&#39;d&#39;</span>, <span class="string">b&#39;e&#39;</span>), (<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;h&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>), (<span class="string">b&#39;d&#39;</span>, <span class="string">b&#39;e&#39;</span>), (<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;h&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>), (<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;h&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;d&#39;</span>, <span class="string">b&#39;e&#39;</span>), (<span class="string">b&#39;k&#39;</span>, <span class="string">b&#39;l&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>), (<span class="string">b&#39;d&#39;</span>, <span class="string">b&#39;e&#39;</span>), (<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;h&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;h&#39;</span>, <span class="string">b&#39;h&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;h&#39;</span>, <span class="string">b&#39;h&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>), (<span class="string">b&#39;e&#39;</span>, <span class="string">b&#39;f&#39;</span>), (<span class="string">b&#39;i&#39;</span>, <span class="string">b&#39;j&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;c&#39;</span>, <span class="string">b&#39;d&#39;</span>), (<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;h&#39;</span>), (<span class="string">b&#39;k&#39;</span>, <span class="string">b&#39;l&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;b&#39;</span>), (<span class="string">b&#39;c&#39;</span>, <span class="string">b&#39;d&#39;</span>), (<span class="string">b&#39;e&#39;</span>, <span class="string">b&#39;f&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;b&#39;</span>, <span class="string">b&#39;c&#39;</span>), (<span class="string">b&#39;d&#39;</span>, <span class="string">b&#39;e&#39;</span>), (<span class="string">b&#39;f&#39;</span>, <span class="string">b&#39;g&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;b&#39;</span>, <span class="string">b&#39;f&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bintersect(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_difference_unicode() {
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, udifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, udifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, udifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;b&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, udifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;z&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;y&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, udifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;m&#39;</span>, <span class="string">&#39;m&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;l&#39;</span>), (<span class="string">&#39;n&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, udifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>), (<span class="string">&#39;g&#39;</span>, <span class="string">&#39;i&#39;</span>), (<span class="string">&#39;r&#39;</span>, <span class="string">&#39;t&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, udifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>), (<span class="string">&#39;g&#39;</span>, <span class="string">&#39;i&#39;</span>), (<span class="string">&#39;r&#39;</span>, <span class="string">&#39;t&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;d&#39;</span>, <span class="string">&#39;v&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, udifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>), (<span class="string">&#39;g&#39;</span>, <span class="string">&#39;i&#39;</span>), (<span class="string">&#39;r&#39;</span>, <span class="string">&#39;t&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;b&#39;</span>, <span class="string">&#39;g&#39;</span>), (<span class="string">&#39;s&#39;</span>, <span class="string">&#39;u&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>), (<span class="string">&#39;h&#39;</span>, <span class="string">&#39;i&#39;</span>), (<span class="string">&#39;r&#39;</span>, <span class="string">&#39;r&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, udifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>), (<span class="string">&#39;g&#39;</span>, <span class="string">&#39;i&#39;</span>), (<span class="string">&#39;r&#39;</span>, <span class="string">&#39;t&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;b&#39;</span>, <span class="string">&#39;d&#39;</span>), (<span class="string">&#39;e&#39;</span>, <span class="string">&#39;g&#39;</span>), (<span class="string">&#39;s&#39;</span>, <span class="string">&#39;u&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;a&#39;</span>), (<span class="string">&#39;h&#39;</span>, <span class="string">&#39;i&#39;</span>), (<span class="string">&#39;r&#39;</span>, <span class="string">&#39;r&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, udifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;x&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>), (<span class="string">&#39;e&#39;</span>, <span class="string">&#39;g&#39;</span>), (<span class="string">&#39;s&#39;</span>, <span class="string">&#39;u&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;x&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, udifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;c&#39;</span>), (<span class="string">&#39;e&#39;</span>, <span class="string">&#39;g&#39;</span>), (<span class="string">&#39;s&#39;</span>, <span class="string">&#39;u&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;d&#39;</span>, <span class="string">&#39;d&#39;</span>), (<span class="string">&#39;h&#39;</span>, <span class="string">&#39;r&#39;</span>), (<span class="string">&#39;v&#39;</span>, <span class="string">&#39;z&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, udifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_difference_bytes() {
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, bdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, bdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;b&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;z&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;y&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;m&#39;</span>, <span class="string">b&#39;m&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;l&#39;</span>), (<span class="string">b&#39;n&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>), (<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;i&#39;</span>), (<span class="string">b&#39;r&#39;</span>, <span class="string">b&#39;t&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[]);
<span class="macro">assert_eq!</span>(expected, bdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>), (<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;i&#39;</span>), (<span class="string">b&#39;r&#39;</span>, <span class="string">b&#39;t&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;d&#39;</span>, <span class="string">b&#39;v&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>), (<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;i&#39;</span>), (<span class="string">b&#39;r&#39;</span>, <span class="string">b&#39;t&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;b&#39;</span>, <span class="string">b&#39;g&#39;</span>), (<span class="string">b&#39;s&#39;</span>, <span class="string">b&#39;u&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>), (<span class="string">b&#39;h&#39;</span>, <span class="string">b&#39;i&#39;</span>), (<span class="string">b&#39;r&#39;</span>, <span class="string">b&#39;r&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>), (<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;i&#39;</span>), (<span class="string">b&#39;r&#39;</span>, <span class="string">b&#39;t&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;b&#39;</span>, <span class="string">b&#39;d&#39;</span>), (<span class="string">b&#39;e&#39;</span>, <span class="string">b&#39;g&#39;</span>), (<span class="string">b&#39;s&#39;</span>, <span class="string">b&#39;u&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;a&#39;</span>), (<span class="string">b&#39;h&#39;</span>, <span class="string">b&#39;i&#39;</span>), (<span class="string">b&#39;r&#39;</span>, <span class="string">b&#39;r&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;x&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>), (<span class="string">b&#39;e&#39;</span>, <span class="string">b&#39;g&#39;</span>), (<span class="string">b&#39;s&#39;</span>, <span class="string">b&#39;u&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;x&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;c&#39;</span>), (<span class="string">b&#39;e&#39;</span>, <span class="string">b&#39;g&#39;</span>), (<span class="string">b&#39;s&#39;</span>, <span class="string">b&#39;u&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;d&#39;</span>, <span class="string">b&#39;d&#39;</span>), (<span class="string">b&#39;h&#39;</span>, <span class="string">b&#39;r&#39;</span>), (<span class="string">b&#39;v&#39;</span>, <span class="string">b&#39;z&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_symmetric_difference_unicode() {
<span class="kw">let </span>cls1 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;m&#39;</span>)]);
<span class="kw">let </span>cls2 = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;g&#39;</span>, <span class="string">&#39;t&#39;</span>)]);
<span class="kw">let </span>expected = uclass(<span class="kw-2">&amp;</span>[(<span class="string">&#39;a&#39;</span>, <span class="string">&#39;f&#39;</span>), (<span class="string">&#39;n&#39;</span>, <span class="string">&#39;t&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, usymdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>class_symmetric_difference_bytes() {
<span class="kw">let </span>cls1 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;m&#39;</span>)]);
<span class="kw">let </span>cls2 = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;g&#39;</span>, <span class="string">b&#39;t&#39;</span>)]);
<span class="kw">let </span>expected = bclass(<span class="kw-2">&amp;</span>[(<span class="string">b&#39;a&#39;</span>, <span class="string">b&#39;f&#39;</span>), (<span class="string">b&#39;n&#39;</span>, <span class="string">b&#39;t&#39;</span>)]);
<span class="macro">assert_eq!</span>(expected, bsymdifference(<span class="kw-2">&amp;</span>cls1, <span class="kw-2">&amp;</span>cls2));
}
<span class="comment">// We use a thread with an explicit stack size to test that our destructor
// for Hir can handle arbitrarily sized expressions in constant stack
// space. In case we run on a platform without threads (WASM?), we limit
// this test to Windows/Unix.
</span><span class="attribute">#[test]
#[cfg(any(unix, windows))]
</span><span class="kw">fn </span>no_stack_overflow_on_drop() {
<span class="kw">use </span>std::thread;
<span class="kw">let </span>run = || {
<span class="kw">let </span><span class="kw-2">mut </span>expr = Hir::empty();
<span class="kw">for _ in </span><span class="number">0</span>..<span class="number">100 </span>{
expr = Hir::capture(Capture {
index: <span class="number">1</span>,
name: <span class="prelude-val">None</span>,
sub: Box::new(expr),
});
expr = Hir::repetition(Repetition {
min: <span class="number">0</span>,
max: <span class="prelude-val">Some</span>(<span class="number">1</span>),
greedy: <span class="bool-val">true</span>,
sub: Box::new(expr),
});
expr = Hir {
kind: HirKind::Concat(<span class="macro">vec!</span>[expr]),
props: Properties::empty(),
};
expr = Hir {
kind: HirKind::Alternation(<span class="macro">vec!</span>[expr]),
props: Properties::empty(),
};
}
<span class="macro">assert!</span>(!<span class="macro">matches!</span>(<span class="kw-2">*</span>expr.kind(), HirKind::Empty));
};
<span class="comment">// We run our test on a thread with a small stack size so we can
// force the issue more easily.
//
// NOTE(2023-03-21): See the corresponding test in &#39;crate::ast::tests&#39;
// for context on the specific stack size chosen here.
</span>thread::Builder::new()
.stack_size(<span class="number">16 </span>&lt;&lt; <span class="number">10</span>)
.spawn(run)
.unwrap()
.join()
.unwrap();
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>look_set_iter() {
<span class="kw">let </span>set = LookSet::empty();
<span class="macro">assert_eq!</span>(<span class="number">0</span>, set.iter().count());
<span class="kw">let </span>set = LookSet::full();
<span class="macro">assert_eq!</span>(<span class="number">10</span>, set.iter().count());
<span class="kw">let </span>set =
LookSet::empty().insert(Look::StartLF).insert(Look::WordUnicode);
<span class="macro">assert_eq!</span>(<span class="number">2</span>, set.iter().count());
<span class="kw">let </span>set = LookSet::empty().insert(Look::StartLF);
<span class="macro">assert_eq!</span>(<span class="number">1</span>, set.iter().count());
<span class="kw">let </span>set = LookSet::empty().insert(Look::WordAsciiNegate);
<span class="macro">assert_eq!</span>(<span class="number">1</span>, set.iter().count());
}
<span class="attribute">#[test]
</span><span class="kw">fn </span>look_set_debug() {
<span class="kw">let </span>res = <span class="macro">format!</span>(<span class="string">&quot;{:?}&quot;</span>, LookSet::empty());
<span class="macro">assert_eq!</span>(<span class="string">&quot;∅&quot;</span>, res);
<span class="kw">let </span>res = <span class="macro">format!</span>(<span class="string">&quot;{:?}&quot;</span>, LookSet::full());
<span class="macro">assert_eq!</span>(<span class="string">&quot;Az^$rRbB𝛃𝚩&quot;</span>, res);
}
}
</code></pre></div>
</section></div></main><div id="rustdoc-vars" data-root-path="../../../" data-current-crate="regex_syntax" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.66.0-nightly (5c8bff74b 2022-10-21)" ></div></body></html>